From 97aabbede911b549e50d7ad753b4755d5c8d85a7 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 3 Jul 2011 04:07:47 +0200 Subject: [PATCH] Add BLowLevelPackageContentHandler section hooks * Add hooks HandleSectionStart() and HandleSectionEnd(). They are invoked to bracket package file section, so the handler can discriminate which section the attributes belong to. HandleSectionStart() features a return parameter _handleSection, which allows to handler to pick which sections it wants to handle. * "package dump" does now print the section names. --- .../os/package/hpkg/PackageContentHandler.h | 6 +++ headers/private/package/hpkg/ReaderImplBase.h | 16 ++++-- src/bin/package/command_dump.cpp | 37 ++++++++++++++ src/kits/package/hpkg/PackageReaderImpl.cpp | 25 +++++++--- src/kits/package/hpkg/ReaderImplBase.cpp | 50 ++++++++++++++++--- .../package/hpkg/RepositoryReaderImpl.cpp | 8 +-- 6 files changed, 122 insertions(+), 20 deletions(-) diff --git a/headers/os/package/hpkg/PackageContentHandler.h b/headers/os/package/hpkg/PackageContentHandler.h index 2d421155d1..b09992b85c 100644 --- a/headers/os/package/hpkg/PackageContentHandler.h +++ b/headers/os/package/hpkg/PackageContentHandler.h @@ -26,6 +26,12 @@ class BLowLevelPackageContentHandler { public: virtual ~BLowLevelPackageContentHandler(); + virtual status_t HandleSectionStart( + BHPKGPackageSectionID sectionID, + bool& _handleSection) = 0; + virtual status_t HandleSectionEnd( + BHPKGPackageSectionID sectionID) = 0; + virtual status_t HandleAttribute(BHPKGAttributeID attributeID, const BPackageAttributeValue& value, void* parentToken, void*& _token) = 0; diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index a65a7c80bc..75273e92c2 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -51,11 +51,15 @@ protected: uint64 heapOffset; uint64 heapSize; - AttributeHandlerContext(BErrorOutput* errorOutput, - BPackageContentHandler* packageContentHandler); + BHPKGPackageSectionID section; AttributeHandlerContext(BErrorOutput* errorOutput, - BLowLevelPackageContentHandler* lowLevelHandler); + BPackageContentHandler* packageContentHandler, + BHPKGPackageSectionID section); + + AttributeHandlerContext(BErrorOutput* errorOutput, + BLowLevelPackageContentHandler* lowLevelHandler, + BHPKGPackageSectionID section); void ErrorOccurred(); }; @@ -200,7 +204,8 @@ protected: AttributeHandlerContext* context, AttributeHandler* rootAttributeHandler); status_t ParseAttributeTree( - AttributeHandlerContext* context); + AttributeHandlerContext* context, + bool& _sectionHandled); virtual status_t ReadAttributeValue(uint8 type, uint8 encoding, AttributeValue& _value); @@ -225,6 +230,9 @@ protected: SectionInfo fPackageAttributesSection; private: + status_t _ParseAttributeTree( + AttributeHandlerContext* context); + template inline status_t _Read(Type& _value); diff --git a/src/bin/package/command_dump.cpp b/src/bin/package/command_dump.cpp index c5387c31b6..fdf55d2d31 100644 --- a/src/bin/package/command_dump.cpp +++ b/src/bin/package/command_dump.cpp @@ -34,6 +34,43 @@ struct PackageContentDumpHandler : BLowLevelPackageContentHandler { { } + 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) { diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp b/src/kits/package/hpkg/PackageReaderImpl.cpp index fe08df212b..6f7b2986d8 100644 --- a/src/kits/package/hpkg/PackageReaderImpl.cpp +++ b/src/kits/package/hpkg/PackageReaderImpl.cpp @@ -587,12 +587,18 @@ PackageReaderImpl::Init(int fd, bool keepFD) status_t PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler) { - AttributeHandlerContext context(ErrorOutput(), contentHandler); + AttributeHandlerContext context(ErrorOutput(), contentHandler, + B_HPKG_SECTION_PACKAGE_ATTRIBUTES); RootAttributeHandler rootAttributeHandler; + status_t error = ParsePackageAttributesSection(&context, &rootAttributeHandler); - if (error == B_OK) + + if (error == B_OK) { + context.section = B_HPKG_SECTION_PACKAGE_TOC; error = _ParseTOC(&context, &rootAttributeHandler); + } + return error; } @@ -600,12 +606,18 @@ PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler) status_t PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler) { - AttributeHandlerContext context(ErrorOutput(), contentHandler); + AttributeHandlerContext context(ErrorOutput(), contentHandler, + B_HPKG_SECTION_PACKAGE_ATTRIBUTES); LowLevelAttributeHandler rootAttributeHandler; + status_t error = ParsePackageAttributesSection(&context, &rootAttributeHandler); - if (error == B_OK) + + if (error == B_OK) { + context.section = B_HPKG_SECTION_PACKAGE_TOC; error = _ParseTOC(&context, &rootAttributeHandler); + } + return error; } @@ -627,8 +639,9 @@ PackageReaderImpl::_ParseTOC(AttributeHandlerContext* context, ClearAttributeHandlerStack(); PushAttributeHandler(rootAttributeHandler); - status_t error = ParseAttributeTree(context); - if (error == B_OK) { + bool sectionHandled; + status_t error = ParseAttributeTree(context, sectionHandled); + if (error == B_OK && sectionHandled) { if (fTOCSection.currentOffset < fTOCSection.uncompressedLength) { ErrorOutput()->PrintError("Error: %llu excess byte(s) in TOC " "section\n", diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp b/src/kits/package/hpkg/ReaderImplBase.cpp index 8da4d32073..727991d764 100644 --- a/src/kits/package/hpkg/ReaderImplBase.cpp +++ b/src/kits/package/hpkg/ReaderImplBase.cpp @@ -38,21 +38,25 @@ static const size_t kScratchBufferSize = 64 * 1024; ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext( - BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler) + BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler, + BHPKGPackageSectionID section) : errorOutput(errorOutput), packageContentHandler(packageContentHandler), - hasLowLevelHandler(false) + hasLowLevelHandler(false), + section(section) { } ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext( - BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler) + BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler, + BHPKGPackageSectionID section) : errorOutput(errorOutput), lowLevelHandler(lowLevelHandler), - hasLowLevelHandler(true) + hasLowLevelHandler(true), + section(section) { } @@ -669,8 +673,9 @@ ReaderImplBase::ParsePackageAttributesSection( ClearAttributeHandlerStack(); PushAttributeHandler(rootAttributeHandler); - status_t error = ParseAttributeTree(context); - if (error == B_OK) { + bool sectionHandled; + status_t error = ParseAttributeTree(context, sectionHandled); + if (error == B_OK && sectionHandled) { if (fPackageAttributesSection.currentOffset < fPackageAttributesSection.uncompressedLength) { fErrorOutput->PrintError("Error: %llu excess byte(s) in package " @@ -698,7 +703,38 @@ ReaderImplBase::ParsePackageAttributesSection( status_t -ReaderImplBase::ParseAttributeTree(AttributeHandlerContext* context) +ReaderImplBase::ParseAttributeTree(AttributeHandlerContext* context, + bool& _sectionHandled) +{ + if (context->hasLowLevelHandler) { + bool handleSection = false; + status_t error = context->lowLevelHandler->HandleSectionStart( + context->section, handleSection); + if (error != B_OK) + return error; + + if (!handleSection) { + _sectionHandled = false; + return B_OK; + } + } + + status_t error = _ParseAttributeTree(context); + + if (context->hasLowLevelHandler) { + status_t endError = context->lowLevelHandler->HandleSectionEnd( + context->section); + if (error == B_OK) + error = endError; + } + + _sectionHandled = true; + return error; +} + + +status_t +ReaderImplBase::_ParseAttributeTree(AttributeHandlerContext* context) { int level = 0; diff --git a/src/kits/package/hpkg/RepositoryReaderImpl.cpp b/src/kits/package/hpkg/RepositoryReaderImpl.cpp index 253faffbcb..5f315a4000 100644 --- a/src/kits/package/hpkg/RepositoryReaderImpl.cpp +++ b/src/kits/package/hpkg/RepositoryReaderImpl.cpp @@ -254,11 +254,13 @@ RepositoryReaderImpl::GetRepositoryInfo(BRepositoryInfo* _repositoryInfo) const status_t RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler) { - AttributeHandlerContext context(ErrorOutput(), contentHandler); - PackageAttributeHandler rootAttributeHandler; status_t result = contentHandler->HandleRepositoryInfo(fRepositoryInfo); - if (result == B_OK) + if (result == B_OK) { + AttributeHandlerContext context(ErrorOutput(), contentHandler, + B_HPKG_SECTION_PACKAGE_ATTRIBUTES); + PackageAttributeHandler rootAttributeHandler; result = ParsePackageAttributesSection(&context, &rootAttributeHandler); + } return result; }