Refactoring step towards implementation of RepositoryWriter:

* pulled commonly useful parts out of PackageWriterImpl into 
  WriterImplBase
* moved CachedStringTable and related methods into a separate class,
  StringCache, in order to support having more than one string cache
  per package file
* made package attribute section use a string cache, too, as that's
  going to be very useful for repositories
* instead of writing package attributes directly, we now collect
  corresponding PackageAttributes and write those later
* adjusted package reader accordingly


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40376 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2011-02-07 22:25:16 +00:00
parent a19d237fcf
commit f202217364
13 changed files with 1185 additions and 726 deletions
+1
View File
@@ -35,6 +35,7 @@ public:
uint64 uncompressedMainSize,
uint64 uncompressedTOCSize) = 0;
virtual void OnPackageAttributesSizeInfo(
uint32 stringCount,
uint32 uncompressedSize) = 0;
virtual void OnPackageSizeInfo(uint32 headerSize,
uint64 heapSize, uint64 tocSize,
@@ -0,0 +1,62 @@
/*
* Copyright 2011, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__REPOSITORY_WRITER_H_
#define _PACKAGE__HPKG__REPOSITORY_WRITER_H_
#include <SupportDefs.h>
#include <package/hpkg/ErrorOutput.h>
namespace BPackageKit {
namespace BHPKG {
namespace BPrivate {
class RepositoryWriterImpl;
}
using BPrivate::RepositoryWriterImpl;
class BRepositoryWriterListener : public BErrorOutput {
public:
virtual void PrintErrorVarArgs(const char* format,
va_list args) = 0;
virtual void OnPackageAdded(
const BPackageInfo& packageInfo) = 0;
virtual void OnPackageAttributesSizeInfo(
uint32 uncompressedSize) = 0;
virtual void OnRepositorySizeInfo(uint32 headerSize,
uint32 packageAttributesSize,
uint64 totalSize) = 0;
};
class BRepositoryWriter {
public:
public:
BRepositoryWriter(
BRepositoryWriterListener* listener);
~BRepositoryWriter();
status_t Init(const char* fileName);
status_t AddPackage(const BPackageInfo& packageInfo);
status_t Finish();
private:
RepositoryWriterImpl* fImpl;
};
} // namespace BHPKG
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__REPOSITORY_WRITER_H_
@@ -65,17 +65,22 @@ private:
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;
}
};
@@ -90,7 +95,8 @@ private:
const SectionInfo& section) const;
status_t _ParseTOCAttributeTypes();
status_t _ParseTOCStrings();
status_t _ParseStrings();
status_t _ParseContent(AttributeHandlerContext* context,
AttributeHandler* rootAttributeHandler);
@@ -153,15 +159,12 @@ private:
uint64 fTOCAttributeTypesLength;
uint64 fTOCAttributeTypesCount;
uint64 fTOCStringsLength;
uint64 fTOCStringsCount;
SectionInfo fTOCSection;
SectionInfo fPackageAttributesSection;
SectionInfo* fCurrentSection;
AttributeTypeReference* fAttributeTypes;
char** fStrings;
AttributeHandlerList* fAttributeHandlerStack;
@@ -10,9 +10,9 @@
#include <util/DoublyLinkedList.h>
#include <util/OpenHashTable.h>
#include <package/PackageInfo.h>
#include <package/hpkg/PackageWriter.h>
#include <package/hpkg/Strings.h>
#include <package/hpkg/WriterImplBase.h>
namespace BPackageKit {
@@ -29,7 +29,7 @@ namespace BPrivate {
struct hpkg_header;
class PackageWriterImpl {
class PackageWriterImpl : public WriterImplBase {
public:
PackageWriterImpl(
BPackageWriterListener* listener);
@@ -40,18 +40,13 @@ public:
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 SubPathAdder;
struct ZlibDataWriter;
typedef BOpenHashTable<AttributeTypeHashDefinition>
AttributeTypeTable;
@@ -66,33 +61,25 @@ private:
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);
void _WritePackageVersion(
void _RegisterPackageInfo(
PackageAttributeList& attributeList,
const BPackageInfo& packageInfo);
void _RegisterPackageVersion(
PackageAttributeList& attributeList,
const BPackageVersion& version);
void _WritePackageResolvableExpressionList(
void _RegisterPackageResolvableExpressionList(
PackageAttributeList& attributeList,
const BObjectList<
BPackageResolvableExpression>& list,
uint8 id);
template<typename Type>
inline void _Write(const Type& value);
void _WriteTOC(hpkg_header& header);
int32 _WriteTOCSections(uint64& _attributeTypesSize,
uint64& _stringsSize, uint64& _mainSize);
void _WriteAttributeTypes();
void _WriteAttributeChildren(Attribute* attribute);
void _WriteBuffer(const void* buffer, size_t size,
off_t offset);
void _WritePackageAttributes(hpkg_header& header);
void _AddEntry(int dirFD, Entry* entry,
const char* fileName, char* pathBuffer);
@@ -111,38 +98,30 @@ private:
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(BDataReader& dataReader, off_t size);
status_t _WriteUncompressedData(BDataReader& dataReader,
off_t size, uint64 writeOffset);
status_t _WriteZlibCompressedData(BDataReader& dataReader,
status_t _WriteZlibCompressedData(
BDataReader& dataReader,
off_t size, uint64 writeOffset,
uint64& _compressedSize);
private:
BPackageWriterListener* fListener;
const char* fFileName;
int fFD;
bool fFinished;
off_t fHeapOffset;
off_t fHeapEnd;
void* fDataBuffer;
size_t fDataBufferSize;
BPackageInfo fPackageInfo;
DataWriter* fDataWriter;
Entry* fRootEntry;
Attribute* fRootAttribute;
Attribute* fTopAttribute;
CachedStringTable* fCachedStrings;
StringCache fStringCache;
AttributeTypeTable* fAttributeTypes;
};
+11
View File
@@ -6,6 +6,8 @@
#define _PACKAGE__HPKG__PRIVATE__STRINGS_H_
#include <new>
#include <util/OpenHashTable.h>
@@ -86,6 +88,15 @@ struct CachedStringUsageGreater {
};
struct StringCache : public CachedStringTable {
StringCache();
~StringCache();
CachedString* Get(const char* value);
};
} // namespace BPrivate
} // namespace BHPKG
@@ -0,0 +1,234 @@
/*
* Copyright 2011, Oliver Tappe <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
#define _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
#include <util/DoublyLinkedList.h>
#include <package/hpkg/haiku_package.h>
#include <package/hpkg/DataOutput.h>
#include <package/hpkg/Strings.h>
#include <package/hpkg/ZlibCompressor.h>
#include <package/PackageInfo.h>
namespace BPackageKit {
namespace BHPKG {
class BDataReader;
class BErrorOutput;
namespace BPrivate {
struct hpkg_header;
class WriterImplBase {
public:
WriterImplBase(BErrorOutput* errorOutput);
~WriterImplBase();
protected:
struct AttributeValue {
union {
int64 signedInt;
uint64 unsignedInt;
CachedString* string;
struct {
uint64 size;
union {
uint64 offset;
uint8 raw[B_HPKG_MAX_INLINE_DATA_SIZE];
};
} data;
};
uint8 type;
int8 encoding;
AttributeValue();
~AttributeValue();
void SetTo(int8 value);
void SetTo(uint8 value);
void SetTo(int16 value);
void SetTo(uint16 value);
void SetTo(int32 value);
void SetTo(uint32 value);
void SetTo(int64 value);
void SetTo(uint64 value);
void SetTo(CachedString* value);
void SetToData(uint64 size, uint64 offset);
void SetToData(uint64 size, const void* rawData);
uint8 ApplicableEncoding() const;
private:
static uint8 _ApplicableIntEncoding(uint64 value);
};
struct PackageAttribute :
public DoublyLinkedListLinkImpl<PackageAttribute>,
public AttributeValue {
HPKGPackageAttributeID id;
DoublyLinkedList<PackageAttribute> children;
PackageAttribute(HPKGPackageAttributeID id_, uint8 type,
uint8 encoding);
~PackageAttribute();
void AddChild(PackageAttribute* child);
private:
void _DeleteChildren();
};
struct DataWriter {
DataWriter();
virtual ~DataWriter();
uint64 BytesWritten() const;
virtual status_t WriteDataNoThrow(const void* buffer,
size_t size) = 0;
void WriteDataThrows(const void* buffer, size_t size);
protected:
uint64 fBytesWritten;
};
struct FDDataWriter : DataWriter {
FDDataWriter(int fd, off_t offset, BErrorOutput* errorOutput);
virtual status_t WriteDataNoThrow(const void* buffer,
size_t size);
off_t Offset() const;
private:
int fFD;
off_t fOffset;
BErrorOutput* fErrorOutput;
};
struct ZlibDataWriter : DataWriter, private BDataOutput {
ZlibDataWriter(DataWriter* dataWriter);
void Init();
void Finish();
virtual status_t WriteDataNoThrow(const void* buffer,
size_t size);
private:
// BDataOutput
virtual status_t WriteData(const void* buffer, size_t size);
private:
DataWriter* fDataWriter;
ZlibCompressor fCompressor;
};
typedef DoublyLinkedList<PackageAttribute> PackageAttributeList;
protected:
status_t Init(const char* fileName, const char* type);
int32 WriteCachedStrings(const StringCache& cache,
uint32 minUsageCount);
void WritePackageAttributes(
const PackageAttributeList& attributes);
void WritePackageVersion(
const BPackageVersion& version);
void WritePackageResolvableExpressionList(
const BObjectList<
BPackageResolvableExpression>& list,
uint8 id);
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);
protected:
BErrorOutput* fErrorOutput;
const char* fFileName;
int fFD;
bool fFinished;
void* fDataBuffer;
const size_t fDataBufferSize;
DataWriter* fDataWriter;
StringCache fPackageStringCache;
DoublyLinkedList<PackageAttribute> fPackageAttributes;
};
inline uint64
WriterImplBase::DataWriter::BytesWritten() const
{
return fBytesWritten;
}
inline void
WriterImplBase::DataWriter::WriteDataThrows(const void* buffer, size_t size)
{
status_t error = WriteDataNoThrow(buffer, size);
if (error != B_OK)
throw status_t(error);
}
inline off_t
WriterImplBase::FDDataWriter::Offset() const
{
return fOffset;
}
template<typename Type>
inline void
WriterImplBase::Write(const Type& value)
{
fDataWriter->WriteDataThrows(&value, sizeof(Type));
}
inline void
WriterImplBase::WriteString(const char* string)
{
fDataWriter->WriteDataThrows(string, strlen(string) + 1);
}
} // namespace BPrivate
} // namespace BHPKG
} // namespace BPackageKit
#endif // _PACKAGE__HPKG__PRIVATE__WRITER_IMPL_BASE_H_
@@ -29,6 +29,8 @@ struct hpkg_header {
uint32 attributes_compression;
uint32 attributes_length_compressed;
uint32 attributes_length_uncompressed;
uint32 attributes_strings_length;
uint32 attributes_strings_count;
// TOC section
uint32 toc_compression;