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:
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;

View File

@ -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<typename Type>
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,
const BPackageAttributeValue& value, void* parentToken, void*& _token)
{

View File

@ -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",

View File

@ -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;

View File

@ -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;
}