Package/repository file format: Add a minor version header field

* Add minor_version to hpkg_header and hpkg_repo_header and make
  heap_compression uint16.
* If the minor version of a package/repository file is greater than the
  current one unknown attributes are ignored without error. This allows
  introducing new harmless attributes without making the resulting files
  unreadable for older package kit versions.
This commit is contained in:
Ingo Weinhold 2013-05-22 00:20:13 +02:00
parent 5dae1541d6
commit 47039b852e
8 changed files with 48 additions and 16 deletions

View File

@ -16,11 +16,13 @@ namespace BHPKG {
// magic & version of package and repository files
enum {
B_HPKG_MAGIC = 'hpkg',
B_HPKG_VERSION = 2,
B_HPKG_MAGIC = 'hpkg',
B_HPKG_VERSION = 2,
B_HPKG_MINOR_VERSION = 0,
//
B_HPKG_REPO_MAGIC = 'hpkr',
B_HPKG_REPO_VERSION = 2
B_HPKG_REPO_MAGIC = 'hpkr',
B_HPKG_REPO_VERSION = 2,
B_HPKG_REPO_MINOR_VERSION = 0
};

View File

@ -24,9 +24,10 @@ struct hpkg_header {
uint16 header_size;
uint16 version;
uint64 total_size;
uint16 minor_version;
// heap
uint32 heap_compression;
uint16 heap_compression;
uint32 heap_chunk_size;
uint64 heap_size_compressed;
uint64 heap_size_uncompressed;
@ -50,9 +51,10 @@ struct hpkg_repo_header {
uint16 header_size;
uint16 version;
uint64 total_size;
uint16 minor_version;
// heap
uint32 heap_compression;
uint16 heap_compression;
uint32 heap_chunk_size;
uint64 heap_size_compressed;
uint64 heap_size_uncompressed;

View File

@ -72,6 +72,9 @@ protected:
BErrorOutput* ErrorOutput() const;
uint16 MinorFormatVersion() const
{ return fMinorFormatVersion; }
uint64 UncompressedHeapSize() const;
PackageFileHeapReader* RawHeapReader() const
@ -175,6 +178,7 @@ private:
BErrorOutput* fErrorOutput;
int fFD;
bool fOwnsFD;
uint16 fMinorFormatVersion;
PackageFileHeapReader* fRawHeapReader;
BAbstractBufferedDataReader* fHeapReader;
@ -199,7 +203,8 @@ public:
BLowLevelPackageContentHandler* lowLevelHandler;
};
bool hasLowLevelHandler;
bool ignoreUnknownAttributes;
BHPKGPackageSectionID section;
public:
@ -207,12 +212,14 @@ public:
BErrorOutput* errorOutput,
BPackageContentHandler*
packageContentHandler,
BHPKGPackageSectionID section);
BHPKGPackageSectionID section,
bool ignoreUnknownAttributes);
AttributeHandlerContext(
BErrorOutput* errorOutput,
BLowLevelPackageContentHandler*
lowLevelHandler,
BHPKGPackageSectionID section);
BHPKGPackageSectionID section,
bool ignoreUnknownAttributes);
void ErrorOccurred();
};
@ -375,6 +382,8 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags)
return B_MISMATCHED_VALUES;
}
fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
// header size
uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
if (heapOffset < (off_t)sizeof(header)) {
@ -405,7 +414,7 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags)
}
error = InitHeapReader(
B_BENDIAN_TO_HOST_INT32(header.heap_compression),
B_BENDIAN_TO_HOST_INT16(header.heap_compression),
B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
compressedHeapSize,
B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));

View File

