diff --git a/headers/os/package/hpkg/HPKGDefs.h b/headers/os/package/hpkg/HPKGDefs.h index 7cd931b52a..b11a788044 100644 --- a/headers/os/package/hpkg/HPKGDefs.h +++ b/headers/os/package/hpkg/HPKGDefs.h @@ -166,6 +166,13 @@ enum { }; +enum { + B_HPKG_COMPRESSION_LEVEL_NONE = 0, + B_HPKG_COMPRESSION_LEVEL_FASTEST = 1, + B_HPKG_COMPRESSION_LEVEL_BEST = 9 +}; + + } // namespace BHPKG } // namespace BPackageKit diff --git a/headers/os/package/hpkg/PackageWriter.h b/headers/os/package/hpkg/PackageWriter.h index e3eb30d59b..99c924bfec 100644 --- a/headers/os/package/hpkg/PackageWriter.h +++ b/headers/os/package/hpkg/PackageWriter.h @@ -41,13 +41,32 @@ public: }; +class BPackageWriterParameters { +public: + BPackageWriterParameters(); + ~BPackageWriterParameters(); + + uint32 Flags() const; + void SetFlags(uint32 flags); + + int32 CompressionLevel() const; + void SetCompressionLevel(int32 compressionLevel); + +private: + uint32 fFlags; + int32 fCompressionLevel; +}; + + class BPackageWriter { public: BPackageWriter( BPackageWriterListener* listener); ~BPackageWriter(); - status_t Init(const char* fileName, uint32 flags = 0); + status_t Init(const char* fileName, + const BPackageWriterParameters* parameters + = NULL); status_t SetInstallPath(const char* installPath); void SetCheckLicenses(bool checkLicenses); status_t AddEntry(const char* fileName, int fd = -1); diff --git a/headers/private/package/hpkg/PackageFileHeapWriter.h b/headers/private/package/hpkg/PackageFileHeapWriter.h index 3b4d24e590..d62f82e1b4 100644 --- a/headers/private/package/hpkg/PackageFileHeapWriter.h +++ b/headers/private/package/hpkg/PackageFileHeapWriter.h @@ -35,7 +35,8 @@ class PackageFileHeapWriter : public PackageFileHeapAccessorBase, private AbstractDataWriter { public: PackageFileHeapWriter(BErrorOutput* errorOutput, - int fd, off_t heapOffset); + int fd, off_t heapOffset, + int32 compressionLevel); ~PackageFileHeapWriter(); void Init(); @@ -86,6 +87,7 @@ private: void* fCompressedDataBuffer; size_t fPendingDataSize; Array fOffsets; + int32 fCompressionLevel; }; diff --git a/headers/private/package/hpkg/PackageWriterImpl.h b/headers/private/package/hpkg/PackageWriterImpl.h index 306f5ccd26..c9499c8879 100644 --- a/headers/private/package/hpkg/PackageWriterImpl.h +++ b/headers/private/package/hpkg/PackageWriterImpl.h @@ -29,6 +29,7 @@ namespace BHPKG { class BDataReader; class BErrorOutput; +class BPackageWriterParameters; namespace BPrivate { @@ -46,7 +47,8 @@ public: BPackageWriterListener* listener); ~PackageWriterImpl(); - status_t Init(const char* fileName, uint32 flags); + status_t Init(const char* fileName, + const BPackageWriterParameters& parameters); status_t SetInstallPath(const char* installPath); void SetCheckLicenses(bool checkLicenses); status_t AddEntry(const char* fileName, int fd = -1); @@ -62,7 +64,8 @@ private: typedef DoublyLinkedList EntryList; private: - status_t _Init(const char* fileName, uint32 flags); + status_t _Init(const char* fileName, + const BPackageWriterParameters& parameters); status_t _Finish(); status_t _RegisterEntry(const char* fileName, int fd); diff --git a/headers/private/package/hpkg/WriterImplBase.h b/headers/private/package/hpkg/WriterImplBase.h index 0965bcf731..c45d850330 100644 --- a/headers/private/package/hpkg/WriterImplBase.h +++ b/headers/private/package/hpkg/WriterImplBase.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -99,7 +100,8 @@ protected: typedef DoublyLinkedList PackageAttributeList; protected: - status_t Init(const char* fileName, uint32 flags); + status_t Init(const char* fileName, + const BPackageWriterParameters& parameters); void RegisterPackageInfo( PackageAttributeList& attributeList, @@ -168,7 +170,7 @@ private: const char* fFileType; BErrorOutput* fErrorOutput; const char* fFileName; - uint32 fFlags; + BPackageWriterParameters fParameters; int fFD; bool fFinished; @@ -211,7 +213,7 @@ WriterImplBase::FD() const inline uint32 WriterImplBase::Flags() const { - return fFlags; + return fParameters.Flags(); } diff --git a/src/bin/package/command_add.cpp b/src/bin/package/command_add.cpp index 601624c8b5..47592446c3 100644 --- a/src/bin/package/command_add.cpp +++ b/src/bin/package/command_add.cpp @@ -35,6 +35,7 @@ command_add(int argc, const char* const* argv) bool quiet = false; bool verbose = false; bool force = false; + int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST; while (true) { static struct option sLongOptions[] = { @@ -45,12 +46,25 @@ command_add(int argc, const char* const* argv) }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "+C:fhi:qv", sLongOptions, - NULL); + int c = getopt_long(argc, (char**)argv, "+0123456789C:fhi:qv", + sLongOptions, NULL); if (c == -1) break; switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + compressionLevel = c - '0'; + break; + case 'C': changeToDirectory = optarg; break; @@ -96,10 +110,14 @@ command_add(int argc, const char* const* argv) int entriesToAddCount = argc - optind; // create package + BPackageWriterParameters writerParameters; + writerParameters.SetFlags( + B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0)); + writerParameters.SetCompressionLevel(compressionLevel); + PackageWriterListener listener(verbose, quiet); BPackageWriter packageWriter(&listener); - status_t result = packageWriter.Init(packageFileName, - B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0)); + status_t result = packageWriter.Init(packageFileName, &writerParameters); if (result != B_OK) return 1; diff --git a/src/bin/package/command_create.cpp b/src/bin/package/command_create.cpp index 2e9d0275eb..b3777dd92b 100644 --- a/src/bin/package/command_create.cpp +++ b/src/bin/package/command_create.cpp @@ -24,8 +24,9 @@ #include "PackageWritingUtils.h" -using BPackageKit::BHPKG::BPackageWriterListener; using BPackageKit::BHPKG::BPackageWriter; +using BPackageKit::BHPKG::BPackageWriterListener; +using BPackageKit::BHPKG::BPackageWriterParameters; int @@ -37,6 +38,7 @@ command_create(int argc, const char* const* argv) bool isBuildPackage = false; bool quiet = false; bool verbose = false; + int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST; while (true) { static struct option sLongOptions[] = { @@ -47,12 +49,25 @@ command_create(int argc, const char* const* argv) }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "+bC:hi:I:qv", sLongOptions, - NULL); + int c = getopt_long(argc, (char**)argv, "+b0123456789C:hi:I:qv", + sLongOptions, NULL); if (c == -1) break; switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + compressionLevel = c - '0'; + break; + case 'b': isBuildPackage = true; break; @@ -101,9 +116,12 @@ command_create(int argc, const char* const* argv) } // create package + BPackageWriterParameters writerParameters; + writerParameters.SetCompressionLevel(compressionLevel); + PackageWriterListener listener(verbose, quiet); BPackageWriter packageWriter(&listener); - status_t result = packageWriter.Init(packageFileName); + status_t result = packageWriter.Init(packageFileName, &writerParameters); if (result != B_OK) return 1; diff --git a/src/bin/package/package.cpp b/src/bin/package/package.cpp index d7bbe3a968..240517b3a7 100644 --- a/src/bin/package/package.cpp +++ b/src/bin/package/package.cpp @@ -26,6 +26,9 @@ static const char* kUsage = " add [ ] ...\n" " Adds the specified entries to package file .\n" "\n" + " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best " + "compression.\n" + " Defaults to 9.\n" " -C - Change to directory before adding entries.\n" " -f - Force adding, replacing already existing entries. " "Without\n" @@ -41,6 +44,9 @@ static const char* kUsage = " create [ ] \n" " Creates package file from contents of current directory.\n" "\n" + " -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best " + "compression.\n" + " Defaults to 9.\n" " -b - Create an empty build package. Only the .PackageInfo " "will\n" " be added.\n" diff --git a/src/kits/package/hpkg/PackageFileHeapWriter.cpp b/src/kits/package/hpkg/PackageFileHeapWriter.cpp index d7fc523c97..1ca2fe747a 100644 --- a/src/kits/package/hpkg/PackageFileHeapWriter.cpp +++ b/src/kits/package/hpkg/PackageFileHeapWriter.cpp @@ -210,13 +210,14 @@ private: PackageFileHeapWriter::PackageFileHeapWriter(BErrorOutput* errorOutput, int fd, - off_t heapOffset) + off_t heapOffset, int32 compressionLevel) : PackageFileHeapAccessorBase(errorOutput, fd, heapOffset), fPendingDataBuffer(NULL), fCompressedDataBuffer(NULL), fPendingDataSize(0), - fOffsets() + fOffsets(), + fCompressionLevel(compressionLevel) { } @@ -566,9 +567,12 @@ PackageFileHeapWriter::_WriteChunk(const void* data, size_t size, status_t PackageFileHeapWriter::_WriteDataCompressed(const void* data, size_t size) { + if (fCompressionLevel == B_HPKG_COMPRESSION_LEVEL_NONE) + return B_BUFFER_OVERFLOW; + size_t compressedSize; status_t error = ZlibCompressor::CompressSingleBuffer(data, size, - fCompressedDataBuffer, size, compressedSize); + fCompressedDataBuffer, size, compressedSize, fCompressionLevel); if (error != B_OK) return error; diff --git a/src/kits/package/hpkg/PackageWriter.cpp b/src/kits/package/hpkg/PackageWriter.cpp index 3fcbec8e42..2a5582e378 100644 --- a/src/kits/package/hpkg/PackageWriter.cpp +++ b/src/kits/package/hpkg/PackageWriter.cpp @@ -16,6 +16,53 @@ namespace BPackageKit { namespace BHPKG { +// #pragma mark - BPackageWriterParameters + + +BPackageWriterParameters::BPackageWriterParameters() + : + fFlags(0), + fCompressionLevel(B_HPKG_COMPRESSION_LEVEL_BEST) +{ +} + + +BPackageWriterParameters::~BPackageWriterParameters() +{ +} + + +uint32 +BPackageWriterParameters::Flags() const +{ + return fFlags; +} + + +void +BPackageWriterParameters::SetFlags(uint32 flags) +{ + fFlags = flags; +} + + +int32 +BPackageWriterParameters::CompressionLevel() const +{ + return fCompressionLevel; +} + + +void +BPackageWriterParameters::SetCompressionLevel(int32 compressionLevel) +{ + fCompressionLevel = compressionLevel; +} + + +// #pragma mark - BPackageWriter + + BPackageWriter::BPackageWriter(BPackageWriterListener* listener) : fImpl(new (std::nothrow) PackageWriterImpl(listener)) @@ -30,12 +77,16 @@ BPackageWriter::~BPackageWriter() status_t -BPackageWriter::Init(const char* fileName, uint32 flags) +BPackageWriter::Init(const char* fileName, + const BPackageWriterParameters* parameters) { if (fImpl == NULL) return B_NO_MEMORY; - return fImpl->Init(fileName, flags); + BPackageWriterParameters defaultParameters; + + return fImpl->Init(fileName, + parameters != NULL ? *parameters : defaultParameters); } diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index fc407ea7fc..11813db511 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -463,10 +463,11 @@ PackageWriterImpl::~PackageWriterImpl() status_t -PackageWriterImpl::Init(const char* fileName, uint32 flags) +PackageWriterImpl::Init(const char* fileName, + const BPackageWriterParameters& parameters) { try { - return _Init(fileName, flags); + return _Init(fileName, parameters); } catch (status_t error) { return error; } catch (std::bad_alloc) { @@ -602,9 +603,10 @@ PackageWriterImpl::Finish() status_t -PackageWriterImpl::_Init(const char* fileName, uint32 flags) +PackageWriterImpl::_Init(const char* fileName, + const BPackageWriterParameters& parameters) { - status_t result = inherited::Init(fileName, flags); + status_t result = inherited::Init(fileName, parameters); if (result != B_OK) return result; diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp b/src/kits/package/hpkg/RepositoryWriterImpl.cpp index c8ceb33a6b..ec9cf99ccc 100644 --- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp +++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp @@ -250,7 +250,7 @@ RepositoryWriterImpl::Finish() status_t RepositoryWriterImpl::_Init(const char* fileName) { - return inherited::Init(fileName, 0); + return inherited::Init(fileName, BPackageWriterParameters()); } diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index 88d9d9be52..0e3e6aab6c 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -220,7 +220,7 @@ WriterImplBase::WriterImplBase(const char* fileType, BErrorOutput* errorOutput) fFileType(fileType), fErrorOutput(errorOutput), fFileName(NULL), - fFlags(0), + fParameters(), fFD(-1), fFinished(false), fDataWriter(NULL) @@ -236,21 +236,24 @@ WriterImplBase::~WriterImplBase() close(fFD); if (!fFinished && fFileName != NULL - && (fFlags & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) { + && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) { unlink(fFileName); } } status_t -WriterImplBase::Init(const char* fileName, uint32 flags) +WriterImplBase::Init(const char* fileName, + const BPackageWriterParameters& parameters) { + fParameters = parameters; + if (fPackageStringCache.Init() != B_OK) throw std::bad_alloc(); // open file (don't truncate in update mode) int openMode = O_RDWR; - if ((flags & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) + if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) openMode |= O_CREAT | O_TRUNC; fFD = open(fileName, openMode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -261,11 +264,10 @@ WriterImplBase::Init(const char* fileName, uint32 flags) } fFileName = fileName; - fFlags = flags; // create heap writer fHeapWriter = new PackageFileHeapWriter(fErrorOutput, FD(), - sizeof(hpkg_header)); + sizeof(hpkg_header), fParameters.CompressionLevel()); fHeapWriter->Init(); fDataWriter = fHeapWriter->DataWriter();