diff options
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r-- | programs/lz4io.c | 152 |
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); |