Implemented reading of package info attributes from hpkg file

* added kernel-compatible datatypes for reading package info attribute 
  values (PackageInfoAttributeValue.h) - these will be used at a later
  stage by the package-fs to transport those attributes to userland
  when asked to do so (by ioctl)
* implemented parsing of package info attributes in PackageReaderImpl
* added support for compressed package attribute section to 
  PackageReaderImpl
* completed the writing of package info attributes in PackageWriterImpl
  and fixed a couple of bugs exposed by parsing
* adjusted 'package list' to show the package info attributes as they
  are found


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40354 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2011-02-04 17:43:07 +00:00
parent 531d191219
commit 6f0278cdc9
17 changed files with 910 additions and 76 deletions
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_ARCHITECTURE_H_
#define _PACKAGE__PACKAGE_ARCHITECTURE_H_
namespace BPackageKit {
enum BPackageArchitecture {
B_PACKAGE_ARCHITECTURE_ANY = 0,
B_PACKAGE_ARCHITECTURE_X86,
B_PACKAGE_ARCHITECTURE_X86_GCC2,
//
B_PACKAGE_ARCHITECTURE_ENUM_COUNT,
};
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_ARCHITECTURE_H_
+2 -38
View File
@@ -9,6 +9,8 @@
#include <ObjectList.h>
#include <String.h>
#include <package/PackageArchitecture.h>
#include <package/PackageInfoAttributes.h>
#include <package/PackageResolvable.h>
#include <package/PackageResolvableExpression.h>
#include <package/PackageVersion.h>
@@ -20,44 +22,6 @@ class BEntry;
namespace BPackageKit {
enum BPackageInfoIndex {
B_PACKAGE_INFO_NAME = 0,
B_PACKAGE_INFO_SUMMARY, // single line
B_PACKAGE_INFO_DESCRIPTION, // multiple lines possible
B_PACKAGE_INFO_VENDOR, // e.g. "Haiku Project"
B_PACKAGE_INFO_PACKAGER, // e-mail address preferred
B_PACKAGE_INFO_ARCHITECTURE,
B_PACKAGE_INFO_VERSION, // <major>[.<minor>[.<micro>]]
B_PACKAGE_INFO_COPYRIGHTS, // list
B_PACKAGE_INFO_LICENSES, // list
B_PACKAGE_INFO_PROVIDES, // list of resolvables this package provides,
// each optionally giving a version
B_PACKAGE_INFO_REQUIRES, // list of resolvables required by this package,
// each optionally specifying a version relation
// (e.g. libssl.so >= 0.9.8)
B_PACKAGE_INFO_SUPPLEMENTS, // list of resolvables that are supplemented
// by this package, i.e. this package marks
// itself as an extension to other packages
B_PACKAGE_INFO_CONFLICTS, // list of resolvables that inhibit installation
// of this package
B_PACKAGE_INFO_REPLACES, // list of resolvables that this package
// will replace (upon update)
B_PACKAGE_INFO_FRESHENS, // list of resolvables that this package
// contains a patch for
//
B_PACKAGE_INFO_ENUM_COUNT,
};
enum BPackageArchitecture {
B_PACKAGE_ARCHITECTURE_ANY = 0,
B_PACKAGE_ARCHITECTURE_X86,
B_PACKAGE_ARCHITECTURE_X86_GCC2,
//
B_PACKAGE_ARCHITECTURE_ENUM_COUNT,
};
/*
* Keeps a list of package info elements (e.g. name, version, vendor, ...) which
* will be converted to package attributes when creating a package. Usually,
@@ -0,0 +1,44 @@
/*
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_INFO_ATTRIBUTES_H_
#define _PACKAGE__PACKAGE_INFO_ATTRIBUTES_H_
namespace BPackageKit {
enum BPackageInfoAttributeIndex {
B_PACKAGE_INFO_NAME = 0,
B_PACKAGE_INFO_SUMMARY, // single line
B_PACKAGE_INFO_DESCRIPTION, // multiple lines possible
B_PACKAGE_INFO_VENDOR, // e.g. "Haiku Project"
B_PACKAGE_INFO_PACKAGER, // e-mail address preferred
B_PACKAGE_INFO_ARCHITECTURE,
B_PACKAGE_INFO_VERSION, // <major>[.<minor>[.<micro>]]
B_PACKAGE_INFO_COPYRIGHTS, // list
B_PACKAGE_INFO_LICENSES, // list
B_PACKAGE_INFO_PROVIDES, // list of resolvables this package provides,
// each optionally giving a version
B_PACKAGE_INFO_REQUIRES, // list of resolvables required by this package,
// each optionally specifying a version relation
// (e.g. libssl.so >= 0.9.8)
B_PACKAGE_INFO_SUPPLEMENTS, // list of resolvables that are supplemented
// by this package, i.e. this package marks
// itself as an extension to other packages
B_PACKAGE_INFO_CONFLICTS, // list of resolvables that inhibit installation
// of this package
B_PACKAGE_INFO_FRESHENS, // list of resolvables that this package
// contains a patch for
B_PACKAGE_INFO_REPLACES, // list of resolvables that this package
// will replace (upon update)
//
B_PACKAGE_INFO_ENUM_COUNT,
};
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_INFO_ATTRIBUTES_H_
+4 -14
View File
@@ -2,29 +2,19 @@
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_RESOLVALBE_H_
#define _PACKAGE__PACKAGE_RESOLVALBE_H_
#ifndef _PACKAGE__PACKAGE_RESOLVABLE_H_
#define _PACKAGE__PACKAGE_RESOLVABLE_H_
#include <String.h>
#include <package/PackageResolvableType.h>
#include <package/PackageVersion.h>
namespace BPackageKit {
enum BPackageResolvableType {
B_PACKAGE_RESOLVABLE_TYPE_DEFAULT = 0,
B_PACKAGE_RESOLVABLE_TYPE_LIBRARY,
B_PACKAGE_RESOLVABLE_TYPE_COMMAND,
B_PACKAGE_RESOLVABLE_TYPE_APPLICATION,
B_PACKAGE_RESOLVABLE_TYPE_ADD_ON,
//
B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT,
};
/*
* Defines a resolvable (something other packages can depend upon).
* Each resolvable is defined as a name (with an optional type prefix)
@@ -83,4 +73,4 @@ private:
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_RESOLVALBE_H_
#endif // _PACKAGE__PACKAGE_RESOLVABLE_H_
@@ -0,0 +1,27 @@
/*
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_RESOLVABLE_OPERATOR_H_
#define _PACKAGE__PACKAGE_RESOLVABLE_OPERATOR_H_
namespace BPackageKit {
enum BPackageResolvableOperator {
B_PACKAGE_RESOLVABLE_OP_LESS,
B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL,
B_PACKAGE_RESOLVABLE_OP_EQUAL,
B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL,
B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL,
B_PACKAGE_RESOLVABLE_OP_GREATER,
//
B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT
};
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_RESOLVABLE_OPERATOR_H_
@@ -0,0 +1,26 @@
/*
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_RESOLVABLE_TYPE_H_
#define _PACKAGE__PACKAGE_RESOLVABLE_TYPE_H_
namespace BPackageKit {
enum BPackageResolvableType {
B_PACKAGE_RESOLVABLE_TYPE_DEFAULT = 0,
B_PACKAGE_RESOLVABLE_TYPE_LIBRARY,
B_PACKAGE_RESOLVABLE_TYPE_COMMAND,
B_PACKAGE_RESOLVABLE_TYPE_APPLICATION,
B_PACKAGE_RESOLVABLE_TYPE_ADD_ON,
//
B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT,
};
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_RESOLVABLE_TYPE_H_
+31 -1
View File
@@ -28,7 +28,9 @@ enum {
B_HPKG_ATTRIBUTE_TYPE_INT = 1,
B_HPKG_ATTRIBUTE_TYPE_UINT = 2,
B_HPKG_ATTRIBUTE_TYPE_STRING = 3,
B_HPKG_ATTRIBUTE_TYPE_RAW = 4
B_HPKG_ATTRIBUTE_TYPE_RAW = 4,
//
B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT
};
@@ -63,6 +65,34 @@ enum {
#define B_HPKG_PACKAGE_INFO_FILE_NAME ".PackageInfo"
// package attribute IDs
enum BPackageAttributeID {
B_PACKAGE_ATTRIBUTE_NAME = 0,
B_PACKAGE_ATTRIBUTE_SUMMARY,
B_PACKAGE_ATTRIBUTE_DESCRIPTION,
B_PACKAGE_ATTRIBUTE_VENDOR,
B_PACKAGE_ATTRIBUTE_PACKAGER,
B_PACKAGE_ATTRIBUTE_ARCHITECTURE,
B_PACKAGE_ATTRIBUTE_VERSION_MAJOR,
B_PACKAGE_ATTRIBUTE_VERSION_MINOR,
B_PACKAGE_ATTRIBUTE_VERSION_MICRO,
B_PACKAGE_ATTRIBUTE_VERSION_RELEASE,
B_PACKAGE_ATTRIBUTE_COPYRIGHT,
B_PACKAGE_ATTRIBUTE_LICENSE,
B_PACKAGE_ATTRIBUTE_PROVIDES,
B_PACKAGE_ATTRIBUTE_PROVIDES_TYPE,
B_PACKAGE_ATTRIBUTE_REQUIRES,
B_PACKAGE_ATTRIBUTE_SUPPLEMENTS,
B_PACKAGE_ATTRIBUTE_CONFLICTS,
B_PACKAGE_ATTRIBUTE_FRESHENS,
B_PACKAGE_ATTRIBUTE_REPLACES,
B_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR,
//
B_PACKAGE_ATTRIBUTE_ENUM_COUNT,
};
// TODO: make this accessible via a function
// default values
enum {
B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB = 64 * 1024
@@ -17,6 +17,7 @@ namespace BHPKG {
class BPackageAttributeValue;
class BPackageEntry;
class BPackageEntryAttribute;
class BPackageInfoAttributeValue;
class BLowLevelPackageContentHandler {
@@ -43,6 +44,10 @@ public:
BPackageEntryAttribute* attribute) = 0;
virtual status_t HandleEntryDone(BPackageEntry* entry) = 0;
virtual status_t HandlePackageAttribute(
const BPackageInfoAttributeValue& value
) = 0;
virtual void HandleErrorOccurred() = 0;
};
@@ -0,0 +1,95 @@
/*
* Copyright 2009,2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__PACKAGE_INFO_ATTRIBUTE_VALUE_H_
#define _PACKAGE__HPKG__PACKAGE_INFO_ATTRIBUTE_VALUE_H_
#include <SupportDefs.h>
#include <package/PackageArchitecture.h>
#include <package/PackageInfoAttributes.h>
#include <package/PackageResolvableOperator.h>
#include <package/PackageResolvableType.h>
namespace BPackageKit {
namespace BHPKG {
struct BPackageVersionData {
const char* major;
const char* minor;
const char* micro;
uint8 release;
};
struct BPackageResolvableData {
BPackageResolvableType type;
const char* name;
bool haveVersion;
BPackageVersionData version;
};
struct BPackageResolvableExpressionData {
const char* name;
bool haveOpAndVersion;
BPackageResolvableOperator op;
BPackageVersionData version;
};
struct BPackageInfoAttributeValue {
union {
uint64 unsignedInt;
const char* string;
BPackageVersionData version;
BPackageResolvableData resolvable;
BPackageResolvableExpressionData resolvableExpression;
};
uint8 attributeIndex;
public:
inline BPackageInfoAttributeValue();
inline void SetTo(BPackageInfoAttributeIndex index,
uint8 value);
inline void SetTo(BPackageInfoAttributeIndex index,
const char* value);
};
BPackageInfoAttributeValue::BPackageInfoAttributeValue()
:
attributeIndex(B_PACKAGE_INFO_ENUM_COUNT)
{
}
void
BPackageInfoAttributeValue::SetTo(BPackageInfoAttributeIndex index, uint8 value)
{
attributeIndex = index;
unsignedInt = value;
}
void
BPackageInfoAttributeValue::SetTo(BPackageInfoAttributeIndex index,
const char* value)
{
attributeIndex = index;
string = value;
}
} // namespace BHPKG
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__PACKAGE_ATTRIBUTE_VALUE_H_
@@ -12,6 +12,7 @@
#include <package/hpkg/PackageAttributeValue.h>
#include <package/hpkg/PackageContentHandler.h>
#include <package/hpkg/PackageInfoAttributeValue.h>
#include <package/hpkg/PackageReader.h>
@@ -74,6 +75,25 @@ private:
status_t _ParseAttributeTree(
AttributeHandlerContext* context);
status_t _ParsePackageAttributes(
AttributeHandlerContext* context);
status_t _ParsePackageVersion(
BPackageVersionData& _version,
const char* major = NULL);
status_t _ParsePackageProvides(
BPackageResolvableData& _resolvable,
BPackageResolvableType providesType);
status_t _ParsePackageResolvableExpression(
BPackageResolvableExpressionData&
_resolvableExpression,
const char* resolvableName,
bool hasChildren);
status_t _ReadPackageAttribute(uint8& _id,
AttributeValue& _value,
bool* _hasChildren = NULL,
uint64* _tag = NULL);
status_t _ReadAttributeValue(uint8 type, uint8 encoding,
AttributeValue& _value);
@@ -88,6 +108,9 @@ private:
const void*& _buffer);
status_t _ReadTOCBuffer(void* buffer, size_t size);
status_t _ReadPackageAttributesBuffer(void* buffer,
size_t size);
status_t _ReadBuffer(off_t offset, void* buffer,
size_t size);
status_t _ReadCompressedBuffer(off_t offset,
@@ -103,7 +126,7 @@ private:
inline AttributeHandler* _PopAttributeHandler();
private:
BErrorOutput* fErrorOutput;
BErrorOutput* fErrorOutput;
int fFD;
bool fOwnsFD;
@@ -120,6 +143,8 @@ private:
uint64 fTOCStringsLength;
uint64 fTOCStringsCount;
bool fInPackageAttributes;
uint32 fPackageAttributesCompression;
uint32 fPackageAttributesCompressedLength;
uint32 fPackageAttributesUncompressedLength;
@@ -127,6 +152,10 @@ private:
uint8* fTOCSection;
uint64 fCurrentTOCOffset;
uint8* fPackageAttributesSection;
uint64 fCurrentPackageAttributesOffset;
AttributeTypeReference* fAttributeTypes;
char** fStrings;
@@ -141,7 +170,9 @@ template<typename Type>
status_t
PackageReaderImpl::_Read(Type& _value)
{
return _ReadTOCBuffer(&_value, sizeof(Type));
return fInPackageAttributes
? _ReadPackageAttributesBuffer(&_value, sizeof(Type))
: _ReadTOCBuffer(&_value, sizeof(Type));
}
@@ -82,6 +82,10 @@ private:
void _WritePackageVersion(
const BPackageVersion& version);
void _WritePackageResolvableExpressionList(
const BObjectList<
BPackageResolvableExpression>& list,
uint8 id);
template<typename Type>
inline void _Write(const Type& value);
+3 -1
View File
@@ -129,7 +129,7 @@ enum {
// package attribute IDs
enum {
enum BHPKGPackageAttributeID {
B_HPKG_PACKAGE_ATTRIBUTE_NAME = 0,
B_HPKG_PACKAGE_ATTRIBUTE_SUMMARY,
B_HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION,
@@ -150,6 +150,8 @@ enum {
B_HPKG_PACKAGE_ATTRIBUTE_FRESHENS,
B_HPKG_PACKAGE_ATTRIBUTE_REPLACES,
B_HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR,
//
B_HPKG_PACKAGE_ATTRIBUTE_ENUM_COUNT,
};
@@ -257,6 +257,13 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
return B_OK;
}
virtual status_t HandlePackageAttribute(
const BPackageInfoAttributeValue& value)
{
// TODO!
return B_OK;
}
virtual void HandleErrorOccurred()
{
fErrorOccurred = true;
+6
View File
@@ -223,6 +223,12 @@ struct PackageContentExtractHandler : BPackageContentHandler {
return B_OK;
}
virtual status_t HandlePackageAttribute(
const BPackageInfoAttributeValue& value)
{
return B_OK;
}
virtual void HandleErrorOccurred()
{
fErrorOccurred = true;
+123
View File
@@ -14,13 +14,17 @@
#include <package/hpkg/PackageContentHandler.h>
#include <package/hpkg/PackageEntry.h>
#include <package/hpkg/PackageEntryAttribute.h>
#include <package/hpkg/PackageInfoAttributeValue.h>
#include <package/hpkg/PackageReader.h>
#include <package/PackageInfo.h>
#include "package.h"
#include "StandardErrorOutput.h"
using namespace BPackageKit::BHPKG;
using namespace BPackageKit;
struct PackageContentListHandler : BPackageContentHandler {
@@ -104,6 +108,114 @@ struct PackageContentListHandler : BPackageContentHandler {
return B_OK;
}
virtual status_t HandlePackageAttribute(
const BPackageInfoAttributeValue& value)
{
switch (value.attributeIndex) {
case B_PACKAGE_INFO_NAME:
printf("package-attributes:\n");
printf("\tname: %s\n", value.string);
break;
case B_PACKAGE_INFO_SUMMARY:
printf("\tsummary: %s\n", value.string);
break;
case B_PACKAGE_INFO_DESCRIPTION:
printf("\tdescription: %s\n", value.string);
break;
case B_PACKAGE_INFO_VENDOR:
printf("\tvendor: %s\n", value.string);
break;
case B_PACKAGE_INFO_PACKAGER:
printf("\tpackager: %s\n", value.string);
break;
case B_PACKAGE_INFO_ARCHITECTURE:
printf("\tarchitecure: %s\n",
BPackageInfo::kArchitectureNames[value.unsignedInt]);
break;
case B_PACKAGE_INFO_VERSION:
printf("\tversion: %s.%s.%s-%d\n", value.version.major,
value.version.minor, value.version.micro,
value.version.release);
break;
case B_PACKAGE_INFO_COPYRIGHTS:
printf("\tcopyright: %s\n", value.string);
break;
case B_PACKAGE_INFO_LICENSES:
printf("\tlicense: %s\n", value.string);
break;
case B_PACKAGE_INFO_PROVIDES:
printf("\tprovides: %s", value.resolvable.name);
if (value.resolvable.haveVersion) {
printf(" = ");
_PrintPackageVersion(value.resolvable.version);
}
printf("\n");
break;
case B_PACKAGE_INFO_REQUIRES:
printf("\trequires: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
value.resolvableExpression.op]);
_PrintPackageVersion(value.resolvableExpression.version);
}
printf("\n");
break;
case B_PACKAGE_INFO_SUPPLEMENTS:
printf("\tsupplements: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
value.resolvableExpression.op]);
_PrintPackageVersion(value.resolvableExpression.version);
}
printf("\n");
break;
case B_PACKAGE_INFO_CONFLICTS:
printf("\tconflicts: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
value.resolvableExpression.op]);
_PrintPackageVersion(value.resolvableExpression.version);
}
printf("\n");
break;
case B_PACKAGE_INFO_FRESHENS:
printf("\tfreshens: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
value.resolvableExpression.op]);
_PrintPackageVersion(value.resolvableExpression.version);
}
printf("\n");
break;
case B_PACKAGE_INFO_REPLACES:
printf("\treplaces: %s\n", value.string);
break;
default:
printf(
"*** Invalid package attribute section: unexpected "
"package attribute index %d encountered\n",
value.attributeIndex);
return B_BAD_DATA;
}
return B_OK;
}
virtual void HandleErrorOccurred()
{
}
@@ -123,6 +235,17 @@ private:
return buffer;
}
static void _PrintPackageVersion(const BPackageVersionData& version)
{
printf("%s", version.major);
if (version.minor != NULL && version.minor[0] != '\0')
printf(".%s", version.minor);
if (version.micro != NULL && version.micro[0] != '\0')
printf(".%s", version.micro);
if (version.release > 0)
printf("-%d", version.release);
}
private:
int fLevel;
bool fListAttribute;
+425 -4
View File
@@ -41,9 +41,12 @@ namespace BPrivate {
// maximum TOC size we support reading
static const size_t kMaxTOCSize = 64 * 1024 * 1024;
static const size_t kMaxTOCSize = 64 * 1024 * 1024;
static const size_t kScratchBufferSize = 64 * 1024;
// maximum package attributes size we support reading
static const size_t kMaxPackageAttributesSize = 1 * 1024 * 1024;
static const size_t kScratchBufferSize = 64 * 1024;
enum {
@@ -612,7 +615,9 @@ PackageReaderImpl::PackageReaderImpl(BErrorOutput* errorOutput)
fErrorOutput(errorOutput),
fFD(-1),
fOwnsFD(false),
fInPackageAttributes(false),
fTOCSection(NULL),
fPackageAttributesSection(NULL),
fAttributeTypes(NULL),
fStrings(NULL),
fScratchBuffer(NULL),
@@ -630,6 +635,7 @@ PackageReaderImpl::~PackageReaderImpl()
delete[] fStrings;
delete[] fAttributeTypes;
delete[] fTOCSection;
delete[] fPackageAttributesSection;
}
@@ -772,6 +778,15 @@ PackageReaderImpl::Init(int fd, bool keepFD)
return B_UNSUPPORTED;
}
// package attributes size sanity check
if (fPackageAttributesUncompressedLength > kMaxPackageAttributesSize) {
fErrorOutput->PrintError(
"Error: Package file package attributes section size "
"is %llu bytes. This is beyond the reader's sanity limit\n",
fPackageAttributesUncompressedLength);
return B_UNSUPPORTED;
}
// allocate a scratch buffer
fScratchBuffer = new(std::nothrow) uint8[kScratchBufferSize];
if (fScratchBuffer == NULL) {
@@ -786,13 +801,26 @@ PackageReaderImpl::Init(int fd, bool keepFD)
fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY;
}
error = _ReadCompressedBuffer(fTOCSectionOffset, fTOCSection,
fTOCCompressedLength, fTOCUncompressedLength, fTOCCompression);
if (error != B_OK)
return error;
// read in the complete package attributes section
fPackageAttributesSection
= new(std::nothrow) uint8[fPackageAttributesUncompressedLength];
if (fPackageAttributesSection == NULL) {
fErrorOutput->PrintError("Error: Out of memory!\n");
return B_NO_MEMORY;
}
error = _ReadCompressedBuffer(fPackageAttributesOffset,
fPackageAttributesSection, fPackageAttributesCompressedLength,
fPackageAttributesUncompressedLength, fPackageAttributesCompression);
if (error != B_OK)
return error;
// start parsing the TOC
fInPackageAttributes = false;
fCurrentTOCOffset = 0;
// attribute types
@@ -816,7 +844,15 @@ PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler)
{
AttributeHandlerContext context(fErrorOutput, contentHandler);
RootAttributeHandler rootAttributeHandler;
return _ParseContent(&context, &rootAttributeHandler);
status_t result = _ParseContent(&context, &rootAttributeHandler);
if (result != B_OK)
return result;
fInPackageAttributes = true;
fCurrentPackageAttributesOffset = 0;
return _ParsePackageAttributes(&context);
}
@@ -1070,6 +1106,350 @@ PackageReaderImpl::_ParseAttributeTree(AttributeHandlerContext* context)
}
status_t
PackageReaderImpl::_ParsePackageAttributes(AttributeHandlerContext* context)
{
while (true) {
uint8 id;
AttributeValue attributeValue;
bool hasChildren;
uint64 tag;
BPackageInfoAttributeValue handlerValue;
status_t error
= _ReadPackageAttribute(id, attributeValue, &hasChildren, &tag);
if (error != B_OK)
return error;
if (tag == 0)
return B_OK;
switch (id) {
case B_HPKG_PACKAGE_ATTRIBUTE_NAME:
handlerValue.SetTo(B_PACKAGE_INFO_NAME, attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_SUMMARY:
handlerValue.SetTo(B_PACKAGE_INFO_SUMMARY,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION:
handlerValue.SetTo(B_PACKAGE_INFO_DESCRIPTION,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_VENDOR:
handlerValue.SetTo(B_PACKAGE_INFO_VENDOR,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_PACKAGER:
handlerValue.SetTo(B_PACKAGE_INFO_PACKAGER,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE:
if (attributeValue.unsignedInt
>= B_PACKAGE_ARCHITECTURE_ENUM_COUNT) {
fErrorOutput->PrintError(
"Error: Invalid package attribute section: "
"Invalid package architecture %lld encountered\n",
attributeValue.unsignedInt);
return B_BAD_DATA;
}
handlerValue.SetTo(B_PACKAGE_INFO_ARCHITECTURE,
(uint8)attributeValue.unsignedInt);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR:
error = _ParsePackageVersion(handlerValue.version,
attributeValue.string);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_VERSION;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_COPYRIGHT:
handlerValue.SetTo(B_PACKAGE_INFO_COPYRIGHTS,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_LICENSE:
handlerValue.SetTo(B_PACKAGE_INFO_LICENSES,
attributeValue.string);
break;
case B_HPKG_PACKAGE_ATTRIBUTE_PROVIDES_TYPE:
error = _ParsePackageProvides(handlerValue.resolvable,
(BPackageResolvableType)attributeValue.unsignedInt);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_PROVIDES;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_REQUIRES:
error = _ParsePackageResolvableExpression(
handlerValue.resolvableExpression, attributeValue.string,
hasChildren);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_REQUIRES;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_SUPPLEMENTS:
error = _ParsePackageResolvableExpression(
handlerValue.resolvableExpression, attributeValue.string,
hasChildren);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_SUPPLEMENTS;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_CONFLICTS:
error = _ParsePackageResolvableExpression(
handlerValue.resolvableExpression, attributeValue.string,
hasChildren);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_CONFLICTS;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_FRESHENS:
error = _ParsePackageResolvableExpression(
handlerValue.resolvableExpression, attributeValue.string,
hasChildren);
if (error != B_OK)
return error;
handlerValue.attributeIndex = B_PACKAGE_INFO_FRESHENS;
break;
case B_HPKG_PACKAGE_ATTRIBUTE_REPLACES:
handlerValue.SetTo(B_PACKAGE_INFO_REPLACES,
attributeValue.string);
break;
default:
fErrorOutput->PrintError(
"Error: Invalid package attribute section: unexpected "
"package attribute id %d encountered\n", id);
return B_BAD_DATA;
}
error = context->packageContentHandler->HandlePackageAttribute(
handlerValue);
if (error != B_OK)
return error;
}
}
status_t
PackageReaderImpl::_ParsePackageVersion(BPackageVersionData& _version,
const char* major)
{
uint8 id;
AttributeValue value;
status_t error;
_version.major = NULL;
_version.minor = NULL;
_version.micro = NULL;
_version.release = 0;
// major (may have been read already)
if (major == NULL) {
error = _ReadPackageAttribute(id, value);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package version, expected major\n");
return B_BAD_DATA;
}
major = value.string;
}
_version.major = major;
// minor
error = _ReadPackageAttribute(id, value);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_VERSION_MINOR) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package version, expected minor\n");
return B_BAD_DATA;
}
_version.minor = value.string;
// micro
error = _ReadPackageAttribute(id, value);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_VERSION_MICRO) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package version, expected micro\n");
return B_BAD_DATA;
}
_version.micro = value.string;
// release
error = _ReadPackageAttribute(id, value);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_VERSION_RELEASE) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package version, expected release\n");
return B_BAD_DATA;
}
_version.release = (uint8)value.unsignedInt;
return B_OK;
}
status_t
PackageReaderImpl::_ParsePackageProvides(BPackageResolvableData& _resolvable,
BPackageResolvableType providesType)
{
uint8 id;
AttributeValue value;
bool hasChildren;
if (providesType >= B_PACKAGE_RESOLVABLE_TYPE_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid package attribute section: "
"Invalid package provides type %lld encountered\n", providesType);
return B_BAD_DATA;
}
_resolvable.type = providesType;
_resolvable.haveVersion = false;
// provides name
status_t error = _ReadPackageAttribute(id, value, &hasChildren);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_PROVIDES) {
fErrorOutput->PrintError("Error: Invalid package attribute section: "
"Invalid package provides, expected name of resolvable\n");
return B_BAD_DATA;
}
_resolvable.name = value.string;
// there may be a version added as child
if (hasChildren) {
error = _ParsePackageVersion(_resolvable.version);
if (error != B_OK)
return error;
_resolvable.haveVersion = true;
uint64 tag;
if ((error = _ReadUnsignedLEB128(tag)) != B_OK)
return error;
if (tag != 0) {
fErrorOutput->PrintError("Error: Invalid package attribute "
"section: Invalid package provides, expected end-tag\n");
return B_BAD_DATA;
}
}
return B_OK;
}
status_t
PackageReaderImpl::_ParsePackageResolvableExpression(
BPackageResolvableExpressionData& _resolvableExpression,
const char* resolvableName, bool hasChildren)
{
_resolvableExpression.name = resolvableName;
_resolvableExpression.haveOpAndVersion = false;
// there may be an operator and a version added as child
if (hasChildren) {
// resolvable-expression operator
uint8 id;
AttributeValue value;
status_t error = _ReadPackageAttribute(id, value);
if (error != B_OK)
return error;
if (id != B_HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package resolvable expression, expected operator\n");
return B_BAD_DATA;
}
if (value.unsignedInt >= B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package resolvable operator %lld encountered\n",
value.unsignedInt);
return B_BAD_DATA;
}
_resolvableExpression.op
= (BPackageResolvableOperator)value.unsignedInt;
error = _ParsePackageVersion(_resolvableExpression.version);
if (error != B_OK)
return error;
_resolvableExpression.haveOpAndVersion = true;
uint64 tag;
if ((error = _ReadUnsignedLEB128(tag)) != B_OK)
return error;
if (tag != 0) {
fErrorOutput->PrintError("Error: Invalid package attribute section:"
" Invalid package resolvable expression, expected end-tag\n");
return B_BAD_DATA;
}
}
return B_OK;
}
status_t
PackageReaderImpl::_ReadPackageAttribute(uint8& _id, AttributeValue& _value,
bool* _hasChildren, uint64* _tag)
{
uint64 tag;
status_t error = _ReadUnsignedLEB128(tag);
if (error != B_OK)
return error;
if (tag != 0) {
// get the type
uint16 type = B_HPKG_PACKAGE_ATTRIBUTE_TAG_TYPE(tag);
if (type >= B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid package attribute "
"section: attribute type %d not supported!\n", type);
return B_BAD_DATA;
}
// get the value
error = _ReadAttributeValue(type,
B_HPKG_PACKAGE_ATTRIBUTE_TAG_ENCODING(tag), _value);
if (error != B_OK)
return error;
_id = B_HPKG_PACKAGE_ATTRIBUTE_TAG_ID(tag);
if (_id >= B_HPKG_PACKAGE_ATTRIBUTE_ENUM_COUNT) {
fErrorOutput->PrintError("Error: Invalid package attribute section: "
"attribute id %d not supported!\n", _id);
return B_BAD_DATA;
}
}
if (_hasChildren != NULL)
*_hasChildren = B_HPKG_PACKAGE_ATTRIBUTE_TAG_HAS_CHILDREN(tag);
if (_tag != NULL)
*_tag = tag;
return B_OK;
}
status_t
PackageReaderImpl::_ReadAttributeValue(uint8 type, uint8 encoding,
AttributeValue& _value)
@@ -1235,6 +1615,29 @@ PackageReaderImpl::_ReadUnsignedLEB128(uint64& _value)
status_t
PackageReaderImpl::_ReadString(const char*& _string, size_t* _stringLength)
{
if (fInPackageAttributes) {
const char* string = (const char*)fPackageAttributesSection
+ fCurrentPackageAttributesOffset;
size_t stringLength = strnlen(string,
fPackageAttributesUncompressedLength
- fCurrentPackageAttributesOffset);
if (stringLength == fPackageAttributesUncompressedLength
- fCurrentPackageAttributesOffset) {
fErrorOutput->PrintError(
"_ReadString(): string extends beyond package attributes "
"section end\n");
return B_BAD_DATA;
}
_string = string;
if (_stringLength != NULL)
*_stringLength = stringLength;
fCurrentPackageAttributesOffset += stringLength + 1;
return B_OK;
}
const char* string = (const char*)fTOCSection + fCurrentTOCOffset;
size_t stringLength = strnlen(string,
fTOCUncompressedLength - fCurrentTOCOffset);
@@ -1284,6 +1687,24 @@ PackageReaderImpl::_ReadTOCBuffer(void* buffer, size_t size)
}
status_t
PackageReaderImpl::_ReadPackageAttributesBuffer(void* buffer, size_t size)
{
if (size > fPackageAttributesUncompressedLength
- fCurrentPackageAttributesOffset) {
fErrorOutput->PrintError(
"_ReadPackageAttributesBuffer(%lu): read beyond section end\n",
size);
return B_BAD_DATA;
}
memcpy(buffer, fPackageAttributesSection + fCurrentPackageAttributesOffset,
size);
fCurrentPackageAttributesOffset += size;
return B_OK;
}
status_t
PackageReaderImpl::_ReadBuffer(off_t offset, void* buffer, size_t size)
{
+51 -16
View File
@@ -1068,6 +1068,7 @@ PackageWriterImpl::_WritePackageAttributes(hpkg_header& header)
_WriteString(licenseList.ItemAt(i)->String());
}
// provides list
const BObjectList<BPackageResolvable>& providesList
= fPackageInfo.ProvidesList();
for (int i = 0; i < providesList.CountItems(); ++i) {
@@ -1075,31 +1076,41 @@ PackageWriterImpl::_WritePackageAttributes(hpkg_header& header)
bool hasVersion = resolvable->Version().InitCheck() == B_OK;
_WriteUnsignedLEB128(B_HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
B_HPKG_PACKAGE_ATTRIBUTE_PROVIDES_TYPE, B_HPKG_ATTRIBUTE_TYPE_UINT,
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT, hasVersion ? 1 : 0));
_Write<uint8>(fPackageInfo.Architecture());
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT, 0));
_Write<uint8>((uint8)resolvable->Type());
_WriteUnsignedLEB128(B_HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
B_HPKG_PACKAGE_ATTRIBUTE_PROVIDES, B_HPKG_ATTRIBUTE_TYPE_STRING,
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 1));
_WriteString(resolvable->AsString().String());
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, hasVersion));
_WriteString(resolvable->Name().String());
if (hasVersion) {
_WritePackageVersion(resolvable->Version());
_Write<uint8>(0);
}
}
const BObjectList<BPackageResolvableExpression>& requiresList
= fPackageInfo.RequiresList();
for (int i = 0; i < requiresList.CountItems(); ++i) {
BPackageResolvableExpression* resolvableExpr = requiresList.ItemAt(i);
bool hasVersion = resolvableExpr->Version().InitCheck() == B_OK;
// requires list
_WritePackageResolvableExpressionList(fPackageInfo.RequiresList(),
B_HPKG_PACKAGE_ATTRIBUTE_REQUIRES);
// supplements list
_WritePackageResolvableExpressionList(fPackageInfo.SupplementsList(),
B_HPKG_PACKAGE_ATTRIBUTE_SUPPLEMENTS);
// conflicts list
_WritePackageResolvableExpressionList(fPackageInfo.ConflictsList(),
B_HPKG_PACKAGE_ATTRIBUTE_CONFLICTS);
// freshens list
_WritePackageResolvableExpressionList(fPackageInfo.FreshensList(),
B_HPKG_PACKAGE_ATTRIBUTE_FRESHENS);
// replaces list
const BObjectList<BString>& replacesList = fPackageInfo.ReplacesList();
for (int i = 0; i < replacesList.CountItems(); ++i) {
_WriteUnsignedLEB128(B_HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
B_HPKG_PACKAGE_ATTRIBUTE_REQUIRES, B_HPKG_ATTRIBUTE_TYPE_STRING,
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, hasVersion));
_WriteString(resolvableExpr->AsString().String());
if (hasVersion) {
_WritePackageVersion(resolvableExpr->Version());
_Write<uint8>(0);
}
B_HPKG_PACKAGE_ATTRIBUTE_REPLACES, B_HPKG_ATTRIBUTE_TYPE_STRING,
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
_WriteString(replacesList.ItemAt(i)->String());
}
_Write<uint8>(0);
@@ -1143,6 +1154,30 @@ PackageWriterImpl::_WritePackageVersion(const BPackageVersion& version)
}
void
PackageWriterImpl::_WritePackageResolvableExpressionList(
const BObjectList<BPackageResolvableExpression>& list, uint8 id)
{
for (int i = 0; i < list.CountItems(); ++i) {
BPackageResolvableExpression* resolvableExpr = list.ItemAt(i);
bool hasVersion = resolvableExpr->Version().InitCheck() == B_OK;
_WriteUnsignedLEB128(B_HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
id, B_HPKG_ATTRIBUTE_TYPE_STRING,
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, hasVersion));
_WriteString(resolvableExpr->Name().String());
if (hasVersion) {
_WriteUnsignedLEB128(B_HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
B_HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR,
B_HPKG_ATTRIBUTE_TYPE_UINT, B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT,
0));
_Write<uint8>(resolvableExpr->Operator());
_WritePackageVersion(resolvableExpr->Version());
_Write<uint8>(0);
}
}
}
void
PackageWriterImpl::_WriteAttributeValue(const AttributeValue& value,
uint8 encoding)