@ -375,7 +375,8 @@ status_t
PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler)
{
AttributeHandlerContext context(ErrorOutput(), contentHandler,
B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
MinorFormatVersion() > B_HPKG_MINOR_VERSION);
RootAttributeHandler rootAttributeHandler;
status_t error
@ -394,7 +395,8 @@ status_t
PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler)
{
AttributeHandlerContext context(ErrorOutput(), contentHandler,
B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
MinorFormatVersion() > B_HPKG_MINOR_VERSION);
LowLevelAttributeHandler rootAttributeHandler;
status_t error

View File

@ -1077,7 +1077,7 @@ PackageWriterImpl::_Finish()
uint64 compressedHeapSize = fHeapWriter->CompressedHeapSize();
header.heap_compression = B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
header.heap_compression = B_HOST_TO_BENDIAN_INT16(B_HPKG_COMPRESSION_ZLIB);
header.heap_chunk_size = B_HOST_TO_BENDIAN_INT32(fHeapWriter->ChunkSize());
header.heap_size_compressed = B_HOST_TO_BENDIAN_INT64(
fHeapWriter->CompressedHeapSize());
@ -1104,6 +1104,7 @@ PackageWriterImpl::_Finish()
header.header_size = B_HOST_TO_BENDIAN_INT16(fHeaderSize);
header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_VERSION);
header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);
header.minor_version = B_HOST_TO_BENDIAN_INT16(B_HPKG_MINOR_VERSION);
// write the header
RawWriteBuffer(&header, sizeof(hpkg_header), 0);

View File

@ -39,11 +39,12 @@ static const size_t kScratchBufferSize = 64 * 1024;
ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
BErrorOutput* errorOutput, BPackageContentHandler* packageContentHandler,
BHPKGPackageSectionID section)
BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
:
errorOutput(errorOutput),
packageContentHandler(packageContentHandler),
hasLowLevelHandler(false),
ignoreUnknownAttributes(ignoreUnknownAttributes),
section(section)
{
}
@ -51,11 +52,12 @@ ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
BErrorOutput* errorOutput, BLowLevelPackageContentHandler* lowLevelHandler,
BHPKGPackageSectionID section)
BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
:
errorOutput(errorOutput),
lowLevelHandler(lowLevelHandler),
hasLowLevelHandler(true),
ignoreUnknownAttributes(ignoreUnknownAttributes),
section(section)
{
}
@ -140,6 +142,9 @@ ReaderImplBase::PackageVersionAttributeHandler::HandleAttribute(
break;
default:
if (context->ignoreUnknownAttributes)
break;
context->errorOutput->PrintError("Error: Invalid package "
"attribute section: unexpected package attribute id %d "
"encountered when parsing package version\n", id);
@ -212,6 +217,9 @@ ReaderImplBase::PackageResolvableAttributeHandler::HandleAttribute(
break;
default:
if (context->ignoreUnknownAttributes)
break;
context->errorOutput->PrintError("Error: Invalid package "
"attribute section: unexpected package attribute id %d "
"encountered when parsing package resolvable\n", id);
@ -281,6 +289,9 @@ ReaderImplBase::PackageResolvableExpressionAttributeHandler::HandleAttribute(
return B_OK;
default:
if (context->ignoreUnknownAttributes)
break;
context->errorOutput->PrintError("Error: Invalid package "
"attribute section: unexpected package attribute id %d "
"encountered when parsing package resolvable-expression\n",
@ -445,6 +456,9 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute(
break;
default:
if (context->ignoreUnknownAttributes)
break;
context->errorOutput->PrintError(
"Error: Invalid package attribute section: unexpected "
"package attribute id %d encountered\n", id);

View File

@ -141,7 +141,8 @@ RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler)
status_t result = contentHandler->HandleRepositoryInfo(fRepositoryInfo);
if (result == B_OK) {
AttributeHandlerContext context(ErrorOutput(), contentHandler,
B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
MinorFormatVersion() > B_HPKG_REPO_MINOR_VERSION);
PackageAttributeHandler rootAttributeHandler;
result = ParsePackageAttributesSection(&context, &rootAttributeHandler);
}

View File

@ -285,6 +285,7 @@ RepositoryWriterImpl::_Finish()
header.header_size = B_HOST_TO_BENDIAN_INT16((uint16)sizeof(header));
header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_REPO_VERSION);
header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);
header.minor_version = B_HOST_TO_BENDIAN_INT16(B_HPKG_REPO_MINOR_VERSION);
RawWriteBuffer(&header, sizeof(header), 0);