/* * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "package.h" using namespace BPackageKit::BHPKG; struct PackageContentDumpHandler : BLowLevelPackageContentHandler { PackageContentDumpHandler() : fLevel(0), fErrorOccurred(false), fHasChildren(false) { } virtual status_t HandleSectionStart(BHPKGPackageSectionID sectionID, bool& _handleSection) { const char* sectionName; switch (sectionID) { case B_HPKG_SECTION_HEADER: sectionName = "header"; break; case B_HPKG_SECTION_HEAP: sectionName = "heap"; break; case B_HPKG_SECTION_PACKAGE_TOC: sectionName = "TOC"; break; case B_HPKG_SECTION_PACKAGE_ATTRIBUTES: sectionName = "package attributes"; break; case B_HPKG_SECTION_REPOSITORY_INFO: sectionName = "repository info"; break; default: sectionName = ""; break; } printf("\n==== SECTION: %s ====\n", sectionName); _handleSection = true; return B_OK; } virtual status_t HandleSectionEnd(BHPKGPackageSectionID sectionID) { return B_OK; } virtual status_t HandleAttribute(BHPKGAttributeID attributeID, const BPackageAttributeValue& value, void* parentToken, void*& _token) { if (fErrorOccurred) return B_OK; printf("%*s>%s: ", fLevel * 2, "", AttributeNameForID(attributeID)); _PrintValue(value); printf("\n"); fHasChildren = false; fLevel++; return B_OK; } virtual status_t HandleAttributeDone(BHPKGAttributeID attributeID, const BPackageAttributeValue& value, void* parentToken, void* token) { if (fErrorOccurred) return B_OK; fLevel--; if (fHasChildren) printf("%*s<%s\n", fLevel * 2, "", AttributeNameForID(attributeID)); fHasChildren = true; return B_OK; } virtual void HandleErrorOccurred() { fErrorOccurred = true; } private: void _PrintValue(const BPackageAttributeValue& value) { switch (value.type) { case B_HPKG_ATTRIBUTE_TYPE_INT: printf("%lld (%#llx)", (long long)value.signedInt, (long long)value.signedInt); break; case B_HPKG_ATTRIBUTE_TYPE_UINT: printf("%llu (%#llx)", (unsigned long long)value.unsignedInt, (unsigned long long)value.unsignedInt); break; case B_HPKG_ATTRIBUTE_TYPE_STRING: printf("\"%s\"", value.string); break; case B_HPKG_ATTRIBUTE_TYPE_RAW: switch (value.encoding) { case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE: printf("data: size: %llu, inline", (unsigned long long)value.data.size); // TODO: Print the data bytes! break; case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP: printf("data: size: %llu, offset: %llu", (unsigned long long)value.data.size, (unsigned long long)value.data.offset); break; default: break; } break; default: printf("\n", value.type); break; } } private: int fLevel; bool fErrorOccurred; bool fHasChildren; }; int command_dump(int argc, const char* const* argv) { while (true) { static struct option sLongOptions[] = { { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; opterr = 0; // don't print errors int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL); if (c == -1) break; switch (c) { case 'h': print_usage_and_exit(false); break; default: print_usage_and_exit(true); break; } } // One argument should remain -- the package file name. if (optind + 1 != argc) print_usage_and_exit(true); const char* packageFileName = argv[optind++]; // open package BStandardErrorOutput errorOutput; BPackageReader packageReader(&errorOutput); status_t error = packageReader.Init(packageFileName); if (error != B_OK) return 1; // list PackageContentDumpHandler handler; error = packageReader.ParseContent(&handler); if (error != B_OK) return 1; return 0; }