Author: zooey Date: 2011-02-14 18:24:50 +0100 (Mon, 14 Feb 2011) New Revision: 40491 Changeset: http://dev.haiku-os.org/changeset/40491 Modified: haiku/trunk/headers/os/package/hpkg/RepositoryWriter.h haiku/trunk/headers/private/package/hpkg/RepositoryWriterImpl.h haiku/trunk/src/bin/package_repo/command_create.cpp haiku/trunk/src/kits/package/hpkg/RepositoryWriter.cpp haiku/trunk/src/kits/package/hpkg/RepositoryWriterImpl.cpp Log: * added embedding of license texts that need approval into repository Modified: haiku/trunk/headers/os/package/hpkg/RepositoryWriter.h =================================================================== --- haiku/trunk/headers/os/package/hpkg/RepositoryWriter.h 2011-02-14 17:23:43 UTC (rev 40490) +++ haiku/trunk/headers/os/package/hpkg/RepositoryWriter.h 2011-02-14 17:24:50 UTC (rev 40491) @@ -43,6 +43,7 @@ uint32 uncompressedSize) = 0; virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoLength, + uint32 licenseCount, uint32 packageCount, uint32 packageAttributesSize, uint64 totalSize) = 0; @@ -54,7 +55,7 @@ public: BRepositoryWriter( BRepositoryWriterListener* listener, - const BRepositoryInfo* repositoryInfo); + BRepositoryInfo* repositoryInfo); ~BRepositoryWriter(); status_t Init(const char* fileName); Modified: haiku/trunk/headers/private/package/hpkg/RepositoryWriterImpl.h =================================================================== --- haiku/trunk/headers/private/package/hpkg/RepositoryWriterImpl.h 2011-02-14 17:23:43 UTC (rev 40490) +++ haiku/trunk/headers/private/package/hpkg/RepositoryWriterImpl.h 2011-02-14 17:24:50 UTC (rev 40491) @@ -30,14 +30,13 @@ struct hpkg_header; -class RepositoryWriterImpl - : public WriterImplBase, private BPackageContentHandler { +class RepositoryWriterImpl : public WriterImplBase { typedef WriterImplBase inherited; public: RepositoryWriterImpl( BRepositoryWriterListener* listener, - const BRepositoryInfo* repositoryInfo); + BRepositoryInfo* repositoryInfo); ~RepositoryWriterImpl(); status_t Init(const char* fileName); @@ -45,20 +44,6 @@ status_t Finish(); private: - // BPackageContentHandler - virtual status_t HandleEntry(BPackageEntry* entry); - virtual status_t HandleEntryAttribute(BPackageEntry* entry, - BPackageEntryAttribute* attribute); - virtual status_t HandleEntryDone(BPackageEntry* entry); - - virtual status_t HandlePackageAttribute( - const BPackageInfoAttributeValue& value - ); - virtual status_t HandlePackageAttributesDone(); - - virtual void HandleErrorOccurred(); - -private: status_t _Init(const char* fileName); status_t _AddPackage(const BEntry& packageEntry); status_t _Finish(); @@ -75,7 +60,7 @@ private: BRepositoryWriterListener* fListener; - const BRepositoryInfo* fRepositoryInfo; + BRepositoryInfo* fRepositoryInfo; BPackageInfo fPackageInfo; uint32 fPackageCount; Modified: haiku/trunk/src/bin/package_repo/command_create.cpp =================================================================== --- haiku/trunk/src/bin/package_repo/command_create.cpp 2011-02-14 17:23:43 UTC (rev 40490) +++ haiku/trunk/src/bin/package_repo/command_create.cpp 2011-02-14 17:24:50 UTC (rev 40491) @@ -85,12 +85,15 @@ } virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoSize, - uint32 packageCount, uint32 packageAttributesSize, uint64 totalSize) + uint32 licenseCount, uint32 packageCount, uint32 packageAttributesSize, + uint64 totalSize) { if (fQuiet) return; printf("----- Package Repository Info -----\n"); + if (fVerbose) + printf("embedded license count %10lu\n", licenseCount); printf("package count %10lu\n", packageCount); printf("-----------------------------------\n"); printf("header size: %10lu\n", headerSize); Modified: haiku/trunk/src/kits/package/hpkg/RepositoryWriter.cpp =================================================================== --- haiku/trunk/src/kits/package/hpkg/RepositoryWriter.cpp 2011-02-14 17:23:43 UTC (rev 40490) +++ haiku/trunk/src/kits/package/hpkg/RepositoryWriter.cpp 2011-02-14 17:24:50 UTC (rev 40491) @@ -18,7 +18,7 @@ BRepositoryWriter::BRepositoryWriter(BRepositoryWriterListener* listener, - const BRepositoryInfo* repositoryInfo) + BRepositoryInfo* repositoryInfo) : fImpl(new (std::nothrow) RepositoryWriterImpl(listener, repositoryInfo)) { Modified: haiku/trunk/src/kits/package/hpkg/RepositoryWriterImpl.cpp =================================================================== --- haiku/trunk/src/kits/package/hpkg/RepositoryWriterImpl.cpp 2011-02-14 17:23:43 UTC (rev 40490) +++ haiku/trunk/src/kits/package/hpkg/RepositoryWriterImpl.cpp 2011-02-14 17:24:50 UTC (rev 40491) @@ -14,9 +14,14 @@ #include <Message.h> #include <Path.h> +#include <AutoDeleter.h> + #include <package/hpkg/HPKGDefsPrivate.h> +#include <package/hpkg/PackageDataReader.h> +#include <package/hpkg/PackageEntry.h> #include <package/hpkg/PackageInfoAttributeValue.h> #include <package/hpkg/PackageReader.h> +#include <package/BlockBufferCacheNoLock.h> #include <package/ChecksumAccessors.h> #include <package/RepositoryInfo.h> @@ -31,12 +36,230 @@ using BPackageKit::BPrivate::GeneralFileChecksumAccessor; +namespace { + + +struct PackageEntryDataFetcher { + PackageEntryDataFetcher(BErrorOutput* errorOutput, + BPackageData& packageData) + : + fErrorOutput(errorOutput), + fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2), + fPackageData(packageData) + { + } + + status_t ReadIntoString(BDataReader* dataReader, BString& _contents) + { + // create a BPackageDataReader + BPackageDataReader* reader; + status_t result = BPackageDataReaderFactory(&fBufferCache) + .CreatePackageDataReader(dataReader, fPackageData, reader); + if (result != B_OK) + return result; + ObjectDeleter<BPackageDataReader> readerDeleter(reader); + + // copy data into the given string + int32 bufferSize = fPackageData.UncompressedSize(); + char* buffer = _contents.LockBuffer(bufferSize); + if (buffer == NULL) + return B_NO_MEMORY; + + result = reader->ReadData(0, buffer, bufferSize); + if (result != B_OK) { + fErrorOutput->PrintError("Error: Failed to read data: %s\n", + strerror(result)); + _contents.UnlockBuffer(0); + } else + _contents.UnlockBuffer(bufferSize); + + return result; + } + +private: + BErrorOutput* fErrorOutput; + BBlockBufferCacheNoLock fBufferCache; + BPackageData& fPackageData; +}; + + +struct PackageContentHandler : public BPackageContentHandler { + PackageContentHandler(BErrorOutput* errorOutput, BPackageInfo* packageInfo, + int packageFileFD, BRepositoryInfo* repositoryInfo) + : + fErrorOutput(errorOutput), + fPackageInfo(packageInfo), + fPackageFileReader(packageFileFD), + fRepositoryInfo(repositoryInfo) + { + } + + virtual status_t HandleEntry(BPackageEntry* entry) + { + // if license must be approved, read any license files from package such + // that those can be stored in the repository later + if ((fPackageInfo->Flags() & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0 + || entry == NULL) + return B_OK; + + // return if not in ./data/licenses folder + const BPackageEntry* parent = entry->Parent(); + BString licenseFolderName("licenses"); + if (parent == NULL || licenseFolderName != parent->Name()) + return B_OK; + + parent = parent->Parent(); + BString dataFolderName("data"); + if (parent == NULL || dataFolderName != parent->Name()) + return B_OK; + + if (parent->Parent() != NULL) + return B_OK; + + // check if license already is in repository + const BObjectList<BString>& licenseNames + = fRepositoryInfo->LicenseNames(); + for (int i = 0; i < licenseNames.CountItems(); ++i) { + if (licenseNames.ItemAt(i)->ICompare(entry->Name()) == 0) { + // license already exists + return B_OK; + } + } + + // fetch contents of license file + BPackageData& packageData = entry->Data(); + PackageEntryDataFetcher dataFetcher(fErrorOutput, packageData); + + BString licenseText; + status_t result; + if (packageData.IsEncodedInline()) { + BBufferDataReader dataReader(packageData.InlineData(), + packageData.CompressedSize()); + result = dataFetcher.ReadIntoString(&dataReader, licenseText); + } else { + result + = dataFetcher.ReadIntoString(&fPackageFileReader, licenseText); + } + + if (result != B_OK) + return result; + + // add license to repository + return fRepositoryInfo->AddLicense(entry->Name(), licenseText); + } + + virtual status_t HandleEntryAttribute(BPackageEntry* entry, + BPackageEntryAttribute* attribute) + { + return B_OK; + } + + virtual status_t HandleEntryDone(BPackageEntry* entry) + { + return B_OK; + } + + virtual status_t HandlePackageAttribute( + const BPackageInfoAttributeValue& value) + { + switch (value.attributeID) { + case B_PACKAGE_INFO_NAME: + fPackageInfo->SetName(value.string); + break; + + case B_PACKAGE_INFO_SUMMARY: + fPackageInfo->SetSummary(value.string); + break; + + case B_PACKAGE_INFO_DESCRIPTION: + fPackageInfo->SetDescription(value.string); + break; + + case B_PACKAGE_INFO_VENDOR: + fPackageInfo->SetVendor(value.string); + break; + + case B_PACKAGE_INFO_PACKAGER: + fPackageInfo->SetPackager(value.string); + break; + + case B_PACKAGE_INFO_FLAGS: + fPackageInfo->SetFlags(value.unsignedInt); + break; + + case B_PACKAGE_INFO_ARCHITECTURE: + fPackageInfo->SetArchitecture( + (BPackageArchitecture)value.unsignedInt); + break; + + case B_PACKAGE_INFO_VERSION: + fPackageInfo->SetVersion(value.version); + break; + + case B_PACKAGE_INFO_COPYRIGHTS: + fPackageInfo->AddCopyright(value.string); + break; + + case B_PACKAGE_INFO_LICENSES: + fPackageInfo->AddLicense(value.string); + break; + + case B_PACKAGE_INFO_PROVIDES: + fPackageInfo->AddProvides(value.resolvable); + break; + + case B_PACKAGE_INFO_REQUIRES: + fPackageInfo->AddRequires(value.resolvableExpression); + break; + + case B_PACKAGE_INFO_SUPPLEMENTS: + fPackageInfo->AddSupplements(value.resolvableExpression); + break; + + case B_PACKAGE_INFO_CONFLICTS: + fPackageInfo->AddConflicts(value.resolvableExpression); + break; + + case B_PACKAGE_INFO_FRESHENS: + fPackageInfo->AddFreshens(value.resolvableExpression); + break; + + case B_PACKAGE_INFO_REPLACES: + fPackageInfo->AddReplaces(value.string); + break; + + default: + fErrorOutput->PrintError( + "Invalid package attribute section: unexpected package " + "attribute id %d encountered\n", value.attributeID); + return B_BAD_DATA; + } + + return B_OK; + } + + virtual void HandleErrorOccurred() + { + } + +private: + BErrorOutput* fErrorOutput; + BPackageInfo* fPackageInfo; + BPackageReader* fPackageReader; + BFDDataReader fPackageFileReader; + BRepositoryInfo* fRepositoryInfo; +}; + + +} // anonymous namespace + + struct RepositoryWriterImpl::PackageNameSet : public std::set<BString> { }; RepositoryWriterImpl::RepositoryWriterImpl(BRepositoryWriterListener* listener, - const BRepositoryInfo* repositoryInfo) + BRepositoryInfo* repositoryInfo) : inherited(listener), fListener(listener), @@ -97,125 +320,6 @@ status_t -RepositoryWriterImpl::HandleEntry(BPackageEntry* entry) -{ - return B_OK; -} - - -status_t -RepositoryWriterImpl::HandleEntryAttribute(BPackageEntry* entry, - BPackageEntryAttribute* attribute) -{ - return B_OK; -} - - -status_t -RepositoryWriterImpl::HandleEntryDone(BPackageEntry* entry) -{ - return B_OK; -} - - -status_t -RepositoryWriterImpl::HandlePackageAttribute( - const BPackageInfoAttributeValue& value) -{ - switch (value.attributeID) { - case B_PACKAGE_INFO_NAME: - fPackageInfo.SetName(value.string); - break; - - case B_PACKAGE_INFO_SUMMARY: - fPackageInfo.SetSummary(value.string); - break; - - case B_PACKAGE_INFO_DESCRIPTION: - fPackageInfo.SetDescription(value.string); - break; - - case B_PACKAGE_INFO_VENDOR: - fPackageInfo.SetVendor(value.string); - break; - - case B_PACKAGE_INFO_PACKAGER: - fPackageInfo.SetPackager(value.string); - break; - - case B_PACKAGE_INFO_FLAGS: - fPackageInfo.SetFlags(value.unsignedInt); - break; - - case B_PACKAGE_INFO_ARCHITECTURE: - fPackageInfo.SetArchitecture( - (BPackageArchitecture)value.unsignedInt); - break; - - case B_PACKAGE_INFO_VERSION: - fPackageInfo.SetVersion(value.version); - break; - - case B_PACKAGE_INFO_COPYRIGHTS: - fPackageInfo.AddCopyright(value.string); - break; - - case B_PACKAGE_INFO_LICENSES: - fPackageInfo.AddLicense(value.string); - break; - - case B_PACKAGE_INFO_PROVIDES: - fPackageInfo.AddProvides(value.resolvable); - break; - - case B_PACKAGE_INFO_REQUIRES: - fPackageInfo.AddRequires(value.resolvableExpression); - break; - - case B_PACKAGE_INFO_SUPPLEMENTS: - fPackageInfo.AddSupplements(value.resolvableExpression); - break; - - case B_PACKAGE_INFO_CONFLICTS: - fPackageInfo.AddConflicts(value.resolvableExpression); - break; - - case B_PACKAGE_INFO_FRESHENS: - fPackageInfo.AddFreshens(value.resolvableExpression); - break; - - case B_PACKAGE_INFO_REPLACES: - fPackageInfo.AddReplaces(value.string); - break; - - default: - fListener->PrintError( - "Invalid package attribute section: unexpected package " - "attribute id %d encountered\n", value.attributeID); - return B_BAD_DATA; - } - - return B_OK; -} - - -status_t -RepositoryWriterImpl::HandlePackageAttributesDone() -{ - status_t result = _RegisterCurrentPackageInfo(); - fPackageInfo.Clear(); - - return result; -} - - -void -RepositoryWriterImpl::HandleErrorOccurred() -{ -} - - -status_t RepositoryWriterImpl::_Init(const char* fileName) { return inherited::Init(fileName, "repository"); @@ -239,7 +343,8 @@ sizeof(header) + infoLengthCompressed, packagesLengthCompressed); fListener->OnRepositoryDone(sizeof(header), infoLengthCompressed, - fPackageCount, packagesLengthCompressed, totalSize); + fRepositoryInfo->LicenseNames().CountItems(), fPackageCount, + packagesLengthCompressed, totalSize); // general header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_REPO_MAGIC); @@ -278,6 +383,13 @@ fPackageInfo.Clear(); + // parse package + PackageContentHandler contentHandler(fListener, &fPackageInfo, + packageReader.PackageFileFD(), fRepositoryInfo); + if ((result = packageReader.ParseContent(&contentHandler)) != B_OK) + return result; + + // determine package's checksum GeneralFileChecksumAccessor checksumAccessor(packageEntry); BString checksum; if ((result = checksumAccessor.GetChecksum(checksum)) != B_OK) { @@ -286,9 +398,11 @@ } fPackageInfo.SetChecksum(checksum); + // register package's attributes + if ((result = _RegisterCurrentPackageInfo()) != B_OK) + return result; - - return packageReader.ParseContent(this); + return B_OK; }