summaryrefslogtreecommitdiffstats
path: root/programs/lz4io.c
diff options
context:
space:
mode:
authorPrzemyslaw Skibinski <inikep@gmail.com>2016-11-10 07:42:56 (GMT)
committerPrzemyslaw Skibinski <inikep@gmail.com>2016-11-10 07:42:56 (GMT)
commit6a160b72e34b14da63101050889c4a04fc9c9c23 (patch)
tree474c3b4a34d70260b459b44e5306e3d8040e6e3c /programs/lz4io.c
parent063b4d92e10bb6b430e515e5cdd36b64fce6a01a (diff)
parent924f00c86ce9075d520967c893dbfbe13a7bf073 (diff)
downloadlz4-6a160b72e34b14da63101050889c4a04fc9c9c23.zip
lz4-6a160b72e34b14da63101050889c4a04fc9c9c23.tar.gz
lz4-6a160b72e34b14da63101050889c4a04fc9c9c23.tar.bz2
Merge remote-tracking branch 'refs/remotes/lz4/dev' into dev
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r--programs/lz4io.c152
1 files changed, 95 insertions, 57 deletions
diff --git a/programs/lz4io.c b/programs/lz4io.c
index 73957e1..61d8009 100644
--- a/programs/lz4io.c
+++ b/programs/lz4io.c
@@ -245,51 +245,65 @@ static int LZ4IO_GetBlockSize_FromBlockId (int id) { return (1 << (8 + (2 * id))
static int LZ4IO_isSkippableMagicNumber(unsigned int magic) { return (magic & LZ4IO_SKIPPABLEMASK) == LZ4IO_SKIPPABLE0; }
-static int LZ4IO_getFiles(const char* input_filename, const char* output_filename, FILE** pfinput, FILE** pfoutput)
+/** LZ4IO_openSrcFile() :
+ * condition : `dstFileName` must be non-NULL.
+ * @result : FILE* to `dstFileName`, or NULL if it fails */
+static FILE* LZ4IO_openSrcFile(const char* srcFileName)
{
- if (!strcmp (input_filename, stdinmark)) {
- DISPLAYLEVEL(4,"Using stdin for input \n");
- *pfinput = stdin;
+ FILE* f;
+
+ if (!strcmp (srcFileName, stdinmark)) {
+ DISPLAYLEVEL(4,"Using stdin for input\n");
+ f = stdin;
SET_BINARY_MODE(stdin);
} else {
- *pfinput = fopen(input_filename, "rb");
+ f = fopen(srcFileName, "rb");
+ if ( f==NULL ) DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno));
}
- if ( *pfinput==0 ) {
- DISPLAYLEVEL(1, "Unable to access file for processing: %s \n", input_filename);
- return 1;
- }
+ return f;
+}
+
+/** FIO_openDstFile() :
+ * condition : `dstFileName` must be non-NULL.
+ * @result : FILE* to `dstFileName`, or NULL if it fails */
+static FILE* LZ4IO_openDstFile(const char* dstFileName)
+{
+ FILE* f;
- if (!strcmp (output_filename, stdoutmark)) {
- DISPLAYLEVEL(4,"Using stdout for output \n");
- *pfoutput = stdout;
+ if (!strcmp (dstFileName, stdoutmark)) {
+ DISPLAYLEVEL(4,"Using stdout for output\n");
+ f = stdout;
SET_BINARY_MODE(stdout);
if (g_sparseFileSupport==1) {
g_sparseFileSupport = 0;
DISPLAYLEVEL(4, "Sparse File Support is automatically disabled on stdout ; try --sparse \n");
}
} else {
- /* Check if destination file already exists */
- *pfoutput=0;
- if (strcmp(output_filename, nulmark)) *pfoutput = fopen( output_filename, "rb" );
- if (*pfoutput!=0) {
- fclose(*pfoutput);
- if (!g_overwrite) {
- int ch = 'Y';
- DISPLAYLEVEL(2, "Warning : %s already exists\n", output_filename);
- if ((g_displayLevel <= 1) || (*pfinput == stdin))
- EXM_THROW(11, "Operation aborted : %s already exists", output_filename); /* No interaction possible */
- DISPLAYLEVEL(2, "Overwrite ? (Y/n) : ");
- while((ch = getchar()) != '\n' && ch != EOF) /* flush integrated */
- if ((ch!='Y') && (ch!='y')) EXM_THROW(12, "No. Operation aborted : %s already exists", output_filename);
- }
- }
- *pfoutput = fopen( output_filename, "wb" );
+ if (!g_overwrite && strcmp (dstFileName, nulmark)) { /* Check if destination file already exists */
+ f = fopen( dstFileName, "rb" );
+ if (f != NULL) { /* dest exists, prompt for overwrite authorization */
+ fclose(f);
+ if (g_displayLevel <= 1) { /* No interaction possible */
+ DISPLAY("zstd: %s already exists; not overwritten \n", dstFileName);
+ return NULL;
+ }
+ DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName);
+ { int ch = getchar();
+ if ((ch!='Y') && (ch!='y')) {
+ DISPLAY(" not overwritten \n");
+ return NULL;
+ }
+ while ((ch!=EOF) && (ch!='\n')) ch = getchar(); /* flush rest of input line */
+ } } }
+ f = fopen( dstFileName, "wb" );
+ if (f==NULL) DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
}
- if (*pfoutput==0) EXM_THROW(13, "Pb opening %s", output_filename);
+ /* sparse file */
+ if (f && g_sparseFileSupport) { SET_SPARSE_FILE_MODE(foutput); }
- return 0;
+ return f;
}
@@ -333,8 +347,10 @@ int LZ4IO_compressFilename_Legacy(const char* input_filename, const char* output
clock_t const start = clock();
if (compressionlevel < 3) compressionFunction = LZ4IO_LZ4_compress; else compressionFunction = LZ4_compress_HC;
- if (LZ4IO_getFiles(input_filename, output_filename, &finput, &foutput))
- EXM_THROW(20, "File error");
+ finput = LZ4IO_openSrcFile(input_filename);
+ if (finput == NULL) EXM_THROW(20, "%s : open file error ", input_filename);
+ foutput = LZ4IO_openDstFile(output_filename);
+ if (foutput == NULL) { fclose(finput); EXM_THROW(20, "%s : open file error ", input_filename); }
/* Allocate Memory */
in_buff = (char*)malloc(LEGACY_BLOCKSIZE);
@@ -446,10 +462,12 @@ static int LZ4IO_compressFilename_extRess(cRess_t ress, const char* srcFileName,
LZ4F_preferences_t prefs;
/* Init */
+ srcFile = LZ4IO_openSrcFile(srcFileName);
+ if (srcFile == NULL) return 1;
+ dstFile = LZ4IO_openDstFile(dstFileName);
+ if (dstFile == NULL) { fclose(srcFile); return 1; }
memset(&prefs, 0, sizeof(prefs));
- /* File check */
- if (LZ4IO_getFiles(srcFileName, dstFileName, &srcFile, &dstFile)) return 1;
/* Set compression parameters */
prefs.autoFlush = 1;
@@ -670,7 +688,7 @@ static unsigned LZ4IO_fwriteSparse(FILE* file, const void* buffer, size_t buffer
static void LZ4IO_fwriteSparseEnd(FILE* file, unsigned storedSkips)
{
- if (storedSkips>0) { /* implies g_sparseFileSupport */
+ if (storedSkips>0) { /* implies g_sparseFileSupport>0 */
int const seekResult = fseek(file, storedSkips-1, SEEK_CUR);
if (seekResult != 0) EXM_THROW(69, "Final skip error (sparse file)\n");
{ const char lastZeroByte[1] = { 0 };
@@ -739,6 +757,7 @@ typedef struct {
size_t srcBufferSize;
void* dstBuffer;
size_t dstBufferSize;
+ FILE* dstFile;
LZ4F_decompressionContext_t dCtx;
} dRess_t;
@@ -805,7 +824,7 @@ static unsigned long long LZ4IO_decompressLZ4F(dRess_t ress, FILE* srcFile, FILE
/* Write Block */
if (decodedBytes) {
- storedSkips = LZ4IO_fwriteSparse(dstFile, ress.dstBuffer, decodedBytes, storedSkips);
+ if (!g_testMode) storedSkips = LZ4IO_fwriteSparse(dstFile, ress.dstBuffer, decodedBytes, storedSkips);
filesize += decodedBytes;
DISPLAYUPDATE(2, "\rDecompressed : %u MB ", (unsigned)(filesize>>20));
}
@@ -816,7 +835,7 @@ static unsigned long long LZ4IO_decompressLZ4F(dRess_t ress, FILE* srcFile, FILE
/* can be out because readSize == 0, which could be an fread() error */
if (ferror(srcFile)) EXM_THROW(67, "Read error");
- LZ4IO_fwriteSparseEnd(dstFile, storedSkips);
+ if (!g_testMode) LZ4IO_fwriteSparseEnd(dstFile, storedSkips);
if (nextToLoad!=0) EXM_THROW(68, "Unfinished stream");
return filesize;
@@ -880,7 +899,7 @@ static unsigned long long selectDecoder(dRess_t ress, FILE* finput, FILE* foutpu
g_magicRead = 0;
} else {
size_t const nbReadBytes = fread(MNstore, 1, MAGICNUMBER_SIZE, finput);
- if (nbReadBytes==0) return ENDOFSTREAM; /* EOF */
+ if (nbReadBytes==0) { nbCalls = 0; return ENDOFSTREAM; } /* EOF */
if (nbReadBytes != MAGICNUMBER_SIZE) EXM_THROW(40, "Unrecognized header : Magic Number unreadable");
magicNumber = LZ4IO_readLE32(MNstore); /* Little Endian format */
}
@@ -904,8 +923,10 @@ static unsigned long long selectDecoder(dRess_t ress, FILE* finput, FILE* foutpu
EXTENDED_FORMAT; /* macro extension for custom formats */
default:
if (nbCalls == 1) { /* just started */
- if (!g_testMode && g_overwrite)
+ if (!g_testMode && g_overwrite) {
+ nbCalls = 0;
return LZ4IO_passThrough(finput, foutput, MNstore);
+ }
EXM_THROW(44,"Unrecognized header : file cannot be decoded"); /* Wrong magic number at the beginning of 1st stream */
}
DISPLAYLEVEL(2, "Stream followed by undecodable data\n");
@@ -914,18 +935,15 @@ static unsigned long long selectDecoder(dRess_t ress, FILE* finput, FILE* foutpu
}
-static int LZ4IO_decompressFile_extRess(dRess_t ress, const char* input_filename, const char* output_filename)
+static int LZ4IO_decompressSrcFile(dRess_t ress, const char* input_filename, const char* output_filename)
{
+ FILE* const foutput = ress.dstFile;
unsigned long long filesize = 0, decodedSize=0;
FILE* finput;
- FILE* foutput;
/* Init */
- if (LZ4IO_getFiles(input_filename, output_filename, &finput, &foutput))
- return 1;
-
- /* sparse file */
- if (g_sparseFileSupport) { SET_SPARSE_FILE_MODE(foutput); }
+ finput = LZ4IO_openSrcFile(input_filename);
+ if (finput==NULL) return 1;
/* Loop over multiple streams */
do {
@@ -936,6 +954,29 @@ static int LZ4IO_decompressFile_extRess(dRess_t ress, const char* input_filename
/* Close */
fclose(finput);
+
+ if (g_removeSrcFile) { if (remove(input_filename)) EXM_THROW(45, "Remove error : %s: %s", input_filename, strerror(errno)); } /* remove source file : --rm */
+
+ /* Final Status */
+ DISPLAYLEVEL(2, "\r%79s\r", "");
+ DISPLAYLEVEL(2, "%-20.20s : decoded %llu bytes \n", input_filename, filesize);
+ (void)output_filename;
+
+ return 0;
+}
+
+
+static int LZ4IO_decompressDstFile(dRess_t ress, const char* input_filename, const char* output_filename)
+{
+ FILE* foutput;
+
+ /* Init */
+ foutput = LZ4IO_openDstFile(output_filename);
+ if (foutput==NULL) return 1; /* failure */
+
+ ress.dstFile = foutput;
+ LZ4IO_decompressSrcFile(ress, input_filename, output_filename);
+
fclose(foutput);
/* Copy owner, file permissions and modification time */
@@ -944,12 +985,6 @@ static int LZ4IO_decompressFile_extRess(dRess_t ress, const char* input_filename
UTIL_setFileStat(output_filename, &statbuf);
}
- if (g_removeSrcFile) { if (remove(input_filename)) EXM_THROW(45, "Remove error : %s: %s", input_filename, strerror(errno)); } /* remove source file : --rm */
-
- /* Final Status */
- DISPLAYLEVEL(2, "\r%79s\r", "");
- DISPLAYLEVEL(2, "Successfully decoded %llu bytes \n", filesize);
-
return 0;
}
@@ -959,7 +994,7 @@ int LZ4IO_decompressFilename(const char* input_filename, const char* output_file
dRess_t const ress = LZ4IO_createDResources();
clock_t const start = clock();
- int const missingFiles = LZ4IO_decompressFile_extRess(ress, input_filename, output_filename);
+ int const missingFiles = LZ4IO_decompressDstFile(ress, input_filename, output_filename);
{ clock_t const end = clock();
double const seconds = (double)(end - start) / CLOCKS_PER_SEC;
@@ -971,7 +1006,6 @@ int LZ4IO_decompressFilename(const char* input_filename, const char* output_file
}
-#define MAXSUFFIXSIZE 8
int LZ4IO_decompressMultipleFilenames(const char** inFileNamesTable, int ifntSize, const char* suffix)
{
int i;
@@ -980,13 +1014,18 @@ int LZ4IO_decompressMultipleFilenames(const char** inFileNamesTable, int ifntSiz
char* outFileName = (char*)malloc(FNSPACE);
size_t ofnSize = FNSPACE;
size_t const suffixSize = strlen(suffix);
- dRess_t const ress = LZ4IO_createDResources();
+ dRess_t ress = LZ4IO_createDResources();
if (outFileName==NULL) exit(1); /* not enough memory */
+ ress.dstFile = LZ4IO_openDstFile(stdoutmark);
for (i=0; i<ifntSize; i++) {
size_t const ifnSize = strlen(inFileNamesTable[i]);
const char* const suffixPtr = inFileNamesTable[i] + ifnSize - suffixSize;
+ if (!strcmp(suffix, stdoutmark)) {
+ missingFiles += LZ4IO_decompressSrcFile(ress, inFileNamesTable[i], stdoutmark);
+ continue;
+ }
if (ofnSize <= ifnSize-suffixSize+1) { free(outFileName); ofnSize = ifnSize + 20; outFileName = (char*)malloc(ofnSize); if (outFileName==NULL) exit(1); }
if (ifnSize <= suffixSize || strcmp(suffixPtr, suffix) != 0) {
DISPLAYLEVEL(1, "File extension doesn't match expected LZ4_EXTENSION (%4s); will not process file: %s\n", suffix, inFileNamesTable[i]);
@@ -995,8 +1034,7 @@ int LZ4IO_decompressMultipleFilenames(const char** inFileNamesTable, int ifntSiz
}
memcpy(outFileName, inFileNamesTable[i], ifnSize - suffixSize);
outFileName[ifnSize-suffixSize] = '\0';
-
- missingFiles += LZ4IO_decompressFile_extRess(ress, inFileNamesTable[i], outFileName);
+ missingFiles += LZ4IO_decompressDstFile(ress, inFileNamesTable[i], outFileName);
}
LZ4IO_freeDResources(ress);