diff options
author | Yann Collet <cyan@fb.com> | 2019-04-22 21:01:19 (GMT) |
---|---|---|
committer | Yann Collet <cyan@fb.com> | 2019-04-22 21:01:19 (GMT) |
commit | 0d4c885abb793b3bdb7ad6c815671e5847b53e6e (patch) | |
tree | 037697915b9eeae5cc86e18fd4a153164da49bee /programs/lz4io.c | |
parent | ae5cea9112479df58d226f79ae34c07bc636a04d (diff) | |
download | lz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.zip lz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.tar.gz lz4-0d4c885abb793b3bdb7ad6c815671e5847b53e6e.tar.bz2 |
refactored --list function
better handling of special conditions,
better scoping of variables.
Also : updated man page
Diffstat (limited to 'programs/lz4io.c')
-rw-r--r-- | programs/lz4io.c | 176 |
1 files changed, 97 insertions, 79 deletions
diff --git a/programs/lz4io.c b/programs/lz4io.c index 1e6efe1..e3eed93 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -1275,87 +1275,105 @@ typedef struct { LZ4F_frameInfo_t frameInfo; const char* fileName; unsigned long long fileSize; -} LZ4F_compFileInfo_t; - -#define LZ4F_INIT_FILEINFO { LZ4F_INIT_FRAMEINFO, NULL, 0ULL } - - -static int LZ4IO_getCompressedFileInfo(const char* input_filename, LZ4F_compFileInfo_t* cfinfo){ - const char *b, - *e; - char *t; - stat_t statbuf; - size_t readSize = LZ4F_HEADER_SIZE_MAX; - LZ4F_errorCode_t errorCode; - dRess_t ress; - /* Open file */ - FILE* const finput = LZ4IO_openSrcFile(input_filename); - if (finput==NULL) return 1; - - /* Get file size */ - if (!UTIL_getFileStat(input_filename, &statbuf)){ - EXM_THROW(60, "Can't stat file : %s", input_filename); - } - - cfinfo->fileSize = (unsigned long long)statbuf.st_size; - - /* Get basename without extension */ - b = strrchr(input_filename, '/'); - if (!b){ - b = strrchr(input_filename, '\\'); - } - if (b && b != input_filename){ - b++; - } else{ - b=input_filename; - } - e = strrchr(b, '.'); - - /* Allocate Memory */ - t = (char*)malloc( (size_t)(e-b+1) * sizeof(char)); - ress.srcBuffer = malloc(LZ4IO_dBufferSize); - if (!t || !ress.srcBuffer) - EXM_THROW(21, "Allocation error : not enough memory"); - strncpy(t, b, (e-b)); - t[e-b] = '\0'; - cfinfo->fileName = t; - - /* init */ - errorCode = LZ4F_createDecompressionContext(&ress.dCtx, LZ4F_VERSION); - if (LZ4F_isError(errorCode)) EXM_THROW(60, "Can't create LZ4F context : %s", LZ4F_getErrorName(errorCode)); - - if (!fread(ress.srcBuffer, readSize, 1, finput)){ - EXM_THROW(30, "Error reading %s ", input_filename); - } - LZ4F_getFrameInfo(ress.dCtx, &cfinfo->frameInfo, ress.srcBuffer, &readSize); - - /* Close input/free resources */ - fclose(finput); - free(ress.srcBuffer); - return 0; -} +} LZ4IO_cFileInfo_t; + +#define LZ4IO_INIT_CFILEINFO { LZ4F_INIT_FRAMEINFO, NULL, 0ULL } + + +/* This function is limited, + * it only works fine for a file consisting of a single valid frame. + * It will / may stop program execution if a single filename is wrong. + * It will not look at content beyond first frame header. + * + * Things to improve : + * - continue execution after an error, just report an error code, keep all memory clean + * - check the entire file for additional content after first frame + * + combine results from multiple frames, give total + * - Optional : + * + report nb of blocks, hence max. possible decompressed size (when not reported in header) + * + report block type (B4D, B7I, etc.) + */ +static int +LZ4IO_getCompressedFileInfo(LZ4IO_cFileInfo_t* cfinfo, const char* input_filename) +{ + /* Get file size */ + cfinfo->fileSize = UTIL_getFileSize(input_filename); /* returns 0 if cannot read information */ -int LZ4IO_displayCompressedFilesInfo(const char** inFileNames, const size_t ifnIdx){ - size_t idx; - int op_result=0; - double ratio; - DISPLAY("%16s\t%-20s\t%-20s\t%-10s\t%s\n","BlockChecksumFlag","Compressed", "Uncompressed", "Ratio", "Filename"); - for(idx=0; idx<ifnIdx; idx++){ - /* Get file info */ - LZ4F_compFileInfo_t cfinfo = LZ4F_INIT_FILEINFO; - op_result=LZ4IO_getCompressedFileInfo(inFileNames[idx], &cfinfo); - if (op_result != 0){ - DISPLAYLEVEL(1, "Failed to get frame info for file %s\n", inFileNames[idx]); - /* Don't bother trying to process any other file */ - break; + /* Get filename without path prefix */ + { const char* b = strrchr(input_filename, '/'); + if (!b) { + b = strrchr(input_filename, '\\'); + } + if (b && b != input_filename) { + b++; + } else { + b = input_filename; + } + cfinfo->fileName = b; } - if(cfinfo.frameInfo.contentSize){ - ratio = (double)cfinfo.fileSize / cfinfo.frameInfo.contentSize; - DISPLAY("%-16d\t%-20llu\t%-20llu\t%-8.4f\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize,cfinfo.frameInfo.contentSize, ratio, cfinfo.fileName); + + /* Read file and extract header */ + { size_t readSize = LZ4F_HEADER_SIZE_MAX; + void* buffer = malloc(readSize); + LZ4F_dctx* dctx; + + if (!buffer) EXM_THROW(21, "Allocation error : not enough memory"); + { LZ4F_errorCode_t const errorCode = + LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION); + if (LZ4F_isError(errorCode)) + EXM_THROW(60, "Can't create LZ4F context : %s", + LZ4F_getErrorName(errorCode)); + } + + { FILE* const finput = LZ4IO_openSrcFile(input_filename); + if (finput==NULL) return 1; + if (!fread(buffer, readSize, 1, finput)) { + EXM_THROW(30, "Error reading %s ", input_filename); + } + fclose(finput); + } + + { LZ4F_errorCode_t const errorCode = + LZ4F_getFrameInfo(dctx, &cfinfo->frameInfo, buffer, &readSize); + if (LZ4F_isError(errorCode)) + EXM_THROW(60, "Cannot interpret LZ4 frame : %s", + LZ4F_getErrorName(errorCode)); + } + + /* clean */ + free(buffer); + LZ4F_freeDecompressionContext(dctx); } - else{ - DISPLAY("%-16d\t%-20llu\t%-20s\t%-10s\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize, "-", "-", cfinfo.fileName); + + return 0; +} + +int LZ4IO_displayCompressedFilesInfo(const char** inFileNames, const size_t ifnIdx) +{ + size_t idx; + + DISPLAY("%16s\t%-20s\t%-20s\t%-10s\t%s\n", + "BlockChecksumFlag","Compressed", "Uncompressed", "Ratio", "Filename"); + + for (idx=0; idx<ifnIdx; idx++) { + /* Get file info */ + LZ4IO_cFileInfo_t cfinfo = LZ4IO_INIT_CFILEINFO; + int const op_result = LZ4IO_getCompressedFileInfo(&cfinfo, inFileNames[idx]); + if (op_result != 0) { + DISPLAYLEVEL(1, "Failed to get frame info for file %s\n", inFileNames[idx]); + /* Don't bother processing any more file */ + return 1; + } + if (cfinfo.frameInfo.contentSize) { + double const ratio = (double)cfinfo.fileSize / cfinfo.frameInfo.contentSize; + DISPLAY("%-16d\t%-20llu\t%-20llu\t%-8.4f\t%s\n", + cfinfo.frameInfo.blockChecksumFlag, cfinfo.fileSize, + cfinfo.frameInfo.contentSize, ratio, cfinfo.fileName); + } else { + DISPLAY("%-16d\t%-20llu\t%-20s\t%-10s\t%s\n", + cfinfo.frameInfo.blockChecksumFlag, cfinfo.fileSize, + "-", "-", cfinfo.fileName); + } } - } - return op_result; + return 0; } |