Write uncompressed package attributes if necessary
When compression doesn't save space, using it nonetheless results in a file that the reader complains about. So we fall back to writing an uncompressed package attributes section in such a case. The same still needs to be done for the TOC section.
This commit is contained in:
parent
443be501c0
commit
de9e64b235
@ -65,6 +65,12 @@ private:
|
||||
void _WriteAttributeChildren(Attribute* attribute);
|
||||
|
||||
void _WritePackageAttributes(hpkg_header& header);
|
||||
uint32 _WritePackageAttributesCompressed(
|
||||
uint32& _stringsLengthUncompressed,
|
||||
uint32& _attributesLengthUncompressed);
|
||||
uint32 _WritePackageAttributesUncompressed(
|
||||
uint32& _stringsLengthUncompressed,
|
||||
uint32& _attributesLengthUncompressed);
|
||||
|
||||
void _AddEntry(int dirFD, Entry* entry,
|
||||
const char* fileName, char* pathBuffer);
|
||||
|
@ -640,35 +640,81 @@ PackageWriterImpl::_WritePackageAttributes(hpkg_header& header)
|
||||
{
|
||||
// write the package attributes (zlib writer on top of a file writer)
|
||||
off_t startOffset = fHeapEnd;
|
||||
|
||||
uint32 compression = B_HPKG_COMPRESSION_ZLIB;
|
||||
uint32 stringsLengthUncompressed;
|
||||
uint32 attributesLengthUncompressed;
|
||||
uint32 stringsCount = _WritePackageAttributesCompressed(
|
||||
stringsLengthUncompressed, attributesLengthUncompressed);
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
|
||||
if ((off_t)attributesLengthUncompressed <= endOffset - startOffset) {
|
||||
// the compressed section isn't shorter -- write uncompressed
|
||||
fHeapEnd = startOffset;
|
||||
compression = B_HPKG_COMPRESSION_NONE;
|
||||
stringsCount = _WritePackageAttributesUncompressed(
|
||||
stringsLengthUncompressed, attributesLengthUncompressed);
|
||||
|
||||
endOffset = fHeapEnd;
|
||||
}
|
||||
|
||||
fListener->OnPackageAttributesSizeInfo(stringsCount,
|
||||
attributesLengthUncompressed);
|
||||
|
||||
// update the header
|
||||
header.attributes_compression = B_HOST_TO_BENDIAN_INT32(compression);
|
||||
header.attributes_length_compressed
|
||||
= B_HOST_TO_BENDIAN_INT32(endOffset - startOffset);
|
||||
header.attributes_length_uncompressed
|
||||
= B_HOST_TO_BENDIAN_INT32(attributesLengthUncompressed);
|
||||
header.attributes_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount);
|
||||
header.attributes_strings_length
|
||||
= B_HOST_TO_BENDIAN_INT32(stringsLengthUncompressed);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
PackageWriterImpl::_WritePackageAttributesCompressed(
|
||||
uint32& _stringsLengthUncompressed, uint32& _attributesLengthUncompressed)
|
||||
{
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(FD(), startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
SetDataWriter(&zlibWriter);
|
||||
zlibWriter.Init();
|
||||
|
||||
// write cached strings and package attributes tree
|
||||
uint32 stringsLengthUncompressed;
|
||||
uint32 stringsCount = WritePackageAttributes(PackageAttributes(),
|
||||
stringsLengthUncompressed);
|
||||
_stringsLengthUncompressed);
|
||||
|
||||
zlibWriter.Finish();
|
||||
fHeapEnd = realWriter.Offset();
|
||||
SetDataWriter(NULL);
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
_attributesLengthUncompressed = zlibWriter.BytesWritten();
|
||||
return stringsCount;
|
||||
}
|
||||
|
||||
fListener->OnPackageAttributesSizeInfo(stringsCount,
|
||||
zlibWriter.BytesWritten());
|
||||
|
||||
// update the header
|
||||
header.attributes_compression
|
||||
= B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
|
||||
header.attributes_length_compressed
|
||||
= B_HOST_TO_BENDIAN_INT32(endOffset - startOffset);
|
||||
header.attributes_length_uncompressed
|
||||
= B_HOST_TO_BENDIAN_INT32(zlibWriter.BytesWritten());
|
||||
header.attributes_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount);
|
||||
header.attributes_strings_length
|
||||
= B_HOST_TO_BENDIAN_INT32(stringsLengthUncompressed);
|
||||
uint32
|
||||
PackageWriterImpl::_WritePackageAttributesUncompressed(
|
||||
uint32& _stringsLengthUncompressed, uint32& _attributesLengthUncompressed)
|
||||
{
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(FD(), startOffset, fListener);
|
||||
|
||||
SetDataWriter(&realWriter);
|
||||
|
||||
// write cached strings and package attributes tree
|
||||
uint32 stringsCount = WritePackageAttributes(PackageAttributes(),
|
||||
_stringsLengthUncompressed);
|
||||
|
||||
fHeapEnd = realWriter.Offset();
|
||||
SetDataWriter(NULL);
|
||||
|
||||
_attributesLengthUncompressed = realWriter.BytesWritten();
|
||||
return stringsCount;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user