package kit: some fixes for multi-version support
* Use enums/constants/functions instead of preprocessor macros. * Missing include in PackageInfoAttributeValue.h. * PackageReaderImpl::Init(): Check version before header size and return B_MISMATCHED_VALUES instead of B_BAD_DATA, if the version doesn't match. This allows callers to determine the condition and try a reader for a different version. A more flexible interface for that case would be nice, but since we want to support the old package version only temporarily, the current solution should be good enough.
This commit is contained in:
@@ -73,11 +73,13 @@ enum {
|
||||
|
||||
// maximum number of bytes of data to be encoded inline; more will be allocated
|
||||
// on the heap
|
||||
#define B_HPKG_MAX_INLINE_DATA_SIZE 8
|
||||
enum {
|
||||
B_HPKG_MAX_INLINE_DATA_SIZE = 8
|
||||
};
|
||||
|
||||
|
||||
// name of file containing package information (in package's root folder)
|
||||
#define B_HPKG_PACKAGE_INFO_FILE_NAME ".PackageInfo"
|
||||
extern const char* const B_HPKG_PACKAGE_INFO_FILE_NAME;
|
||||
|
||||
|
||||
// package attribute IDs
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <package/PackageArchitecture.h>
|
||||
#include <package/PackageInfoAttributes.h>
|
||||
#include <package/PackageResolvableOperator.h>
|
||||
|
||||
@@ -64,17 +64,41 @@ struct hpkg_repo_header {
|
||||
|
||||
// attribute tag arithmetics
|
||||
// (using 6 bits for id, 3 for type, 1 for hasChildren and 2 for encoding)
|
||||
#define HPKG_ATTRIBUTE_TAG_COMPOSE(id, type, encoding, hasChildren) \
|
||||
(((uint16(encoding) << 10) | (uint16((hasChildren) ? 1 : 0) << 9) \
|
||||
| (uint16(type) << 6) | (uint16(id))) + 1)
|
||||
#define HPKG_ATTRIBUTE_TAG_ENCODING(tag) \
|
||||
((uint16((tag) - 1) >> 10) & 0x3)
|
||||
#define HPKG_ATTRIBUTE_TAG_HAS_CHILDREN(tag) \
|
||||
(((uint16((tag) - 1) >> 9) & 0x1) != 0)
|
||||
#define HPKG_ATTRIBUTE_TAG_TYPE(tag) \
|
||||
((uint16((tag) - 1) >> 6) & 0x7)
|
||||
#define HPKG_ATTRIBUTE_TAG_ID(tag) \
|
||||
(uint16((tag) - 1) & 0x3f)
|
||||
static inline uint16
|
||||
compose_attribute_tag(uint16 id, uint16 type, uint16 encoding, bool hasChildren)
|
||||
{
|
||||
return ((encoding << 10) | (uint16(hasChildren ? 1 : 0) << 9) | (type << 6)
|
||||
| id)
|
||||
+ 1;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
attribute_tag_encoding(uint16 tag)
|
||||
{
|
||||
return ((tag - 1) >> 10) & 0x3;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
attribute_tag_has_children(uint16 tag)
|
||||
{
|
||||
return (((tag - 1) >> 9) & 0x1) != 0;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
attribute_tag_type(uint16 tag)
|
||||
{
|
||||
return ((tag - 1) >> 6) & 0x7;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16
|
||||
attribute_tag_id(uint16 tag)
|
||||
{
|
||||
return (tag - 1) & 0x3f;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
@@ -77,6 +77,7 @@ HAIKU_PACKAGE_FS_PACKAGE_READER_SOURCES =
|
||||
DataReader.cpp
|
||||
ErrorOutput.cpp
|
||||
FDDataReader.cpp
|
||||
HPKGDefs.cpp
|
||||
PackageContentHandler.cpp
|
||||
PackageData.cpp
|
||||
PackageDataReader.cpp
|
||||
|
||||
@@ -956,8 +956,10 @@ Volume::_AddPackageContent(Package* package, bool notify)
|
||||
for (PackageNodeList::Iterator it = package->Nodes().GetIterator();
|
||||
PackageNode* node = it.Next();) {
|
||||
// skip over ".PackageInfo" file, it isn't part of the package content
|
||||
if (strcmp(node->Name(), B_HPKG_PACKAGE_INFO_FILE_NAME) == 0)
|
||||
if (strcmp(node->Name(),
|
||||
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
|
||||
continue;
|
||||
}
|
||||
error = _AddPackageContentRootNode(package, node, notify);
|
||||
if (error != B_OK) {
|
||||
_RemovePackageContent(package, node, notify);
|
||||
@@ -981,8 +983,10 @@ Volume::_RemovePackageContent(Package* package, PackageNode* endNode,
|
||||
PackageNode* nextNode = package->Nodes().GetNext(node);
|
||||
|
||||
// skip over ".PackageInfo" file, it isn't part of the package content
|
||||
if (strcmp(node->Name(), B_HPKG_PACKAGE_INFO_FILE_NAME) != 0)
|
||||
if (strcmp(node->Name(),
|
||||
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) != 0) {
|
||||
_RemovePackageContentRootNode(package, node, NULL, notify);
|
||||
}
|
||||
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ add_current_directory_entries(BPackageWriter& packageWriter,
|
||||
|
||||
// skip the .PackageInfo, if requested
|
||||
if (skipPackageInfo
|
||||
&& strcmp(entry->d_name, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
|
||||
&& strcmp(entry->d_name,
|
||||
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,8 +150,8 @@ command_create(int argc, const char* const* argv)
|
||||
}
|
||||
|
||||
// add the .PackageInfo
|
||||
result = packageWriter.AddEntry(B_HPKG_PACKAGE_INFO_FILE_NAME,
|
||||
packageInfoFD);
|
||||
result = packageWriter.AddEntry(
|
||||
BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME, packageInfoFD);
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ HPKG_SOURCES =
|
||||
DataReader.cpp
|
||||
ErrorOutput.cpp
|
||||
FDDataReader.cpp
|
||||
HPKGDefs.cpp
|
||||
PackageContentHandler.cpp
|
||||
PackageData.cpp
|
||||
PackageDataReader.cpp
|
||||
|
||||
@@ -19,6 +19,7 @@ HPKG_SOURCES =
|
||||
DataReader.cpp
|
||||
ErrorOutput.cpp
|
||||
FDDataReader.cpp
|
||||
HPKGDefs.cpp
|
||||
PackageContentHandler.cpp
|
||||
PackageData.cpp
|
||||
PackageDataReader.cpp
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <package/hpkg/HPKGDefs.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
namespace BHPKG {
|
||||
|
||||
|
||||
const char* const B_HPKG_PACKAGE_INFO_FILE_NAME = ".PackageInfo";
|
||||
|
||||
|
||||
} // namespace BHPKG
|
||||
|
||||
} // namespace BPackageKit
|
||||
@@ -433,6 +433,13 @@ PackageReaderImpl::Init(int fd, bool keepFD)
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// version
|
||||
if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
|
||||
ErrorOutput()->PrintError("Error: Invalid/unsupported package file "
|
||||
"version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
|
||||
return B_MISMATCHED_VALUES;
|
||||
}
|
||||
|
||||
// header size
|
||||
fHeapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
|
||||
if ((size_t)fHeapOffset < sizeof(hpkg_header)) {
|
||||
@@ -441,13 +448,6 @@ PackageReaderImpl::Init(int fd, bool keepFD)
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// version
|
||||
if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
|
||||
ErrorOutput()->PrintError("Error: Invalid/unsupported package file "
|
||||
"version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// total size
|
||||
fTotalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
|
||||
if (fTotalSize != (uint64)st.st_size) {
|
||||
|
||||
@@ -1442,7 +1442,7 @@ PackageWriterImpl::_WriteAttributeChildren(Attribute* attribute)
|
||||
while (Attribute* child = it.Next()) {
|
||||
// write tag
|
||||
uint8 encoding = child->value.ApplicableEncoding();
|
||||
WriteUnsignedLEB128(HPKG_ATTRIBUTE_TAG_COMPOSE(child->id,
|
||||
WriteUnsignedLEB128(compose_attribute_tag(child->id,
|
||||
child->value.type, encoding, !child->children.IsEmpty()));
|
||||
|
||||
// write value
|
||||
|
||||
@@ -799,7 +799,7 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
|
||||
|
||||
if (tag != 0) {
|
||||
// get the type
|
||||
uint16 type = HPKG_ATTRIBUTE_TAG_TYPE(tag);
|
||||
uint16 type = attribute_tag_type(tag);
|
||||
if (type >= B_HPKG_ATTRIBUTE_TYPE_ENUM_COUNT) {
|
||||
fErrorOutput->PrintError("Error: Invalid %s section: attribute "
|
||||
"type %d not supported!\n", fCurrentSection->name, type);
|
||||
@@ -807,12 +807,12 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
|
||||
}
|
||||
|
||||
// get the value
|
||||
error = ReadAttributeValue(type, HPKG_ATTRIBUTE_TAG_ENCODING(tag),
|
||||
error = ReadAttributeValue(type, attribute_tag_encoding(tag),
|
||||
_value);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
_id = HPKG_ATTRIBUTE_TAG_ID(tag);
|
||||
_id = attribute_tag_id(tag);
|
||||
if (_id >= B_HPKG_ATTRIBUTE_ID_ENUM_COUNT) {
|
||||
fErrorOutput->PrintError("Error: Invalid %s section: "
|
||||
"attribute id %d not supported!\n", fCurrentSection->name, _id);
|
||||
@@ -821,7 +821,7 @@ ReaderImplBase::_ReadAttribute(uint8& _id, AttributeValue& _value,
|
||||
}
|
||||
|
||||
if (_hasChildren != NULL)
|
||||
*_hasChildren = HPKG_ATTRIBUTE_TAG_HAS_CHILDREN(tag);
|
||||
*_hasChildren = attribute_tag_has_children(tag);
|
||||
if (_tag != NULL)
|
||||
*_tag = tag;
|
||||
|
||||
|
||||
@@ -782,7 +782,7 @@ WriterImplBase::_WritePackageAttributes(
|
||||
uint8 encoding = attribute->ApplicableEncoding();
|
||||
|
||||
// write tag
|
||||
WriteUnsignedLEB128(HPKG_ATTRIBUTE_TAG_COMPOSE(
|
||||
WriteUnsignedLEB128(compose_attribute_tag(
|
||||
attribute->id, attribute->type, encoding,
|
||||
!attribute->children.IsEmpty()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user