Write uncompressed package file TOC, if necessary

This commit is contained in:
Ingo Weinhold 2011-07-03 04:46:26 +02:00
parent 2fac6eaa60
commit 8ffba2a6cb
2 changed files with 71 additions and 18 deletions

View File

@ -79,6 +79,14 @@ private:
void _AttributeRemoved(Attribute* attribute); void _AttributeRemoved(Attribute* attribute);
void _WriteTOC(hpkg_header& header); void _WriteTOC(hpkg_header& header);
int32 _WriteTOCCompressed(
uint64& _uncompressedStringsSize,
uint64& _uncompressedMainSize,
uint64& _tocUncompressedSize);
int32 _WriteTOCUncompressed(
uint64& _uncompressedStringsSize,
uint64& _uncompressedMainSize,
uint64& _tocUncompressedSize);
int32 _WriteTOCSections(uint64& _stringsSize, int32 _WriteTOCSections(uint64& _stringsSize,
uint64& _mainSize); uint64& _mainSize);
void _WriteAttributeChildren(Attribute* attribute); void _WriteAttributeChildren(Attribute* attribute);

View File

@ -1316,40 +1316,85 @@ PackageWriterImpl::_WriteTOC(hpkg_header& header)
{ {
// prepare the writer (zlib writer on top of a file writer) // prepare the writer (zlib writer on top of a file writer)
off_t startOffset = fHeapEnd; off_t startOffset = fHeapEnd;
FDDataWriter realWriter(FD(), startOffset, fListener);
// write the sections
uint32 compression = B_HPKG_COMPRESSION_ZLIB;
uint64 uncompressedStringsSize;
uint64 uncompressedMainSize;
uint64 tocUncompressedSize;
int32 cachedStringsWritten = _WriteTOCCompressed(uncompressedStringsSize,
uncompressedMainSize, tocUncompressedSize);
off_t endOffset = fHeapEnd;
if (endOffset - startOffset >= (off_t)tocUncompressedSize) {
// the compressed section isn't shorter -- write uncompressed
fHeapEnd = startOffset;
compression = B_HPKG_COMPRESSION_NONE;
cachedStringsWritten = _WriteTOCUncompressed(uncompressedStringsSize,
uncompressedMainSize, tocUncompressedSize);
endOffset = fHeapEnd;
}
fListener->OnTOCSizeInfo(uncompressedStringsSize, uncompressedMainSize,
tocUncompressedSize);
// update the header
// TOC
header.toc_compression = B_HOST_TO_BENDIAN_INT32(compression);
header.toc_length_compressed = B_HOST_TO_BENDIAN_INT64(
endOffset - startOffset);
header.toc_length_uncompressed = B_HOST_TO_BENDIAN_INT64(
tocUncompressedSize);
// TOC subsections
header.toc_strings_length = B_HOST_TO_BENDIAN_INT64(
uncompressedStringsSize);
header.toc_strings_count = B_HOST_TO_BENDIAN_INT64(cachedStringsWritten);
}
int32
PackageWriterImpl::_WriteTOCCompressed(uint64& _uncompressedStringsSize,
uint64& _uncompressedMainSize, uint64& _tocUncompressedSize)
{
FDDataWriter realWriter(FD(), fHeapEnd, fListener);
ZlibDataWriter zlibWriter(&realWriter); ZlibDataWriter zlibWriter(&realWriter);
SetDataWriter(&zlibWriter); SetDataWriter(&zlibWriter);
zlibWriter.Init(); zlibWriter.Init();
// write the sections // write the sections
uint64 uncompressedStringsSize;
uint64 uncompressedMainSize;
int32 cachedStringsWritten int32 cachedStringsWritten
= _WriteTOCSections(uncompressedStringsSize, uncompressedMainSize); = _WriteTOCSections(_uncompressedStringsSize, _uncompressedMainSize);
// finish the writer // finish the writer
zlibWriter.Finish(); zlibWriter.Finish();
fHeapEnd = realWriter.Offset(); fHeapEnd = realWriter.Offset();
SetDataWriter(NULL); SetDataWriter(NULL);
off_t endOffset = fHeapEnd; _tocUncompressedSize = zlibWriter.BytesWritten();
return cachedStringsWritten;
}
fListener->OnTOCSizeInfo(uncompressedStringsSize, uncompressedMainSize,
zlibWriter.BytesWritten());
// update the header int32
PackageWriterImpl::_WriteTOCUncompressed(uint64& _uncompressedStringsSize,
uint64& _uncompressedMainSize, uint64& _tocUncompressedSize)
{
FDDataWriter realWriter(FD(), fHeapEnd, fListener);
SetDataWriter(&realWriter);
// TOC // write the sections
header.toc_compression = B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB); int32 cachedStringsWritten
header.toc_length_compressed = B_HOST_TO_BENDIAN_INT64( = _WriteTOCSections(_uncompressedStringsSize, _uncompressedMainSize);
endOffset - startOffset);
header.toc_length_uncompressed = B_HOST_TO_BENDIAN_INT64(
zlibWriter.BytesWritten());
// TOC subsections fHeapEnd = realWriter.Offset();
header.toc_strings_length = B_HOST_TO_BENDIAN_INT64( SetDataWriter(NULL);
uncompressedStringsSize);
header.toc_strings_count = B_HOST_TO_BENDIAN_INT64(cachedStringsWritten); _tocUncompressedSize = realWriter.BytesWritten();
return cachedStringsWritten;
} }