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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<uint64> fOffsets;
|
||||
int32 fCompressionLevel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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<Entry> 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);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <package/hpkg/DataOutput.h>
|
||||
#include <package/hpkg/DataWriters.h>
|
||||
#include <package/hpkg/PackageWriter.h>
|
||||
#include <package/hpkg/Strings.h>
|
||||
#include <package/hpkg/ZlibCompressor.h>
|
||||
|
||||
@@ -99,7 +100,8 @@ protected:
|
||||
typedef DoublyLinkedList<PackageAttribute> 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ static const char* kUsage =
|
||||
" add [ <options> ] <package> <entries>...\n"
|
||||
" Adds the specified entries <entries> to package file <package>.\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"
|
||||
" -f - Force adding, replacing already existing entries. "
|
||||
"Without\n"
|
||||
@@ -41,6 +44,9 @@ static const char* kUsage =
|
||||
" create [ <options> ] <package>\n"
|
||||
" Creates package file <package> 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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ RepositoryWriterImpl::Finish()
|
||||
status_t
|
||||
RepositoryWriterImpl::_Init(const char* fileName)
|
||||
{
|
||||
return inherited::Init(fileName, 0);
|
||||
return inherited::Init(fileName, BPackageWriterParameters());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user