More work on package kit:

* added class BPackageInfo, which contains packaging attributes of
  a package (the values relevant for package management) 
* implemented parser (mostly) for reading a BPackageInfo from a config
  file (.PackageInfo) in order to pass them on to the PackageWriter 
  when creating a package
* pulled hpkg-related stuff from bin/package into the package kit
* adjusted packagefs-Volume to skip .PackageInfo files when populating
  the mountpoint, as those files shouldn't appear as part of an
  activated package


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40301 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2011-01-27 23:17:03 +00:00
parent fe0019dda4
commit 0d6b3b20e1
56 changed files with 1734 additions and 122 deletions
+3 -2
View File
@@ -15,8 +15,9 @@ extern const char* kPackageVendorAttribute;
extern const char* kPackageVersionAttribute;
// attributes kept local to packages
extern const char* kPackageCopyrightAttribute;
extern const char* kPackageLicenseAttribute;
extern const char* kPackageCopyrightsAttribute;
extern const char* kPackageLicensesAttribute;
extern const char* kPackagePackagerAttribute;
extern const char* kPackageProvidesAttribute;
extern const char* kPackageRequiresAttribute;
+183
View File
@@ -0,0 +1,183 @@
/*
* Copyright 2011, Oliver Tappe <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__PACKAGE_INFO_H_
#define _PACKAGE__PACKAGE_INFO_H_
#include <ObjectList.h>
#include <String.h>
class BEntry;
namespace BPackageKit {
enum BPackageInfoIndex {
B_PACKAGE_INFO_NAME = 0,
B_PACKAGE_INFO_SUMMARY, // single line, 72 chars max
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,
B_PACKAGE_INFO_COPYRIGHTS, // list
B_PACKAGE_INFO_LICENSES, // list
B_PACKAGE_INFO_PROVIDES, // list
B_PACKAGE_INFO_REQUIRES, // list
//
B_PACKAGE_INFO_ENUM_COUNT,
};
enum BPackageArchitecture {
B_PACKAGE_ARCHITECTURE_NONE = 0,
B_PACKAGE_ARCHITECTURE_X86,
B_PACKAGE_ARCHITECTURE_X86_GCC2,
//
B_PACKAGE_ARCHITECTURE_ENUM_COUNT,
};
class BPackageVersion {
public:
void MakeEmpty() {}
};
class BPackageProvision {
public:
int Compare(const BPackageProvision& other) const
{
return fX.Compare(other.fX);
}
private:
BString fX;
};
class BPackageRequirement {
public:
int Compare(const BPackageRequirement& other) const
{
return fX.Compare(other.fX);
}
private:
BString fX;
};
/*
* Keeps a list of package info elements (e.g. name, version, vendor, ...) which
* will be converted to package attributes when creating a package. Usually,
* these elements have been parsed from a ".PackageInfo"-file.
* Alternatively, the package reader populates a BPackageInfo object by
* collecting package attributes from an existing package.
*/
class BPackageInfo {
public:
struct ParseErrorListener {
virtual ~ParseErrorListener();
virtual void OnError(const BString& msg, int line, int col) = 0;
};
public:
BPackageInfo();
~BPackageInfo();
status_t ReadFromConfigFile(
const BEntry& packageInfoEntry,
ParseErrorListener* listener = NULL);
status_t ReadFromConfigString(
const BString& packageInfoString,
ParseErrorListener* listener = NULL);
status_t InitCheck() const;
const BString& Name() const;
const BString& Summary() const;
const BString& Description() const;
const BString& Vendor() const;
const BString& Packager() const;
BPackageArchitecture Architecture() const;
const BPackageVersion& Version() const;
const BObjectList<BString>& Copyrights() const;
const BObjectList<BString>& Licenses() const;
const BObjectList<BPackageRequirement>& Requirements() const;
const BObjectList<BPackageProvision>& Provisions() const;
void SetName(const BString& name);
void SetSummary(const BString& summary);
void SetDescription(const BString& description);
void SetVendor(const BString& vendor);
void SetPackager(const BString& packager);
void SetArchitecture(
BPackageArchitecture architecture);
void SetVersion(const BPackageVersion& version);
void ClearCopyrights();
status_t AddCopyright(const BString& copyright);
status_t RemoveCopyright(const BString& copyright);
void ClearLicenses();
status_t AddLicense(const BString& license);
status_t RemoveLicense(const BString& license);
void ClearProvisions();
status_t AddProvision(
const BPackageProvision& provision);
status_t RemoveProvision(
const BPackageProvision& provision);
void ClearRequirements();
status_t AddRequirement(
const BPackageRequirement& requirement);
status_t RemoveRequirement(
const BPackageRequirement& requirement);
void MakeEmpty();
public:
static status_t GetElementName(
BPackageInfoIndex index,
const char** name);
private:
class Parser;
friend class Parser;
static const char* kElementNames[];
static const char* kArchitectureNames[];
private:
BString fName;
BString fSummary;
BString fDescription;
BString fVendor;
BString fPackager;
BPackageArchitecture fArchitecture;
BPackageVersion fVersion;
BObjectList<BString> fCopyrights;
BObjectList<BString> fLicenses;
BObjectList<BPackageProvision> fProvisions;
BObjectList<BPackageRequirement> fRequirements;
};
} // namespace BPackageKit
#endif // _PACKAGE__PACKAGE_INFO_H_
+3 -3
View File
@@ -2,8 +2,8 @@
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__ROSTER_H_
#define _PACKAGE__ROSTER_H_
#ifndef _PACKAGE__PACKAGE_ROSTER_H_
#define _PACKAGE__PACKAGE_ROSTER_H_
#include <Entry.h>
@@ -68,4 +68,4 @@ private:
} // namespace BPackageKit
#endif // _PACKAGE__ROSTER_H_
#endif // _PACKAGE__PACKAGE_ROSTER_H_
@@ -0,0 +1,71 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__BLOCK_BUFFER_CACHE_H_
#define _PACKAGE__HPKG__BLOCK_BUFFER_CACHE_H_
#include <package/hpkg/BufferCache.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class BlockBufferCache : public BufferCache {
public:
BlockBufferCache(size_t blockSize,
uint32 maxCachedBlocks);
virtual ~BlockBufferCache();
virtual status_t Init();
virtual CachedBuffer* GetBuffer(size_t size,
CachedBuffer** owner = NULL,
bool* _newBuffer = NULL);
virtual void PutBufferAndCache(CachedBuffer** owner);
virtual void PutBuffer(CachedBuffer** owner);
virtual bool Lock() = 0;
virtual void Unlock() = 0;
private:
typedef DoublyLinkedList<CachedBuffer> BufferList;
private:
CachedBuffer* _AllocateBuffer(size_t size,
CachedBuffer** owner, bool* _newBuffer);
// object must not be locked
private:
size_t fBlockSize;
uint32 fMaxCachedBlocks;
uint32 fAllocatedBlocks;
BufferList fUnusedBuffers;
BufferList fCachedBuffers;
};
class BlockBufferCacheNoLock : public BlockBufferCache {
public:
BlockBufferCacheNoLock(size_t blockSize,
uint32 maxCachedBlocks);
virtual ~BlockBufferCacheNoLock();
virtual bool Lock();
virtual void Unlock();
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__BLOCK_BUFFER_CACHE_H_
+105
View File
@@ -0,0 +1,105 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__BUFFER_CACHE_H_
#define _PACKAGE__HPKG__BUFFER_CACHE_H_
#include <stddef.h>
#include <util/DoublyLinkedList.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class CachedBuffer : public DoublyLinkedListLinkImpl<CachedBuffer> {
public:
CachedBuffer(size_t size);
~CachedBuffer();
void* Buffer() const { return fBuffer; }
size_t Size() const { return fSize; }
// implementation private
CachedBuffer** Owner() const { return fOwner; }
void SetOwner(CachedBuffer** owner)
{ fOwner = owner; }
void SetCached(bool cached) { fCached = cached; }
bool IsCached() const { return fCached; }
private:
CachedBuffer** fOwner;
void* fBuffer;
size_t fSize;
bool fCached;
};
class BufferCache {
public:
virtual ~BufferCache();
virtual CachedBuffer* GetBuffer(size_t size,
CachedBuffer** owner = NULL,
bool* _newBuffer = NULL) = 0;
virtual void PutBufferAndCache(CachedBuffer** owner) = 0;
// caller is buffer owner and wants the
// buffer cached, if possible
virtual void PutBuffer(CachedBuffer** owner) = 0;
// puts the buffer for good, owner might
// have called PutBufferAndCache() before
// and might not own a buffer anymore
};
class CachedBufferPutter {
public:
CachedBufferPutter(BufferCache* cache, CachedBuffer** owner)
:
fCache(cache),
fOwner(owner),
fBuffer(NULL)
{
}
CachedBufferPutter(BufferCache* cache, CachedBuffer* buffer)
:
fCache(cache),
fOwner(NULL),
fBuffer(buffer)
{
}
~CachedBufferPutter()
{
if (fCache != NULL) {
if (fOwner != NULL)
fCache->PutBufferAndCache(fOwner);
else if (fBuffer != NULL)
fCache->PutBuffer(&fBuffer);
}
}
private:
BufferCache* fCache;
CachedBuffer** fOwner;
CachedBuffer* fBuffer;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__BUFFER_CACHE_H_
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef DATA_OUTPUT_H
#define DATA_OUTPUT_H
#include <SupportDefs.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class DataOutput {
public:
virtual ~DataOutput();
virtual status_t WriteData(const void* buffer, size_t size) = 0;
};
class BufferDataOutput : public DataOutput {
public:
BufferDataOutput(void* buffer, size_t size);
size_t BytesWritten() const { return fBytesWritten; }
virtual status_t WriteData(const void* buffer, size_t size);
private:
void* fBuffer;
size_t fSize;
size_t fBytesWritten;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // DATA_OUTPUT_H
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef DATA_READER_H
#define DATA_READER_H
#include <SupportDefs.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class DataReader {
public:
virtual ~DataReader();
virtual status_t ReadData(off_t offset, void* buffer,
size_t size) = 0;
};
class FDDataReader : public DataReader {
public:
FDDataReader(int fd);
virtual status_t ReadData(off_t offset, void* buffer,
size_t size);
private:
int fFD;
};
class AttributeDataReader : public DataReader {
public:
AttributeDataReader(int fd,
const char* attribute, uint32 type);
virtual status_t ReadData(off_t offset, void* buffer,
size_t size);
private:
int fFD;
uint32 fType;
const char* fAttribute;
};
class BufferDataReader : public DataReader {
public:
BufferDataReader(const void* data, size_t size);
virtual status_t ReadData(off_t offset, void* buffer,
size_t size);
private:
const void* fData;
size_t fSize;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // DATA_READER_H
@@ -0,0 +1,38 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ERROR_OUTPUT_H
#define ERROR_OUTPUT_H
#include <stdarg.h>
#include <SupportDefs.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class ErrorOutput {
public:
virtual ~ErrorOutput();
virtual void PrintErrorVarArgs(const char* format,
va_list args) = 0;
void PrintError(const char* format, ...);
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // ERROR_OUTPUT_H
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef FD_CLOSER_H
#define FD_CLOSER_H
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
struct FDCloser {
FDCloser(int fd)
:
fFD(fd)
{
}
~FDCloser()
{
if (fFD >= 0)
close(fFD);
}
private:
int fFD;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // FD_CLOSER_H
@@ -0,0 +1,161 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_ATTRIBUTE_VALUE_H
#define PACKAGE_ATTRIBUTE_VALUE_H
#include <string.h>
#include <package/hpkg/haiku_package.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
struct PackageAttributeValue {
union {
int64 signedInt;
uint64 unsignedInt;
const char* string;
struct {
uint64 size;
union {
uint64 offset;
uint8 raw[B_HPKG_MAX_INLINE_DATA_SIZE];
};
} data;
};
uint8 type;
uint8 encoding;
public:
inline PackageAttributeValue();
inline void SetTo(int8 value);
inline void SetTo(uint8 value);
inline void SetTo(int16 value);
inline void SetTo(uint16 value);
inline void SetTo(int32 value);
inline void SetTo(uint32 value);
inline void SetTo(int64 value);
inline void SetTo(uint64 value);
inline void SetTo(const char* value);
inline void SetToData(uint64 size, uint64 offset);
inline void SetToData(uint64 size, const void* rawData);
};
PackageAttributeValue::PackageAttributeValue()
:
type(B_HPKG_ATTRIBUTE_TYPE_INVALID)
{
}
void
PackageAttributeValue::SetTo(int8 value)
{
signedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_INT;
}
void
PackageAttributeValue::SetTo(uint8 value)
{
unsignedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_UINT;
}
void
PackageAttributeValue::SetTo(int16 value)
{
signedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_INT;
}
void
PackageAttributeValue::SetTo(uint16 value)
{
unsignedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_UINT;
}
void
PackageAttributeValue::SetTo(int32 value)
{
signedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_INT;
}
void
PackageAttributeValue::SetTo(uint32 value)
{
unsignedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_UINT;
}
void
PackageAttributeValue::SetTo(int64 value)
{
signedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_INT;
}
void
PackageAttributeValue::SetTo(uint64 value)
{
unsignedInt = value;
type = B_HPKG_ATTRIBUTE_TYPE_UINT;
}
void
PackageAttributeValue::SetTo(const char* value)
{
string = value;
type = B_HPKG_ATTRIBUTE_TYPE_STRING;
}
void
PackageAttributeValue::SetToData(uint64 size, uint64 offset)
{
data.size = size;
data.offset = offset;
type = B_HPKG_ATTRIBUTE_TYPE_RAW;
encoding = B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP;
}
void
PackageAttributeValue::SetToData(uint64 size, const void* rawData)
{
data.size = size;
if (size > 0)
memcpy(data.raw, rawData, size);
type = B_HPKG_ATTRIBUTE_TYPE_RAW;
encoding = B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE;
}
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_ATTRIBUTE_VALUE_H
@@ -0,0 +1,66 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_DATA_H
#define PACKAGE_DATA_H
#include <package/hpkg/haiku_package.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class PackageData {
public:
PackageData();
uint64 CompressedSize() const
{ return fCompressedSize; }
uint64 UncompressedSize() const
{ return fUncompressedSize; }
uint64 Offset() const
{ return fEncodedInline ? 0 : fOffset; }
uint32 Compression() const { return fCompression; }
uint32 ChunkSize() const { return fChunkSize; }
bool IsEncodedInline() const
{ return fEncodedInline; }
const uint8* InlineData() const { return fInlineData; }
void SetData(uint64 size, uint64 offset);
void SetData(uint8 size, const void* data);
void SetCompression(uint32 compression)
{ fCompression = compression; }
void SetUncompressedSize(uint64 size)
{ fUncompressedSize = size; }
void SetChunkSize(uint32 size)
{ fChunkSize = size; }
private:
uint64 fCompressedSize;
uint64 fUncompressedSize;
union {
uint64 fOffset;
uint8 fInlineData[B_HPKG_MAX_INLINE_DATA_SIZE];
};
uint32 fChunkSize;
uint32 fCompression;
bool fEncodedInline;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_DATA_H
@@ -0,0 +1,65 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_DATA_READER_H
#define PACKAGE_DATA_READER_H
#include <package/hpkg/DataReader.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class BufferCache;
class DataOutput;
class PackageData;
class PackageDataReader : public DataReader {
public:
PackageDataReader(DataReader* dataReader);
virtual ~PackageDataReader();
virtual status_t Init(const PackageData& data) = 0;
virtual status_t ReadData(off_t offset, void* buffer,
size_t size);
virtual status_t ReadDataToOutput(off_t offset, size_t size,
DataOutput* output) = 0;
virtual uint64 Size() const = 0;
virtual size_t BlockSize() const = 0;
protected:
DataReader* fDataReader;
};
class PackageDataReaderFactory {
public:
PackageDataReaderFactory(
BufferCache* bufferCache);
status_t CreatePackageDataReader(DataReader* dataReader,
const PackageData& data,
PackageDataReader*& _reader);
private:
BufferCache* fBufferCache;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_DATA_READER_H
@@ -0,0 +1,98 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_ENTRY_H
#define PACKAGE_ENTRY_H
#include <sys/stat.h>
#include <package/hpkg/PackageData.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class PackageEntry {
public:
PackageEntry(PackageEntry* parent,
const char* name);
const PackageEntry* Parent() const { return fParent; }
const char* Name() const { return fName; }
void* UserToken() const { return fUserToken; }
mode_t Mode() const { return fMode; }
const timespec& AccessTime() const
{ return fAccessTime; }
const timespec& ModifiedTime() const
{ return fModifiedTime; }
const timespec& CreationTime() const
{ return fCreationTime; }
PackageData& Data() { return fData; }
const char* SymlinkPath() const { return fSymlinkPath; }
void SetUserToken(void* token)
{ fUserToken = token; }
void SetType(uint32 type);
void SetPermissions(uint32 permissions);
void SetAccessTime(uint32 seconds)
{ fAccessTime.tv_sec = seconds; }
void SetAccessTimeNanos(uint32 nanos)
{ fAccessTime.tv_nsec = nanos; }
void SetModifiedTime(uint32 seconds)
{ fModifiedTime.tv_sec = seconds; }
void SetModifiedTimeNanos(uint32 nanos)
{ fModifiedTime.tv_nsec = nanos; }
void SetCreationTime(uint32 seconds)
{ fCreationTime.tv_sec = seconds; }
void SetCreationTimeNanos(uint32 nanos)
{ fCreationTime.tv_nsec = nanos; }
void SetSymlinkPath(const char* path)
{ fSymlinkPath = path; }
private:
PackageEntry* fParent;
const char* fName;
void* fUserToken;
mode_t fMode;
timespec fAccessTime;
timespec fModifiedTime;
timespec fCreationTime;
PackageData fData;
const char* fSymlinkPath;
};
inline void
PackageEntry::SetType(uint32 type)
{
fMode = (fMode & ~(uint32)S_IFMT) | (type & S_IFMT);
}
inline void
PackageEntry::SetPermissions(uint32 permissions)
{
fMode = (fMode & ~(uint32)ALLPERMS) | (permissions & ALLPERMS);
}
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_ENTRY_H
@@ -0,0 +1,44 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_ENTRY_ATTRIBUTE_H
#define PACKAGE_ENTRY_ATTRIBUTE_H
#include <package/hpkg/PackageData.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class PackageEntryAttribute {
public:
PackageEntryAttribute(const char* name);
const char* Name() const { return fName; }
uint32 Type() const { return fType; }
PackageData& Data() { return fData; }
void SetType(uint32 type) { fType = type; }
private:
const char* fName;
uint32 fType;
PackageData fData;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_ENTRY_ATTRIBUTE_H
@@ -0,0 +1,180 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_READER_H
#define PACKAGE_READER_H
#include <SupportDefs.h>
#include <util/SinglyLinkedList.h>
#include <package/hpkg/PackageAttributeValue.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class ErrorOutput;
class PackageEntry;
class PackageEntryAttribute;
class LowLevelPackageContentHandler {
public:
virtual ~LowLevelPackageContentHandler();
virtual status_t HandleAttribute(const char* attributeName,
const PackageAttributeValue& value,
void* parentToken, void*& _token) = 0;
virtual status_t HandleAttributeDone(const char* attributeName,
const PackageAttributeValue& value,
void* token) = 0;
virtual void HandleErrorOccurred() = 0;
};
class PackageContentHandler {
public:
virtual ~PackageContentHandler();
virtual status_t HandleEntry(PackageEntry* entry) = 0;
virtual status_t HandleEntryAttribute(PackageEntry* entry,
PackageEntryAttribute* attribute) = 0;
virtual status_t HandleEntryDone(PackageEntry* entry) = 0;
virtual void HandleErrorOccurred() = 0;
};
class PackageReader {
public:
PackageReader(ErrorOutput* errorOutput);
~PackageReader();
status_t Init(const char* fileName);
status_t Init(int fd, bool keepFD);
status_t ParseContent(
PackageContentHandler* contentHandler);
status_t ParseContent(
LowLevelPackageContentHandler*
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;
typedef PackageAttributeValue AttributeValue;
typedef SinglyLinkedList<AttributeHandler> AttributeHandlerList;
private:
status_t _Init(const char* fileName);
const char* _CheckCompression(uint32 compression,
uint64 compressedLength,
uint64 uncompressedLength) const;
status_t _ParseTOCAttributeTypes();
status_t _ParseTOCStrings();
status_t _ParseContent(AttributeHandlerContext* context,
AttributeHandler* rootAttributeHandler);
status_t _ParseAttributeTree(
AttributeHandlerContext* context);
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 _ReadTOCBuffer(void* buffer, size_t size);
status_t _ReadBuffer(off_t offset, void* buffer,
size_t size);
status_t _ReadCompressedBuffer(off_t offset,
void* buffer, size_t compressedSize,
size_t uncompressedSize,
uint32 compression);
static int8 _GetStandardIndex(const AttributeType* type);
inline AttributeHandler* _CurrentAttributeHandler() const;
inline void _PushAttributeHandler(
AttributeHandler* handler);
inline AttributeHandler* _PopAttributeHandler();
private:
ErrorOutput* fErrorOutput;
int fFD;
bool fOwnsFD;
uint64 fTotalSize;
uint64 fHeapOffset;
uint64 fHeapSize;
uint32 fTOCCompression;
uint64 fTOCCompressedLength;
uint64 fTOCUncompressedLength;
uint64 fTOCSectionOffset;
uint64 fTOCAttributeTypesLength;
uint64 fTOCAttributeTypesCount;
uint64 fTOCStringsLength;
uint64 fTOCStringsCount;
uint32 fPackageAttributesCompression;
uint32 fPackageAttributesCompressedLength;
uint32 fPackageAttributesUncompressedLength;
uint64 fPackageAttributesOffset;
uint8* fTOCSection;
uint64 fCurrentTOCOffset;
AttributeTypeReference* fAttributeTypes;
char** fStrings;
AttributeHandlerList* fAttributeHandlerStack;
uint8* fScratchBuffer;
size_t fScratchBufferSize;
};
template<typename Type>
status_t
PackageReader::_Read(Type& _value)
{
return _ReadTOCBuffer(&_value, sizeof(Type));
}
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_READER_H
@@ -0,0 +1,142 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_WRITER_H
#define PACKAGE_WRITER_H
#include <util/DoublyLinkedList.h>
#include <util/OpenHashTable.h>
#include <package/hpkg/Strings.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class DataReader;
struct hpkg_header;
namespace BPackageKit {
class BPackageInfo;
}
class PackageWriter {
public:
PackageWriter();
~PackageWriter();
status_t Init(const char* fileName);
status_t AddEntry(const char* fileName);
status_t Finish();
private:
struct AttributeValue;
struct AttributeTypeKey;
struct AttributeType;
struct AttributeTypeHashDefinition;
struct Attribute;
struct AttributeTypeUsageGreater;
struct Entry;
struct DataWriter;
struct DummyDataWriter;
struct FDDataWriter;
struct ZlibDataWriter;
typedef BOpenHashTable<AttributeTypeHashDefinition>
AttributeTypeTable;
typedef DoublyLinkedList<Entry> EntryList;
private:
status_t _Init(const char* fileName);
status_t _Finish();
status_t _RegisterEntry(const char* fileName);
Entry* _RegisterEntry(Entry* parent,
const char* name, size_t nameLength,
bool isImplicit);
void _WriteTOC(hpkg_header& header);
int32 _WriteTOCSections(uint64& _attributeTypesSize,
uint64& _stringsSize, uint64& _mainSize);
void _WriteAttributeTypes();
int32 _WriteCachedStrings();
void _WriteAttributeChildren(Attribute* attribute);
void _WritePackageAttributes(hpkg_header& header);
void _WriteAttributeValue(
const AttributeValue& value,
uint8 encoding);
void _WriteUnsignedLEB128(uint64 value);
inline void _WriteString(const char* string);
template<typename Type>
inline void _Write(const Type& value);
void _WriteBuffer(const void* buffer, size_t size,
off_t offset);
void _AddEntry(int dirFD, Entry* entry,
const char* fileName);
Attribute* _AddAttribute(const char* attributeName,
const AttributeValue& value);
template<typename Type>
inline Attribute* _AddAttribute(const char* attributeName,
Type value);
Attribute* _AddStringAttribute(const char* attributeName,
const char* value);
Attribute* _AddDataAttribute(const char* attributeName,
uint64 dataSize, uint64 dataOffset);
Attribute* _AddDataAttribute(const char* attributeName,
uint64 dataSize, const uint8* data);
CachedString* _GetCachedString(const char* value);
AttributeType* _GetAttributeType(const char* attributeName,
uint8 type);
status_t _AddData(DataReader& dataReader, off_t size);
status_t _WriteUncompressedData(DataReader& dataReader,
off_t size, uint64 writeOffset);
status_t _WriteZlibCompressedData(DataReader& dataReader,
off_t size, uint64 writeOffset,
uint64& _compressedSize);
private:
const char* fFileName;
int fFD;
bool fFinished;
off_t fHeapOffset;
off_t fHeapEnd;
void* fDataBuffer;
size_t fDataBufferSize;
DataWriter* fDataWriter;
Entry* fRootEntry;
Attribute* fRootAttribute;
Attribute* fTopAttribute;
CachedStringTable* fCachedStrings;
AttributeTypeTable* fAttributeTypes;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // PACKAGE_WRITER_H
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef STACKER_H
#define STACKER_H
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
template<typename Type>
class Stacker {
public:
Stacker(Type*& location, Type* element)
:
fLocation(&location),
fPreviousElement(location)
{
*fLocation = element;
}
Stacker(Type** location, Type* element)
:
fLocation(location),
fPreviousElement(*location)
{
*fLocation = element;
}
~Stacker()
{
if (fLocation != NULL)
*fLocation = fPreviousElement;
}
private:
Type** fLocation;
Type* fPreviousElement;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // STACKER_H
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef STRINGS_H
#define STRINGS_H
#include <util/OpenHashTable.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
uint32 hash_string(const char* string);
struct CachedString {
char* string;
int32 index;
uint32 usageCount;
CachedString* next; // hash table link
CachedString()
:
string(NULL),
index(-1),
usageCount(1)
{
}
~CachedString()
{
free(string);
}
bool Init(const char* string)
{
this->string = strdup(string);
if (this->string == NULL)
return false;
return true;
}
};
struct CachedStringHashDefinition {
typedef const char* KeyType;
typedef CachedString ValueType;
size_t HashKey(const char* key) const
{
return hash_string(key);
}
size_t Hash(const CachedString* value) const
{
return HashKey(value->string);
}
bool Compare(const char* key, const CachedString* value) const
{
return strcmp(value->string, key) == 0;
}
CachedString*& GetLink(CachedString* value) const
{
return value->next;
}
};
typedef BOpenHashTable<CachedStringHashDefinition> CachedStringTable;
struct CachedStringUsageGreater {
bool operator()(const CachedString* a, const CachedString* b)
{
return a->usageCount > b->usageCount;
}
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // STRINGS_H
@@ -0,0 +1,32 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ZLIB_COMPRESSION_BASE_H
#define ZLIB_COMPRESSION_BASE_H
#include <SupportDefs.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class ZlibCompressionBase {
public:
static status_t TranslateZlibError(int error);
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // ZLIB_COMPRESSION_BASE_H
@@ -0,0 +1,52 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ZLIB_COMPRESSOR_H
#define ZLIB_COMPRESSOR_H
#include <zlib.h>
#include <package/hpkg/ZlibCompressionBase.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class DataOutput;
class ZlibCompressor : public ZlibCompressionBase {
public:
ZlibCompressor(DataOutput* output);
~ZlibCompressor();
status_t Init();
status_t CompressNext(const void* input,
size_t inputSize);
status_t Finish();
static status_t CompressSingleBuffer(const void* input,
size_t inputSize, void* output,
size_t outputSize, size_t& _compressedSize);
private:
z_stream fStream;
DataOutput* fOutput;
bool fStreamInitialized;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // ZLIB_COMPRESSOR_H
@@ -0,0 +1,54 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ZLIB_DECOMPRESSOR_H
#define ZLIB_DECOMPRESSOR_H
#include <zlib.h>
#include <package/hpkg/ZlibCompressionBase.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
class DataOutput;
class ZlibDecompressor : public ZlibCompressionBase {
public:
ZlibDecompressor(DataOutput* output);
~ZlibDecompressor();
status_t Init();
status_t DecompressNext(const void* input,
size_t inputSize);
status_t Finish();
static status_t DecompressSingleBuffer(const void* input,
size_t inputSize, void* output,
size_t outputSize,
size_t& _uncompressedSize);
private:
z_stream fStream;
DataOutput* fOutput;
bool fStreamInitialized;
bool fFinished;
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // ZLIB_DECOMPRESSOR_H
@@ -9,6 +9,13 @@
#include <SupportDefs.h>
namespace BPackageKit {
namespace BHaikuPackage {
namespace BPrivate {
// header
struct hpkg_header {
uint32 magic; // "hpkg"
@@ -141,6 +148,10 @@ enum {
#define 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"
// default values
enum {
B_HPKG_DEFAULT_FILE_TYPE = B_HPKG_FILE_TYPE_FILE,
@@ -152,4 +163,11 @@ enum {
};
} // namespace BPrivate
} // namespace BHaikuPackage
} // namespace BPackageKit
#endif // _HAIKU_PACKAGE_H