mirror of
https://review.haiku-os.org/haiku
synced 2025-02-07 06:16:11 +01:00
1f633814fa
Instead of handling compression for individual file/attribute data we do now compress the whole heap where they are stored. This significantly improves compression ratios. We still divide the uncompressed data into 64 KiB chunks and use a chunk offset array for the compressed chunks to allow for quick random access without too much overhead. The tradeoff is a limited possible compression ratio -- i.e. we won't be as good as tar.gz (though surprisingly with my test archives we did better than zip). The other package file sections (package attributes and TOC) are no longer compressed individually. Their uncompressed data are simply pushed onto the heap where the usual compression strategy applies. To simplify things the repository format has been changed in the same manner although it doesn't otherwise use the heap, since it only stores meta data. Due to the data compression having been exposed in public and private API, this change touches a lot of package kit using code, including packagefs and the boot loader packagefs support. The latter two haven't been tested yet. Moreover packagefs needs a new kind of cache so we avoid re-reading the same heap chunk for two different data items it contains.
150 lines
3.7 KiB
C++
150 lines
3.7 KiB
C++
/*
|
|
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
|
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _PACKAGE__HPKG__PRIVATE__PACKAGE_WRITER_IMPL_H_
|
|
#define _PACKAGE__HPKG__PRIVATE__PACKAGE_WRITER_IMPL_H_
|
|
|
|
|
|
#include <util/DoublyLinkedList.h>
|
|
#include <util/OpenHashTable.h>
|
|
|
|
#include <String.h>
|
|
|
|
#include <package/hpkg/PackageWriter.h>
|
|
#include <package/hpkg/Strings.h>
|
|
#include <package/hpkg/WriterImplBase.h>
|
|
|
|
|
|
namespace BPrivate {
|
|
template<typename Value> class RangeArray;
|
|
}
|
|
|
|
|
|
namespace BPackageKit {
|
|
|
|
namespace BHPKG {
|
|
|
|
|
|
class BDataReader;
|
|
class BErrorOutput;
|
|
|
|
|
|
namespace BPrivate {
|
|
|
|
|
|
struct hpkg_header;
|
|
class PackageFileHeapWriter;
|
|
|
|
|
|
class PackageWriterImpl : public WriterImplBase {
|
|
typedef WriterImplBase inherited;
|
|
|
|
public:
|
|
PackageWriterImpl(
|
|
BPackageWriterListener* listener);
|
|
~PackageWriterImpl();
|
|
|
|
status_t Init(const char* fileName, uint32 flags);
|
|
status_t SetInstallPath(const char* installPath);
|
|
void SetCheckLicenses(bool checkLicenses);
|
|
status_t AddEntry(const char* fileName, int fd = -1);
|
|
status_t Finish();
|
|
|
|
private:
|
|
struct Attribute;
|
|
struct PackageContentHandler;
|
|
struct Entry;
|
|
struct SubPathAdder;
|
|
struct HeapAttributeOffsetter;
|
|
|
|
typedef DoublyLinkedList<Entry> EntryList;
|
|
|
|
private:
|
|
status_t _Init(const char* fileName, uint32 flags);
|
|
status_t _Finish();
|
|
|
|
status_t _RegisterEntry(const char* fileName, int fd);
|
|
Entry* _RegisterEntry(Entry* parent,
|
|
const char* name, size_t nameLength, int fd,
|
|
bool isImplicit);
|
|
|
|
status_t _CheckLicenses();
|
|
bool _IsEntryInPackage(const char* fileName);
|
|
|
|
void _UpdateReadPackageInfo();
|
|
void _UpdateCheckEntryCollisions();
|
|
void _UpdateCheckEntryCollisions(
|
|
Attribute* parentAttribute, int dirFD,
|
|
Entry* entry, const char* fileName,
|
|
char* pathBuffer);
|
|
void _CompactHeap();
|
|
void _AttributeRemoved(Attribute* attribute);
|
|
|
|
void _WriteTOC(hpkg_header& header, uint64& _length);
|
|
void _WriteAttributeChildren(Attribute* attribute);
|
|
|
|
void _WritePackageAttributes(hpkg_header& header,
|
|
uint64& _length);
|
|
uint32 _WritePackageAttributesCompressed(
|
|
uint32& _stringsLengthUncompressed,
|
|
uint32& _attributesLengthUncompressed);
|
|
|
|
void _AddEntry(int dirFD, Entry* entry,
|
|
const char* fileName, char* pathBuffer);
|
|
void _AddDirectoryChildren(Entry* entry, int fd,
|
|
char* pathBuffer);
|
|
|
|
Attribute* _AddAttribute(BHPKGAttributeID attributeID,
|
|
const AttributeValue& value);
|
|
|
|
template<typename Type>
|
|
inline Attribute* _AddAttribute(BHPKGAttributeID attributeID,
|
|
Type value);
|
|
|
|
Attribute* _AddStringAttribute(
|
|
BHPKGAttributeID attributeID,
|
|
const char* value);
|
|
Attribute* _AddDataAttribute(BHPKGAttributeID attributeID,
|
|
uint64 dataSize, uint64 dataOffset);
|
|
Attribute* _AddDataAttribute(BHPKGAttributeID attributeID,
|
|
uint64 dataSize, const uint8* data);
|
|
|
|
status_t _AddData(BDataReader& dataReader, off_t size);
|
|
|
|
status_t _WriteZlibCompressedData(
|
|
BDataReader& dataReader,
|
|
off_t size, uint64 writeOffset,
|
|
uint64& _compressedSize);
|
|
|
|
private:
|
|
BPackageWriterListener* fListener;
|
|
|
|
off_t fHeapOffset;
|
|
uint16 fHeaderSize;
|
|
|
|
::BPrivate::RangeArray<uint64>* fHeapRangesToRemove;
|
|
|
|
Entry* fRootEntry;
|
|
|
|
Attribute* fRootAttribute;
|
|
Attribute* fTopAttribute;
|
|
|
|
StringCache fStringCache;
|
|
|
|
BPackageInfo fPackageInfo;
|
|
BString fInstallPath;
|
|
bool fCheckLicenses;
|
|
};
|
|
|
|
|
|
} // namespace BPrivate
|
|
|
|
} // namespace BHPKG
|
|
|
|
} // namespace BPackageKit
|
|
|
|
|
|
#endif // _PACKAGE__HPKG__PRIVATE__PACKAGE_WRITER_IMPL_H_
|