|
@@ -24,6 +24,7 @@
|
|
#include "jfile.hpp"
|
|
#include "jfile.hpp"
|
|
#include "jencrypt.hpp"
|
|
#include "jencrypt.hpp"
|
|
#include "jflz.hpp"
|
|
#include "jflz.hpp"
|
|
|
|
+#include "jlz4.hpp"
|
|
|
|
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
#include <io.h>
|
|
#include <io.h>
|
|
@@ -1830,6 +1831,7 @@ typedef enum { ICFcreate, ICFread, ICFappend } ICFmode;
|
|
static const __int64 COMPRESSEDFILEFLAG = I64C(0xc0528ce99f10da55);
|
|
static const __int64 COMPRESSEDFILEFLAG = I64C(0xc0528ce99f10da55);
|
|
#define COMPRESSEDFILEBLOCKSIZE (0x10000)
|
|
#define COMPRESSEDFILEBLOCKSIZE (0x10000)
|
|
static const __int64 FASTCOMPRESSEDFILEFLAG = I64C(0xc1518de99f10da55);
|
|
static const __int64 FASTCOMPRESSEDFILEFLAG = I64C(0xc1518de99f10da55);
|
|
|
|
+static const __int64 LZ4COMPRESSEDFILEFLAG = I64C(0xc1200e0b71321c73);
|
|
|
|
|
|
#pragma pack(push,1)
|
|
#pragma pack(push,1)
|
|
|
|
|
|
@@ -1839,8 +1841,8 @@ struct CompressedFileTrailer
|
|
offset_t expandedSize;
|
|
offset_t expandedSize;
|
|
offset_t indexPos; // end of blocks
|
|
offset_t indexPos; // end of blocks
|
|
size32_t blockSize;
|
|
size32_t blockSize;
|
|
- size32_t recordSize; // 0 is lzw compressed
|
|
|
|
- __int64 compressedType;
|
|
|
|
|
|
+ size32_t recordSize; // 0 is lzw or fast (flz) or lz4 compressed
|
|
|
|
+ __int64 compressedType;
|
|
unsigned crc; // must be last
|
|
unsigned crc; // must be last
|
|
unsigned numBlocks() { return (unsigned)((indexPos+blockSize-1)/blockSize); }
|
|
unsigned numBlocks() { return (unsigned)((indexPos+blockSize-1)/blockSize); }
|
|
unsigned method()
|
|
unsigned method()
|
|
@@ -1851,6 +1853,8 @@ struct CompressedFileTrailer
|
|
return COMPRESS_METHOD_LZW;
|
|
return COMPRESS_METHOD_LZW;
|
|
if (compressedType==FASTCOMPRESSEDFILEFLAG)
|
|
if (compressedType==FASTCOMPRESSEDFILEFLAG)
|
|
return COMPRESS_METHOD_FASTLZ;
|
|
return COMPRESS_METHOD_FASTLZ;
|
|
|
|
+ if (compressedType==LZ4COMPRESSEDFILEFLAG)
|
|
|
|
+ return COMPRESS_METHOD_LZ4;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1924,6 +1928,7 @@ class CCompressedFile : public CInterface, implements ICompressedFileIO
|
|
bool writeException;
|
|
bool writeException;
|
|
Owned<ICompressor> compressor;
|
|
Owned<ICompressor> compressor;
|
|
Owned<IExpander> expander;
|
|
Owned<IExpander> expander;
|
|
|
|
+ __int64 compType;
|
|
|
|
|
|
unsigned indexNum() { return indexbuf.length()/sizeof(offset_t); }
|
|
unsigned indexNum() { return indexbuf.length()/sizeof(offset_t); }
|
|
|
|
|
|
@@ -2041,7 +2046,7 @@ class CCompressedFile : public CInterface, implements ICompressedFileIO
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else { // lzw
|
|
|
|
|
|
+ else { // lzw or fastlz (flz) or lz4
|
|
assertex(expander.get());
|
|
assertex(expander.get());
|
|
size32_t exp = expander->init(compbuf);
|
|
size32_t exp = expander->init(compbuf);
|
|
if (exp!=expsize) {
|
|
if (exp!=expsize) {
|
|
@@ -2101,14 +2106,14 @@ class CCompressedFile : public CInterface, implements ICompressedFileIO
|
|
src += len;
|
|
src += len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else // lzw or fastlz (flz) or lz4
|
|
src += compressor->write(src, len);
|
|
src += compressor->write(src, len);
|
|
return (size32_t)(src-(const byte *)expbuf);
|
|
return (size32_t)(src-(const byte *)expbuf);
|
|
}
|
|
}
|
|
public:
|
|
public:
|
|
IMPLEMENT_IINTERFACE;
|
|
IMPLEMENT_IINTERFACE;
|
|
|
|
|
|
- CCompressedFile(IFileIO *_fileio,IMemoryMappedFile *_mmfile,CompressedFileTrailer &_trailer,ICFmode _mode, bool _setcrc,ICompressor *_compressor,IExpander *_expander, bool fast)
|
|
|
|
|
|
+ CCompressedFile(IFileIO *_fileio,IMemoryMappedFile *_mmfile,CompressedFileTrailer &_trailer,ICFmode _mode, bool _setcrc,ICompressor *_compressor,IExpander *_expander, __int64 _compType)
|
|
: fileio(_fileio), mmfile(_mmfile)
|
|
: fileio(_fileio), mmfile(_mmfile)
|
|
{
|
|
{
|
|
compressor.set(_compressor);
|
|
compressor.set(_compressor);
|
|
@@ -2119,6 +2124,7 @@ public:
|
|
mode = _mode;
|
|
mode = _mode;
|
|
curblockpos = 0;
|
|
curblockpos = 0;
|
|
curblocknum = (unsigned)-1; // relies on wrap
|
|
curblocknum = (unsigned)-1; // relies on wrap
|
|
|
|
+ compType = _compType;
|
|
if (mode!=ICFread) {
|
|
if (mode!=ICFread) {
|
|
if (!_fileio&&_mmfile)
|
|
if (!_fileio&&_mmfile)
|
|
throw MakeStringException(-1,"Compressed Write not supported on memory mapped files");
|
|
throw MakeStringException(-1,"Compressed Write not supported on memory mapped files");
|
|
@@ -2134,9 +2140,11 @@ public:
|
|
if (trailer.recordSize==0) {
|
|
if (trailer.recordSize==0) {
|
|
if (!compressor)
|
|
if (!compressor)
|
|
{
|
|
{
|
|
- if (fast)
|
|
|
|
|
|
+ if (compType == COMPRESS_METHOD_FASTLZ)
|
|
compressor.setown(createFastLZCompressor());
|
|
compressor.setown(createFastLZCompressor());
|
|
- else
|
|
|
|
|
|
+ else if (compType == COMPRESS_METHOD_LZ4)
|
|
|
|
+ compressor.setown(createLZ4Compressor());
|
|
|
|
+ else // COMPRESS_METHOD_LZW
|
|
compressor.setown(createLZWCompressor(true));
|
|
compressor.setown(createLZWCompressor(true));
|
|
}
|
|
}
|
|
compressor->open(compblkptr, trailer.blockSize);
|
|
compressor->open(compblkptr, trailer.blockSize);
|
|
@@ -2162,9 +2170,11 @@ public:
|
|
}
|
|
}
|
|
if (trailer.recordSize==0) {
|
|
if (trailer.recordSize==0) {
|
|
if (!expander) {
|
|
if (!expander) {
|
|
- if (fast)
|
|
|
|
|
|
+ if (compType == COMPRESS_METHOD_FASTLZ)
|
|
expander.setown(createFastLZExpander());
|
|
expander.setown(createFastLZExpander());
|
|
- else
|
|
|
|
|
|
+ else if (compType == COMPRESS_METHOD_LZ4)
|
|
|
|
+ expander.setown(createLZ4Expander());
|
|
|
|
+ else // COMPRESS_METHOD_LZW
|
|
expander.setown(createLZWExpander(true));
|
|
expander.setown(createLZWExpander(true));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2316,11 +2326,19 @@ ICompressedFileIO *createCompressedFileReader(IFileIO *fileio,IExpander *expande
|
|
CompressedFileTrailer trailer;
|
|
CompressedFileTrailer trailer;
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
wintrailer.translate(trailer);
|
|
wintrailer.translate(trailer);
|
|
- if ((trailer.compressedType==COMPRESSEDFILEFLAG)||(trailer.compressedType==FASTCOMPRESSEDFILEFLAG)) {
|
|
|
|
|
|
+ if ( (trailer.compressedType==COMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==FASTCOMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==LZ4COMPRESSEDFILEFLAG) )
|
|
|
|
+ {
|
|
if (expander&&(trailer.recordSize!=0)) {
|
|
if (expander&&(trailer.recordSize!=0)) {
|
|
throw MakeStringException(-1, "Compressed file format error(%d), Encrypted?",trailer.recordSize);
|
|
throw MakeStringException(-1, "Compressed file format error(%d), Encrypted?",trailer.recordSize);
|
|
}
|
|
}
|
|
- CCompressedFile *cfile = new CCompressedFile(fileio,NULL,trailer,ICFread,false,NULL,expander,(trailer.compressedType==FASTCOMPRESSEDFILEFLAG));
|
|
|
|
|
|
+ __int64 compType1 = COMPRESS_METHOD_LZW;
|
|
|
|
+ if (trailer.compressedType == FASTCOMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_FASTLZ;
|
|
|
|
+ else if (trailer.compressedType == LZ4COMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_LZ4;
|
|
|
|
+ CCompressedFile *cfile = new CCompressedFile(fileio,NULL,trailer,ICFread,false,NULL,expander,compType1);
|
|
return cfile;
|
|
return cfile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2342,11 +2360,19 @@ ICompressedFileIO *createCompressedFileReader(IFile *file,IExpander *expander, b
|
|
CompressedFileTrailer trailer;
|
|
CompressedFileTrailer trailer;
|
|
memcpy(&wintrailer,mmfile->base()+fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer));
|
|
memcpy(&wintrailer,mmfile->base()+fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer));
|
|
wintrailer.translate(trailer);
|
|
wintrailer.translate(trailer);
|
|
- if ((trailer.compressedType==COMPRESSEDFILEFLAG)||(trailer.compressedType==FASTCOMPRESSEDFILEFLAG)) {
|
|
|
|
|
|
+ if ( (trailer.compressedType==COMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==FASTCOMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==LZ4COMPRESSEDFILEFLAG) )
|
|
|
|
+ {
|
|
if (expander&&(trailer.recordSize!=0)) {
|
|
if (expander&&(trailer.recordSize!=0)) {
|
|
throw MakeStringException(-1, "Compressed file format error(%d), Encrypted?",trailer.recordSize);
|
|
throw MakeStringException(-1, "Compressed file format error(%d), Encrypted?",trailer.recordSize);
|
|
}
|
|
}
|
|
- CCompressedFile *cfile = new CCompressedFile(NULL,mmfile,trailer,ICFread,false,NULL,expander,(trailer.compressedType==FASTCOMPRESSEDFILEFLAG));
|
|
|
|
|
|
+ __int64 compType1 = COMPRESS_METHOD_LZW;
|
|
|
|
+ if (trailer.compressedType == FASTCOMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_FASTLZ;
|
|
|
|
+ else if (trailer.compressedType == LZ4COMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_LZ4;
|
|
|
|
+ CCompressedFile *cfile = new CCompressedFile(NULL,mmfile,trailer,ICFread,false,NULL,expander,compType1);
|
|
return cfile;
|
|
return cfile;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2362,7 +2388,7 @@ ICompressedFileIO *createCompressedFileReader(IFile *file,IExpander *expander, b
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-ICompressedFileIO *createCompressedFileWriter(IFileIO *fileio,size32_t recordsize,bool _setcrc,ICompressor *compressor,bool fast)
|
|
|
|
|
|
+ICompressedFileIO *createCompressedFileWriter(IFileIO *fileio,size32_t recordsize,bool _setcrc,ICompressor *compressor, __int64 _compType)
|
|
{
|
|
{
|
|
CompressedFileTrailer trailer;
|
|
CompressedFileTrailer trailer;
|
|
offset_t fsize = fileio->size();
|
|
offset_t fsize = fileio->size();
|
|
@@ -2373,7 +2399,20 @@ ICompressedFileIO *createCompressedFileWriter(IFileIO *fileio,size32_t recordsiz
|
|
CompressedFileTrailer trailer;
|
|
CompressedFileTrailer trailer;
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
wintrailer.translate(trailer);
|
|
wintrailer.translate(trailer);
|
|
- if ((trailer.compressedType==COMPRESSEDFILEFLAG)||(trailer.compressedType==FASTCOMPRESSEDFILEFLAG)) {
|
|
|
|
|
|
+ if ( (trailer.compressedType==COMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==FASTCOMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==LZ4COMPRESSEDFILEFLAG) )
|
|
|
|
+ {
|
|
|
|
+ // mck - check trailer.compressedType against _compType ?
|
|
|
|
+ __int64 compType1 = 0;
|
|
|
|
+ if (trailer.compressedType == COMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_LZW;
|
|
|
|
+ else if (trailer.compressedType == FASTCOMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_FASTLZ;
|
|
|
|
+ else if (trailer.compressedType == LZ4COMPRESSEDFILEFLAG)
|
|
|
|
+ compType1 = COMPRESS_METHOD_LZ4;
|
|
|
|
+ if (_compType != compType1)
|
|
|
|
+ throw MakeStringException(-1,"Appending to file with different compression method");
|
|
if ((recordsize==trailer.recordSize)||!trailer.recordSize)
|
|
if ((recordsize==trailer.recordSize)||!trailer.recordSize)
|
|
break;
|
|
break;
|
|
throw MakeStringException(-1,"Appending to file with different record size (%d,%d)",recordsize,trailer.recordSize);
|
|
throw MakeStringException(-1,"Appending to file with different record size (%d,%d)",recordsize,trailer.recordSize);
|
|
@@ -2386,24 +2425,37 @@ ICompressedFileIO *createCompressedFileWriter(IFileIO *fileio,size32_t recordsiz
|
|
else {
|
|
else {
|
|
memset(&trailer,0,sizeof(trailer));
|
|
memset(&trailer,0,sizeof(trailer));
|
|
trailer.crc = ~0U;
|
|
trailer.crc = ~0U;
|
|
- trailer.compressedType = fast?FASTCOMPRESSEDFILEFLAG:COMPRESSEDFILEFLAG;
|
|
|
|
- trailer.blockSize = COMPRESSEDFILEBLOCKSIZE;
|
|
|
|
|
|
+ if (_compType == COMPRESS_METHOD_FASTLZ)
|
|
|
|
+ {
|
|
|
|
+ trailer.compressedType = FASTCOMPRESSEDFILEFLAG;
|
|
|
|
+ trailer.blockSize = FASTCOMPRESSEDFILEBLOCKSIZE;
|
|
|
|
+ }
|
|
|
|
+ else if (_compType == COMPRESS_METHOD_LZ4)
|
|
|
|
+ {
|
|
|
|
+ trailer.compressedType = LZ4COMPRESSEDFILEFLAG;
|
|
|
|
+ trailer.blockSize = LZ4COMPRESSEDFILEBLOCKSIZE;
|
|
|
|
+ }
|
|
|
|
+ else // lzw
|
|
|
|
+ {
|
|
|
|
+ trailer.compressedType = COMPRESSEDFILEFLAG;
|
|
|
|
+ trailer.blockSize = COMPRESSEDFILEBLOCKSIZE;
|
|
|
|
+ }
|
|
trailer.recordSize = recordsize;
|
|
trailer.recordSize = recordsize;
|
|
}
|
|
}
|
|
if (compressor)
|
|
if (compressor)
|
|
trailer.recordSize = 0; // force not row compressed if compressor specified
|
|
trailer.recordSize = 0; // force not row compressed if compressor specified
|
|
- CCompressedFile *cfile = new CCompressedFile(fileio,NULL,trailer,fsize?ICFappend:ICFcreate,_setcrc,compressor,NULL,fast);
|
|
|
|
|
|
+ CCompressedFile *cfile = new CCompressedFile(fileio,NULL,trailer,fsize?ICFappend:ICFcreate,_setcrc,compressor,NULL,_compType);
|
|
return cfile;
|
|
return cfile;
|
|
}
|
|
}
|
|
|
|
|
|
-ICompressedFileIO *createCompressedFileWriter(IFile *file,size32_t recordsize,bool append,bool _setcrc,ICompressor *compressor,bool fast, IFEflags extraFlags)
|
|
|
|
|
|
+ICompressedFileIO *createCompressedFileWriter(IFile *file,size32_t recordsize,bool append,bool _setcrc,ICompressor *compressor, __int64 _compType, IFEflags extraFlags)
|
|
{
|
|
{
|
|
if (file) {
|
|
if (file) {
|
|
if (append&&!file->exists())
|
|
if (append&&!file->exists())
|
|
append = false;
|
|
append = false;
|
|
Owned<IFileIO> fileio = file->open(append?IFOreadwrite:IFOcreate, extraFlags);
|
|
Owned<IFileIO> fileio = file->open(append?IFOreadwrite:IFOcreate, extraFlags);
|
|
if (fileio)
|
|
if (fileio)
|
|
- return createCompressedFileWriter(fileio,recordsize,_setcrc,compressor,fast);
|
|
|
|
|
|
+ return createCompressedFileWriter(fileio,recordsize,_setcrc,compressor,_compType);
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -2603,7 +2655,9 @@ IPropertyTree *getBlockedFileDetails(IFile *file)
|
|
CompressedFileTrailer trailer;
|
|
CompressedFileTrailer trailer;
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
if (fileio->read(fsize-sizeof(WinCompressedFileTrailer),sizeof(WinCompressedFileTrailer),&wintrailer)==sizeof(WinCompressedFileTrailer)) {
|
|
wintrailer.translate(trailer);
|
|
wintrailer.translate(trailer);
|
|
- if ((trailer.compressedType==COMPRESSEDFILEFLAG)||(trailer.compressedType==FASTCOMPRESSEDFILEFLAG)) {
|
|
|
|
|
|
+ if ((trailer.compressedType==COMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==FASTCOMPRESSEDFILEFLAG) ||
|
|
|
|
+ (trailer.compressedType==LZ4COMPRESSEDFILEFLAG)) {
|
|
trailer.setDetails(*tree);
|
|
trailer.setDetails(*tree);
|
|
unsigned nb = trailer.numBlocks();
|
|
unsigned nb = trailer.numBlocks();
|
|
MemoryAttr indexbuf;
|
|
MemoryAttr indexbuf;
|
|
@@ -2681,6 +2735,13 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
|
|
virtual ICompressor *getCompressor(const char *options) { return createFastLZCompressor(); }
|
|
virtual ICompressor *getCompressor(const char *options) { return createFastLZCompressor(); }
|
|
virtual IExpander *getExpander(const char *options) { return createFastLZExpander(); }
|
|
virtual IExpander *getExpander(const char *options) { return createFastLZExpander(); }
|
|
};
|
|
};
|
|
|
|
+ class CLZ4CompressHandler : public CCompressHandlerBase
|
|
|
|
+ {
|
|
|
|
+ public:
|
|
|
|
+ CLZ4CompressHandler() : CCompressHandlerBase("LZ4") { }
|
|
|
|
+ virtual ICompressor *getCompressor(const char *options) { return createLZ4Compressor(); }
|
|
|
|
+ virtual IExpander *getExpander(const char *options) { return createLZ4Expander(); }
|
|
|
|
+ };
|
|
class CAESCompressHandler : public CCompressHandlerBase
|
|
class CAESCompressHandler : public CCompressHandlerBase
|
|
{
|
|
{
|
|
public:
|
|
public:
|
|
@@ -2710,12 +2771,14 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
|
|
virtual ICompressor *getCompressor(const char *options) { return createLZWCompressor(true); }
|
|
virtual ICompressor *getCompressor(const char *options) { return createLZWCompressor(true); }
|
|
virtual IExpander *getExpander(const char *options) { return createLZWExpander(true); }
|
|
virtual IExpander *getExpander(const char *options) { return createLZWExpander(true); }
|
|
};
|
|
};
|
|
- ICompressHandler *flzCompressor = new CFLZCompressHandler();
|
|
|
|
- addCompressorHandler(flzCompressor);
|
|
|
|
|
|
+ addCompressorHandler(new CFLZCompressHandler());
|
|
addCompressorHandler(new CAESCompressHandler());
|
|
addCompressorHandler(new CAESCompressHandler());
|
|
addCompressorHandler(new CDiffCompressHandler());
|
|
addCompressorHandler(new CDiffCompressHandler());
|
|
addCompressorHandler(new CLZWCompressHandler());
|
|
addCompressorHandler(new CLZWCompressHandler());
|
|
- defaultCompressor.set(flzCompressor);
|
|
|
|
|
|
+ addCompressorHandler(new CDENCompressHandler());
|
|
|
|
+ ICompressHandler *lz4Compressor = new CLZ4CompressHandler();
|
|
|
|
+ addCompressorHandler(lz4Compressor);
|
|
|
|
+ defaultCompressor.set(lz4Compressor);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|