Cleanup:
* PackageWriterImpl no longer accesses members of WriterImplBase directly, but uses getters/setters instead * package attribute registration has been moved from PackageWriterImpl to WriterImplBase, as it will be used in the same manner by the RepositoryWriter git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40388 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9ef9c027aa
commit
4ee7d007d6
@ -61,18 +61,6 @@ private:
|
||||
const char* name, size_t nameLength,
|
||||
bool isImplicit);
|
||||
|
||||
void _RegisterPackageInfo(
|
||||
PackageAttributeList& attributeList,
|
||||
const BPackageInfo& packageInfo);
|
||||
void _RegisterPackageVersion(
|
||||
PackageAttributeList& attributeList,
|
||||
const BPackageVersion& version);
|
||||
void _RegisterPackageResolvableExpressionList(
|
||||
PackageAttributeList& attributeList,
|
||||
const BObjectList<
|
||||
BPackageResolvableExpression>& list,
|
||||
uint8 id);
|
||||
|
||||
void _WriteTOC(hpkg_header& header);
|
||||
int32 _WriteTOCSections(uint64& _attributeTypesSize,
|
||||
uint64& _stringsSize, uint64& _mainSize);
|
||||
@ -116,6 +104,9 @@ private:
|
||||
off_t fHeapOffset;
|
||||
off_t fHeapEnd;
|
||||
|
||||
void* fDataBuffer;
|
||||
const size_t fDataBufferSize;
|
||||
|
||||
Entry* fRootEntry;
|
||||
|
||||
Attribute* fRootAttribute;
|
||||
|
59
headers/private/package/hpkg/RepositoryWriterImpl.h
Normal file
59
headers/private/package/hpkg/RepositoryWriterImpl.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__HPKG__PRIVATE__REPOSITORY_WRITER_IMPL_H_
|
||||
#define _PACKAGE__HPKG__PRIVATE__REPOSITORY_WRITER_IMPL_H_
|
||||
|
||||
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
#include <package/PackageInfo.h>
|
||||
#include <package/hpkg/Strings.h>
|
||||
#include <package/hpkg/WriterImplBase.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
namespace BHPKG {
|
||||
|
||||
|
||||
class BDataReader;
|
||||
class BErrorOutput;
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
struct hpkg_header;
|
||||
|
||||
class RepositoryWriterImpl : public WriterImplBase {
|
||||
public:
|
||||
RepositoryWriterImpl(
|
||||
BRepositoryWriterListener* listener);
|
||||
~RepositoryWriterImpl();
|
||||
|
||||
status_t Init(const char* fileName);
|
||||
status_t AddPackage(const BPackageInfo& packageInfo);
|
||||
status_t Finish();
|
||||
|
||||
private:
|
||||
status_t _Init(const char* fileName);
|
||||
status_t _AddPackage(const BPackageInfo& packageInfo);
|
||||
status_t _Finish();
|
||||
|
||||
private:
|
||||
BRepositoryWriterListener* fListener;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
} // namespace BHPKG
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__HPKG__PRIVATE__REPOSITORY_WRITER_IMPL_H_
|
@ -93,9 +93,9 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct DataWriter {
|
||||
DataWriter();
|
||||
virtual ~DataWriter();
|
||||
struct AbstractDataWriter {
|
||||
AbstractDataWriter();
|
||||
virtual ~AbstractDataWriter();
|
||||
|
||||
uint64 BytesWritten() const;
|
||||
|
||||
@ -109,7 +109,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct FDDataWriter : DataWriter {
|
||||
struct FDDataWriter : AbstractDataWriter {
|
||||
FDDataWriter(int fd, off_t offset, BErrorOutput* errorOutput);
|
||||
|
||||
virtual status_t WriteDataNoThrow(const void* buffer,
|
||||
@ -124,8 +124,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct ZlibDataWriter : DataWriter, private BDataOutput {
|
||||
ZlibDataWriter(DataWriter* dataWriter);
|
||||
struct ZlibDataWriter : AbstractDataWriter, private BDataOutput {
|
||||
ZlibDataWriter(AbstractDataWriter* dataWriter);
|
||||
|
||||
void Init();
|
||||
|
||||
@ -139,8 +139,8 @@ protected:
|
||||
virtual status_t WriteData(const void* buffer, size_t size);
|
||||
|
||||
private:
|
||||
DataWriter* fDataWriter;
|
||||
ZlibCompressor fCompressor;
|
||||
AbstractDataWriter* fDataWriter;
|
||||
ZlibCompressor fCompressor;
|
||||
};
|
||||
|
||||
|
||||
@ -149,11 +149,24 @@ protected:
|
||||
protected:
|
||||
status_t Init(const char* fileName, const char* type);
|
||||
|
||||
void RegisterPackageInfo(
|
||||
PackageAttributeList& attributeList,
|
||||
const BPackageInfo& packageInfo);
|
||||
void RegisterPackageVersion(
|
||||
PackageAttributeList& attributeList,
|
||||
const BPackageVersion& version);
|
||||
void RegisterPackageResolvableExpressionList(
|
||||
PackageAttributeList& attributeList,
|
||||
const BObjectList<
|
||||
BPackageResolvableExpression>& list,
|
||||
uint8 id);
|
||||
|
||||
int32 WriteCachedStrings(const StringCache& cache,
|
||||
uint32 minUsageCount);
|
||||
|
||||
void WritePackageAttributes(
|
||||
const PackageAttributeList& attributes);
|
||||
int32 WritePackageAttributes(
|
||||
const PackageAttributeList& attributes,
|
||||
uint32& _stringsLengthUncompressed);
|
||||
void WritePackageVersion(
|
||||
const BPackageVersion& version);
|
||||
void WritePackageResolvableExpressionList(
|
||||
@ -172,30 +185,40 @@ protected:
|
||||
void WriteBuffer(const void* buffer, size_t size,
|
||||
off_t offset);
|
||||
|
||||
protected:
|
||||
int FD() const;
|
||||
AbstractDataWriter* DataWriter() const;
|
||||
const PackageAttributeList& PackageAttributes() const;
|
||||
PackageAttributeList& PackageAttributes();
|
||||
|
||||
void SetDataWriter(AbstractDataWriter* dataWriter);
|
||||
void SetFinished(bool finished);
|
||||
|
||||
private:
|
||||
void _WritePackageAttributes(
|
||||
const PackageAttributeList& attributes);
|
||||
|
||||
private:
|
||||
BErrorOutput* fErrorOutput;
|
||||
const char* fFileName;
|
||||
int fFD;
|
||||
bool fFinished;
|
||||
void* fDataBuffer;
|
||||
const size_t fDataBufferSize;
|
||||
|
||||
DataWriter* fDataWriter;
|
||||
AbstractDataWriter* fDataWriter;
|
||||
|
||||
StringCache fPackageStringCache;
|
||||
DoublyLinkedList<PackageAttribute> fPackageAttributes;
|
||||
PackageAttributeList fPackageAttributes;
|
||||
};
|
||||
|
||||
|
||||
inline uint64
|
||||
WriterImplBase::DataWriter::BytesWritten() const
|
||||
WriterImplBase::AbstractDataWriter::BytesWritten() const
|
||||
{
|
||||
return fBytesWritten;
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
WriterImplBase::DataWriter::WriteDataThrows(const void* buffer, size_t size)
|
||||
WriterImplBase::AbstractDataWriter::WriteDataThrows(const void* buffer, size_t size)
|
||||
{
|
||||
status_t error = WriteDataNoThrow(buffer, size);
|
||||
if (error != B_OK)
|
||||
@ -224,6 +247,48 @@ WriterImplBase::WriteString(const char* string)
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
WriterImplBase::FD() const
|
||||
{
|
||||
return fFD;
|
||||
}
|
||||
|
||||
|
||||
inline WriterImplBase::AbstractDataWriter*
|
||||
WriterImplBase::DataWriter() const
|
||||
{
|
||||
return fDataWriter;
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
WriterImplBase::SetDataWriter(AbstractDataWriter* dataWriter)
|
||||
{
|
||||
fDataWriter = dataWriter;
|
||||
}
|
||||
|
||||
|
||||
inline const WriterImplBase::PackageAttributeList&
|
||||
WriterImplBase::PackageAttributes() const
|
||||
{
|
||||
return fPackageAttributes;
|
||||
}
|
||||
|
||||
|
||||
inline WriterImplBase::PackageAttributeList&
|
||||
WriterImplBase::PackageAttributes()
|
||||
{
|
||||
return fPackageAttributes;
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
WriterImplBase::SetFinished(bool finished)
|
||||
{
|
||||
fFinished = finished;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
} // namespace BHPKG
|
||||
|
@ -291,6 +291,8 @@ PackageWriterImpl::PackageWriterImpl(BPackageWriterListener* listener)
|
||||
:
|
||||
WriterImplBase(listener),
|
||||
fListener(listener),
|
||||
fDataBuffer(NULL),
|
||||
fDataBufferSize(2 * B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB),
|
||||
fRootEntry(NULL),
|
||||
fRootAttribute(NULL),
|
||||
fTopAttribute(NULL),
|
||||
@ -315,12 +317,6 @@ PackageWriterImpl::~PackageWriterImpl()
|
||||
delete fRootEntry;
|
||||
|
||||
free(fDataBuffer);
|
||||
|
||||
if (fFD >= 0)
|
||||
close(fFD);
|
||||
|
||||
if (!fFinished && fFileName != NULL)
|
||||
unlink(fFileName);
|
||||
}
|
||||
|
||||
|
||||
@ -359,7 +355,7 @@ PackageWriterImpl::AddEntry(const char* fileName)
|
||||
&errorListener);
|
||||
if (result != B_OK || (result = packageInfo.InitCheck()) != B_OK)
|
||||
return result;
|
||||
_RegisterPackageInfo(fPackageAttributes, packageInfo);
|
||||
RegisterPackageInfo(PackageAttributes(), packageInfo);
|
||||
}
|
||||
|
||||
return _RegisterEntry(fileName);
|
||||
@ -376,7 +372,7 @@ status_t
|
||||
PackageWriterImpl::Finish()
|
||||
{
|
||||
try {
|
||||
if (fPackageAttributes.IsEmpty()) {
|
||||
if (PackageAttributes().IsEmpty()) {
|
||||
fListener->PrintError("No package-info file found (%s)!\n",
|
||||
B_HPKG_PACKAGE_INFO_FILE_NAME);
|
||||
return B_BAD_DATA;
|
||||
@ -398,6 +394,11 @@ PackageWriterImpl::_Init(const char* fileName)
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// allocate data buffer
|
||||
fDataBuffer = malloc(fDataBufferSize);
|
||||
if (fDataBuffer == NULL)
|
||||
throw std::bad_alloc();
|
||||
|
||||
if (fStringCache.Init() != B_OK)
|
||||
throw std::bad_alloc();
|
||||
|
||||
@ -455,7 +456,7 @@ PackageWriterImpl::_Finish()
|
||||
// write the header
|
||||
WriteBuffer(&header, sizeof(hpkg_header), 0);
|
||||
|
||||
fFinished = true;
|
||||
SetFinished(true);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -530,195 +531,14 @@ PackageWriterImpl::_RegisterEntry(Entry* parent, const char* name,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWriterImpl::_RegisterPackageInfo(PackageAttributeList& attributeList,
|
||||
const BPackageInfo& packageInfo)
|
||||
{
|
||||
// name
|
||||
PackageAttribute* name = new PackageAttribute(HPKG_PACKAGE_ATTRIBUTE_NAME,
|
||||
B_HPKG_ATTRIBUTE_TYPE_STRING, B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
name->string = fPackageStringCache.Get(packageInfo.Name().String());
|
||||
attributeList.Add(name);
|
||||
|
||||
// summary
|
||||
PackageAttribute* summary = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_SUMMARY, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
summary->string = fPackageStringCache.Get(packageInfo.Summary().String());
|
||||
attributeList.Add(summary);
|
||||
|
||||
// description
|
||||
PackageAttribute* description = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
description->string
|
||||
= fPackageStringCache.Get(packageInfo.Description().String());
|
||||
attributeList.Add(description);
|
||||
|
||||
// vendor
|
||||
PackageAttribute* vendor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VENDOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
vendor->string = fPackageStringCache.Get(packageInfo.Vendor().String());
|
||||
attributeList.Add(vendor);
|
||||
|
||||
// packager
|
||||
PackageAttribute* packager = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PACKAGER, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
packager->string = fPackageStringCache.Get(packageInfo.Packager().String());
|
||||
attributeList.Add(packager);
|
||||
|
||||
// architecture
|
||||
PackageAttribute* architecture = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
architecture->unsignedInt = packageInfo.Architecture();
|
||||
attributeList.Add(packager);
|
||||
|
||||
// version
|
||||
_RegisterPackageVersion(attributeList, packageInfo.Version());
|
||||
|
||||
// copyright list
|
||||
const BObjectList<BString>& copyrightList = packageInfo.CopyrightList();
|
||||
for (int i = 0; i < copyrightList.CountItems(); ++i) {
|
||||
PackageAttribute* copyright = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_COPYRIGHT, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
copyright->string
|
||||
= fPackageStringCache.Get(copyrightList.ItemAt(i)->String());
|
||||
attributeList.Add(copyright);
|
||||
}
|
||||
|
||||
// license list
|
||||
const BObjectList<BString>& licenseList = packageInfo.LicenseList();
|
||||
for (int i = 0; i < licenseList.CountItems(); ++i) {
|
||||
PackageAttribute* license = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_LICENSE, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
license->string
|
||||
= fPackageStringCache.Get(licenseList.ItemAt(i)->String());
|
||||
attributeList.Add(license);
|
||||
}
|
||||
|
||||
// provides list
|
||||
const BObjectList<BPackageResolvable>& providesList
|
||||
= packageInfo.ProvidesList();
|
||||
for (int i = 0; i < providesList.CountItems(); ++i) {
|
||||
BPackageResolvable* resolvable = providesList.ItemAt(i);
|
||||
bool hasVersion = resolvable->Version().InitCheck() == B_OK;
|
||||
|
||||
PackageAttribute* providesType = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES_TYPE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
providesType->unsignedInt = resolvable->Type();
|
||||
attributeList.Add(providesType);
|
||||
|
||||
PackageAttribute* provides = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
provides->string = fPackageStringCache.Get(resolvable->Name().String());
|
||||
attributeList.Add(provides);
|
||||
|
||||
if (hasVersion)
|
||||
_RegisterPackageVersion(provides->children, resolvable->Version());
|
||||
}
|
||||
|
||||
// requires list
|
||||
_RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.RequiresList(), HPKG_PACKAGE_ATTRIBUTE_REQUIRES);
|
||||
|
||||
// supplements list
|
||||
_RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.SupplementsList(), HPKG_PACKAGE_ATTRIBUTE_SUPPLEMENTS);
|
||||
|
||||
// conflicts list
|
||||
_RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.ConflictsList(), HPKG_PACKAGE_ATTRIBUTE_CONFLICTS);
|
||||
|
||||
// freshens list
|
||||
_RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.FreshensList(), HPKG_PACKAGE_ATTRIBUTE_FRESHENS);
|
||||
|
||||
// replaces list
|
||||
const BObjectList<BString>& replacesList = packageInfo.ReplacesList();
|
||||
for (int i = 0; i < replacesList.CountItems(); ++i) {
|
||||
PackageAttribute* replaces = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_REPLACES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
replaces->string
|
||||
= fPackageStringCache.Get(replacesList.ItemAt(i)->String());
|
||||
attributeList.Add(replaces);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWriterImpl::_RegisterPackageVersion(PackageAttributeList& attributeList,
|
||||
const BPackageVersion& version)
|
||||
{
|
||||
PackageAttribute* versionMajor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMajor->string = fPackageStringCache.Get(version.Major().String());
|
||||
attributeList.Add(versionMajor);
|
||||
|
||||
PackageAttribute* versionMinor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MINOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMinor->string = fPackageStringCache.Get(version.Minor().String());
|
||||
attributeList.Add(versionMinor);
|
||||
|
||||
PackageAttribute* versionMicro = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MICRO, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMicro->string = fPackageStringCache.Get(version.Micro().String());
|
||||
attributeList.Add(versionMicro);
|
||||
|
||||
PackageAttribute* versionRelease = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_RELEASE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
versionRelease->unsignedInt = version.Release();
|
||||
attributeList.Add(versionRelease);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWriterImpl::_RegisterPackageResolvableExpressionList(
|
||||
PackageAttributeList& attributeList,
|
||||
const BObjectList<BPackageResolvableExpression>& expressionList, uint8 id)
|
||||
{
|
||||
for (int i = 0; i < expressionList.CountItems(); ++i) {
|
||||
BPackageResolvableExpression* resolvableExpr = expressionList.ItemAt(i);
|
||||
bool hasVersion = resolvableExpr->Version().InitCheck() == B_OK;
|
||||
|
||||
PackageAttribute* name = new PackageAttribute(
|
||||
(HPKGPackageAttributeID)id, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
name->string = fPackageStringCache.Get(resolvableExpr->Name().String());
|
||||
attributeList.Add(name);
|
||||
|
||||
if (hasVersion) {
|
||||
PackageAttribute* op = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR,
|
||||
B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
op->unsignedInt = resolvableExpr->Operator();
|
||||
name->children.Add(op);
|
||||
_RegisterPackageVersion(name->children, resolvableExpr->Version());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageWriterImpl::_WriteTOC(hpkg_header& header)
|
||||
{
|
||||
// prepare the writer (zlib writer on top of a file writer)
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(fFD, startOffset, fListener);
|
||||
FDDataWriter realWriter(FD(), startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
fDataWriter = &zlibWriter;
|
||||
SetDataWriter(&zlibWriter);
|
||||
zlibWriter.Init();
|
||||
|
||||
// write the sections
|
||||
@ -732,7 +552,7 @@ PackageWriterImpl::_WriteTOC(hpkg_header& header)
|
||||
// finish the writer
|
||||
zlibWriter.Finish();
|
||||
fHeapEnd = realWriter.Offset();
|
||||
fDataWriter = NULL;
|
||||
SetDataWriter(NULL);
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
|
||||
@ -765,20 +585,20 @@ PackageWriterImpl::_WriteTOCSections(uint64& _attributeTypesSize,
|
||||
uint64& _stringsSize, uint64& _mainSize)
|
||||
{
|
||||
// write the attribute type abbreviations
|
||||
uint64 attributeTypesOffset = fDataWriter->BytesWritten();
|
||||
uint64 attributeTypesOffset = DataWriter()->BytesWritten();
|
||||
_WriteAttributeTypes();
|
||||
|
||||
// write the cached strings
|
||||
uint64 cachedStringsOffset = fDataWriter->BytesWritten();
|
||||
uint64 cachedStringsOffset = DataWriter()->BytesWritten();
|
||||
int32 cachedStringsWritten = WriteCachedStrings(fStringCache, 2);
|
||||
|
||||
// write the main TOC section
|
||||
uint64 mainOffset = fDataWriter->BytesWritten();
|
||||
uint64 mainOffset = DataWriter()->BytesWritten();
|
||||
_WriteAttributeChildren(fRootAttribute);
|
||||
|
||||
_attributeTypesSize = cachedStringsOffset - attributeTypesOffset;
|
||||
_stringsSize = mainOffset - cachedStringsOffset;
|
||||
_mainSize = fDataWriter->BytesWritten() - mainOffset;
|
||||
_mainSize = DataWriter()->BytesWritten() - mainOffset;
|
||||
|
||||
return cachedStringsWritten;
|
||||
}
|
||||
@ -845,21 +665,19 @@ PackageWriterImpl::_WritePackageAttributes(hpkg_header& header)
|
||||
{
|
||||
// write the package attributes (zlib writer on top of a file writer)
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(fFD, startOffset, fListener);
|
||||
FDDataWriter realWriter(FD(), startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
fDataWriter = &zlibWriter;
|
||||
SetDataWriter(&zlibWriter);
|
||||
zlibWriter.Init();
|
||||
|
||||
// write the cached strings
|
||||
uint32 stringsCount = WriteCachedStrings(fPackageStringCache, 2);
|
||||
|
||||
// write package attributes tree
|
||||
off_t attributesOffset = startOffset + fDataWriter->BytesWritten();
|
||||
WritePackageAttributes(fPackageAttributes);
|
||||
// write cached strings and package attributes tree
|
||||
uint32 stringsLengthUncompressed;
|
||||
uint32 stringsCount = WritePackageAttributes(PackageAttributes(),
|
||||
stringsLengthUncompressed);
|
||||
|
||||
zlibWriter.Finish();
|
||||
fHeapEnd = realWriter.Offset();
|
||||
fDataWriter = NULL;
|
||||
SetDataWriter(NULL);
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
|
||||
@ -873,10 +691,9 @@ PackageWriterImpl::_WritePackageAttributes(hpkg_header& header)
|
||||
= B_HOST_TO_BENDIAN_INT32(endOffset - startOffset);
|
||||
header.attributes_length_uncompressed
|
||||
= B_HOST_TO_BENDIAN_INT32(zlibWriter.BytesWritten());
|
||||
header.attributes_strings_count
|
||||
= B_HOST_TO_BENDIAN_INT32(stringsCount);
|
||||
header.attributes_strings_count = B_HOST_TO_BENDIAN_INT32(stringsCount);
|
||||
header.attributes_strings_length
|
||||
= B_HOST_TO_BENDIAN_INT32(attributesOffset - startOffset);
|
||||
= B_HOST_TO_BENDIAN_INT32(stringsLengthUncompressed);
|
||||
}
|
||||
|
||||
|
||||
@ -1182,7 +999,7 @@ PackageWriterImpl::_WriteUncompressedData(BDataReader& dataReader, off_t size,
|
||||
}
|
||||
|
||||
// write to heap
|
||||
ssize_t bytesWritten = pwrite(fFD, fDataBuffer, toCopy, writeOffset);
|
||||
ssize_t bytesWritten = pwrite(FD(), fDataBuffer, toCopy, writeOffset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError("Failed to write data: %s\n",
|
||||
strerror(errno));
|
||||
@ -1267,7 +1084,7 @@ PackageWriterImpl::_WriteZlibCompressedData(BDataReader& dataReader, off_t size,
|
||||
offsetTable[chunkIndex - 1] = writeOffset - dataOffset;
|
||||
|
||||
// write to heap
|
||||
ssize_t bytesWritten = pwrite(fFD, writeBuffer, bytesToWrite,
|
||||
ssize_t bytesWritten = pwrite(FD(), writeBuffer, bytesToWrite,
|
||||
writeOffset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError("Failed to write data: %s\n",
|
||||
@ -1288,7 +1105,7 @@ PackageWriterImpl::_WriteZlibCompressedData(BDataReader& dataReader, off_t size,
|
||||
// write the offset table
|
||||
if (chunkCount > 1) {
|
||||
size_t bytesToWrite = (chunkCount - 1) * sizeof(uint64);
|
||||
ssize_t bytesWritten = pwrite(fFD, offsetTable, bytesToWrite,
|
||||
ssize_t bytesWritten = pwrite(FD(), offsetTable, bytesToWrite,
|
||||
offsetTableOffset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError("Failed to write data: %s\n",
|
||||
|
64
src/kits/package/hpkg/RepositoryWriter.cpp
Normal file
64
src/kits/package/hpkg/RepositoryWriter.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <package/hpkg/RepositoryWriter.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <package/hpkg/RepositoryWriterImpl.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
namespace BHPKG {
|
||||
|
||||
|
||||
BRepositoryWriter::BRepositoryWriter(BRepositoryWriterListener* listener)
|
||||
:
|
||||
fImpl(new (std::nothrow) RepositoryWriterImpl(listener))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRepositoryWriter::~BRepositoryWriter()
|
||||
{
|
||||
delete fImpl;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryWriter::Init(const char* fileName)
|
||||
{
|
||||
if (fImpl == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
return fImpl->Init(fileName);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryWriter::AddPackage(const BPackageInfo& packageInfo)
|
||||
{
|
||||
if (fImpl == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fImpl->AddPackage(packageInfo);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryWriter::Finish()
|
||||
{
|
||||
if (fImpl == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fImpl->Finish();
|
||||
}
|
||||
|
||||
|
||||
} // namespace BHPKG
|
||||
|
||||
} // namespace BPackageKit
|
590
src/kits/package/hpkg/RepositoryWriterImpl.cpp
Normal file
590
src/kits/package/hpkg/RepositoryWriterImpl.cpp
Normal file
@ -0,0 +1,590 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <package/hpkg/RepositoryWriterImpl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <Entry.h>
|
||||
#include <fs_attr.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include <package/hpkg/haiku_package.h>
|
||||
|
||||
#include <package/hpkg/DataOutput.h>
|
||||
#include <package/hpkg/DataReader.h>
|
||||
#include <package/hpkg/ZlibCompressor.h>
|
||||
|
||||
|
||||
using BPrivate::FileDescriptorCloser;
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
namespace BHPKG {
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
RepositoryWriterImpl::RepositoryWriterImpl(BRepositoryWriterListener* listener)
|
||||
:
|
||||
fListener(listener),
|
||||
fFileName(NULL),
|
||||
fFD(-1),
|
||||
fFinished(false),
|
||||
fDataWriter(NULL),
|
||||
fCachedStrings(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RepositoryWriterImpl::~RepositoryWriterImpl()
|
||||
{
|
||||
if (fCachedStrings != NULL) {
|
||||
CachedString* cachedString = fCachedStrings->Clear(true);
|
||||
while (cachedString != NULL) {
|
||||
CachedString* next = cachedString->next;
|
||||
delete cachedString;
|
||||
cachedString = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (fFD >= 0)
|
||||
close(fFD);
|
||||
|
||||
if (!fFinished && fFileName != NULL)
|
||||
unlink(fFileName);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::Init(const char* fileName)
|
||||
{
|
||||
try {
|
||||
return _Init(fileName);
|
||||
} catch (status_t error) {
|
||||
return error;
|
||||
} catch (std::bad_alloc) {
|
||||
fListener->PrintError("Out of memory!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::AddPackage(const BPackageInfo& packageInfo)
|
||||
{
|
||||
try {
|
||||
return _RegisterPackage(packageInfo);
|
||||
} catch (status_t error) {
|
||||
return error;
|
||||
} catch (std::bad_alloc) {
|
||||
fListener->PrintError("Out of memory!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::Finish()
|
||||
{
|
||||
try {
|
||||
return _Finish();
|
||||
} catch (status_t error) {
|
||||
return error;
|
||||
} catch (std::bad_alloc) {
|
||||
fListener->PrintError("Out of memory!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_Init(const char* fileName)
|
||||
{
|
||||
// create hash tables
|
||||
fCachedStrings = new CachedStringTable;
|
||||
if (fCachedStrings->Init() != B_OK)
|
||||
throw std::bad_alloc();
|
||||
|
||||
// allocate data buffer
|
||||
fDataBufferSize = 2 * B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
|
||||
fDataBuffer = malloc(fDataBufferSize);
|
||||
if (fDataBuffer == NULL)
|
||||
throw std::bad_alloc();
|
||||
|
||||
// open file
|
||||
fFD = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (fFD < 0) {
|
||||
fListener->PrintError("Failed to open package file \"%s\": %s\n",
|
||||
fileName, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
fFileName = fileName;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_Finish()
|
||||
{
|
||||
hpkg_repo_header header;
|
||||
|
||||
// write the cached strings and package attributes
|
||||
_WriteCachedStrings();
|
||||
WritePackageAttributes(header);
|
||||
|
||||
off_t totalSize = fHeapEnd;
|
||||
|
||||
fListener->OnPackageSizeInfo(sizeof(hpkg_header), heapSize,
|
||||
B_BENDIAN_TO_HOST_INT64(header.toc_length_compressed),
|
||||
B_BENDIAN_TO_HOST_INT32(header.attributes_length_compressed),
|
||||
totalSize);
|
||||
|
||||
// prepare the header
|
||||
|
||||
// general
|
||||
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_INT64(totalSize);
|
||||
|
||||
// write the header
|
||||
_WriteBuffer(&header, sizeof(header), 0);
|
||||
|
||||
fFinished = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_AddPackage(const BPackageInfo& packageInfo)
|
||||
{
|
||||
// fPackageInfos.AddItem(packageInfo);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::_WriteTOC(hpkg_header& header)
|
||||
{
|
||||
// prepare the writer (zlib writer on top of a file writer)
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(fFD, startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
fDataWriter = &zlibWriter;
|
||||
zlibWriter.Init();
|
||||
|
||||
// write the sections
|
||||
uint64 uncompressedAttributeTypesSize;
|
||||
uint64 uncompressedStringsSize;
|
||||
uint64 uncompressedMainSize;
|
||||
int32 cachedStringsWritten = _WriteTOCSections(
|
||||
uncompressedAttributeTypesSize, uncompressedStringsSize,
|
||||
uncompressedMainSize);
|
||||
|
||||
// finish the writer
|
||||
zlibWriter.Finish();
|
||||
fHeapEnd = realWriter.Offset();
|
||||
fDataWriter = NULL;
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
|
||||
fListener->OnTOCSizeInfo(uncompressedAttributeTypesSize,
|
||||
uncompressedStringsSize, uncompressedMainSize,
|
||||
zlibWriter.BytesWritten());
|
||||
|
||||
// update the header
|
||||
|
||||
// TOC
|
||||
header.toc_compression = B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
|
||||
header.toc_length_compressed = B_HOST_TO_BENDIAN_INT64(
|
||||
endOffset - startOffset);
|
||||
header.toc_length_uncompressed = B_HOST_TO_BENDIAN_INT64(
|
||||
zlibWriter.BytesWritten());
|
||||
|
||||
header.toc_strings_length = B_HOST_TO_BENDIAN_INT64(
|
||||
uncompressedStringsSize);
|
||||
header.toc_strings_count = B_HOST_TO_BENDIAN_INT64(cachedStringsWritten);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
RepositoryWriterImpl::_WriteTOCSections(uint64& _attributeTypesSize,
|
||||
uint64& _stringsSize, uint64& _mainSize)
|
||||
{
|
||||
// write the attribute type abbreviations
|
||||
uint64 attributeTypesOffset = fDataWriter->BytesWritten();
|
||||
_WriteAttributeTypes();
|
||||
|
||||
// write the cached strings
|
||||
uint64 cachedStringsOffset = fDataWriter->BytesWritten();
|
||||
int32 cachedStringsWritten = _WriteCachedStrings();
|
||||
|
||||
// write the main TOC section
|
||||
uint64 mainOffset = fDataWriter->BytesWritten();
|
||||
_WriteAttributeChildren(fRootAttribute);
|
||||
|
||||
_attributeTypesSize = cachedStringsOffset - attributeTypesOffset;
|
||||
_stringsSize = mainOffset - cachedStringsOffset;
|
||||
_mainSize = fDataWriter->BytesWritten() - mainOffset;
|
||||
|
||||
return cachedStringsWritten;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::_WritePackageAttributes(hpkg_header& header)
|
||||
{
|
||||
// write the package attributes (zlib writer on top of a file writer)
|
||||
off_t startOffset = fHeapEnd;
|
||||
FDDataWriter realWriter(fFD, startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
fDataWriter = &zlibWriter;
|
||||
zlibWriter.Init();
|
||||
|
||||
// name
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_NAME, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(fPackageInfo.Name().String());
|
||||
|
||||
// summary
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_SUMMARY, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(fPackageInfo.Summary().String());
|
||||
|
||||
// description
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(fPackageInfo.Description().String());
|
||||
|
||||
// vendor
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VENDOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(fPackageInfo.Vendor().String());
|
||||
|
||||
// packager
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PACKAGER, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(fPackageInfo.Packager().String());
|
||||
|
||||
// architecture
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT, 0));
|
||||
_Write<uint8>(fPackageInfo.Architecture());
|
||||
|
||||
// version
|
||||
_WritePackageVersion(fPackageInfo.Version());
|
||||
|
||||
// copyright list
|
||||
const BObjectList<BString>& copyrightList = fPackageInfo.CopyrightList();
|
||||
for (int i = 0; i < copyrightList.CountItems(); ++i) {
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_COPYRIGHT, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(copyrightList.ItemAt(i)->String());
|
||||
}
|
||||
|
||||
// license list
|
||||
const BObjectList<BString>& licenseList = fPackageInfo.LicenseList();
|
||||
for (int i = 0; i < licenseList.CountItems(); ++i) {
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_LICENSE, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(licenseList.ItemAt(i)->String());
|
||||
}
|
||||
|
||||
// provides list
|
||||
const BObjectList<BPackageResolvable>& providesList
|
||||
= fPackageInfo.ProvidesList();
|
||||
for (int i = 0; i < providesList.CountItems(); ++i) {
|
||||
BPackageResolvable* resolvable = providesList.ItemAt(i);
|
||||
bool hasVersion = resolvable->Version().InitCheck() == B_OK;
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES_TYPE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT, 0));
|
||||
_Write<uint8>((uint8)resolvable->Type());
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, hasVersion));
|
||||
_WriteString(resolvable->Name().String());
|
||||
if (hasVersion) {
|
||||
_WritePackageVersion(resolvable->Version());
|
||||
_Write<uint8>(0);
|
||||
}
|
||||
}
|
||||
|
||||
// requires list
|
||||
_WritePackageResolvableExpressionList(fPackageInfo.RequiresList(),
|
||||
HPKG_PACKAGE_ATTRIBUTE_REQUIRES);
|
||||
|
||||
// supplements list
|
||||
_WritePackageResolvableExpressionList(fPackageInfo.SupplementsList(),
|
||||
HPKG_PACKAGE_ATTRIBUTE_SUPPLEMENTS);
|
||||
|
||||
// conflicts list
|
||||
_WritePackageResolvableExpressionList(fPackageInfo.ConflictsList(),
|
||||
HPKG_PACKAGE_ATTRIBUTE_CONFLICTS);
|
||||
|
||||
// freshens list
|
||||
_WritePackageResolvableExpressionList(fPackageInfo.FreshensList(),
|
||||
HPKG_PACKAGE_ATTRIBUTE_FRESHENS);
|
||||
|
||||
// replaces list
|
||||
const BObjectList<BString>& replacesList = fPackageInfo.ReplacesList();
|
||||
for (int i = 0; i < replacesList.CountItems(); ++i) {
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_REPLACES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(replacesList.ItemAt(i)->String());
|
||||
}
|
||||
|
||||
_Write<uint8>(0);
|
||||
|
||||
zlibWriter.Finish();
|
||||
fHeapEnd = realWriter.Offset();
|
||||
fDataWriter = NULL;
|
||||
|
||||
off_t endOffset = fHeapEnd;
|
||||
|
||||
fListener->OnPackageAttributesSizeInfo(zlibWriter.BytesWritten());
|
||||
|
||||
// update the header
|
||||
header.attributes_compression
|
||||
= B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
|
||||
header.attributes_length_compressed
|
||||
= B_HOST_TO_BENDIAN_INT32(endOffset - startOffset);
|
||||
header.attributes_length_uncompressed
|
||||
= B_HOST_TO_BENDIAN_INT32(zlibWriter.BytesWritten());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::_WritePackageVersion(const BPackageVersion& version)
|
||||
{
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(version.Major());
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MINOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(version.Minor());
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MICRO, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE, 0));
|
||||
_WriteString(version.Micro());
|
||||
_WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_RELEASE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT, 0));
|
||||
_Write<uint8>(version.Release());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::_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(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(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
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
|
||||
RepositoryWriterImpl::_WriteUnsignedLEB128(uint64 value)
|
||||
{
|
||||
uint8 bytes[10];
|
||||
int32 count = 0;
|
||||
do {
|
||||
uint8 byte = value & 0x7f;
|
||||
value >>= 7;
|
||||
bytes[count++] = byte | (value != 0 ? 0x80 : 0);
|
||||
} while (value != 0);
|
||||
|
||||
fDataWriter->WriteDataThrows(bytes, count);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::_WriteBuffer(const void* buffer, size_t size, off_t offset)
|
||||
{
|
||||
ssize_t bytesWritten = pwrite(fFD, buffer, size, offset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError(
|
||||
"_WriteBuffer(%p, %lu) failed to write data: %s\n", buffer, size,
|
||||
strerror(errno));
|
||||
throw status_t(errno);
|
||||
}
|
||||
if ((size_t)bytesWritten != size) {
|
||||
fListener->PrintError(
|
||||
"_WriteBuffer(%p, %lu) failed to write all data\n", buffer, size);
|
||||
throw status_t(B_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CachedString*
|
||||
RepositoryWriterImpl::_GetCachedString(const char* value)
|
||||
{
|
||||
CachedString* string = fCachedStrings->Lookup(value);
|
||||
if (string != NULL) {
|
||||
string->usageCount++;
|
||||
return string;
|
||||
}
|
||||
|
||||
string = new CachedString;
|
||||
if (!string->Init(value)) {
|
||||
delete string;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
fCachedStrings->Insert(string);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_WriteZlibCompressedData(BDataReader& dataReader, off_t size,
|
||||
uint64 writeOffset, uint64& _compressedSize)
|
||||
{
|
||||
// Use zlib compression only for data large enough.
|
||||
if (size < kZlibCompressionSizeThreshold)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// fDataBuffer is 2 * B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, so split it into
|
||||
// two halves we can use for reading and compressing
|
||||
const size_t chunkSize = B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
|
||||
uint8* inputBuffer = (uint8*)fDataBuffer;
|
||||
uint8* outputBuffer = (uint8*)fDataBuffer + chunkSize;
|
||||
|
||||
// account for the offset table
|
||||
uint64 chunkCount = (size + (chunkSize - 1)) / chunkSize;
|
||||
off_t offsetTableOffset = writeOffset;
|
||||
uint64* offsetTable = NULL;
|
||||
if (chunkCount > 1) {
|
||||
offsetTable = new uint64[chunkCount - 1];
|
||||
writeOffset = offsetTableOffset + (chunkCount - 1) * sizeof(uint64);
|
||||
}
|
||||
ArrayDeleter<uint64> offsetTableDeleter(offsetTable);
|
||||
|
||||
const uint64 dataOffset = writeOffset;
|
||||
const uint64 dataEndLimit = offsetTableOffset + size;
|
||||
|
||||
// read the data, compress them and write them to the heap
|
||||
off_t readOffset = 0;
|
||||
off_t remainingSize = size;
|
||||
uint64 chunkIndex = 0;
|
||||
while (remainingSize > 0) {
|
||||
// read data
|
||||
size_t toCopy = std::min(remainingSize, (off_t)chunkSize);
|
||||
status_t error = dataReader.ReadData(readOffset, inputBuffer, toCopy);
|
||||
if (error != B_OK) {
|
||||
fListener->PrintError("Failed to read data: %s\n", strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// compress
|
||||
size_t compressedSize;
|
||||
error = ZlibCompressor::CompressSingleBuffer(inputBuffer, toCopy,
|
||||
outputBuffer, toCopy, compressedSize);
|
||||
|
||||
const void* writeBuffer;
|
||||
size_t bytesToWrite;
|
||||
if (error == B_OK) {
|
||||
writeBuffer = outputBuffer;
|
||||
bytesToWrite = compressedSize;
|
||||
} else {
|
||||
if (error != B_BUFFER_OVERFLOW)
|
||||
return error;
|
||||
writeBuffer = inputBuffer;
|
||||
bytesToWrite = toCopy;
|
||||
}
|
||||
|
||||
// check the total compressed data size
|
||||
if (writeOffset + bytesToWrite >= dataEndLimit)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
|
||||
if (chunkIndex > 0)
|
||||
offsetTable[chunkIndex - 1] = writeOffset - dataOffset;
|
||||
|
||||
// write to heap
|
||||
ssize_t bytesWritten = pwrite(fFD, writeBuffer, bytesToWrite,
|
||||
writeOffset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError("Failed to write data: %s\n",
|
||||
strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
if ((size_t)bytesWritten != bytesToWrite) {
|
||||
fListener->PrintError("Failed to write all data\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
remainingSize -= toCopy;
|
||||
readOffset += toCopy;
|
||||
writeOffset += bytesToWrite;
|
||||
chunkIndex++;
|
||||
}
|
||||
|
||||
// write the offset table
|
||||
if (chunkCount > 1) {
|
||||
size_t bytesToWrite = (chunkCount - 1) * sizeof(uint64);
|
||||
ssize_t bytesWritten = pwrite(fFD, offsetTable, bytesToWrite,
|
||||
offsetTableOffset);
|
||||
if (bytesWritten < 0) {
|
||||
fListener->PrintError("Failed to write data: %s\n",
|
||||
strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
if ((size_t)bytesWritten != bytesToWrite) {
|
||||
fListener->PrintError("Failed to write all data\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
_compressedSize = writeOffset - offsetTableOffset;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
} // namespace BHPKG
|
||||
|
||||
} // namespace BPackageKit
|
@ -176,17 +176,17 @@ WriterImplBase::AttributeValue::_ApplicableIntEncoding(uint64 value)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - DataWriter
|
||||
// #pragma mark - AbstractDataWriter
|
||||
|
||||
|
||||
WriterImplBase::DataWriter::DataWriter()
|
||||
WriterImplBase::AbstractDataWriter::AbstractDataWriter()
|
||||
:
|
||||
fBytesWritten(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WriterImplBase::DataWriter::~DataWriter()
|
||||
WriterImplBase::AbstractDataWriter::~AbstractDataWriter()
|
||||
{
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ WriterImplBase::FDDataWriter::WriteDataNoThrow(const void* buffer, size_t size)
|
||||
// #pragma mark - ZlibDataWriter
|
||||
|
||||
|
||||
WriterImplBase::ZlibDataWriter::ZlibDataWriter(DataWriter* dataWriter)
|
||||
WriterImplBase::ZlibDataWriter::ZlibDataWriter(AbstractDataWriter* dataWriter)
|
||||
:
|
||||
fDataWriter(dataWriter),
|
||||
fCompressor(this)
|
||||
@ -316,8 +316,6 @@ WriterImplBase::WriterImplBase(BErrorOutput* errorOutput)
|
||||
fFileName(NULL),
|
||||
fFD(-1),
|
||||
fFinished(false),
|
||||
fDataBuffer(NULL),
|
||||
fDataBufferSize(2 * B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB),
|
||||
fDataWriter(NULL)
|
||||
{
|
||||
}
|
||||
@ -339,11 +337,6 @@ WriterImplBase::Init(const char* fileName, const char* type)
|
||||
if (fPackageStringCache.Init() != B_OK)
|
||||
throw std::bad_alloc();
|
||||
|
||||
// allocate data buffer
|
||||
fDataBuffer = malloc(fDataBufferSize);
|
||||
if (fDataBuffer == NULL)
|
||||
throw std::bad_alloc();
|
||||
|
||||
// open file
|
||||
fFD = open(fileName, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
@ -359,6 +352,187 @@ WriterImplBase::Init(const char* fileName, const char* type)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList,
|
||||
const BPackageInfo& packageInfo)
|
||||
{
|
||||
// name
|
||||
PackageAttribute* name = new PackageAttribute(HPKG_PACKAGE_ATTRIBUTE_NAME,
|
||||
B_HPKG_ATTRIBUTE_TYPE_STRING, B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
name->string = fPackageStringCache.Get(packageInfo.Name().String());
|
||||
attributeList.Add(name);
|
||||
|
||||
// summary
|
||||
PackageAttribute* summary = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_SUMMARY, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
summary->string = fPackageStringCache.Get(packageInfo.Summary().String());
|
||||
attributeList.Add(summary);
|
||||
|
||||
// description
|
||||
PackageAttribute* description = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
description->string
|
||||
= fPackageStringCache.Get(packageInfo.Description().String());
|
||||
attributeList.Add(description);
|
||||
|
||||
// vendor
|
||||
PackageAttribute* vendor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VENDOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
vendor->string = fPackageStringCache.Get(packageInfo.Vendor().String());
|
||||
attributeList.Add(vendor);
|
||||
|
||||
// packager
|
||||
PackageAttribute* packager = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PACKAGER, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
packager->string = fPackageStringCache.Get(packageInfo.Packager().String());
|
||||
attributeList.Add(packager);
|
||||
|
||||
// architecture
|
||||
PackageAttribute* architecture = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
architecture->unsignedInt = packageInfo.Architecture();
|
||||
attributeList.Add(packager);
|
||||
|
||||
// version
|
||||
RegisterPackageVersion(attributeList, packageInfo.Version());
|
||||
|
||||
// copyright list
|
||||
const BObjectList<BString>& copyrightList = packageInfo.CopyrightList();
|
||||
for (int i = 0; i < copyrightList.CountItems(); ++i) {
|
||||
PackageAttribute* copyright = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_COPYRIGHT, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
copyright->string
|
||||
= fPackageStringCache.Get(copyrightList.ItemAt(i)->String());
|
||||
attributeList.Add(copyright);
|
||||
}
|
||||
|
||||
// license list
|
||||
const BObjectList<BString>& licenseList = packageInfo.LicenseList();
|
||||
for (int i = 0; i < licenseList.CountItems(); ++i) {
|
||||
PackageAttribute* license = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_LICENSE, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
license->string
|
||||
= fPackageStringCache.Get(licenseList.ItemAt(i)->String());
|
||||
attributeList.Add(license);
|
||||
}
|
||||
|
||||
// provides list
|
||||
const BObjectList<BPackageResolvable>& providesList
|
||||
= packageInfo.ProvidesList();
|
||||
for (int i = 0; i < providesList.CountItems(); ++i) {
|
||||
BPackageResolvable* resolvable = providesList.ItemAt(i);
|
||||
bool hasVersion = resolvable->Version().InitCheck() == B_OK;
|
||||
|
||||
PackageAttribute* providesType = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES_TYPE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
providesType->unsignedInt = resolvable->Type();
|
||||
attributeList.Add(providesType);
|
||||
|
||||
PackageAttribute* provides = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_PROVIDES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
provides->string = fPackageStringCache.Get(resolvable->Name().String());
|
||||
attributeList.Add(provides);
|
||||
|
||||
if (hasVersion)
|
||||
RegisterPackageVersion(provides->children, resolvable->Version());
|
||||
}
|
||||
|
||||
// requires list
|
||||
RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.RequiresList(), HPKG_PACKAGE_ATTRIBUTE_REQUIRES);
|
||||
|
||||
// supplements list
|
||||
RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.SupplementsList(), HPKG_PACKAGE_ATTRIBUTE_SUPPLEMENTS);
|
||||
|
||||
// conflicts list
|
||||
RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.ConflictsList(), HPKG_PACKAGE_ATTRIBUTE_CONFLICTS);
|
||||
|
||||
// freshens list
|
||||
RegisterPackageResolvableExpressionList(attributeList,
|
||||
packageInfo.FreshensList(), HPKG_PACKAGE_ATTRIBUTE_FRESHENS);
|
||||
|
||||
// replaces list
|
||||
const BObjectList<BString>& replacesList = packageInfo.ReplacesList();
|
||||
for (int i = 0; i < replacesList.CountItems(); ++i) {
|
||||
PackageAttribute* replaces = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_REPLACES, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
replaces->string
|
||||
= fPackageStringCache.Get(replacesList.ItemAt(i)->String());
|
||||
attributeList.Add(replaces);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriterImplBase::RegisterPackageVersion(PackageAttributeList& attributeList,
|
||||
const BPackageVersion& version)
|
||||
{
|
||||
PackageAttribute* versionMajor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMajor->string = fPackageStringCache.Get(version.Major().String());
|
||||
attributeList.Add(versionMajor);
|
||||
|
||||
PackageAttribute* versionMinor = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MINOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMinor->string = fPackageStringCache.Get(version.Minor().String());
|
||||
attributeList.Add(versionMinor);
|
||||
|
||||
PackageAttribute* versionMicro = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MICRO, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
versionMicro->string = fPackageStringCache.Get(version.Micro().String());
|
||||
attributeList.Add(versionMicro);
|
||||
|
||||
PackageAttribute* versionRelease = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_RELEASE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
versionRelease->unsignedInt = version.Release();
|
||||
attributeList.Add(versionRelease);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriterImplBase::RegisterPackageResolvableExpressionList(
|
||||
PackageAttributeList& attributeList,
|
||||
const BObjectList<BPackageResolvableExpression>& expressionList, uint8 id)
|
||||
{
|
||||
for (int i = 0; i < expressionList.CountItems(); ++i) {
|
||||
BPackageResolvableExpression* resolvableExpr = expressionList.ItemAt(i);
|
||||
bool hasVersion = resolvableExpr->Version().InitCheck() == B_OK;
|
||||
|
||||
PackageAttribute* name = new PackageAttribute(
|
||||
(HPKGPackageAttributeID)id, B_HPKG_ATTRIBUTE_TYPE_STRING,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
|
||||
name->string = fPackageStringCache.Get(resolvableExpr->Name().String());
|
||||
attributeList.Add(name);
|
||||
|
||||
if (hasVersion) {
|
||||
PackageAttribute* op = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_RESOLVABLE_OPERATOR,
|
||||
B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
op->unsignedInt = resolvableExpr->Operator();
|
||||
name->children.Add(op);
|
||||
RegisterPackageVersion(name->children, resolvableExpr->Version());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
WriterImplBase::WriteCachedStrings(const StringCache& cache,
|
||||
uint32 minUsageCount)
|
||||
@ -403,28 +577,18 @@ WriterImplBase::WriteCachedStrings(const StringCache& cache,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
int32
|
||||
WriterImplBase::WritePackageAttributes(
|
||||
const PackageAttributeList& packageAttributes)
|
||||
const PackageAttributeList& packageAttributes,
|
||||
uint32& _stringsLengthUncompressed)
|
||||
{
|
||||
DoublyLinkedList<PackageAttribute>::ConstIterator it
|
||||
= packageAttributes.GetIterator();
|
||||
while (PackageAttribute* attribute = it.Next()) {
|
||||
uint8 encoding = attribute->ApplicableEncoding();
|
||||
// write the cached strings
|
||||
uint32 stringsCount = WriteCachedStrings(fPackageStringCache, 2);
|
||||
_stringsLengthUncompressed = DataWriter()->BytesWritten();
|
||||
|
||||
// write tag
|
||||
WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
attribute->id, attribute->type, encoding,
|
||||
!attribute->children.IsEmpty()));
|
||||
_WritePackageAttributes(packageAttributes);
|
||||
|
||||
// write value
|
||||
WriteAttributeValue(*attribute, encoding);
|
||||
|
||||
if (!attribute->children.IsEmpty())
|
||||
WritePackageAttributes(attribute->children);
|
||||
}
|
||||
|
||||
WriteUnsignedLEB128(0);
|
||||
return stringsCount;
|
||||
}
|
||||
|
||||
|
||||
@ -526,6 +690,31 @@ WriterImplBase::WriteBuffer(const void* buffer, size_t size, off_t offset)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriterImplBase::_WritePackageAttributes(
|
||||
const PackageAttributeList& packageAttributes)
|
||||
{
|
||||
DoublyLinkedList<PackageAttribute>::ConstIterator it
|
||||
= packageAttributes.GetIterator();
|
||||
while (PackageAttribute* attribute = it.Next()) {
|
||||
uint8 encoding = attribute->ApplicableEncoding();
|
||||
|
||||
// write tag
|
||||
WriteUnsignedLEB128(HPKG_PACKAGE_ATTRIBUTE_TAG_COMPOSE(
|
||||
attribute->id, attribute->type, encoding,
|
||||
!attribute->children.IsEmpty()));
|
||||
|
||||
// write value
|
||||
WriteAttributeValue(*attribute, encoding);
|
||||
|
||||
if (!attribute->children.IsEmpty())
|
||||
_WritePackageAttributes(attribute->children);
|
||||
}
|
||||
|
||||
WriteUnsignedLEB128(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
} // namespace BHPKG
|
||||
|
Loading…
Reference in New Issue
Block a user