Merge branch 'dev' into adding_read_files_from_file_feature
This commit is contained in:
+6
-3
@@ -173,10 +173,13 @@ Benchmark arguments :
|
||||
```
|
||||
|
||||
#### Restricted usage of Environment Variables
|
||||
Using environment variables to set compression/decompression parameters has security implications. Therefore,
|
||||
we intentionally restrict its usage. Currently, only `ZSTD_CLEVEL` is supported for setting compression level.
|
||||
Using environment variables to set parameters has security implications.
|
||||
Therefore, this avenue is intentionally restricted.
|
||||
Only `ZSTD_CLEVEL` is supported currently, for setting compression level.
|
||||
`ZSTD_CLEVEL` can be used to set the level between 1 and 19 (the "normal" range).
|
||||
If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a warning message.
|
||||
Note that command line options will override corresponding environment variable settings.
|
||||
`ZSTD_CLEVEL` just replaces the default compression level (`3`).
|
||||
It can be overridden by corresponding command line arguments.
|
||||
|
||||
#### Long distance matching mode
|
||||
The long distance matching mode, enabled with `--long`, is designed to improve
|
||||
|
||||
+19
-20
@@ -88,7 +88,7 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
|
||||
#endif
|
||||
#define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
|
||||
|
||||
#define EXM_THROW_INT(errorNum, ...) { \
|
||||
#define RETURN_ERROR_INT(errorNum, ...) { \
|
||||
DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \
|
||||
DISPLAYLEVEL(1, "Error %i : ", errorNum); \
|
||||
DISPLAYLEVEL(1, __VA_ARGS__); \
|
||||
@@ -401,9 +401,9 @@ BMK_benchMemAdvancedNoAlloc(
|
||||
BMK_initCCtxArgs cctxprep;
|
||||
BMK_initDCtxArgs dctxprep;
|
||||
|
||||
cbp.benchFn = local_defaultCompress;
|
||||
cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */
|
||||
cbp.benchPayload = cctx;
|
||||
cbp.initFn = local_initCCtx;
|
||||
cbp.initFn = local_initCCtx; /* BMK_initCCtx */
|
||||
cbp.initPayload = &cctxprep;
|
||||
cbp.errorFn = ZSTD_isError;
|
||||
cbp.blockCount = nbBlocks;
|
||||
@@ -534,8 +534,8 @@ BMK_benchMemAdvancedNoAlloc(
|
||||
if (u==srcSize-1) { /* should never happen */
|
||||
DISPLAY("no difference detected\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* for (u=0; u<srcSize; u++) */
|
||||
} /* if ((adv->mode == BMK_both) && (crcOrig!=crcCheck)) */
|
||||
} /* CRC Checking */
|
||||
|
||||
if (displayLevel == 1) { /* hidden display mode -q, used by python speed benchmark */
|
||||
@@ -754,8 +754,7 @@ static int BMK_loadFiles(void* buffer, size_t bufferSize,
|
||||
size_t pos = 0, totalSize = 0;
|
||||
unsigned n;
|
||||
for (n=0; n<nbFiles; n++) {
|
||||
FILE* f;
|
||||
U64 fileSize = UTIL_getFileSize(fileNamesTable[n]);
|
||||
U64 fileSize = UTIL_getFileSize(fileNamesTable[n]); /* last file may be shortened */
|
||||
if (UTIL_isDirectory(fileNamesTable[n])) {
|
||||
DISPLAYLEVEL(2, "Ignoring %s directory... \n", fileNamesTable[n]);
|
||||
fileSizes[n] = 0;
|
||||
@@ -766,20 +765,20 @@ static int BMK_loadFiles(void* buffer, size_t bufferSize,
|
||||
fileSizes[n] = 0;
|
||||
continue;
|
||||
}
|
||||
f = fopen(fileNamesTable[n], "rb");
|
||||
if (f==NULL) EXM_THROW_INT(10, "impossible to open file %s", fileNamesTable[n]);
|
||||
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
|
||||
if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */
|
||||
{ size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f);
|
||||
if (readSize != (size_t)fileSize) EXM_THROW_INT(11, "could not read %s", fileNamesTable[n]);
|
||||
pos += readSize;
|
||||
}
|
||||
fileSizes[n] = (size_t)fileSize;
|
||||
totalSize += (size_t)fileSize;
|
||||
fclose(f);
|
||||
}
|
||||
{ FILE* const f = fopen(fileNamesTable[n], "rb");
|
||||
if (f==NULL) RETURN_ERROR_INT(10, "impossible to open file %s", fileNamesTable[n]);
|
||||
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
|
||||
if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */
|
||||
{ size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f);
|
||||
if (readSize != (size_t)fileSize) RETURN_ERROR_INT(11, "could not read %s", fileNamesTable[n]);
|
||||
pos += readSize;
|
||||
}
|
||||
fileSizes[n] = (size_t)fileSize;
|
||||
totalSize += (size_t)fileSize;
|
||||
fclose(f);
|
||||
} }
|
||||
|
||||
if (totalSize == 0) EXM_THROW_INT(12, "no data to bench");
|
||||
if (totalSize == 0) RETURN_ERROR_INT(12, "no data to bench");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,6 @@ BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* BENCH_ZSTD_H_3242387 */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
|
||||
+253
-111
@@ -284,9 +284,10 @@ void FIO_addAbortHandler()
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Parameters: Typedefs
|
||||
* Parameters: FIO_prefs_t
|
||||
***************************************/
|
||||
|
||||
/* typedef'd to FIO_prefs_t within fileio.h */
|
||||
struct FIO_prefs_s {
|
||||
|
||||
/* Algorithm preferences */
|
||||
@@ -308,6 +309,7 @@ struct FIO_prefs_s {
|
||||
size_t streamSrcSize;
|
||||
size_t targetCBlockSize;
|
||||
int srcSizeHint;
|
||||
int testMode;
|
||||
ZSTD_literalCompressionMode_e literalCompressionMode;
|
||||
|
||||
/* IO preferences */
|
||||
@@ -355,6 +357,7 @@ FIO_prefs_t* FIO_createPreferences(void)
|
||||
ret->streamSrcSize = 0;
|
||||
ret->targetCBlockSize = 0;
|
||||
ret->srcSizeHint = 0;
|
||||
ret->testMode = 0;
|
||||
ret->literalCompressionMode = ZSTD_lcm_auto;
|
||||
return ret;
|
||||
}
|
||||
@@ -435,6 +438,10 @@ void FIO_setSrcSizeHint(FIO_prefs_t* const prefs, size_t srcSizeHint) {
|
||||
prefs->srcSizeHint = (int)MIN((size_t)INT_MAX, srcSizeHint);
|
||||
}
|
||||
|
||||
void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode) {
|
||||
prefs->testMode = (testMode!=0);
|
||||
}
|
||||
|
||||
void FIO_setLiteralCompressionMode(
|
||||
FIO_prefs_t* const prefs,
|
||||
ZSTD_literalCompressionMode_e mode) {
|
||||
@@ -529,8 +536,12 @@ static FILE* FIO_openSrcFile(const char* srcFileName)
|
||||
/** FIO_openDstFile() :
|
||||
* condition : `dstFileName` must be non-NULL.
|
||||
* @result : FILE* to `dstFileName`, or NULL if it fails */
|
||||
static FILE* FIO_openDstFile(FIO_prefs_t* const prefs, const char* srcFileName, const char* dstFileName)
|
||||
static FILE*
|
||||
FIO_openDstFile(FIO_prefs_t* const prefs,
|
||||
const char* srcFileName, const char* dstFileName)
|
||||
{
|
||||
if (prefs->testMode) return NULL; /* do not open file in test mode */
|
||||
|
||||
assert(dstFileName != NULL);
|
||||
if (!strcmp (dstFileName, stdoutmark)) {
|
||||
DISPLAYLEVEL(4,"Using stdout for output \n");
|
||||
@@ -555,10 +566,14 @@ static FILE* FIO_openDstFile(FIO_prefs_t* const prefs, const char* srcFileName,
|
||||
if (UTIL_isRegularFile(dstFileName)) {
|
||||
/* Check if destination file already exists */
|
||||
FILE* const fCheck = fopen( dstFileName, "rb" );
|
||||
#if !defined(_WIN32)
|
||||
/* this test does not work on Windows :
|
||||
* `NUL` and `nul` are detected as regular files */
|
||||
if (!strcmp(dstFileName, nulmark)) {
|
||||
EXM_THROW(40, "%s is unexpectedly categorized as a regular file",
|
||||
dstFileName);
|
||||
}
|
||||
#endif
|
||||
if (fCheck != NULL) { /* dst file exists, authorization prompt */
|
||||
fclose(fCheck);
|
||||
if (!prefs->overwrite) {
|
||||
@@ -585,7 +600,7 @@ static FILE* FIO_openDstFile(FIO_prefs_t* const prefs, const char* srcFileName,
|
||||
{ FILE* const f = fopen( dstFileName, "wb" );
|
||||
if (f == NULL) {
|
||||
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
|
||||
} else {
|
||||
} else if(srcFileName != NULL && strcmp (srcFileName, stdinmark)) {
|
||||
chmod(dstFileName, 00600);
|
||||
}
|
||||
return f;
|
||||
@@ -628,6 +643,96 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName)
|
||||
return (size_t)fileSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* FIO_checkFilenameCollisions() :
|
||||
* Checks for and warns if there are any files that would have the same output path
|
||||
*/
|
||||
int FIO_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles) {
|
||||
const char **filenameTableSorted, *c, *prevElem, *filename;
|
||||
unsigned u;
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
|
||||
c = "\\";
|
||||
#else
|
||||
c = "/";
|
||||
#endif
|
||||
|
||||
filenameTableSorted = (const char**) malloc(sizeof(char*) * nbFiles);
|
||||
if (!filenameTableSorted) {
|
||||
DISPLAY("Unable to malloc new str array, not checking for name collisions\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (u = 0; u < nbFiles; ++u) {
|
||||
filename = strrchr(filenameTable[u], c[0]);
|
||||
if (filename == NULL) {
|
||||
filenameTableSorted[u] = filenameTable[u];
|
||||
} else {
|
||||
filenameTableSorted[u] = filename+1;
|
||||
}
|
||||
}
|
||||
|
||||
qsort((void*)filenameTableSorted, nbFiles, sizeof(char*), UTIL_compareStr);
|
||||
prevElem = filenameTableSorted[0];
|
||||
for (u = 1; u < nbFiles; ++u) {
|
||||
if (strcmp(prevElem, filenameTableSorted[u]) == 0) {
|
||||
DISPLAY("WARNING: Two files have same filename: %s\n", prevElem);
|
||||
}
|
||||
prevElem = filenameTableSorted[u];
|
||||
}
|
||||
|
||||
free((void*)filenameTableSorted);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char*
|
||||
extractFilename(const char* path, char separator)
|
||||
{
|
||||
const char* search = strrchr(path, separator);
|
||||
if (search == NULL) return path;
|
||||
return search+1;
|
||||
}
|
||||
|
||||
/* FIO_createFilename_fromOutDir() :
|
||||
* Takes a source file name and specified output directory, and
|
||||
* allocates memory for and returns a pointer to final path.
|
||||
* This function never returns an error (it may abort() in case of pb)
|
||||
*/
|
||||
static char*
|
||||
FIO_createFilename_fromOutDir(const char* path, const char* outDirName, const size_t suffixLen)
|
||||
{
|
||||
const char* filenameStart;
|
||||
char separator;
|
||||
char* result;
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
|
||||
separator = '\\';
|
||||
#else
|
||||
separator = '/';
|
||||
#endif
|
||||
|
||||
filenameStart = extractFilename(path, separator);
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
|
||||
filenameStart = extractFilename(filenameStart, '/'); /* sometimes, '/' separator is also used on Windows (mingw+msys2) */
|
||||
#endif
|
||||
|
||||
result = (char*) calloc(1, strlen(outDirName) + 1 + strlen(filenameStart) + suffixLen + 1);
|
||||
if (!result) {
|
||||
EXM_THROW(30, "zstd: FIO_createFilename_fromOutDir: %s", strerror(errno));
|
||||
}
|
||||
|
||||
memcpy(result, outDirName, strlen(outDirName));
|
||||
if (outDirName[strlen(outDirName)-1] == separator) {
|
||||
memcpy(result + strlen(outDirName), filenameStart, strlen(filenameStart));
|
||||
} else {
|
||||
memcpy(result + strlen(outDirName), &separator, 1);
|
||||
memcpy(result + strlen(outDirName) + 1, filenameStart, strlen(filenameStart));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef ZSTD_NOCOMPRESS
|
||||
|
||||
/* **********************************************************************
|
||||
@@ -729,13 +834,12 @@ static void FIO_freeCResources(cRess_t ress)
|
||||
|
||||
#ifdef ZSTD_GZCOMPRESS
|
||||
static unsigned long long
|
||||
FIO_compressGzFrame(cRess_t* ress,
|
||||
FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but not changed */
|
||||
const char* srcFileName, U64 const srcFileSize,
|
||||
int compressionLevel, U64* readsize)
|
||||
{
|
||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||
z_stream strm;
|
||||
int ret;
|
||||
|
||||
if (compressionLevel > Z_BEST_COMPRESSION)
|
||||
compressionLevel = Z_BEST_COMPRESSION;
|
||||
@@ -744,11 +848,12 @@ FIO_compressGzFrame(cRess_t* ress,
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
ret = deflateInit2(&strm, compressionLevel, Z_DEFLATED,
|
||||
{ int const ret = deflateInit2(&strm, compressionLevel, Z_DEFLATED,
|
||||
15 /* maxWindowLogSize */ + 16 /* gzip only */,
|
||||
8, Z_DEFAULT_STRATEGY); /* see http://www.zlib.net/manual.html */
|
||||
if (ret != Z_OK)
|
||||
EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
|
||||
if (ret != Z_OK) {
|
||||
EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
|
||||
} }
|
||||
|
||||
strm.next_in = 0;
|
||||
strm.avail_in = 0;
|
||||
@@ -756,6 +861,7 @@ FIO_compressGzFrame(cRess_t* ress,
|
||||
strm.avail_out = (uInt)ress->dstBufferSize;
|
||||
|
||||
while (1) {
|
||||
int ret;
|
||||
if (strm.avail_in == 0) {
|
||||
size_t const inSize = fread(ress->srcBuffer, 1, ress->srcBufferSize, ress->srcFile);
|
||||
if (inSize == 0) break;
|
||||
@@ -766,32 +872,31 @@ FIO_compressGzFrame(cRess_t* ress,
|
||||
ret = deflate(&strm, Z_NO_FLUSH);
|
||||
if (ret != Z_OK)
|
||||
EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, ret);
|
||||
{ size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
|
||||
if (decompBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
|
||||
EXM_THROW(73, "Write error : cannot write to output file");
|
||||
outFileSize += decompBytes;
|
||||
{ size_t const cSize = ress->dstBufferSize - strm.avail_out;
|
||||
if (cSize) {
|
||||
if (fwrite(ress->dstBuffer, 1, cSize, ress->dstFile) != cSize)
|
||||
EXM_THROW(73, "Write error : cannot write to output file : %s ", strerror(errno));
|
||||
outFileSize += cSize;
|
||||
strm.next_out = (Bytef*)ress->dstBuffer;
|
||||
strm.avail_out = (uInt)ress->dstBufferSize;
|
||||
}
|
||||
}
|
||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN)
|
||||
DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%",
|
||||
} }
|
||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) {
|
||||
DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%% ",
|
||||
(unsigned)(inFileSize>>20),
|
||||
(double)outFileSize/inFileSize*100)
|
||||
else
|
||||
DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%",
|
||||
} else {
|
||||
DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%% ",
|
||||
(unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20),
|
||||
(double)outFileSize/inFileSize*100);
|
||||
}
|
||||
} }
|
||||
|
||||
while (1) {
|
||||
ret = deflate(&strm, Z_FINISH);
|
||||
{ size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
|
||||
if (decompBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
|
||||
EXM_THROW(75, "Write error : %s", strerror(errno));
|
||||
outFileSize += decompBytes;
|
||||
int const ret = deflate(&strm, Z_FINISH);
|
||||
{ size_t const cSize = ress->dstBufferSize - strm.avail_out;
|
||||
if (cSize) {
|
||||
if (fwrite(ress->dstBuffer, 1, cSize, ress->dstFile) != cSize)
|
||||
EXM_THROW(75, "Write error : %s ", strerror(errno));
|
||||
outFileSize += cSize;
|
||||
strm.next_out = (Bytef*)ress->dstBuffer;
|
||||
strm.avail_out = (uInt)ress->dstBufferSize;
|
||||
} }
|
||||
@@ -800,11 +905,11 @@ FIO_compressGzFrame(cRess_t* ress,
|
||||
EXM_THROW(77, "zstd: %s: deflate error %d \n", srcFileName, ret);
|
||||
}
|
||||
|
||||
ret = deflateEnd(&strm);
|
||||
if (ret != Z_OK)
|
||||
EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
|
||||
{ int const ret = deflateEnd(&strm);
|
||||
if (ret != Z_OK) {
|
||||
EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
|
||||
} }
|
||||
*readsize = inFileSize;
|
||||
|
||||
return outFileSize;
|
||||
}
|
||||
#endif
|
||||
@@ -827,14 +932,14 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
||||
if (plain_lzma) {
|
||||
lzma_options_lzma opt_lzma;
|
||||
if (lzma_lzma_preset(&opt_lzma, compressionLevel))
|
||||
EXM_THROW(71, "zstd: %s: lzma_lzma_preset error", srcFileName);
|
||||
EXM_THROW(81, "zstd: %s: lzma_lzma_preset error", srcFileName);
|
||||
ret = lzma_alone_encoder(&strm, &opt_lzma); /* LZMA */
|
||||
if (ret != LZMA_OK)
|
||||
EXM_THROW(71, "zstd: %s: lzma_alone_encoder error %d", srcFileName, ret);
|
||||
EXM_THROW(82, "zstd: %s: lzma_alone_encoder error %d", srcFileName, ret);
|
||||
} else {
|
||||
ret = lzma_easy_encoder(&strm, compressionLevel, LZMA_CHECK_CRC64); /* XZ */
|
||||
if (ret != LZMA_OK)
|
||||
EXM_THROW(71, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
|
||||
EXM_THROW(83, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
|
||||
}
|
||||
|
||||
strm.next_in = 0;
|
||||
@@ -854,11 +959,11 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
||||
ret = lzma_code(&strm, action);
|
||||
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||
EXM_THROW(72, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
|
||||
EXM_THROW(84, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
|
||||
{ size_t const compBytes = ress->dstBufferSize - strm.avail_out;
|
||||
if (compBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, compBytes, ress->dstFile) != compBytes)
|
||||
EXM_THROW(73, "Write error : %s", strerror(errno));
|
||||
EXM_THROW(85, "Write error : %s", strerror(errno));
|
||||
outFileSize += compBytes;
|
||||
strm.next_out = (BYTE*)ress->dstBuffer;
|
||||
strm.avail_out = ress->dstBufferSize;
|
||||
@@ -1276,9 +1381,7 @@ static int FIO_compressFilename_dstFile(FIO_prefs_t* const prefs,
|
||||
int result;
|
||||
stat_t statbuf;
|
||||
int transfer_permissions = 0;
|
||||
|
||||
assert(ress.srcFile != NULL);
|
||||
|
||||
if (ress.dstFile == NULL) {
|
||||
closeDstFile = 1;
|
||||
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s", dstFileName);
|
||||
@@ -1369,11 +1472,9 @@ FIO_compressFilename_srcFile(FIO_prefs_t* const prefs,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int FIO_compressFilename(FIO_prefs_t* const prefs,
|
||||
const char* dstFileName, const char* srcFileName,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams)
|
||||
int FIO_compressFilename(FIO_prefs_t* const prefs, const char* dstFileName,
|
||||
const char* srcFileName, const char* dictFileName,
|
||||
int compressionLevel, ZSTD_compressionParameters comprParams)
|
||||
{
|
||||
cRess_t const ress = FIO_createCResources(prefs, dictFileName, compressionLevel, comprParams);
|
||||
int const result = FIO_compressFilename_srcFile(prefs, ress, dstFileName, srcFileName, compressionLevel);
|
||||
@@ -1383,20 +1484,24 @@ int FIO_compressFilename(FIO_prefs_t* const prefs,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* FIO_determineCompressedName() :
|
||||
* create a destination filename for compressed srcFileName.
|
||||
* @return a pointer to it.
|
||||
* This function never returns an error (it may abort() in case of pb)
|
||||
*/
|
||||
static const char*
|
||||
FIO_determineCompressedName(const char* srcFileName, const char* suffix)
|
||||
FIO_determineCompressedName(const char* srcFileName, const char* outDirName, const char* suffix)
|
||||
{
|
||||
static size_t dfnbCapacity = 0;
|
||||
static char* dstFileNameBuffer = NULL; /* using static allocation : this function cannot be multi-threaded */
|
||||
|
||||
size_t const sfnSize = strlen(srcFileName);
|
||||
char* outDirFilename = NULL;
|
||||
size_t sfnSize = strlen(srcFileName);
|
||||
size_t const suffixSize = strlen(suffix);
|
||||
if (outDirName) {
|
||||
outDirFilename = FIO_createFilename_fromOutDir(srcFileName, outDirName, suffixSize);
|
||||
sfnSize = strlen(outDirFilename);
|
||||
assert(outDirFilename != NULL);
|
||||
}
|
||||
|
||||
if (dfnbCapacity <= sfnSize+suffixSize+1) {
|
||||
/* resize buffer for dstName */
|
||||
@@ -1405,22 +1510,30 @@ FIO_determineCompressedName(const char* srcFileName, const char* suffix)
|
||||
dstFileNameBuffer = (char*)malloc(dfnbCapacity);
|
||||
if (!dstFileNameBuffer) {
|
||||
EXM_THROW(30, "zstd: %s", strerror(errno));
|
||||
} }
|
||||
}
|
||||
}
|
||||
assert(dstFileNameBuffer != NULL);
|
||||
memcpy(dstFileNameBuffer, srcFileName, sfnSize);
|
||||
memcpy(dstFileNameBuffer+sfnSize, suffix, suffixSize+1 /* Include terminating null */);
|
||||
|
||||
if (outDirFilename) {
|
||||
memcpy(dstFileNameBuffer, outDirFilename, sfnSize);
|
||||
free(outDirFilename);
|
||||
} else {
|
||||
memcpy(dstFileNameBuffer, srcFileName, sfnSize);
|
||||
}
|
||||
memcpy(dstFileNameBuffer+sfnSize, suffix, suffixSize+1 /* Include terminating null */);
|
||||
return dstFileNameBuffer;
|
||||
}
|
||||
|
||||
|
||||
/* FIO_compressMultipleFilenames() :
|
||||
* compress nbFiles files
|
||||
* into one destination (outFileName)
|
||||
* or into one file each (outFileName == NULL, but suffix != NULL).
|
||||
* into either one destination (outFileName),
|
||||
* or into one file each (outFileName == NULL, but suffix != NULL),
|
||||
* or into a destination folder (specified with -O)
|
||||
*/
|
||||
int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
const char** inFileNamesTable, unsigned nbFiles,
|
||||
const char* outDirName,
|
||||
const char* outFileName, const char* suffix,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams)
|
||||
@@ -1430,7 +1543,6 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
|
||||
/* init */
|
||||
assert(outFileName != NULL || suffix != NULL);
|
||||
|
||||
if (outFileName != NULL) { /* output into a single destination (stdout typically) */
|
||||
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
||||
if (ress.dstFile == NULL) { /* could not open outFileName */
|
||||
@@ -1448,9 +1560,12 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
unsigned u;
|
||||
for (u=0; u<nbFiles; u++) {
|
||||
const char* const srcFileName = inFileNamesTable[u];
|
||||
const char* const dstFileName = FIO_determineCompressedName(srcFileName, suffix); /* cannot fail */
|
||||
const char* const dstFileName = FIO_determineCompressedName(srcFileName, outDirName, suffix); /* cannot fail */
|
||||
error |= FIO_compressFilename_srcFile(prefs, ress, dstFileName, srcFileName, compressionLevel);
|
||||
} }
|
||||
}
|
||||
if (outDirName)
|
||||
FIO_checkFilenameCollisions(inFileNamesTable ,nbFiles);
|
||||
}
|
||||
|
||||
FIO_freeCResources(ress);
|
||||
return error;
|
||||
@@ -1512,7 +1627,11 @@ static void FIO_freeDResources(dRess_t ress)
|
||||
|
||||
/** FIO_fwriteSparse() :
|
||||
* @return : storedSkips, to be provided to next call to FIO_fwriteSparse() of LZ4IO_fwriteSparseEnd() */
|
||||
static unsigned FIO_fwriteSparse(FIO_prefs_t* const prefs, FILE* file, const void* buffer, size_t bufferSize, unsigned storedSkips)
|
||||
static unsigned
|
||||
FIO_fwriteSparse(const FIO_prefs_t* const prefs,
|
||||
FILE* file,
|
||||
const void* buffer, size_t bufferSize,
|
||||
unsigned storedSkips)
|
||||
{
|
||||
const size_t* const bufferT = (const size_t*)buffer; /* Buffer is supposed malloc'ed, hence aligned on size_t */
|
||||
size_t bufferSizeT = bufferSize / sizeof(size_t);
|
||||
@@ -1520,10 +1639,12 @@ static unsigned FIO_fwriteSparse(FIO_prefs_t* const prefs, FILE* file, const voi
|
||||
const size_t* ptrT = bufferT;
|
||||
static const size_t segmentSizeT = (32 KB) / sizeof(size_t); /* 0-test re-attempted every 32 KB */
|
||||
|
||||
if (prefs->testMode) return 0; /* do not output anything in test mode */
|
||||
|
||||
if (!prefs->sparseFileSupport) { /* normal write */
|
||||
size_t const sizeCheck = fwrite(buffer, 1, bufferSize, file);
|
||||
if (sizeCheck != bufferSize)
|
||||
EXM_THROW(70, "Write error : %s (cannot write decoded block)",
|
||||
EXM_THROW(70, "Write error : cannot write decoded block : %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@@ -1532,7 +1653,7 @@ static unsigned FIO_fwriteSparse(FIO_prefs_t* const prefs, FILE* file, const voi
|
||||
if (storedSkips > 1 GB) {
|
||||
int const seekResult = LONG_SEEK(file, 1 GB, SEEK_CUR);
|
||||
if (seekResult != 0)
|
||||
EXM_THROW(71, "1 GB skip error (sparse file support)");
|
||||
EXM_THROW(91, "1 GB skip error (sparse file support)");
|
||||
storedSkips -= 1 GB;
|
||||
}
|
||||
|
||||
@@ -1548,13 +1669,14 @@ static unsigned FIO_fwriteSparse(FIO_prefs_t* const prefs, FILE* file, const voi
|
||||
|
||||
if (nb0T != seg0SizeT) { /* not all 0s */
|
||||
int const seekResult = LONG_SEEK(file, storedSkips, SEEK_CUR);
|
||||
if (seekResult) EXM_THROW(72, "Sparse skip error ; try --no-sparse");
|
||||
if (seekResult) EXM_THROW(92, "Sparse skip error ; try --no-sparse");
|
||||
storedSkips = 0;
|
||||
seg0SizeT -= nb0T;
|
||||
ptrT += nb0T;
|
||||
{ size_t const sizeCheck = fwrite(ptrT, sizeof(size_t), seg0SizeT, file);
|
||||
if (sizeCheck != seg0SizeT)
|
||||
EXM_THROW(73, "Write error : cannot write decoded block");
|
||||
EXM_THROW(93, "Write error : cannot write decoded block : %s",
|
||||
strerror(errno));
|
||||
} }
|
||||
ptrT += seg0SizeT;
|
||||
}
|
||||
@@ -1571,19 +1693,21 @@ static unsigned FIO_fwriteSparse(FIO_prefs_t* const prefs, FILE* file, const voi
|
||||
if (restPtr != restEnd) {
|
||||
int seekResult = LONG_SEEK(file, storedSkips, SEEK_CUR);
|
||||
if (seekResult)
|
||||
EXM_THROW(74, "Sparse skip error ; try --no-sparse");
|
||||
EXM_THROW(94, "Sparse skip error ; try --no-sparse");
|
||||
storedSkips = 0;
|
||||
{ size_t const sizeCheck = fwrite(restPtr, 1, (size_t)(restEnd - restPtr), file);
|
||||
if (sizeCheck != (size_t)(restEnd - restPtr))
|
||||
EXM_THROW(75, "Write error : cannot write decoded end of block");
|
||||
EXM_THROW(95, "Write error : cannot write decoded end of block : %s",
|
||||
strerror(errno));
|
||||
} } } }
|
||||
|
||||
return storedSkips;
|
||||
}
|
||||
|
||||
static void
|
||||
FIO_fwriteSparseEnd(FIO_prefs_t* const prefs, FILE* file, unsigned storedSkips)
|
||||
FIO_fwriteSparseEnd(const FIO_prefs_t* const prefs, FILE* file, unsigned storedSkips)
|
||||
{
|
||||
if (prefs->testMode) assert(storedSkips == 0);
|
||||
if (storedSkips>0) {
|
||||
assert(prefs->sparseFileSupport > 0); /* storedSkips>0 implies sparse support is enabled */
|
||||
(void)prefs; /* assert can be disabled, in which case prefs becomes unused */
|
||||
@@ -1593,14 +1717,14 @@ FIO_fwriteSparseEnd(FIO_prefs_t* const prefs, FILE* file, unsigned storedSkips)
|
||||
* so that skipped ones get implicitly translated as zero by FS */
|
||||
{ const char lastZeroByte[1] = { 0 };
|
||||
if (fwrite(lastZeroByte, 1, 1, file) != 1)
|
||||
EXM_THROW(69, "Write error : cannot write last zero");
|
||||
EXM_THROW(69, "Write error : cannot write last zero : %s", strerror(errno));
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
/** FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode
|
||||
@return : 0 (no error) */
|
||||
static int FIO_passThrough(FIO_prefs_t* const prefs,
|
||||
static int FIO_passThrough(const FIO_prefs_t* const prefs,
|
||||
FILE* foutput, FILE* finput,
|
||||
void* buffer, size_t bufferSize,
|
||||
size_t alreadyLoaded)
|
||||
@@ -1612,7 +1736,7 @@ static int FIO_passThrough(FIO_prefs_t* const prefs,
|
||||
/* assumption : ress->srcBufferLoaded bytes already loaded and stored within buffer */
|
||||
{ size_t const sizeCheck = fwrite(buffer, 1, alreadyLoaded, foutput);
|
||||
if (sizeCheck != alreadyLoaded) {
|
||||
DISPLAYLEVEL(1, "Pass-through write error \n");
|
||||
DISPLAYLEVEL(1, "Pass-through write error : %s\n", strerror(errno));
|
||||
return 1;
|
||||
} }
|
||||
|
||||
@@ -1640,7 +1764,10 @@ static unsigned FIO_highbit64(unsigned long long v)
|
||||
|
||||
/* FIO_zstdErrorHelp() :
|
||||
* detailed error message when requested window size is too large */
|
||||
static void FIO_zstdErrorHelp(FIO_prefs_t* const prefs, dRess_t* ress, size_t err, char const* srcFileName)
|
||||
static void
|
||||
FIO_zstdErrorHelp(const FIO_prefs_t* const prefs,
|
||||
const dRess_t* ress,
|
||||
size_t err, const char* srcFileName)
|
||||
{
|
||||
ZSTD_frameHeader header;
|
||||
|
||||
@@ -1672,12 +1799,10 @@ static void FIO_zstdErrorHelp(FIO_prefs_t* const prefs, dRess_t* ress, size_t er
|
||||
* @return : size of decoded zstd frame, or an error code
|
||||
*/
|
||||
#define FIO_ERROR_FRAME_DECODING ((unsigned long long)(-2))
|
||||
static unsigned long long FIO_decompressZstdFrame(
|
||||
FIO_prefs_t* const prefs,
|
||||
dRess_t* ress,
|
||||
FILE* finput,
|
||||
const char* srcFileName,
|
||||
U64 alreadyDecoded)
|
||||
static unsigned long long
|
||||
FIO_decompressZstdFrame(const FIO_prefs_t* const prefs,
|
||||
dRess_t* ress, FILE* finput,
|
||||
const char* srcFileName, U64 alreadyDecoded)
|
||||
{
|
||||
U64 frameSize = 0;
|
||||
U32 storedSkips = 0;
|
||||
@@ -1741,13 +1866,16 @@ static unsigned long long FIO_decompressZstdFrame(
|
||||
|
||||
|
||||
#ifdef ZSTD_GZDECOMPRESS
|
||||
static unsigned long long FIO_decompressGzFrame(dRess_t* ress,
|
||||
FILE* srcFile, const char* srcFileName)
|
||||
static unsigned long long
|
||||
FIO_decompressGzFrame(const FIO_prefs_t* const prefs,
|
||||
dRess_t* ress, FILE* srcFile,
|
||||
const char* srcFileName)
|
||||
{
|
||||
unsigned long long outFileSize = 0;
|
||||
z_stream strm;
|
||||
int flush = Z_NO_FLUSH;
|
||||
int decodingError = 0;
|
||||
unsigned storedSkips = 0;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
@@ -1782,10 +1910,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress,
|
||||
}
|
||||
{ size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
|
||||
if (decompBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) {
|
||||
DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno));
|
||||
decodingError = 1; break;
|
||||
}
|
||||
storedSkips = FIO_fwriteSparse(prefs, ress->dstFile, ress->dstBuffer, decompBytes, storedSkips);
|
||||
outFileSize += decompBytes;
|
||||
strm.next_out = (Bytef*)ress->dstBuffer;
|
||||
strm.avail_out = (uInt)ress->dstBufferSize;
|
||||
@@ -1802,19 +1927,24 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress,
|
||||
DISPLAYLEVEL(1, "zstd: %s: inflateEnd error \n", srcFileName);
|
||||
decodingError = 1;
|
||||
}
|
||||
FIO_fwriteSparseEnd(prefs, ress->dstFile, storedSkips);
|
||||
return decodingError ? FIO_ERROR_FRAME_DECODING : outFileSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ZSTD_LZMADECOMPRESS
|
||||
static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, const char* srcFileName, int plain_lzma)
|
||||
static unsigned long long
|
||||
FIO_decompressLzmaFrame(const FIO_prefs_t* const prefs,
|
||||
dRess_t* ress, FILE* srcFile,
|
||||
const char* srcFileName, int plain_lzma)
|
||||
{
|
||||
unsigned long long outFileSize = 0;
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
lzma_action action = LZMA_RUN;
|
||||
lzma_ret initRet;
|
||||
int decodingError = 0;
|
||||
unsigned storedSkips = 0;
|
||||
|
||||
strm.next_in = 0;
|
||||
strm.avail_in = 0;
|
||||
@@ -1857,10 +1987,7 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
|
||||
}
|
||||
{ size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
|
||||
if (decompBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) {
|
||||
DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno));
|
||||
decodingError = 1; break;
|
||||
}
|
||||
storedSkips = FIO_fwriteSparse(prefs, ress->dstFile, ress->dstBuffer, decompBytes, storedSkips);
|
||||
outFileSize += decompBytes;
|
||||
strm.next_out = (BYTE*)ress->dstBuffer;
|
||||
strm.avail_out = ress->dstBufferSize;
|
||||
@@ -1872,19 +1999,23 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
|
||||
memmove(ress->srcBuffer, strm.next_in, strm.avail_in);
|
||||
ress->srcBufferLoaded = strm.avail_in;
|
||||
lzma_end(&strm);
|
||||
FIO_fwriteSparseEnd(prefs, ress->dstFile, storedSkips);
|
||||
return decodingError ? FIO_ERROR_FRAME_DECODING : outFileSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ZSTD_LZ4DECOMPRESS
|
||||
static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
|
||||
FILE* srcFile, const char* srcFileName)
|
||||
static unsigned long long
|
||||
FIO_decompressLz4Frame(const FIO_prefs_t* const prefs,
|
||||
dRess_t* ress, FILE* srcFile,
|
||||
const char* srcFileName)
|
||||
{
|
||||
unsigned long long filesize = 0;
|
||||
LZ4F_errorCode_t nextToLoad;
|
||||
LZ4F_decompressionContext_t dCtx;
|
||||
LZ4F_errorCode_t const errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
|
||||
int decodingError = 0;
|
||||
unsigned storedSkips = 0;
|
||||
|
||||
if (LZ4F_isError(errorCode)) {
|
||||
DISPLAYLEVEL(1, "zstd: failed to create lz4 decompression context \n");
|
||||
@@ -1928,10 +2059,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
|
||||
|
||||
/* Write Block */
|
||||
if (decodedBytes) {
|
||||
if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) {
|
||||
DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno));
|
||||
decodingError = 1; nextToLoad = 0; break;
|
||||
}
|
||||
storedSkips = FIO_fwriteSparse(prefs, ress->dstFile, ress->dstBuffer, decodedBytes, storedSkips);
|
||||
filesize += decodedBytes;
|
||||
DISPLAYUPDATE(2, "\rDecompressed : %u MB ", (unsigned)(filesize>>20));
|
||||
}
|
||||
@@ -1952,6 +2080,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
|
||||
|
||||
LZ4F_freeDecompressionContext(dCtx);
|
||||
ress->srcBufferLoaded = 0; /* LZ4F will reach exact frame boundary */
|
||||
FIO_fwriteSparseEnd(prefs, ress->dstFile, storedSkips);
|
||||
|
||||
return decodingError ? FIO_ERROR_FRAME_DECODING : filesize;
|
||||
}
|
||||
@@ -1965,8 +2094,9 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
|
||||
* @return : 0 : OK
|
||||
* 1 : error
|
||||
*/
|
||||
static int FIO_decompressFrames(FIO_prefs_t* const prefs, dRess_t ress, FILE* srcFile,
|
||||
const char* dstFileName, const char* srcFileName)
|
||||
static int FIO_decompressFrames(const FIO_prefs_t* const prefs,
|
||||
dRess_t ress, FILE* srcFile,
|
||||
const char* dstFileName, const char* srcFileName)
|
||||
{
|
||||
unsigned readSomething = 0;
|
||||
unsigned long long filesize = 0;
|
||||
@@ -1998,7 +2128,7 @@ static int FIO_decompressFrames(FIO_prefs_t* const prefs, dRess_t ress, FILE* sr
|
||||
filesize += frameSize;
|
||||
} else if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */
|
||||
#ifdef ZSTD_GZDECOMPRESS
|
||||
unsigned long long const frameSize = FIO_decompressGzFrame(&ress, srcFile, srcFileName);
|
||||
unsigned long long const frameSize = FIO_decompressGzFrame(prefs, &ress, srcFile, srcFileName);
|
||||
if (frameSize == FIO_ERROR_FRAME_DECODING) return 1;
|
||||
filesize += frameSize;
|
||||
#else
|
||||
@@ -2008,7 +2138,7 @@ static int FIO_decompressFrames(FIO_prefs_t* const prefs, dRess_t ress, FILE* sr
|
||||
} else if ((buf[0] == 0xFD && buf[1] == 0x37) /* xz magic number */
|
||||
|| (buf[0] == 0x5D && buf[1] == 0x00)) { /* lzma header (no magic number) */
|
||||
#ifdef ZSTD_LZMADECOMPRESS
|
||||
unsigned long long const frameSize = FIO_decompressLzmaFrame(&ress, srcFile, srcFileName, buf[0] != 0xFD);
|
||||
unsigned long long const frameSize = FIO_decompressLzmaFrame(prefs, &ress, srcFile, srcFileName, buf[0] != 0xFD);
|
||||
if (frameSize == FIO_ERROR_FRAME_DECODING) return 1;
|
||||
filesize += frameSize;
|
||||
#else
|
||||
@@ -2017,7 +2147,7 @@ static int FIO_decompressFrames(FIO_prefs_t* const prefs, dRess_t ress, FILE* sr
|
||||
#endif
|
||||
} else if (MEM_readLE32(buf) == LZ4_MAGICNUMBER) {
|
||||
#ifdef ZSTD_LZ4DECOMPRESS
|
||||
unsigned long long const frameSize = FIO_decompressLz4Frame(&ress, srcFile, srcFileName);
|
||||
unsigned long long const frameSize = FIO_decompressLz4Frame(prefs, &ress, srcFile, srcFileName);
|
||||
if (frameSize == FIO_ERROR_FRAME_DECODING) return 1;
|
||||
filesize += frameSize;
|
||||
#else
|
||||
@@ -2057,11 +2187,11 @@ static int FIO_decompressDstFile(FIO_prefs_t* const prefs,
|
||||
int transfer_permissions = 0;
|
||||
int releaseDstFile = 0;
|
||||
|
||||
if (ress.dstFile == NULL) {
|
||||
if ((ress.dstFile == NULL) && (prefs->testMode==0)) {
|
||||
releaseDstFile = 1;
|
||||
|
||||
ress.dstFile = FIO_openDstFile(prefs, srcFileName, dstFileName);
|
||||
if (ress.dstFile==0) return 1;
|
||||
if (ress.dstFile==NULL) return 1;
|
||||
|
||||
/* Must only be added after FIO_openDstFile() succeeds.
|
||||
* Otherwise we may delete the destination file if it already exists,
|
||||
@@ -2074,7 +2204,6 @@ static int FIO_decompressDstFile(FIO_prefs_t* const prefs,
|
||||
transfer_permissions = 1;
|
||||
}
|
||||
|
||||
|
||||
result = FIO_decompressFrames(prefs, ress, srcFile, dstFileName, srcFileName);
|
||||
|
||||
if (releaseDstFile) {
|
||||
@@ -2164,13 +2293,14 @@ int FIO_decompressFilename(FIO_prefs_t* const prefs,
|
||||
* @return a pointer to it.
|
||||
* @return == NULL if there is an error */
|
||||
static const char*
|
||||
FIO_determineDstName(const char* srcFileName)
|
||||
FIO_determineDstName(const char* srcFileName, const char* outDirName)
|
||||
{
|
||||
static size_t dfnbCapacity = 0;
|
||||
static char* dstFileNameBuffer = NULL; /* using static allocation : this function cannot be multi-threaded */
|
||||
|
||||
size_t const sfnSize = strlen(srcFileName);
|
||||
char* outDirFilename = NULL;
|
||||
size_t sfnSize = strlen(srcFileName);
|
||||
size_t suffixSize;
|
||||
|
||||
const char* const suffixPtr = strrchr(srcFileName, '.');
|
||||
if (suffixPtr == NULL) {
|
||||
DISPLAYLEVEL(1, "zstd: %s: unknown suffix -- ignored \n",
|
||||
@@ -2208,9 +2338,14 @@ FIO_determineDstName(const char* srcFileName)
|
||||
srcFileName, suffixlist);
|
||||
return NULL;
|
||||
}
|
||||
if (outDirName) {
|
||||
outDirFilename = FIO_createFilename_fromOutDir(srcFileName, outDirName, 0);
|
||||
sfnSize = strlen(outDirFilename);
|
||||
assert(outDirFilename != NULL);
|
||||
}
|
||||
|
||||
/* allocate enough space to write dstFilename into it */
|
||||
if (dfnbCapacity+suffixSize <= sfnSize+1) {
|
||||
/* allocate enough space to write dstFilename into it */
|
||||
free(dstFileNameBuffer);
|
||||
dfnbCapacity = sfnSize + 20;
|
||||
dstFileNameBuffer = (char*)malloc(dfnbCapacity);
|
||||
@@ -2220,7 +2355,12 @@ FIO_determineDstName(const char* srcFileName)
|
||||
|
||||
/* return dst name == src name truncated from suffix */
|
||||
assert(dstFileNameBuffer != NULL);
|
||||
memcpy(dstFileNameBuffer, srcFileName, sfnSize - suffixSize);
|
||||
if (outDirFilename) {
|
||||
memcpy(dstFileNameBuffer, outDirFilename, sfnSize - suffixSize);
|
||||
free(outDirFilename);
|
||||
} else {
|
||||
memcpy(dstFileNameBuffer, srcFileName, sfnSize - suffixSize);
|
||||
}
|
||||
dstFileNameBuffer[sfnSize-suffixSize] = '\0';
|
||||
return dstFileNameBuffer;
|
||||
|
||||
@@ -2230,8 +2370,8 @@ FIO_determineDstName(const char* srcFileName)
|
||||
|
||||
int
|
||||
FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
const char* srcNamesTable[], unsigned nbFiles,
|
||||
const char* outFileName,
|
||||
const char** srcNamesTable, unsigned nbFiles,
|
||||
const char* outDirName, const char* outFileName,
|
||||
const char* dictFileName)
|
||||
{
|
||||
int error = 0;
|
||||
@@ -2239,30 +2379,32 @@ FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
|
||||
if (outFileName) {
|
||||
unsigned u;
|
||||
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
||||
if (ress.dstFile == 0) EXM_THROW(71, "cannot open %s", outFileName);
|
||||
if (!prefs->testMode) {
|
||||
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
||||
if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName);
|
||||
}
|
||||
for (u=0; u<nbFiles; u++)
|
||||
error |= FIO_decompressSrcFile(prefs, ress, outFileName, srcNamesTable[u]);
|
||||
if (fclose(ress.dstFile))
|
||||
if ((!prefs->testMode) && (fclose(ress.dstFile)))
|
||||
EXM_THROW(72, "Write error : %s : cannot properly close output file",
|
||||
strerror(errno));
|
||||
} else {
|
||||
unsigned u;
|
||||
for (u=0; u<nbFiles; u++) { /* create dstFileName */
|
||||
const char* const srcFileName = srcNamesTable[u];
|
||||
const char* const dstFileName = FIO_determineDstName(srcFileName);
|
||||
const char* const dstFileName = FIO_determineDstName(srcFileName, outDirName);
|
||||
if (dstFileName == NULL) { error=1; continue; }
|
||||
|
||||
error |= FIO_decompressSrcFile(prefs, ress, dstFileName, srcFileName);
|
||||
}
|
||||
if (outDirName)
|
||||
FIO_checkFilenameCollisions(srcNamesTable ,nbFiles);
|
||||
}
|
||||
|
||||
FIO_freeDResources(ress);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
* .zst file info (--list command)
|
||||
***************************************************************************/
|
||||
@@ -2301,7 +2443,7 @@ FIO_analyzeFrames(fileInfo_t* info, FILE* const srcFile)
|
||||
for ( ; ; ) {
|
||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
||||
size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile);
|
||||
if (numBytesRead < ZSTD_FRAMEHEADERSIZE_MIN) {
|
||||
if (numBytesRead < ZSTD_FRAMEHEADERSIZE_MIN(ZSTD_f_zstd1)) {
|
||||
if ( feof(srcFile)
|
||||
&& (numBytesRead == 0)
|
||||
&& (info->compressedSize > 0)
|
||||
|
||||
+18
-8
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#define stdinmark "/*stdin*\\"
|
||||
#define stdoutmark "/*stdout*\\"
|
||||
#ifdef _WIN32
|
||||
# define nulmark "nul"
|
||||
# define nulmark "NUL"
|
||||
#else
|
||||
# define nulmark "/dev/null"
|
||||
#endif
|
||||
@@ -74,6 +74,7 @@ void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable);
|
||||
void FIO_setStreamSrcSize(FIO_prefs_t* const prefs, size_t streamSrcSize);
|
||||
void FIO_setTargetCBlockSize(FIO_prefs_t* const prefs, size_t targetCBlockSize);
|
||||
void FIO_setSrcSizeHint(FIO_prefs_t* const prefs, size_t srcSizeHint);
|
||||
void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode);
|
||||
void FIO_setLiteralCompressionMode(
|
||||
FIO_prefs_t* const prefs,
|
||||
ZSTD_literalCompressionMode_e mode);
|
||||
@@ -85,13 +86,14 @@ void FIO_setNotificationLevel(int level);
|
||||
* Single File functions
|
||||
***************************************/
|
||||
/** FIO_compressFilename() :
|
||||
@return : 0 == ok; 1 == pb with src file. */
|
||||
* @return : 0 == ok; 1 == pb with src file. */
|
||||
int FIO_compressFilename (FIO_prefs_t* const prefs,
|
||||
const char* outfilename, const char* infilename, const char* dictFileName,
|
||||
int compressionLevel, ZSTD_compressionParameters comprParams);
|
||||
const char* outfilename, const char* infilename,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams);
|
||||
|
||||
/** FIO_decompressFilename() :
|
||||
@return : 0 == ok; 1 == pb with src file. */
|
||||
* @return : 0 == ok; 1 == pb with src file. */
|
||||
int FIO_decompressFilename (FIO_prefs_t* const prefs,
|
||||
const char* outfilename, const char* infilename, const char* dictFileName);
|
||||
|
||||
@@ -102,20 +104,28 @@ int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int dis
|
||||
* Multiple File functions
|
||||
***************************************/
|
||||
/** FIO_compressMultipleFilenames() :
|
||||
@return : nb of missing files */
|
||||
* @return : nb of missing files */
|
||||
int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
const char** srcNamesTable, unsigned nbFiles,
|
||||
const char** inFileNamesTable, unsigned nbFiles,
|
||||
const char* outDirName,
|
||||
const char* outFileName, const char* suffix,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams);
|
||||
|
||||
/** FIO_decompressMultipleFilenames() :
|
||||
@return : nb of missing or skipped files */
|
||||
* @return : nb of missing or skipped files */
|
||||
int FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs,
|
||||
const char** srcNamesTable, unsigned nbFiles,
|
||||
const char* outDirName,
|
||||
const char* outFileName,
|
||||
const char* dictFileName);
|
||||
|
||||
/* FIO_checkFilenameCollisions() :
|
||||
* Checks for and warns if there are any files that would have the same output path
|
||||
*/
|
||||
int FIO_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles);
|
||||
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Advanced stuff (should actually be hosted elsewhere)
|
||||
|
||||
+50
-32
@@ -20,6 +20,9 @@ extern "C" {
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__)
|
||||
#include <direct.h> /* needed for _mkdir in windows */
|
||||
#endif
|
||||
|
||||
int UTIL_fileExist(const char* filename)
|
||||
{
|
||||
@@ -69,7 +72,8 @@ int UTIL_setFileStat(const char *filename, stat_t *statbuf)
|
||||
#else
|
||||
{
|
||||
/* (atime, mtime) */
|
||||
struct timespec timebuf[2] = { {0, UTIME_NOW}, statbuf->st_mtim };
|
||||
struct timespec timebuf[2] = { {0, UTIME_NOW} };
|
||||
timebuf[1] = statbuf->st_mtim;
|
||||
res += utimensat(AT_FDCWD, filename, timebuf, 0);
|
||||
}
|
||||
#endif
|
||||
@@ -98,20 +102,27 @@ U32 UTIL_isDirectory(const char* infilename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UTIL_isSameFile(const char* file1, const char* file2)
|
||||
int UTIL_compareStr(const void *p1, const void *p2) {
|
||||
return strcmp(* (char * const *) p1, * (char * const *) p2);
|
||||
}
|
||||
|
||||
int UTIL_isSameFile(const char* fName1, const char* fName2)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
assert(fName1 != NULL); assert(fName2 != NULL);
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
/* note : Visual does not support file identification by inode.
|
||||
* inode does not work on Windows, even with a posix layer, like msys2.
|
||||
* The following work-around is limited to detecting exact name repetition only,
|
||||
* aka `filename` is considered different from `subdir/../filename` */
|
||||
return !strcmp(file1, file2);
|
||||
return !strcmp(fName1, fName2);
|
||||
#else
|
||||
stat_t file1Stat;
|
||||
stat_t file2Stat;
|
||||
return UTIL_getFileStat(file1, &file1Stat)
|
||||
&& UTIL_getFileStat(file2, &file2Stat)
|
||||
&& (file1Stat.st_dev == file2Stat.st_dev)
|
||||
&& (file1Stat.st_ino == file2Stat.st_ino);
|
||||
{ stat_t file1Stat;
|
||||
stat_t file2Stat;
|
||||
return UTIL_getFileStat(fName1, &file1Stat)
|
||||
&& UTIL_getFileStat(fName2, &file2Stat)
|
||||
&& (file1Stat.st_dev == file2Stat.st_dev)
|
||||
&& (file1Stat.st_ino == file2Stat.st_ino);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -461,19 +472,20 @@ int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char* path;
|
||||
int dirLength, fnameLength, pathLength, nbFiles = 0;
|
||||
size_t dirLength, fnameLength, pathLength;
|
||||
int nbFiles = 0;
|
||||
|
||||
if (!(dir = opendir(dirName))) {
|
||||
UTIL_DISPLAYLEVEL(1, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
dirLength = (int)strlen(dirName);
|
||||
dirLength = strlen(dirName);
|
||||
errno = 0;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (strcmp (entry->d_name, "..") == 0 ||
|
||||
strcmp (entry->d_name, ".") == 0) continue;
|
||||
fnameLength = (int)strlen(entry->d_name);
|
||||
fnameLength = strlen(entry->d_name);
|
||||
path = (char*) malloc(dirLength + fnameLength + 2);
|
||||
if (!path) { closedir(dir); return 0; }
|
||||
memcpy(path, dirName, dirLength);
|
||||
@@ -495,7 +507,8 @@ int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char
|
||||
} else {
|
||||
if (*bufStart + *pos + pathLength >= *bufEnd) {
|
||||
ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
|
||||
*bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
|
||||
assert(newListSize >= 0);
|
||||
*bufStart = (char*)UTIL_realloc(*bufStart, (size_t)newListSize);
|
||||
*bufEnd = *bufStart + newListSize;
|
||||
if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
|
||||
}
|
||||
@@ -544,7 +557,6 @@ UTIL_createFileList(const char **inputNames, unsigned inputNamesNb,
|
||||
unsigned i, nbFiles;
|
||||
char* buf = (char*)malloc(LIST_SIZE_INCREASE);
|
||||
char* bufend = buf + LIST_SIZE_INCREASE;
|
||||
const char** fileTable;
|
||||
|
||||
if (!buf) return NULL;
|
||||
|
||||
@@ -553,36 +565,37 @@ UTIL_createFileList(const char **inputNames, unsigned inputNamesNb,
|
||||
size_t const len = strlen(inputNames[i]);
|
||||
if (buf + pos + len >= bufend) {
|
||||
ptrdiff_t newListSize = (bufend - buf) + LIST_SIZE_INCREASE;
|
||||
buf = (char*)UTIL_realloc(buf, newListSize);
|
||||
assert(newListSize >= 0);
|
||||
buf = (char*)UTIL_realloc(buf, (size_t)newListSize);
|
||||
bufend = buf + newListSize;
|
||||
if (!buf) return NULL;
|
||||
}
|
||||
if (buf + pos + len < bufend) {
|
||||
memcpy(buf+pos, inputNames[i], len+1); /* with final \0 */
|
||||
memcpy(buf+pos, inputNames[i], len+1); /* including final \0 */
|
||||
pos += len + 1;
|
||||
nbFiles++;
|
||||
}
|
||||
} else {
|
||||
nbFiles += UTIL_prepareFileList(inputNames[i], &buf, &pos, &bufend, followLinks);
|
||||
nbFiles += (unsigned)UTIL_prepareFileList(inputNames[i], &buf, &pos, &bufend, followLinks);
|
||||
if (buf == NULL) return NULL;
|
||||
} }
|
||||
|
||||
if (nbFiles == 0) { free(buf); return NULL; }
|
||||
|
||||
fileTable = (const char**)malloc((nbFiles+1) * sizeof(const char*));
|
||||
if (!fileTable) { free(buf); return NULL; }
|
||||
{ const char** const fileTable = (const char**)malloc((nbFiles + 1) * sizeof(*fileTable));
|
||||
if (!fileTable) { free(buf); return NULL; }
|
||||
|
||||
for (i=0, pos=0; i<nbFiles; i++) {
|
||||
fileTable[i] = buf + pos;
|
||||
pos += strlen(fileTable[i]) + 1;
|
||||
for (i = 0, pos = 0; i < nbFiles; i++) {
|
||||
fileTable[i] = buf + pos;
|
||||
if (buf + pos > bufend) { free(buf); free((void*)fileTable); return NULL; }
|
||||
pos += strlen(fileTable[i]) + 1;
|
||||
}
|
||||
|
||||
*allocatedBuffer = buf;
|
||||
*allocatedNamesNb = nbFiles;
|
||||
|
||||
return fileTable;
|
||||
}
|
||||
|
||||
if (buf + pos > bufend) { free(buf); free((void*)fileTable); return NULL; }
|
||||
|
||||
*allocatedBuffer = buf;
|
||||
*allocatedNamesNb = nbFiles;
|
||||
|
||||
return fileTable;
|
||||
}
|
||||
|
||||
|
||||
@@ -615,8 +628,13 @@ int UTIL_countPhysicalCores(void)
|
||||
DWORD returnLength = 0;
|
||||
size_t byteOffset = 0;
|
||||
|
||||
glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
|
||||
"GetLogicalProcessorInformation");
|
||||
#if defined(_MSC_VER)
|
||||
/* Visual Studio does not like the following cast */
|
||||
# pragma warning( disable : 4054 ) /* conversion from function ptr to data ptr */
|
||||
# pragma warning( disable : 4055 ) /* conversion from data ptr to function ptr */
|
||||
#endif
|
||||
glpi = (LPFN_GLPI)(void*)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
|
||||
"GetLogicalProcessorInformation");
|
||||
|
||||
if (glpi == NULL) {
|
||||
goto failed;
|
||||
|
||||
@@ -134,6 +134,7 @@ int UTIL_setFileStat(const char* filename, stat_t* statbuf);
|
||||
U32 UTIL_isDirectory(const char* infilename);
|
||||
int UTIL_getFileStat(const char* infilename, stat_t* statbuf);
|
||||
int UTIL_isSameFile(const char* file1, const char* file2);
|
||||
int UTIL_compareStr(const void *p1, const void *p2);
|
||||
|
||||
U32 UTIL_isLink(const char* infilename);
|
||||
#define UTIL_FILESIZE_UNKNOWN ((U64)(-1))
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+16
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTD" "1" "August 2019" "zstd 1.4.3" "User Commands"
|
||||
.TH "ZSTD" "1" "October 2019" "zstd 1.4.4" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
|
||||
@@ -127,6 +127,14 @@ Does not spawn a thread for compression, use a single thread for both I/O and co
|
||||
\fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\. \fInote\fR : at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-stream\-size=#\fR
|
||||
Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-size\-hint=#\fR
|
||||
When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-rsyncable\fR
|
||||
\fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and the faster compression levels will see a small compression speed hit\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your milage may vary\.
|
||||
.
|
||||
@@ -167,6 +175,10 @@ keep source file(s) after successful compression or decompression\. This is the
|
||||
operate recursively on directories
|
||||
.
|
||||
.TP
|
||||
\fB\-\-output\-dir\-flat[=dir]\fR
|
||||
resulting files are stored into target \fBdir\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBdir\fR, while in combination with \fB\-f\fR, the last file will be present instead\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-format=FORMAT\fR
|
||||
compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\.
|
||||
.
|
||||
@@ -198,6 +210,9 @@ add integrity check computed from uncompressed data (default: enabled)
|
||||
\fB\-\-\fR
|
||||
All arguments after \fB\-\-\fR are treated as files
|
||||
.
|
||||
.SS "Restricted usage of Environment Variables"
|
||||
Using environment variables to set parameters has security implications\. Therefore, this avenue is intentionally restricted\. Only \fBZSTD_CLEVEL\fR is supported currently, for setting compression level\. \fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\. It can be overridden by corresponding command line arguments\.
|
||||
.
|
||||
.SH "DICTIONARY BUILDER"
|
||||
\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It\'s possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\.
|
||||
.
|
||||
|
||||
@@ -191,6 +191,13 @@ the last one takes effect.
|
||||
This is the default behavior.
|
||||
* `-r`:
|
||||
operate recursively on directories
|
||||
* `--output-dir-flat[=dir]`:
|
||||
resulting files are stored into target `dir` directory,
|
||||
instead of same directory as origin file.
|
||||
Be aware that this command can introduce name collision issues,
|
||||
if multiple files, from different directories, end up having the same name.
|
||||
Collision resolution ensures first file with a given name will be present in `dir`,
|
||||
while in combination with `-f`, the last file will be present instead.
|
||||
* `--format=FORMAT`:
|
||||
compress and decompress in other formats. If compiled with
|
||||
support, zstd can compress to or decompress from other compression algorithm
|
||||
@@ -214,6 +221,16 @@ the last one takes effect.
|
||||
* `--`:
|
||||
All arguments after `--` are treated as files
|
||||
|
||||
### Restricted usage of Environment Variables
|
||||
|
||||
Using environment variables to set parameters has security implications.
|
||||
Therefore, this avenue is intentionally restricted.
|
||||
Only `ZSTD_CLEVEL` is supported currently, for setting compression level.
|
||||
`ZSTD_CLEVEL` can be used to set the level between 1 and 19 (the "normal" range).
|
||||
If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a warning message.
|
||||
`ZSTD_CLEVEL` just replaces the default compression level (`3`).
|
||||
It can be overridden by corresponding command line arguments.
|
||||
|
||||
|
||||
DICTIONARY BUILDER
|
||||
------------------
|
||||
|
||||
+41
-29
@@ -139,7 +139,7 @@ static int usage_advanced(const char* programName)
|
||||
#ifndef ZSTD_NOCOMPRESS
|
||||
DISPLAY( "--ultra : enable levels beyond %i, up to %i (requires more memory)\n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
|
||||
DISPLAY( "--long[=#]: enable long distance matching with given window log (default: %u)\n", g_defaultMaxWindowLog);
|
||||
DISPLAY( "--fast[=#]: switch to ultra fast compression level (default: %u)\n", 1);
|
||||
DISPLAY( "--fast[=#]: switch to very fast compression levels (default: %u)\n", 1);
|
||||
DISPLAY( "--adapt : dynamically adapt compression level to I/O conditions \n");
|
||||
DISPLAY( "--stream-size=# : optimize compression parameters for streaming input of given number of bytes \n");
|
||||
DISPLAY( "--size-hint=# optimize compression parameters for streaming input of approximately this size\n");
|
||||
@@ -147,7 +147,7 @@ static int usage_advanced(const char* programName)
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
DISPLAY( " -T# : spawns # compression threads (default: 1, 0==# cores) \n");
|
||||
DISPLAY( " -B# : select size of each job (default: 0==automatic) \n");
|
||||
DISPLAY( " --rsyncable : compress using a rsync-friendly method (-B sets block size) \n");
|
||||
DISPLAY( "--rsyncable : compress using a rsync-friendly method (-B sets block size) \n");
|
||||
#endif
|
||||
DISPLAY( "--no-dictID : don't write dictID into header (dictionary compression)\n");
|
||||
DISPLAY( "--[no-]check : integrity check (default: enabled) \n");
|
||||
@@ -155,6 +155,7 @@ static int usage_advanced(const char* programName)
|
||||
#endif
|
||||
#ifdef UTIL_HAS_CREATEFILELIST
|
||||
DISPLAY( " -r : operate recursively on directories \n");
|
||||
DISPLAY( "--output-dir-flat[=directory]: all resulting files stored into `directory`. \n");
|
||||
#endif
|
||||
DISPLAY( "--format=zstd : compress files to the .zst format (default) \n");
|
||||
#ifdef ZSTD_GZCOMPRESS
|
||||
@@ -286,7 +287,7 @@ static unsigned readU32FromChar(const char** stringPtr) {
|
||||
* If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand.
|
||||
* @return 0 and doesn't modify *stringPtr otherwise.
|
||||
*/
|
||||
static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
|
||||
static int longCommandWArg(const char** stringPtr, const char* longCommand)
|
||||
{
|
||||
size_t const comSize = strlen(longCommand);
|
||||
int const result = !strncmp(*stringPtr, longCommand, comSize);
|
||||
@@ -429,8 +430,8 @@ static ZDICT_fastCover_params_t defaultFastCoverParams(void)
|
||||
static unsigned parseAdaptParameters(const char* stringPtr, int* adaptMinPtr, int* adaptMaxPtr)
|
||||
{
|
||||
for ( ; ;) {
|
||||
if (longCommandWArg(&stringPtr, "min=")) { *adaptMinPtr = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
|
||||
if (longCommandWArg(&stringPtr, "max=")) { *adaptMaxPtr = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
|
||||
if (longCommandWArg(&stringPtr, "min=")) { *adaptMinPtr = (int)readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
|
||||
if (longCommandWArg(&stringPtr, "max=")) { *adaptMaxPtr = (int)readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
|
||||
DISPLAYLEVEL(4, "invalid compression parameter \n");
|
||||
return 0;
|
||||
}
|
||||
@@ -525,7 +526,7 @@ static int init_cLevel(void) {
|
||||
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: numeric value too large\n", ENV_CLEVEL, env);
|
||||
return ZSTDCLI_CLEVEL_DEFAULT;
|
||||
} else if (*ptr == 0) {
|
||||
return sign * absLevel;
|
||||
return sign * (int)absLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,6 +563,7 @@ int main(int argCount, const char* argv[])
|
||||
adaptMax = MAXCLEVEL,
|
||||
rsyncable = 0,
|
||||
nextArgumentIsOutFileName = 0,
|
||||
nextArgumentIsOutDirName = 0,
|
||||
nextArgumentIsMaxDict = 0,
|
||||
nextArgumentIsDictID = 0,
|
||||
nextArgumentsAreFiles = 0,
|
||||
@@ -589,6 +591,7 @@ int main(int argCount, const char* argv[])
|
||||
unsigned filenameIdx = 0;
|
||||
const char* programName = argv[0];
|
||||
const char* outFileName = NULL;
|
||||
const char* outDirName = NULL;
|
||||
const char* dictFileName = NULL;
|
||||
const char* suffix = ZSTD_EXTENSION;
|
||||
unsigned maxDictSize = g_defaultMaxDictSize;
|
||||
@@ -689,6 +692,7 @@ int main(int argCount, const char* argv[])
|
||||
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(prefs, 0); continue; }
|
||||
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(prefs, 1); continue; }
|
||||
if (!strcmp(argument, "--priority=rt")) { setRealTimePrio = 1; continue; }
|
||||
if (!strcmp(argument, "--output-dir-flat")) {nextArgumentIsOutDirName=1; lastCommand=1; continue; }
|
||||
if (!strcmp(argument, "--adapt")) { adapt = 1; continue; }
|
||||
if (longCommandWArg(&argument, "--adapt=")) { adapt = 1; if (!parseAdaptParameters(argument, &adaptMin, &adaptMax)) CLEAN_RETURN(badusage(programName)); continue; }
|
||||
if (!strcmp(argument, "--single-thread")) { nbWorkers = 0; singleThread = 1; continue; }
|
||||
@@ -744,7 +748,7 @@ int main(int argCount, const char* argv[])
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (longCommandWArg(&argument, "--threads=")) { nbWorkers = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--threads=")) { nbWorkers = (int)readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--memlimit=")) { memLimit = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--memory=")) { memLimit = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--memlimit-decompress=")) { memLimit = readU32FromChar(&argument); continue; }
|
||||
@@ -755,6 +759,7 @@ int main(int argCount, const char* argv[])
|
||||
if (longCommandWArg(&argument, "--stream-size=")) { streamSrcSize = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--target-compressed-block-size=")) { targetCBlockSize = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--size-hint=")) { srcSizeHint = readU32FromChar(&argument); continue; }
|
||||
if (longCommandWArg(&argument, "--output-dir-flat=")) { outDirName = argument; continue; }
|
||||
if (longCommandWArg(&argument, "--long")) {
|
||||
unsigned ldmWindowLog = 0;
|
||||
ldmFlag = 1;
|
||||
@@ -866,7 +871,7 @@ int main(int argCount, const char* argv[])
|
||||
#ifndef ZSTD_NOCOMPRESS
|
||||
/* compression Level */
|
||||
if ((*argument>='0') && (*argument<='9')) {
|
||||
dictCLevel = cLevel = readU32FromChar(&argument);
|
||||
dictCLevel = cLevel = (int)readU32FromChar(&argument);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -938,7 +943,7 @@ int main(int argCount, const char* argv[])
|
||||
case 'e':
|
||||
/* compression Level */
|
||||
argument++;
|
||||
cLevelLast = readU32FromChar(&argument);
|
||||
cLevelLast = (int)readU32FromChar(&argument);
|
||||
break;
|
||||
|
||||
/* Modify Nb Iterations (benchmark only) */
|
||||
@@ -964,7 +969,7 @@ int main(int argCount, const char* argv[])
|
||||
/* nb of threads (hidden option) */
|
||||
case 'T':
|
||||
argument++;
|
||||
nbWorkers = readU32FromChar(&argument);
|
||||
nbWorkers = (int)readU32FromChar(&argument);
|
||||
break;
|
||||
|
||||
/* Dictionary Selection level */
|
||||
@@ -1028,6 +1033,13 @@ int main(int argCount, const char* argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nextArgumentIsOutDirName) {
|
||||
nextArgumentIsOutDirName = 0;
|
||||
lastCommand = 0;
|
||||
outDirName = argument;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* add filename to list */
|
||||
filenameTable[filenameIdx++] = argument;
|
||||
}
|
||||
@@ -1094,16 +1106,16 @@ int main(int argCount, const char* argv[])
|
||||
#ifndef ZSTD_NOBENCH
|
||||
benchParams.blockSize = blockSize;
|
||||
benchParams.nbWorkers = nbWorkers;
|
||||
benchParams.realTime = setRealTimePrio;
|
||||
benchParams.realTime = (unsigned)setRealTimePrio;
|
||||
benchParams.nbSeconds = bench_nbSeconds;
|
||||
benchParams.ldmFlag = ldmFlag;
|
||||
benchParams.ldmMinMatch = g_ldmMinMatch;
|
||||
benchParams.ldmHashLog = g_ldmHashLog;
|
||||
benchParams.ldmMinMatch = (int)g_ldmMinMatch;
|
||||
benchParams.ldmHashLog = (int)g_ldmHashLog;
|
||||
if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) {
|
||||
benchParams.ldmBucketSizeLog = g_ldmBucketSizeLog;
|
||||
benchParams.ldmBucketSizeLog = (int)g_ldmBucketSizeLog;
|
||||
}
|
||||
if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) {
|
||||
benchParams.ldmHashRateLog = g_ldmHashRateLog;
|
||||
benchParams.ldmHashRateLog = (int)g_ldmHashRateLog;
|
||||
}
|
||||
benchParams.literalCompressionMode = literalCompressionMode;
|
||||
|
||||
@@ -1144,16 +1156,16 @@ int main(int argCount, const char* argv[])
|
||||
#ifndef ZSTD_NODICT
|
||||
ZDICT_params_t zParams;
|
||||
zParams.compressionLevel = dictCLevel;
|
||||
zParams.notificationLevel = g_displayLevel;
|
||||
zParams.notificationLevel = (unsigned)g_displayLevel;
|
||||
zParams.dictID = dictID;
|
||||
if (dict == cover) {
|
||||
int const optimize = !coverParams.k || !coverParams.d;
|
||||
coverParams.nbThreads = nbWorkers;
|
||||
coverParams.nbThreads = (unsigned)nbWorkers;
|
||||
coverParams.zParams = zParams;
|
||||
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, blockSize, NULL, &coverParams, NULL, optimize);
|
||||
} else if (dict == fastCover) {
|
||||
int const optimize = !fastCoverParams.k || !fastCoverParams.d;
|
||||
fastCoverParams.nbThreads = nbWorkers;
|
||||
fastCoverParams.nbThreads = (unsigned)nbWorkers;
|
||||
fastCoverParams.zParams = zParams;
|
||||
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, blockSize, NULL, NULL, &fastCoverParams, optimize);
|
||||
} else {
|
||||
@@ -1172,7 +1184,7 @@ int main(int argCount, const char* argv[])
|
||||
}
|
||||
|
||||
#ifndef ZSTD_NODECOMPRESS
|
||||
if (operation==zom_test) { outFileName=nulmark; FIO_setRemoveSrcFile(prefs, 0); } /* test mode */
|
||||
if (operation==zom_test) { FIO_setTestMode(prefs, 1); outFileName=nulmark; FIO_setRemoveSrcFile(prefs, 0); } /* test mode */
|
||||
#endif
|
||||
|
||||
/* No input filename ==> use stdin and stdout */
|
||||
@@ -1208,14 +1220,14 @@ int main(int argCount, const char* argv[])
|
||||
if (operation==zom_compress) {
|
||||
#ifndef ZSTD_NOCOMPRESS
|
||||
FIO_setNbWorkers(prefs, nbWorkers);
|
||||
FIO_setBlockSize(prefs, (U32)blockSize);
|
||||
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(prefs, g_overlapLog);
|
||||
FIO_setLdmFlag(prefs, ldmFlag);
|
||||
FIO_setLdmHashLog(prefs, g_ldmHashLog);
|
||||
FIO_setLdmMinMatch(prefs, g_ldmMinMatch);
|
||||
if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) FIO_setLdmBucketSizeLog(prefs, g_ldmBucketSizeLog);
|
||||
if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) FIO_setLdmHashRateLog(prefs, g_ldmHashRateLog);
|
||||
FIO_setAdaptiveMode(prefs, adapt);
|
||||
FIO_setBlockSize(prefs, (int)blockSize);
|
||||
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(prefs, (int)g_overlapLog);
|
||||
FIO_setLdmFlag(prefs, (unsigned)ldmFlag);
|
||||
FIO_setLdmHashLog(prefs, (int)g_ldmHashLog);
|
||||
FIO_setLdmMinMatch(prefs, (int)g_ldmMinMatch);
|
||||
if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) FIO_setLdmBucketSizeLog(prefs, (int)g_ldmBucketSizeLog);
|
||||
if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) FIO_setLdmHashRateLog(prefs, (int)g_ldmHashRateLog);
|
||||
FIO_setAdaptiveMode(prefs, (unsigned)adapt);
|
||||
FIO_setAdaptMin(prefs, adaptMin);
|
||||
FIO_setAdaptMax(prefs, adaptMax);
|
||||
FIO_setRsyncable(prefs, rsyncable);
|
||||
@@ -1229,7 +1241,7 @@ int main(int argCount, const char* argv[])
|
||||
if ((filenameIdx==1) && outFileName)
|
||||
operationResult = FIO_compressFilename(prefs, outFileName, filenameTable[0], dictFileName, cLevel, compressionParams);
|
||||
else
|
||||
operationResult = FIO_compressMultipleFilenames(prefs, filenameTable, filenameIdx, outFileName, suffix, dictFileName, cLevel, compressionParams);
|
||||
operationResult = FIO_compressMultipleFilenames(prefs, filenameTable, filenameIdx, outDirName, outFileName, suffix, dictFileName, cLevel, compressionParams);
|
||||
#else
|
||||
(void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; (void)targetCBlockSize; (void)streamSrcSize; (void)srcSizeHint; /* not used when ZSTD_NOCOMPRESS set */
|
||||
DISPLAY("Compression not supported \n");
|
||||
@@ -1247,7 +1259,7 @@ int main(int argCount, const char* argv[])
|
||||
if (filenameIdx==1 && outFileName)
|
||||
operationResult = FIO_decompressFilename(prefs, outFileName, filenameTable[0], dictFileName);
|
||||
else
|
||||
operationResult = FIO_decompressMultipleFilenames(prefs, filenameTable, filenameIdx, outFileName, dictFileName);
|
||||
operationResult = FIO_decompressMultipleFilenames(prefs, filenameTable, filenameIdx, outDirName, outFileName, dictFileName);
|
||||
#else
|
||||
DISPLAY("Decompression not supported \n");
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTDGREP" "1" "August 2019" "zstd 1.4.3" "User Commands"
|
||||
.TH "ZSTDGREP" "1" "October 2019" "zstd 1.4.4" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTDLESS" "1" "August 2019" "zstd 1.4.3" "User Commands"
|
||||
.TH "ZSTDLESS" "1" "October 2019" "zstd 1.4.4" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdless\fR \- view zstandard\-compressed files
|
||||
|
||||
Reference in New Issue
Block a user