From 4dcc52327b52d043011c084e4ae8894b1f2d1481 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Thu, 10 Feb 2011 19:05:35 +0000 Subject: [PATCH] Fix problems in repository writer * actually write the checksum * compress the repository info archive, too (handle it as separate section) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40426 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/package/hpkg/RepositoryWriter.h | 7 +- .../package/hpkg/RepositoryWriterImpl.h | 8 +-- headers/private/package/hpkg/haiku_package.h | 20 +++--- src/bin/package_repo/command_create.cpp | 26 ++++--- .../package/hpkg/RepositoryWriterImpl.cpp | 70 ++++++++++++------- src/kits/package/hpkg/WriterImplBase.cpp | 10 +++ 6 files changed, 94 insertions(+), 47 deletions(-) diff --git a/headers/os/package/hpkg/RepositoryWriter.h b/headers/os/package/hpkg/RepositoryWriter.h index 102a44978b..854a43e579 100644 --- a/headers/os/package/hpkg/RepositoryWriter.h +++ b/headers/os/package/hpkg/RepositoryWriter.h @@ -36,9 +36,12 @@ public: virtual void OnPackageAdded( const BPackageInfo& packageInfo) = 0; - virtual void OnPackageAttributesSizeInfo(uint32 stringCount, + virtual void OnRepositoryInfoSectionDone( uint32 uncompressedSize) = 0; - virtual void OnRepositorySizeInfo(uint32 headerSize, + virtual void OnPackageAttributesSectionDone( + uint32 stringCount, + uint32 uncompressedSize) = 0; + virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoLength, uint32 packageCount, uint32 packageAttributesSize, diff --git a/headers/private/package/hpkg/RepositoryWriterImpl.h b/headers/private/package/hpkg/RepositoryWriterImpl.h index 6255921221..094e215b81 100644 --- a/headers/private/package/hpkg/RepositoryWriterImpl.h +++ b/headers/private/package/hpkg/RepositoryWriterImpl.h @@ -64,11 +64,11 @@ private: status_t _Finish(); status_t _RegisterCurrentPackageInfo(); - status_t _WriteRepositoryInfo( - ssize_t& _repositoryInfoLength); + status_t _WriteRepositoryInfo(hpkg_repo_header& header, + ssize_t& _infoLengthCompressed); off_t _WritePackageAttributes( - hpkg_repo_header& header, - off_t startOffset); + hpkg_repo_header& header, off_t startOffset, + ssize_t& _packagesLengthCompressed); struct PackageNameSet; diff --git a/headers/private/package/hpkg/haiku_package.h b/headers/private/package/hpkg/haiku_package.h index e111634248..364a4c8ef8 100644 --- a/headers/private/package/hpkg/haiku_package.h +++ b/headers/private/package/hpkg/haiku_package.h @@ -49,18 +49,19 @@ struct hpkg_repo_header { uint32 magic; // "hpkr" uint16 header_size; uint16 version; - uint64 total_size; + uint32 total_size; - // repository header - uint32 repository_header_length; + // repository info section + uint32 info_compression; + uint32 info_length_compressed; + uint32 info_length_uncompressed; // package attributes section - uint32 attributes_compression; - uint32 attributes_length_compressed; - uint32 attributes_length_uncompressed; - - uint64 attributes_strings_length; - uint64 attributes_strings_count; + uint32 packages_compression; + uint32 packages_length_compressed; + uint32 packages_length_uncompressed; + uint32 packages_strings_length; + uint32 packages_strings_count; }; @@ -148,6 +149,7 @@ enum HPKGPackageAttributeID { HPKG_PACKAGE_ATTRIBUTE_FRESHENS, HPKG_PACKAGE_ATTRIBUTE_REPLACES, HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR, + HPKG_PACKAGE_ATTRIBUTE_CHECKSUM, // HPKG_PACKAGE_ATTRIBUTE_ENUM_COUNT, }; diff --git a/src/bin/package_repo/command_create.cpp b/src/bin/package_repo/command_create.cpp index a5eeca4cce..98173f3442 100644 --- a/src/bin/package_repo/command_create.cpp +++ b/src/bin/package_repo/command_create.cpp @@ -48,9 +48,10 @@ public: printf("%s (%s)\n", packageInfo.Name().String(), packageInfo.Version().ToString().String()); if (fVerbose) { - printf("\tsummary: %s\n", packageInfo.Summary().String()); - printf("\tvendor: %s\n", packageInfo.Vendor().String()); - printf("\tpackager: %s\n", packageInfo.Packager().String()); + printf("\tsummary: %s\n", packageInfo.Summary().String()); + printf("\tvendor: %s\n", packageInfo.Vendor().String()); + printf("\tpackager: %s\n", packageInfo.Packager().String()); + printf("\tsha256-checksum: %s\n", packageInfo.Checksum().String()); if (uint32 flags = packageInfo.Flags()) { printf("\tflags:\n"); if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0) @@ -61,21 +62,30 @@ public: } } - virtual void OnPackageAttributesSizeInfo(uint32 stringCount, + virtual void OnRepositoryInfoSectionDone(uint32 uncompressedSize) + { + if (fQuiet || !fVerbose) + return; + + printf("----- Repository Info Section --------------------\n"); + printf("repository info size: %10lu (uncompressed)\n", + uncompressedSize); + } + + virtual void OnPackageAttributesSectionDone(uint32 stringCount, uint32 uncompressedSize) { if (fQuiet || !fVerbose) return; - printf("----- Package Attribute Info ---------------------\n"); + printf("----- Package Attribute Section -------------------\n"); printf("string count: %10lu\n", stringCount); printf("package attributes size: %10lu (uncompressed)\n", uncompressedSize); } - virtual void OnRepositorySizeInfo(uint32 headerSize, - uint32 repositoryInfoSize, uint32 packageCount, - uint32 packageAttributesSize, uint64 totalSize) + virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoSize, + uint32 packageCount, uint32 packageAttributesSize, uint64 totalSize) { if (fQuiet) return; diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp b/src/kits/package/hpkg/RepositoryWriterImpl.cpp index b904f8f99c..607a9bda9f 100644 --- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp +++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp @@ -228,28 +228,24 @@ RepositoryWriterImpl::_Finish() hpkg_repo_header header; // write repository header - ssize_t repositoryInfoLength; - status_t result = _WriteRepositoryInfo(repositoryInfoLength); + ssize_t infoLengthCompressed; + status_t result = _WriteRepositoryInfo(header, infoLengthCompressed); if (result != B_OK) return result; - header.repository_header_length - = B_HOST_TO_BENDIAN_INT32(repositoryInfoLength); - // write package attributes + ssize_t packagesLengthCompressed; off_t totalSize = _WritePackageAttributes(header, - sizeof(header) + repositoryInfoLength); + sizeof(header) + infoLengthCompressed, packagesLengthCompressed); - fListener->OnRepositorySizeInfo(sizeof(header), repositoryInfoLength, - fPackageCount, - B_BENDIAN_TO_HOST_INT32(header.attributes_length_compressed), - totalSize); + fListener->OnRepositoryDone(sizeof(header), infoLengthCompressed, + fPackageCount, packagesLengthCompressed, totalSize); // general header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_REPO_MAGIC); 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.total_size = B_HOST_TO_BENDIAN_INT32(totalSize); // write the header WriteBuffer(&header, sizeof(header), 0); @@ -350,7 +346,8 @@ RepositoryWriterImpl::_RegisterCurrentPackageInfo() status_t -RepositoryWriterImpl::_WriteRepositoryInfo(ssize_t& _repositoryInfoLength) +RepositoryWriterImpl::_WriteRepositoryInfo(hpkg_repo_header& header, + ssize_t& _infoLengthCompressed) { BMessage archive; status_t result = fRepositoryInfo->Archive(&archive); @@ -359,22 +356,45 @@ RepositoryWriterImpl::_WriteRepositoryInfo(ssize_t& _repositoryInfoLength) return result; } - _repositoryInfoLength = archive.FlattenedSize(); - char buffer[_repositoryInfoLength]; - if ((result = archive.Flatten(buffer, _repositoryInfoLength)) != B_OK) { + ssize_t flattenedSize = archive.FlattenedSize(); + char buffer[flattenedSize]; + if ((result = archive.Flatten(buffer, flattenedSize)) != B_OK) { fListener->PrintError("can't flatten repository header!\n"); return result; } off_t startOffset = sizeof(hpkg_repo_header); - WriteBuffer(buffer, _repositoryInfoLength, startOffset); + + // write the package attributes (zlib writer on top of a file writer) + FDDataWriter realWriter(FD(), startOffset, fListener); + ZlibDataWriter zlibWriter(&realWriter); + SetDataWriter(&zlibWriter); + zlibWriter.Init(); + + DataWriter()->WriteDataThrows(buffer, flattenedSize); + + zlibWriter.Finish(); + SetDataWriter(NULL); + + fListener->OnRepositoryInfoSectionDone(zlibWriter.BytesWritten()); + + _infoLengthCompressed = realWriter.BytesWritten(); + + // update the header + header.info_compression + = B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB); + header.info_length_compressed + = B_HOST_TO_BENDIAN_INT32(_infoLengthCompressed); + header.info_length_uncompressed + = B_HOST_TO_BENDIAN_INT32(flattenedSize); return B_OK; } + off_t RepositoryWriterImpl::_WritePackageAttributes(hpkg_repo_header& header, - off_t startOffset) + off_t startOffset, ssize_t& _packagesLengthCompressed) { // write the package attributes (zlib writer on top of a file writer) FDDataWriter realWriter(FD(), startOffset, fListener); @@ -391,18 +411,20 @@ RepositoryWriterImpl::_WritePackageAttributes(hpkg_repo_header& header, off_t endOffset = realWriter.Offset(); SetDataWriter(NULL); - fListener->OnPackageAttributesSizeInfo(stringsCount, + fListener->OnPackageAttributesSectionDone(stringsCount, zlibWriter.BytesWritten()); + _packagesLengthCompressed = endOffset - startOffset; + // update the header - header.attributes_compression + header.packages_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 + header.packages_length_compressed + = B_HOST_TO_BENDIAN_INT32(_packagesLengthCompressed); + header.packages_length_uncompressed = B_HOST_TO_BENDIAN_INT32(zlibWriter.BytesWritten()); - header.attributes_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount); - header.attributes_strings_length + header.packages_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount); + header.packages_strings_length = B_HOST_TO_BENDIAN_INT32(stringsLengthUncompressed); return endOffset; diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index b1e6bf4a2a..7758a031b3 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -479,6 +479,16 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, = fPackageStringCache.Get(replacesList.ItemAt(i)->String()); attributeList.Add(replaces); } + + // checksum (optional, only exists in repositories) + if (packageInfo.Checksum().Length() > 0) { + PackageAttribute* checksum = new PackageAttribute( + HPKG_PACKAGE_ATTRIBUTE_CHECKSUM, B_HPKG_ATTRIBUTE_TYPE_STRING, + B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + checksum->string + = fPackageStringCache.Get(packageInfo.Checksum().String()); + attributeList.Add(checksum); + } }