diff --git a/headers/os/package/hpkg/PackageAttributes.h b/headers/os/package/hpkg/PackageAttributes.h index ba4fc3496f..388158a606 100644 --- a/headers/os/package/hpkg/PackageAttributes.h +++ b/headers/os/package/hpkg/PackageAttributes.h @@ -81,3 +81,4 @@ B_DEFINE_HPKG_ATTRIBUTE(52, STRING, "package:post-install-script", PACKAGE_POST_INSTALL_SCRIPT) B_DEFINE_HPKG_ATTRIBUTE(53, UINT, "package:is-writable-directory", PACKAGE_IS_WRITABLE_DIRECTORY) +B_DEFINE_HPKG_ATTRIBUTE(54, STRING, "package", PACKAGE) diff --git a/headers/os/package/hpkg/RepositoryContentHandler.h b/headers/os/package/hpkg/RepositoryContentHandler.h index d2d7e31582..71e0b2db96 100644 --- a/headers/os/package/hpkg/RepositoryContentHandler.h +++ b/headers/os/package/hpkg/RepositoryContentHandler.h @@ -8,7 +8,7 @@ #include -#include +#include namespace BPackageKit { @@ -20,10 +20,24 @@ class BRepositoryInfo; namespace BHPKG { -class BRepositoryContentHandler : public BPackageContentHandler { +class BPackageInfoAttributeValue; + + +class BRepositoryContentHandler { public: + virtual ~BRepositoryContentHandler(); + virtual status_t HandleRepositoryInfo( const BRepositoryInfo& info) = 0; + + virtual status_t HandlePackage(const char* packageName) = 0; + virtual status_t HandlePackageAttribute( + const BPackageInfoAttributeValue& value) + = 0; + virtual status_t HandlePackageDone(const char* packageName) = 0; + + virtual void HandleErrorOccurred() = 0; + }; diff --git a/headers/private/package/hpkg/RepositoryReaderImpl.h b/headers/private/package/hpkg/RepositoryReaderImpl.h index 4d3951282f..ab40431ef9 100644 --- a/headers/private/package/hpkg/RepositoryReaderImpl.h +++ b/headers/private/package/hpkg/RepositoryReaderImpl.h @@ -38,7 +38,8 @@ public: BRepositoryContentHandler* contentHandler); private: - struct RootAttributeHandler; + class PackagesAttributeHandler; + class PackageContentHandlerAdapter; private: BRepositoryInfo fRepositoryInfo; diff --git a/headers/private/package/hpkg/WriterImplBase.h b/headers/private/package/hpkg/WriterImplBase.h index e9569325ad..0686335ca6 100644 --- a/headers/private/package/hpkg/WriterImplBase.h +++ b/headers/private/package/hpkg/WriterImplBase.h @@ -117,6 +117,10 @@ protected: BPackageResolvableExpression>& list, uint8 id); + PackageAttribute* AddStringAttribute(BHPKGAttributeID id, + const BString& value, + DoublyLinkedList& list); + int32 WriteCachedStrings(const StringCache& cache, uint32 minUsageCount); @@ -163,9 +167,6 @@ private: = B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR; private: - PackageAttribute* _AddStringAttribute(BHPKGAttributeID id, - const BString& value, - DoublyLinkedList& list); inline PackageAttribute* _AddStringAttributeIfNotEmpty( BHPKGAttributeID id, const BString& value, DoublyLinkedList& list); @@ -267,7 +268,7 @@ WriterImplBase::_AddStringAttributeIfNotEmpty(BHPKGAttributeID id, { if (value.IsEmpty()) return NULL; - return _AddStringAttribute(id, value, list); + return AddStringAttribute(id, value, list); } diff --git a/src/bin/package_repo/command_list.cpp b/src/bin/package_repo/command_list.cpp index 9faa532a8b..5bf2c7143f 100644 --- a/src/bin/package_repo/command_list.cpp +++ b/src/bin/package_repo/command_list.cpp @@ -32,18 +32,7 @@ struct RepositoryContentListHandler : BRepositoryContentHandler { { } - virtual status_t HandleEntry(BPackageEntry* entry) - { - return B_OK; - } - - virtual status_t HandleEntryAttribute(BPackageEntry* entry, - BPackageEntryAttribute* attribute) - { - return B_OK; - } - - virtual status_t HandleEntryDone(BPackageEntry* entry) + virtual status_t HandlePackage(const char* packageName) { return B_OK; } @@ -204,6 +193,11 @@ struct RepositoryContentListHandler : BRepositoryContentHandler { return B_OK; } + virtual status_t HandlePackageDone(const char* packageName) + { + return B_OK; + } + virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) { printf("repository-info:\n"); diff --git a/src/build/libpackage/Jamfile b/src/build/libpackage/Jamfile index 6c756f9dc9..ecd7575df8 100644 --- a/src/build/libpackage/Jamfile +++ b/src/build/libpackage/Jamfile @@ -46,6 +46,7 @@ HPKG_SOURCES = PackageWriter.cpp PackageWriterImpl.cpp ReaderImplBase.cpp + RepositoryContentHandler.cpp RepositoryReader.cpp RepositoryReaderImpl.cpp RepositoryWriter.cpp diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index fccb49e1a3..f60fa441f4 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -37,6 +37,7 @@ HPKG_SOURCES = PackageWriterImpl.cpp PoolBuffer.cpp ReaderImplBase.cpp + RepositoryContentHandler.cpp RepositoryReader.cpp RepositoryReaderImpl.cpp RepositoryWriter.cpp diff --git a/src/kits/package/RepositoryCache.cpp b/src/kits/package/RepositoryCache.cpp index 65fabc2338..c172eb5a9b 100644 --- a/src/kits/package/RepositoryCache.cpp +++ b/src/kits/package/RepositoryCache.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2011, Haiku, Inc. All Rights Reserved. + * Copyright 2011-2013, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Oliver Tappe + * Ingo Weinhold */ @@ -26,6 +27,8 @@ #include #include +#include + namespace BPackageKit { @@ -37,136 +40,45 @@ using namespace BHPKG; struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler { - RepositoryContentHandler(BRepositoryInfo* repositoryInfo, - BPackageInfoSet& packages) + RepositoryContentHandler(BRepositoryInfo& repositoryInfo, + BPackageInfoSet& packages, BErrorOutput* errorOutput) : fRepositoryInfo(repositoryInfo), - fPackages(packages) + fPackageInfo(), + fPackages(packages), + fPackageInfoContentHandler(fPackageInfo, errorOutput) { } - virtual status_t HandleEntry(BPackageEntry* entry) + virtual status_t HandlePackage(const char* packageName) { + fPackageInfo.Clear(); return B_OK; } - 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; + return fPackageInfoContentHandler.HandlePackageAttribute(value); + } - case B_PACKAGE_INFO_SUMMARY: - fPackageInfo.SetSummary(value.string); - break; + virtual status_t HandlePackageDone(const char* packageName) + { + status_t result = fPackageInfo.InitCheck(); + if (result != B_OK) + return result; - 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; - - case B_PACKAGE_INFO_URLS: - fPackageInfo.AddURL(value.string); - break; - - case B_PACKAGE_INFO_SOURCE_URLS: - fPackageInfo.AddSourceURL(value.string); - break; - - case B_PACKAGE_INFO_INSTALL_PATH: - fPackageInfo.SetInstallPath(value.string); - break; - - case B_PACKAGE_INFO_CHECKSUM: - { - fPackageInfo.SetChecksum(value.string); - status_t result = fPackageInfo.InitCheck(); - if (result != B_OK) - return result; - - result = fPackages.AddInfo(fPackageInfo); - if (result != B_OK) - return result; - - fPackageInfo.Clear(); - break; - } - - default: - return B_BAD_DATA; - } + result = fPackages.AddInfo(fPackageInfo); + if (result != B_OK) + return result; return B_OK; } virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) { - *fRepositoryInfo = repositoryInfo; + fRepositoryInfo = repositoryInfo; return B_OK; } @@ -176,9 +88,10 @@ struct BRepositoryCache::RepositoryContentHandler : BRepositoryContentHandler { } private: - BRepositoryInfo* fRepositoryInfo; - BPackageInfo fPackageInfo; - BPackageInfoSet& fPackages; + BRepositoryInfo& fRepositoryInfo; + BPackageInfo fPackageInfo; + BPackageInfoSet& fPackages; + BPackageInfoContentHandler fPackageInfoContentHandler; }; @@ -247,7 +160,7 @@ BRepositoryCache::SetTo(const BEntry& entry) if ((result = repositoryReader.Init(repositoryCachePath.Path())) != B_OK) return result; - RepositoryContentHandler handler(&fInfo, fPackages); + RepositoryContentHandler handler(fInfo, fPackages, &errorOutput); if ((result = repositoryReader.ParseContent(&handler)) != B_OK) return result; diff --git a/src/kits/package/hpkg/RepositoryContentHandler.cpp b/src/kits/package/hpkg/RepositoryContentHandler.cpp new file mode 100644 index 0000000000..fae75355d0 --- /dev/null +++ b/src/kits/package/hpkg/RepositoryContentHandler.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2013, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ingo Weinhold + */ + + +#include + + +namespace BPackageKit { + +namespace BHPKG { + + +BRepositoryContentHandler::~BRepositoryContentHandler() +{ +} + + +} // namespace BHPKG + +} // namespace BPackageKit diff --git a/src/kits/package/hpkg/RepositoryReaderImpl.cpp b/src/kits/package/hpkg/RepositoryReaderImpl.cpp index 30554ea4f9..51abf4836c 100644 --- a/src/kits/package/hpkg/RepositoryReaderImpl.cpp +++ b/src/kits/package/hpkg/RepositoryReaderImpl.cpp @@ -40,6 +40,127 @@ static const size_t kMaxRepositoryInfoSize = 1 * 1024 * 1024; static const size_t kMaxPackageAttributesSize = 64 * 1024 * 1024; +// #pragma mark - PackagesAttributeHandler + + +class RepositoryReaderImpl::PackagesAttributeHandler + : public AttributeHandler { +public: + PackagesAttributeHandler(BRepositoryContentHandler* contentHandler) + : + fContentHandler(contentHandler), + fPackageName(NULL) + { + } + + virtual status_t HandleAttribute(AttributeHandlerContext* context, uint8 id, + const AttributeValue& value, AttributeHandler** _handler) + { + switch (id) { + case B_HPKG_ATTRIBUTE_ID_PACKAGE: + { + status_t error = _NotifyPackageDone(); + if (error != B_OK) + return error; + + if (_handler != NULL) { + if (fContentHandler != NULL) { + error = fContentHandler->HandlePackage(value.string); + if (error != B_OK) + return error; + } + + *_handler = new(std::nothrow) PackageAttributeHandler; + if (*_handler == NULL) + return B_NO_MEMORY; + + fPackageName = value.string; + } + break; + } + + default: + if (context->ignoreUnknownAttributes) + break; + + context->errorOutput->PrintError( + "Error: Invalid package attribute section: unexpected " + "top level attribute id %d encountered\n", id); + return B_BAD_DATA; + } + + return B_OK; + } + + virtual status_t Delete(AttributeHandlerContext* context) + { + return _NotifyPackageDone(); + } + +private: + status_t _NotifyPackageDone() + { + if (fPackageName == NULL || fContentHandler == NULL) + return B_OK; + + status_t error = fContentHandler->HandlePackageDone(fPackageName); + fPackageName = NULL; + return error; + } + +private: + BRepositoryContentHandler* fContentHandler; + const char* fPackageName; +}; + + +// #pragma mark - PackageContentHandlerAdapter + + +class RepositoryReaderImpl::PackageContentHandlerAdapter + : public BPackageContentHandler { +public: + PackageContentHandlerAdapter(BRepositoryContentHandler* contentHandler) + : + fContentHandler(contentHandler) + { + } + + virtual status_t HandleEntry(BPackageEntry* entry) + { + return B_OK; + } + + 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) + { + return fContentHandler->HandlePackageAttribute(value); + } + + virtual void HandleErrorOccurred() + { + return fContentHandler->HandleErrorOccurred(); + } + +private: + BRepositoryContentHandler* fContentHandler; +}; + + +// #pragma mark - RepositoryReaderImpl + + RepositoryReaderImpl::RepositoryReaderImpl(BErrorOutput* errorOutput) : inherited("repository", errorOutput) @@ -140,10 +261,12 @@ RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler) { status_t result = contentHandler->HandleRepositoryInfo(fRepositoryInfo); if (result == B_OK) { - AttributeHandlerContext context(ErrorOutput(), contentHandler, + PackageContentHandlerAdapter contentHandlerAdapter(contentHandler); + AttributeHandlerContext context(ErrorOutput(), + contentHandler != NULL ? &contentHandlerAdapter : NULL, B_HPKG_SECTION_PACKAGE_ATTRIBUTES, MinorFormatVersion() > B_HPKG_REPO_MINOR_VERSION); - PackageAttributeHandler rootAttributeHandler; + PackagesAttributeHandler rootAttributeHandler(contentHandler); result = ParsePackageAttributesSection(&context, &rootAttributeHandler); } return result; diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp b/src/kits/package/hpkg/RepositoryWriterImpl.cpp index 921f1fbf82..5602db4e3c 100644 --- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp +++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp @@ -395,7 +395,9 @@ RepositoryWriterImpl::_RegisterCurrentPackageInfo() if ((result = fPackageNames->Add(fPackageInfo.Name())) != B_OK) return result; - RegisterPackageInfo(PackageAttributes(), fPackageInfo); + PackageAttribute* packageAttribute = AddStringAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE, fPackageInfo.Name(), PackageAttributes()); + RegisterPackageInfo(packageAttribute->children, fPackageInfo); fPackageCount++; fListener->OnPackageAdded(fPackageInfo); diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index 66a853f679..0fd01e3509 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -280,23 +280,23 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, const BPackageInfo& packageInfo) { // name - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME, packageInfo.Name(), + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME, packageInfo.Name(), attributeList); // summary - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY, packageInfo.Summary(), attributeList); // description - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION, packageInfo.Description(), attributeList); // vendor - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR, packageInfo.Vendor(), attributeList); // packager - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER, packageInfo.Packager(), attributeList); // base package (optional) @@ -345,7 +345,7 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, bool hasCompatibleVersion = resolvable->CompatibleVersion().InitCheck() == B_OK; - PackageAttribute* provides = _AddStringAttribute( + PackageAttribute* provides = AddStringAttribute( B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES, resolvable->Name(), attributeList); @@ -384,7 +384,7 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, = packageInfo.GlobalWritableFileInfos(); for (int32 i = 0; i < globalWritableFileInfos.CountItems(); ++i) { BGlobalWritableFileInfo* info = globalWritableFileInfos.ItemAt(i); - PackageAttribute* attribute = _AddStringAttribute( + PackageAttribute* attribute = AddStringAttribute( B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_WRITABLE_FILE, info->Path(), attributeList); @@ -412,7 +412,7 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, = packageInfo.UserSettingsFileInfos(); for (int32 i = 0; i < userSettingsFileInfos.CountItems(); ++i) { BUserSettingsFileInfo* info = userSettingsFileInfos.ItemAt(i); - PackageAttribute* attribute = _AddStringAttribute( + PackageAttribute* attribute = AddStringAttribute( B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE, info->Path(), attributeList); @@ -434,7 +434,7 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, const BObjectList& users = packageInfo.Users(); for (int32 i = 0; i < users.CountItems(); ++i) { const BUser* user = users.ItemAt(i); - PackageAttribute* attribute = _AddStringAttribute( + PackageAttribute* attribute = AddStringAttribute( B_HPKG_ATTRIBUTE_ID_PACKAGE_USER, user->Name(), attributeList); _AddStringAttributeIfNotEmpty( @@ -448,7 +448,7 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, attribute->children); for (int32 k = 0; k < user->Groups().CountStrings(); k++) { - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP, user->Groups().StringAt(k), attribute->children); } } @@ -475,11 +475,11 @@ void WriterImplBase::RegisterPackageVersion(PackageAttributeList& attributeList, const BPackageVersion& version, BHPKGAttributeID attributeID) { - PackageAttribute* versionMajor = _AddStringAttribute(attributeID, + PackageAttribute* versionMajor = AddStringAttribute(attributeID, version.Major(), attributeList); if (!version.Minor().IsEmpty()) { - _AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MINOR, + AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MINOR, version.Minor(), versionMajor->children); _AddStringAttributeIfNotEmpty( B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MICRO, version.Micro(), @@ -507,7 +507,7 @@ WriterImplBase::RegisterPackageResolvableExpressionList( { for (int i = 0; i < expressionList.CountItems(); ++i) { BPackageResolvableExpression* resolvableExpr = expressionList.ItemAt(i); - PackageAttribute* name = _AddStringAttribute((BHPKGAttributeID)id, + PackageAttribute* name = AddStringAttribute((BHPKGAttributeID)id, resolvableExpr->Name(), attributeList); if (resolvableExpr->Version().InitCheck() == B_OK) { @@ -523,6 +523,18 @@ WriterImplBase::RegisterPackageResolvableExpressionList( } +WriterImplBase::PackageAttribute* +WriterImplBase::AddStringAttribute(BHPKGAttributeID id, const BString& value, + DoublyLinkedList& list) +{ + PackageAttribute* attribute = new PackageAttribute(id, + B_HPKG_ATTRIBUTE_TYPE_STRING, B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + attribute->string = fPackageStringCache.Get(value); + list.Add(attribute); + return attribute; +} + + int32 WriterImplBase::WriteCachedStrings(const StringCache& cache, uint32 minUsageCount) @@ -682,24 +694,12 @@ WriterImplBase::RawWriteBuffer(const void* buffer, size_t size, off_t offset) } -WriterImplBase::PackageAttribute* -WriterImplBase::_AddStringAttribute(BHPKGAttributeID id, const BString& value, - DoublyLinkedList& list) -{ - PackageAttribute* attribute = new PackageAttribute(id, - B_HPKG_ATTRIBUTE_TYPE_STRING, B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); - attribute->string = fPackageStringCache.Get(value); - list.Add(attribute); - return attribute; -} - - void WriterImplBase::_AddStringAttributeList(BHPKGAttributeID id, const BStringList& value, DoublyLinkedList& list) { for (int32 i = 0; i < value.CountStrings(); i++) - _AddStringAttribute(id, value.StringAt(i), list); + AddStringAttribute(id, value.StringAt(i), list); }