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.
This commit is contained in:
Ingo Weinhold 2011-07-03 04:07:47 +02:00
parent b3211314fc
commit 97aabbede9
6 changed files with 122 additions and 20 deletions

View File

@ -26,6 +26,12 @@ class BLowLevelPackageContentHandler {
public: public:
virtual ~BLowLevelPackageContentHandler(); virtual ~BLowLevelPackageContentHandler();
virtual status_t HandleSectionStart(
BHPKGPackageSectionID sectionID,
bool& _handleSection) = 0;
virtual status_t HandleSectionEnd(
BHPKGPackageSectionID sectionID) = 0;
virtual status_t HandleAttribute(BHPKGAttributeID attributeID, virtual status_t HandleAttribute(BHPKGAttributeID attributeID,
const BPackageAttributeValue& value, const BPackageAttributeValue& value,
void* parentToken, void*& _token) = 0; void* parentToken, void*& _token) = 0;

View File

@ -51,11 +51,15 @@ protected:
uint64 heapOffset; uint64 heapOffset;
uint64 heapSize; uint64 heapSize;
AttributeHandlerContext(BErrorOutput* errorOutput, BHPKGPackageSectionID section;
BPackageContentHandler* packageContentHandler);
AttributeHandlerContext(BErrorOutput* errorOutput, AttributeHandlerContext(BErrorOutput* errorOutput,
BLowLevelPackageContentHandler* lowLevelHandler); BPackageContentHandler* packageContentHandler,
BHPKGPackageSectionID section);
AttributeHandlerContext(BErrorOutput* errorOutput,
BLowLevelPackageContentHandler* lowLevelHandler,
BHPKGPackageSectionID section);
void ErrorOccurred(); void ErrorOccurred();
}; };
@ -200,7 +204,8 @@ protected:
AttributeHandlerContext* context, AttributeHandlerContext* context,
AttributeHandler* rootAttributeHandler); AttributeHandler* rootAttributeHandler);
status_t ParseAttributeTree( status_t ParseAttributeTree(
AttributeHandlerContext* context); AttributeHandlerContext* context,
bool& _sectionHandled);
virtual status_t ReadAttributeValue(uint8 type, uint8 encoding, virtual status_t ReadAttributeValue(uint8 type, uint8 encoding,
AttributeValue& _value); AttributeValue& _value);
@ -225,6 +230,9 @@ protected:
SectionInfo fPackageAttributesSection; SectionInfo fPackageAttributesSection;
private: private:
status_t _ParseAttributeTree(
AttributeHandlerContext* context);
template<typename Type> template<typename Type>
inline status_t _Read(Type& _value); inline status_t _Read(Type& _value);

View File

@ -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 = "<unknown section>";
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, virtual status_t HandleAttribute(BHPKGAttributeID attributeID,
const BPackageAttributeValue& value, void* parentToken, void*& _token) const BPackageAttributeValue& value, void* parentToken, void*& _token)
{ {

View File

@ -587,12 +587,18 @@ PackageReaderImpl::Init(int fd, bool keepFD)
status_t status_t
PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler) PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler)
{ {
AttributeHandlerContext context(ErrorOutput(), contentHandler); AttributeHandlerContext context(ErrorOutput(), contentHandler,
B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
RootAttributeHandler rootAttributeHandler; RootAttributeHandler rootAttributeHandler;
status_t error status_t error
= ParsePackageAttributesSection(&context, &rootAttributeHandler); = ParsePackageAttributesSection(&context, &rootAttributeHandler);
if (error == B_OK)
if (error == B_OK) {
context.section = B_HPKG_SECTION_PACKAGE_TOC;
error = _ParseTOC(&context, &rootAttributeHandler); error = _ParseTOC(&context, &rootAttributeHandler);
}
return error; return error;
} }
@ -600,12 +606,18 @@ PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler)
status_t status_t
PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler) PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler)
{ {
AttributeHandlerContext context(ErrorOutput(), contentHandler); AttributeHandlerContext context(ErrorOutput(), contentHandler,
B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
LowLevelAttributeHandler rootAttributeHandler; LowLevelAttributeHandler rootAttributeHandler;
status_t error status_t error
= ParsePackageAttributesSection(&context, &rootAttributeHandler); = ParsePackageAttributesSection(&context, &rootAttributeHandler);
if (error == B_OK)
if (error == B_OK) {
context.section = B_HPKG_SECTION_PACKAGE_TOC;
error = _ParseTOC(&context, &rootAttributeHandler); error = _ParseTOC(&context, &rootAttributeHandler);
}
return error; return error;
} }
@ -627,8 +639,9 @@ PackageReaderImpl::_ParseTOC(AttributeHandlerContext* context,
ClearAttributeHandlerStack(); ClearAttributeHandlerStack();
PushAttributeHandler(rootAttributeHandler); PushAttributeHandler(rootAttributeHandler);
status_t error = ParseAttributeTree(context); bool sectionHandled;
if (error == B_OK) { status_t error = ParseAttributeTree(context, sectionHandled);
if (error == B_OK && sectionHandled) {
if (fTOCSection.currentOffset < fTOCSection.uncompressedLength) { if (fTOCSection.currentOffset < fTOCSection.uncompressedLength) {
ErrorOutput()->PrintError("Error: %llu excess byte(s) in TOC " ErrorOutput()->PrintError("Error: %llu excess byte(s) in TOC "
"section\n", "section\n",

View File

@ -38,21 +38,25 @@ static const size_t kScratchBufferSize = 64 * 1024;
ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext( ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler) BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler,
BHPKGPackageSectionID section)
: :
errorOutput(errorOutput), errorOutput(errorOutput),
packageContentHandler(packageContentHandler), packageContentHandler(packageContentHandler),
hasLowLevelHandler(false) hasLowLevelHandler(false),
section(section)
{ {
} }
ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext( ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler) BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler,
BHPKGPackageSectionID section)
: :
errorOutput(errorOutput), errorOutput(errorOutput),
lowLevelHandler(lowLevelHandler), lowLevelHandler(lowLevelHandler),
hasLowLevelHandler(true) hasLowLevelHandler(true),
section(section)
{ {
} }
@ -669,8 +673,9 @@ ReaderImplBase::ParsePackageAttributesSection(
ClearAttributeHandlerStack(); ClearAttributeHandlerStack();
PushAttributeHandler(rootAttributeHandler); PushAttributeHandler(rootAttributeHandler);
status_t error = ParseAttributeTree(context); bool sectionHandled;
if (error == B_OK) { status_t error = ParseAttributeTree(context, sectionHandled);
if (error == B_OK && sectionHandled) {
if (fPackageAttributesSection.currentOffset if (fPackageAttributesSection.currentOffset
< fPackageAttributesSection.uncompressedLength) { < fPackageAttributesSection.uncompressedLength) {
fErrorOutput->PrintError("Error: %llu excess byte(s) in package " fErrorOutput->PrintError("Error: %llu excess byte(s) in package "
@ -698,7 +703,38 @@ ReaderImplBase::ParsePackageAttributesSection(
status_t 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; int level = 0;

View File

@ -254,11 +254,13 @@ RepositoryReaderImpl::GetRepositoryInfo(BRepositoryInfo* _repositoryInfo) const
status_t status_t
RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler) RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler)
{ {
AttributeHandlerContext context(ErrorOutput(), contentHandler);
PackageAttributeHandler rootAttributeHandler;
status_t result = contentHandler->HandleRepositoryInfo(fRepositoryInfo); 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); result = ParsePackageAttributesSection(&context, &rootAttributeHandler);
}
return result; return result;
} }