* implemented repository reader and fixed some bugs in writer that

have been exposed during testing of reader

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40494 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2011-02-14 20:25:10 +00:00
parent 973f8e214d
commit 34d56c1bf5
11 changed files with 234 additions and 1929 deletions

View File

@ -20,7 +20,7 @@ namespace BPrivate {
using BPrivate::RepositoryReaderImpl;
class BErrorOutput;
class BRepositoryContentHandler;
class BPackageContentHandler;
class BRepositoryReader {

View File

@ -46,7 +46,7 @@ struct hpkg_repo_header {
uint32 magic; // "hpkr"
uint16 header_size;
uint16 version;
uint32 total_size;
uint64 total_size;
// repository info section
uint32 info_compression;
@ -55,10 +55,10 @@ struct hpkg_repo_header {
// package attributes section
uint32 packages_compression;
uint32 packages_length_compressed;
uint32 packages_length_uncompressed;
uint32 packages_strings_length;
uint32 packages_strings_count;
uint64 packages_length_compressed;
uint64 packages_length_uncompressed;
uint64 packages_strings_length;
uint64 packages_strings_count;
};

View File

@ -6,14 +6,9 @@
#define _PACKAGE__HPKG__PRIVATE__REPOSITORY_READER_IMPL_H_
#include <SupportDefs.h>
#include <package/hpkg/ReaderImplBase.h>
#include <util/SinglyLinkedList.h>
#include <package/hpkg/PackageAttributeValue.h>
#include <package/hpkg/PackageContentHandler.h>
#include <package/hpkg/PackageInfoAttributeValue.h>
#include <package/hpkg/PackageReader.h>
#include <package/RepositoryInfo.h>
namespace BPackageKit {
@ -21,165 +16,34 @@ namespace BPackageKit {
namespace BHPKG {
class BPackageEntry;
class BPackageEntryAttribute;
class BErrorOutput;
namespace BPrivate {
class PackageReaderImpl {
class RepositoryReaderImpl : public ReaderImplBase {
typedef ReaderImplBase inherited;
public:
PackageReaderImpl(
RepositoryReaderImpl(
BErrorOutput* errorOutput);
~PackageReaderImpl();
~RepositoryReaderImpl();
status_t Init(const char* fileName);
status_t Init(int fd, bool keepFD);
status_t GetRepositoryInfo(
BRepositoryInfo* _repositoryInfo) const;
status_t ParseContent(
BPackageContentHandler* contentHandler);
status_t ParseContent(BLowLevelPackageContentHandler*
contentHandler);
int PackageFileFD() { return fFD; }
private:
struct AttributeType;
struct AttributeTypeReference;
struct AttributeHandlerContext;
struct AttributeHandler;
struct IgnoreAttributeHandler;
struct DataAttributeHandler;
struct AttributeAttributeHandler;
struct EntryAttributeHandler;
struct RootAttributeHandler;
struct PackageAttributeHandler;
struct PackageContentListHandler;
struct SectionInfo {
uint32 compression;
uint32 compressedLength;
uint32 uncompressedLength;
uint8* data;
uint64 offset;
uint64 currentOffset;
uint64 stringsLength;
uint64 stringsCount;
char** strings;
const char* name;
SectionInfo(const char* _name)
:
data(NULL),
strings(NULL),
name(_name)
{
}
~SectionInfo()
{
delete[] strings;
delete[] data;
}
};
typedef BPackageAttributeValue AttributeValue;
typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
private:
status_t _Init(const char* fileName);
const char* _CheckCompression(
const SectionInfo& section) const;
status_t _ParseTOCAttributeTypes();
status_t _ParseStrings();
status_t _ParseContent(AttributeHandlerContext* context,
AttributeHandler* rootAttributeHandler);
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);
status_t _ReadUnsignedLEB128(uint64& _value);
status_t _ReadString(const char*& _string,
size_t* _stringLength = NULL);
template<typename Type>
inline status_t _Read(Type& _value);
status_t _GetTOCBuffer(size_t size,
const void*& _buffer);
status_t _ReadSectionBuffer(void* buffer, size_t size);
status_t _ReadBuffer(off_t offset, void* buffer,
size_t size);
status_t _ReadCompressedBuffer(
const SectionInfo& section);
static int8 _GetStandardIndex(const AttributeType* type);
inline AttributeHandler* _CurrentAttributeHandler() const;
inline void _PushAttributeHandler(
AttributeHandler* handler);
inline AttributeHandler* _PopAttributeHandler();
private:
BErrorOutput* fErrorOutput;
int fFD;
bool fOwnsFD;
uint64 fTotalSize;
uint64 fHeapOffset;
uint64 fHeapSize;
uint64 fTOCAttributeTypesLength;
uint64 fTOCAttributeTypesCount;
SectionInfo fTOCSection;
SectionInfo fPackageAttributesSection;
SectionInfo* fCurrentSection;
AttributeTypeReference* fAttributeTypes;
AttributeHandlerList* fAttributeHandlerStack;
uint8* fScratchBuffer;
size_t fScratchBufferSize;
SectionInfo fRepositoryInfoSection;
BRepositoryInfo fRepositoryInfo;
};
template<typename Type>
status_t
PackageReaderImpl::_Read(Type& _value)
{
return _ReadSectionBuffer(&_value, sizeof(Type));
}
} // namespace BPrivate
} // namespace BHPKG

View File

@ -185,13 +185,18 @@ protected:
void WriteBuffer(const void* buffer, size_t size,
off_t offset);
int FD() const;
AbstractDataWriter* DataWriter() const;
const PackageAttributeList& PackageAttributes() const;
PackageAttributeList& PackageAttributes();
inline int FD() const;
void SetDataWriter(AbstractDataWriter* dataWriter);
void SetFinished(bool finished);
inline const PackageAttributeList& PackageAttributes() const;
inline PackageAttributeList& PackageAttributes();
inline const StringCache& PackageStringCache() const;
inline StringCache& PackageStringCache();
inline AbstractDataWriter* DataWriter() const;
inline void SetDataWriter(AbstractDataWriter* dataWriter);
inline void SetFinished(bool finished);
private:
void _WritePackageAttributes(
@ -283,6 +288,20 @@ WriterImplBase::PackageAttributes()
}
inline const StringCache&
WriterImplBase::PackageStringCache() const
{
return fPackageStringCache;
}
inline StringCache&
WriterImplBase::PackageStringCache()
{
return fPackageStringCache;
}
inline void
WriterImplBase::SetFinished(bool finished)
{

View File

@ -48,10 +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("\tsha256-checksum: %s\n", packageInfo.Checksum().String());
printf("\tsummary: %s\n", packageInfo.Summary().String());
printf("\tvendor: %s\n", packageInfo.Vendor().String());
printf("\tpackager: %s\n", packageInfo.Packager().String());
printf("\tchecksum: %s\n", packageInfo.Checksum().String());
if (uint32 flags = packageInfo.Flags()) {
printf("\tflags:\n");
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
@ -59,7 +59,8 @@ public:
if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
printf("\t\tsystem_package\n");
}
}
} else
printf("\tchecksum: %s\n", packageInfo.Checksum().String());
}
virtual void OnRepositoryInfoSectionDone(uint32 uncompressedSize)

View File

@ -12,12 +12,11 @@
#include <string.h>
#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/hpkg/RepositoryReader.h>
#include <package/PackageInfo.h>
#include <package/RepositoryInfo.h>
#include "package.h"
#include "StandardErrorOutput.h"
@ -26,115 +25,64 @@
using namespace BPackageKit::BHPKG;
using namespace BPackageKit;
/*
struct PackageContentListHandler : BPackageContentHandler {
PackageContentListHandler(bool listAttributes)
struct RepositoryContentListHandler : BPackageContentHandler {
RepositoryContentListHandler(bool verbose)
:
fLevel(0),
fListAttribute(listAttributes)
fVerbose(verbose)
{
}
virtual status_t HandleEntry(BPackageEntry* entry)
{
fLevel++;
int indentation = (fLevel - 1) * 2;
printf("%*s", indentation, "");
// name and size
printf("%-*s", indentation < 32 ? 32 - indentation : 0, entry->Name());
printf(" %8llu", entry->Data().UncompressedSize());
// time
struct tm* time = localtime(&entry->ModifiedTime().tv_sec);
printf(" %04d-%02d-%02d %02d:%02d:%02d",
1900 + time->tm_year, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec);
// file type
mode_t mode = entry->Mode();
if (S_ISREG(mode))
printf(" -");
else if (S_ISDIR(mode))
printf(" d");
else if (S_ISLNK(mode))
printf(" l");
else
printf(" ?");
// permissions
char buffer[4];
printf("%s", _PermissionString(buffer, mode >> 6,
(mode & S_ISUID) != 0));
printf("%s", _PermissionString(buffer, mode >> 3,
(mode & S_ISGID) != 0));
printf("%s", _PermissionString(buffer, mode, false));
// print the symlink path
if (S_ISLNK(mode))
printf(" -> %s", entry->SymlinkPath());
printf("\n");
return B_OK;
}
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
BPackageEntryAttribute* attribute)
{
if (!fListAttribute)
return B_OK;
int indentation = fLevel * 2;
printf("%*s<", indentation, "");
printf("%-*s %8llu", indentation < 31 ? 31 - indentation : 0,
attribute->Name(), attribute->Data().UncompressedSize());
uint32 type = attribute->Type();
if (isprint(type & 0xff) && isprint((type >> 8) & 0xff)
&& isprint((type >> 16) & 0xff) && isprint(type >> 24)) {
printf(" '%c%c%c%c'", int(type >> 24), int((type >> 16) & 0xff),
int((type >> 8) & 0xff), int(type & 0xff));
} else
printf(" %#lx", type);
printf(">\n");
return B_OK;
}
virtual status_t HandleEntryDone(BPackageEntry* entry)
{
fLevel--;
return B_OK;
}
virtual status_t HandlePackageAttribute(
const BPackageInfoAttributeValue& value)
{
switch (value.attributeIndex) {
switch (value.attributeID) {
case B_PACKAGE_INFO_NAME:
printf("package-attributes:\n");
printf("\tname: %s\n", value.string);
if (fVerbose) {
printf("package-attributes:\n");
printf("\tname: %s\n", value.string);
} else
printf("package: %s", value.string);
break;
case B_PACKAGE_INFO_SUMMARY:
printf("\tsummary: %s\n", value.string);
if (fVerbose)
printf("\tsummary: %s\n", value.string);
break;
case B_PACKAGE_INFO_DESCRIPTION:
printf("\tdescription: %s\n", value.string);
if (fVerbose)
printf("\tdescription: %s\n", value.string);
break;
case B_PACKAGE_INFO_VENDOR:
printf("\tvendor: %s\n", value.string);
if (fVerbose)
printf("\tvendor: %s\n", value.string);
break;
case B_PACKAGE_INFO_PACKAGER:
printf("\tpackager: %s\n", value.string);
if (fVerbose)
printf("\tpackager: %s\n", value.string);
break;
case B_PACKAGE_INFO_FLAGS:
if (value.unsignedInt == 0)
if (value.unsignedInt == 0 || !fVerbose)
break;
printf("\tflags:\n");
if ((value.unsignedInt & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
@ -144,25 +92,33 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_ARCHITECTURE:
printf("\tarchitecture: %s\n",
BPackageInfo::kArchitectureNames[value.unsignedInt]);
if (fVerbose) {
printf("\tarchitecture: %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);
if (!fVerbose)
printf("(");
_PrintPackageVersion(value.version);
if (!fVerbose)
printf(")\n");
break;
case B_PACKAGE_INFO_COPYRIGHTS:
printf("\tcopyright: %s\n", value.string);
if (fVerbose)
printf("\tcopyright: %s\n", value.string);
break;
case B_PACKAGE_INFO_LICENSES:
printf("\tlicense: %s\n", value.string);
if (fVerbose)
printf("\tlicense: %s\n", value.string);
break;
case B_PACKAGE_INFO_PROVIDES:
if (!fVerbose)
break;
printf("\tprovides: %s", value.resolvable.name);
if (value.resolvable.haveVersion) {
printf(" = ");
@ -172,6 +128,8 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_REQUIRES:
if (!fVerbose)
break;
printf("\trequires: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
@ -182,6 +140,8 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_SUPPLEMENTS:
if (!fVerbose)
break;
printf("\tsupplements: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
@ -192,6 +152,8 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_CONFLICTS:
if (!fVerbose)
break;
printf("\tconflicts: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
@ -202,6 +164,8 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_FRESHENS:
if (!fVerbose)
break;
printf("\tfreshens: %s", value.resolvableExpression.name);
if (value.resolvableExpression.haveOpAndVersion) {
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
@ -212,44 +176,30 @@ struct PackageContentListHandler : BPackageContentHandler {
break;
case B_PACKAGE_INFO_REPLACES:
if (!fVerbose)
break;
printf("\treplaces: %s\n", value.string);
break;
case B_PACKAGE_INFO_CHECKSUM:
printf("\tchecksum: %s\n", value.string);
break;
default:
printf(
"*** Invalid package attribute section: unexpected "
"package attribute index %d encountered\n",
value.attributeIndex);
"package attribute id %d encountered\n", value.attributeID);
return B_BAD_DATA;
}
return B_OK;
}
virtual status_t HandlePackageAttributesDone()
{
return B_OK;
}
virtual void HandleErrorOccurred()
{
}
private:
static const char* _PermissionString(char* buffer, uint32 mode, bool sticky)
{
buffer[0] = (mode & 0x4) != 0 ? 'r' : '-';
buffer[1] = (mode & 0x2) != 0 ? 'w' : '-';
if ((mode & 0x1) != 0)
buffer[2] = sticky ? 's' : 'x';
else
buffer[2] = '-';
buffer[3] = '\0';
return buffer;
}
static void _PrintPackageVersion(const BPackageVersionData& version)
{
printf("%s", version.major);
@ -263,59 +213,60 @@ private:
private:
int fLevel;
bool fListAttribute;
bool fVerbose;
};
*/
int
command_list(int argc, const char* const* argv)
{
bool listAttributes = false;
bool verbose = false;
while (true) {
static struct option sLongOptions[] = {
{ "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+ha", sLongOptions, NULL);
int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
if (c == -1)
break;
switch (c) {
case 'a':
listAttributes = true;
break;
case 'h':
print_usage_and_exit(false);
break;
case 'v':
verbose = true;
break;
default:
print_usage_and_exit(true);
break;
}
}
// One argument should remain -- the package file name.
// One argument should remain -- the repository file name.
if (optind + 1 != argc)
print_usage_and_exit(true);
const char* packageFileName = argv[optind++];
const char* repositoryFileName = argv[optind++];
// open package
// StandardErrorOutput errorOutput;
// BPackageReader packageReader(&errorOutput);
// status_t error = packageReader.Init(packageFileName);
// if (error != B_OK)
// return 1;
// open repository
StandardErrorOutput errorOutput;
BRepositoryReader repositoryReader(&errorOutput);
status_t error = repositoryReader.Init(repositoryFileName);
if (error != B_OK)
return 1;
// list
// PackageContentListHandler handler(listAttributes);
// error = packageReader.ParseContent(&handler);
// if (error != B_OK)
// return 1;
RepositoryContentListHandler handler(verbose);
error = repositoryReader.ParseContent(&handler);
if (error != B_OK)
return 1;
return 0;
}

View File

@ -26,6 +26,8 @@ HPKG_SOURCES =
PackageWriter.cpp
PackageWriterImpl.cpp
ReaderImplBase.cpp
RepositoryReader.cpp
RepositoryReaderImpl.cpp
RepositoryWriter.cpp
RepositoryWriterImpl.cpp
Strings.cpp

View File

@ -408,6 +408,10 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute(
fPackageInfoValue.SetTo(B_PACKAGE_INFO_REPLACES, value.string);
break;
case B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM:
fPackageInfoValue.SetTo(B_PACKAGE_INFO_CHECKSUM, value.string);
break;
default:
context->errorOutput->PrintError(
"Error: Invalid package attribute section: unexpected "

View File

@ -9,6 +9,7 @@
#include <new>
#include <package/hpkg/ErrorOutput.h>
#include <package/hpkg/PackageContentHandler.h>
#include <package/hpkg/RepositoryReaderImpl.h>
@ -41,7 +42,7 @@ BRepositoryReader::Init(const char* fileName)
status_t
BRepositoryReader::ParseContent(BRepositoryContentHandler* contentHandler)
BRepositoryReader::ParseContent(BPackageContentHandler* contentHandler)
{
if (fImpl == NULL)
return B_NO_INIT;

File diff suppressed because it is too large Load Diff

View File

@ -350,7 +350,7 @@ RepositoryWriterImpl::_Finish()
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_INT32(totalSize);
header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);
// write the header
WriteBuffer(&header, sizeof(header), 0);
@ -534,12 +534,12 @@ RepositoryWriterImpl::_WritePackageAttributes(hpkg_repo_header& header,
header.packages_compression
= B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
header.packages_length_compressed
= B_HOST_TO_BENDIAN_INT32(_packagesLengthCompressed);
= B_HOST_TO_BENDIAN_INT64(_packagesLengthCompressed);
header.packages_length_uncompressed
= B_HOST_TO_BENDIAN_INT32(zlibWriter.BytesWritten());
header.packages_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount);
= B_HOST_TO_BENDIAN_INT64(zlibWriter.BytesWritten());
header.packages_strings_count = B_HOST_TO_BENDIAN_INT64(stringsCount);
header.packages_strings_length
= B_HOST_TO_BENDIAN_INT32(stringsLengthUncompressed);
= B_HOST_TO_BENDIAN_INT64(stringsLengthUncompressed);
return endOffset;
}