Allow specifying the compression level for package creation

* Introduce BPackageWriterParameters which comprises all parameters
  for package creation, currently flags and compression level. Such an
  object can be passed to BPackageWriter::Init() and is passed on to
  PackageWriterImpl and WriterImplBase.
* PackageFileHeapWriter: Add compressionLevel property and pass the
  value on to ZlibCompressor.
* package add/create: Add options -0 ... -9 to specify the compression
  level to be used.
This commit is contained in:
Ingo Weinhold
2013-05-25 01:12:26 +02:00
parent 18b19ba49d
commit 796343ed73
13 changed files with 165 additions and 31 deletions
+7
View File
@@ -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 BHPKG
} // namespace BPackageKit } // namespace BPackageKit
+20 -1
View File
@@ -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 { class BPackageWriter {
public: public:
BPackageWriter( BPackageWriter(
BPackageWriterListener* listener); BPackageWriterListener* listener);
~BPackageWriter(); ~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); status_t SetInstallPath(const char* installPath);
void SetCheckLicenses(bool checkLicenses); void SetCheckLicenses(bool checkLicenses);
status_t AddEntry(const char* fileName, int fd = -1); status_t AddEntry(const char* fileName, int fd = -1);
@@ -35,7 +35,8 @@ class PackageFileHeapWriter : public PackageFileHeapAccessorBase,
private AbstractDataWriter { private AbstractDataWriter {
public: public:
PackageFileHeapWriter(BErrorOutput* errorOutput, PackageFileHeapWriter(BErrorOutput* errorOutput,
int fd, off_t heapOffset); int fd, off_t heapOffset,
int32 compressionLevel);
~PackageFileHeapWriter(); ~PackageFileHeapWriter();
void Init(); void Init();
@@ -86,6 +87,7 @@ private:
void* fCompressedDataBuffer; void* fCompressedDataBuffer;
size_t fPendingDataSize; size_t fPendingDataSize;
Array<uint64> fOffsets; Array<uint64> fOffsets;
int32 fCompressionLevel;
}; };
@@ -29,6 +29,7 @@ namespace BHPKG {
class BDataReader; class BDataReader;
class BErrorOutput; class BErrorOutput;
class BPackageWriterParameters;
namespace BPrivate { namespace BPrivate {
@@ -46,7 +47,8 @@ public:
BPackageWriterListener* listener); BPackageWriterListener* listener);
~PackageWriterImpl(); ~PackageWriterImpl();
status_t Init(const char* fileName, uint32 flags); status_t Init(const char* fileName,
const BPackageWriterParameters& parameters);
status_t SetInstallPath(const char* installPath); status_t SetInstallPath(const char* installPath);
void SetCheckLicenses(bool checkLicenses); void SetCheckLicenses(bool checkLicenses);
status_t AddEntry(const char* fileName, int fd = -1); status_t AddEntry(const char* fileName, int fd = -1);
@@ -62,7 +64,8 @@ private:
typedef DoublyLinkedList<Entry> EntryList; typedef DoublyLinkedList<Entry> EntryList;
private: private:
status_t _Init(const char* fileName, uint32 flags); status_t _Init(const char* fileName,
const BPackageWriterParameters& parameters);
status_t _Finish(); status_t _Finish();
status_t _RegisterEntry(const char* fileName, int fd); status_t _RegisterEntry(const char* fileName, int fd);
@@ -12,6 +12,7 @@
#include <package/hpkg/DataOutput.h> #include <package/hpkg/DataOutput.h>
#include <package/hpkg/DataWriters.h> #include <package/hpkg/DataWriters.h>
#include <package/hpkg/PackageWriter.h>
#include <package/hpkg/Strings.h> #include <package/hpkg/Strings.h>
#include <package/hpkg/ZlibCompressor.h> #include <package/hpkg/ZlibCompressor.h>
@@ -99,7 +100,8 @@ protected:
typedef DoublyLinkedList<PackageAttribute> PackageAttributeList; typedef DoublyLinkedList<PackageAttribute> PackageAttributeList;
protected: protected:
status_t Init(const char* fileName, uint32 flags); status_t Init(const char* fileName,
const BPackageWriterParameters& parameters);
void RegisterPackageInfo( void RegisterPackageInfo(
PackageAttributeList& attributeList, PackageAttributeList& attributeList,
@@ -168,7 +170,7 @@ private:
const char* fFileType; const char* fFileType;
BErrorOutput* fErrorOutput; BErrorOutput* fErrorOutput;
const char* fFileName; const char* fFileName;
uint32 fFlags; BPackageWriterParameters fParameters;
int fFD; int fFD;
bool fFinished; bool fFinished;
@@ -211,7 +213,7 @@ WriterImplBase::FD() const
inline uint32 inline uint32
WriterImplBase::Flags() const WriterImplBase::Flags() const
{ {
return fFlags; return fParameters.Flags();
} }
+22 -4
View File
@@ -35,6 +35,7 @@ command_add(int argc, const char* const* argv)
bool quiet = false; bool quiet = false;
bool verbose = false; bool verbose = false;
bool force = false; bool force = false;
int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
while (true) { while (true) {
static struct option sLongOptions[] = { static struct option sLongOptions[] = {
@@ -45,12 +46,25 @@ command_add(int argc, const char* const* argv)
}; };
opterr = 0; // don't print errors opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+C:fhi:qv", sLongOptions, int c = getopt_long(argc, (char**)argv, "+0123456789C:fhi:qv",
NULL); sLongOptions, NULL);
if (c == -1) if (c == -1)
break; break;
switch (c) { 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': case 'C':
changeToDirectory = optarg; changeToDirectory = optarg;
break; break;
@@ -96,10 +110,14 @@ command_add(int argc, const char* const* argv)
int entriesToAddCount = argc - optind; int entriesToAddCount = argc - optind;
// create package // 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); PackageWriterListener listener(verbose, quiet);
BPackageWriter packageWriter(&listener); BPackageWriter packageWriter(&listener);
status_t result = packageWriter.Init(packageFileName, status_t result = packageWriter.Init(packageFileName, &writerParameters);
B_HPKG_WRITER_UPDATE_PACKAGE | (force ? B_HPKG_WRITER_FORCE_ADD : 0));
if (result != B_OK) if (result != B_OK)
return 1; return 1;
+22 -4
View File
@@ -24,8 +24,9 @@
#include "PackageWritingUtils.h" #include "PackageWritingUtils.h"
using BPackageKit::BHPKG::BPackageWriterListener;
using BPackageKit::BHPKG::BPackageWriter; using BPackageKit::BHPKG::BPackageWriter;
using BPackageKit::BHPKG::BPackageWriterListener;
using BPackageKit::BHPKG::BPackageWriterParameters;
int int
@@ -37,6 +38,7 @@ command_create(int argc, const char* const* argv)
bool isBuildPackage = false; bool isBuildPackage = false;
bool quiet = false; bool quiet = false;
bool verbose = false; bool verbose = false;
int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST;
while (true) { while (true) {
static struct option sLongOptions[] = { static struct option sLongOptions[] = {
@@ -47,12 +49,25 @@ command_create(int argc, const char* const* argv)
}; };
opterr = 0; // don't print errors opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+bC:hi:I:qv", sLongOptions, int c = getopt_long(argc, (char**)argv, "+b0123456789C:hi:I:qv",
NULL); sLongOptions, NULL);
if (c == -1) if (c == -1)
break; break;
switch (c) { 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': case 'b':
isBuildPackage = true; isBuildPackage = true;
break; break;
@@ -101,9 +116,12 @@ command_create(int argc, const char* const* argv)
} }
// create package // create package
BPackageWriterParameters writerParameters;
writerParameters.SetCompressionLevel(compressionLevel);
PackageWriterListener listener(verbose, quiet); PackageWriterListener listener(verbose, quiet);
BPackageWriter packageWriter(&listener); BPackageWriter packageWriter(&listener);
status_t result = packageWriter.Init(packageFileName); status_t result = packageWriter.Init(packageFileName, &writerParameters);
if (result != B_OK) if (result != B_OK)
return 1; return 1;
+6
View File
@@ -26,6 +26,9 @@ static const char* kUsage =
" add [ <options> ] <package> <entries>...\n" " add [ <options> ] <package> <entries>...\n"
" Adds the specified entries <entries> to package file <package>.\n" " Adds the specified entries <entries> to package file <package>.\n"
"\n" "\n"
" -0 ... -9 - Use compression level 0 ... 9. 0 means no, 9 best "
"compression.\n"
" Defaults to 9.\n"
" -C <dir> - Change to directory <dir> before adding entries.\n" " -C <dir> - Change to directory <dir> before adding entries.\n"
" -f - Force adding, replacing already existing entries. " " -f - Force adding, replacing already existing entries. "
"Without\n" "Without\n"
@@ -41,6 +44,9 @@ static const char* kUsage =
" create [ <options> ] <package>\n" " create [ <options> ] <package>\n"
" Creates package file <package> from contents of current directory.\n" " Creates package file <package> from contents of current directory.\n"
"\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 " " -b - Create an empty build package. Only the .PackageInfo "
"will\n" "will\n"
" be added.\n" " be added.\n"
@@ -210,13 +210,14 @@ private:
PackageFileHeapWriter::PackageFileHeapWriter(BErrorOutput* errorOutput, int fd, PackageFileHeapWriter::PackageFileHeapWriter(BErrorOutput* errorOutput, int fd,
off_t heapOffset) off_t heapOffset, int32 compressionLevel)
: :
PackageFileHeapAccessorBase(errorOutput, fd, heapOffset), PackageFileHeapAccessorBase(errorOutput, fd, heapOffset),
fPendingDataBuffer(NULL), fPendingDataBuffer(NULL),
fCompressedDataBuffer(NULL), fCompressedDataBuffer(NULL),
fPendingDataSize(0), fPendingDataSize(0),
fOffsets() fOffsets(),
fCompressionLevel(compressionLevel)
{ {
} }
@@ -566,9 +567,12 @@ PackageFileHeapWriter::_WriteChunk(const void* data, size_t size,
status_t status_t
PackageFileHeapWriter::_WriteDataCompressed(const void* data, size_t size) PackageFileHeapWriter::_WriteDataCompressed(const void* data, size_t size)
{ {
if (fCompressionLevel == B_HPKG_COMPRESSION_LEVEL_NONE)
return B_BUFFER_OVERFLOW;
size_t compressedSize; size_t compressedSize;
status_t error = ZlibCompressor::CompressSingleBuffer(data, size, status_t error = ZlibCompressor::CompressSingleBuffer(data, size,
fCompressedDataBuffer, size, compressedSize); fCompressedDataBuffer, size, compressedSize, fCompressionLevel);
if (error != B_OK) if (error != B_OK)
return error; return error;
+53 -2
View File
@@ -16,6 +16,53 @@ namespace BPackageKit {
namespace BHPKG { 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) BPackageWriter::BPackageWriter(BPackageWriterListener* listener)
: :
fImpl(new (std::nothrow) PackageWriterImpl(listener)) fImpl(new (std::nothrow) PackageWriterImpl(listener))
@@ -30,12 +77,16 @@ BPackageWriter::~BPackageWriter()
status_t status_t
BPackageWriter::Init(const char* fileName, uint32 flags) BPackageWriter::Init(const char* fileName,
const BPackageWriterParameters* parameters)
{ {
if (fImpl == NULL) if (fImpl == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
return fImpl->Init(fileName, flags); BPackageWriterParameters defaultParameters;
return fImpl->Init(fileName,
parameters != NULL ? *parameters : defaultParameters);
} }
+6 -4
View File
@@ -463,10 +463,11 @@ PackageWriterImpl::~PackageWriterImpl()
status_t status_t
PackageWriterImpl::Init(const char* fileName, uint32 flags) PackageWriterImpl::Init(const char* fileName,
const BPackageWriterParameters& parameters)
{ {
try { try {
return _Init(fileName, flags); return _Init(fileName, parameters);
} catch (status_t error) { } catch (status_t error) {
return error; return error;
} catch (std::bad_alloc) { } catch (std::bad_alloc) {
@@ -602,9 +603,10 @@ PackageWriterImpl::Finish()
status_t 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) if (result != B_OK)
return result; return result;
@@ -250,7 +250,7 @@ RepositoryWriterImpl::Finish()
status_t status_t
RepositoryWriterImpl::_Init(const char* fileName) RepositoryWriterImpl::_Init(const char* fileName)
{ {
return inherited::Init(fileName, 0); return inherited::Init(fileName, BPackageWriterParameters());
} }
+8 -6
View File
@@ -220,7 +220,7 @@ WriterImplBase::WriterImplBase(const char* fileType, BErrorOutput* errorOutput)
fFileType(fileType), fFileType(fileType),
fErrorOutput(errorOutput), fErrorOutput(errorOutput),
fFileName(NULL), fFileName(NULL),
fFlags(0), fParameters(),
fFD(-1), fFD(-1),
fFinished(false), fFinished(false),
fDataWriter(NULL) fDataWriter(NULL)
@@ -236,21 +236,24 @@ WriterImplBase::~WriterImplBase()
close(fFD); close(fFD);
if (!fFinished && fFileName != NULL if (!fFinished && fFileName != NULL
&& (fFlags & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) { && (Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) == 0) {
unlink(fFileName); unlink(fFileName);
} }
} }
status_t status_t
WriterImplBase::Init(const char* fileName, uint32 flags) WriterImplBase::Init(const char* fileName,
const BPackageWriterParameters& parameters)
{ {
fParameters = parameters;
if (fPackageStringCache.Init() != B_OK) if (fPackageStringCache.Init() != B_OK)
throw std::bad_alloc(); throw std::bad_alloc();
// open file (don't truncate in update mode) // open file (don't truncate in update mode)
int openMode = O_RDWR; 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; openMode |= O_CREAT | O_TRUNC;
fFD = open(fileName, openMode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 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; fFileName = fileName;
fFlags = flags;
// create heap writer // create heap writer
fHeapWriter = new PackageFileHeapWriter(fErrorOutput, FD(), fHeapWriter = new PackageFileHeapWriter(fErrorOutput, FD(),
sizeof(hpkg_header)); sizeof(hpkg_header), fParameters.CompressionLevel());
fHeapWriter->Init(); fHeapWriter->Init();
fDataWriter = fHeapWriter->DataWriter(); fDataWriter = fHeapWriter->DataWriter();