From 55ab3c48aef50fbf56203eb15fd37d84be5cbd46 Mon Sep 17 00:00:00 2001 From: gabrielstedman Date: Sat, 20 Apr 2019 22:06:10 +0100 Subject: [PATCH] Add --list option to display compressed file information. --- programs/lz4cli.c | 34 ++++++++++++++++++++++++++++++++-- programs/lz4io.c | 40 +++++++++++++++++++++++++++++++++++++++- programs/lz4io.h | 11 +++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/programs/lz4cli.c b/programs/lz4cli.c index 8bd7042..adfabc3 100644 --- a/programs/lz4cli.c +++ b/programs/lz4cli.c @@ -40,6 +40,7 @@ #include /* exit, calloc, free */ #include /* strcmp, strlen */ #include "bench.h" /* BMK_benchFile, BMK_SetNbIterations, BMK_SetBlocksize, BMK_SetPause */ +#include "lz4frame.h" #include "lz4io.h" /* LZ4IO_compressFilename, LZ4IO_decompressFilename, LZ4IO_compressMultipleFilenames */ #include "lz4hc.h" /* LZ4HC_CLEVEL_MAX */ #include "lz4.h" /* LZ4_VERSION_STRING */ @@ -141,6 +142,7 @@ static int usage_advanced(const char* exeName) DISPLAY( " -BX : enable block checksum (default:disabled) \n"); DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled) \n"); DISPLAY( "--content-size : compressed frame includes original size (default:not present)\n"); + DISPLAY( "--list : list information about .lz4 files. Only useful if compressed with --content-size flag.\n"); DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n"); DISPLAY( "--favor-decSpeed: compressed files decompress faster, but are less compressed \n"); DISPLAY( "--fast[=#]: switch to ultra fast compression level (default: %i)\n", 1); @@ -286,7 +288,7 @@ static int longCommandWArg(const char** stringPtr, const char* longCommand) return result; } -typedef enum { om_auto, om_compress, om_decompress, om_test, om_bench } operationMode_e; +typedef enum { om_auto, om_compress, om_decompress, om_test, om_bench, om_list } operationMode_e; /** determineOpMode() : * auto-determine operation mode, based on input filename extension @@ -383,6 +385,7 @@ int main(int argc, const char** argv) if (!strcmp(argument, "--no-frame-crc")) { LZ4IO_setStreamChecksumMode(prefs, 0); continue; } if (!strcmp(argument, "--content-size")) { LZ4IO_setContentSize(prefs, 1); continue; } if (!strcmp(argument, "--no-content-size")) { LZ4IO_setContentSize(prefs, 0); continue; } + if (!strcmp(argument, "--list")) { mode = om_list; continue; } if (!strcmp(argument, "--sparse")) { LZ4IO_setSparseFile(prefs, 2); continue; } if (!strcmp(argument, "--no-sparse")) { LZ4IO_setSparseFile(prefs, 0); continue; } if (!strcmp(argument, "--favor-decSpeed")) { LZ4IO_favorDecSpeed(prefs, 1); continue; } @@ -705,7 +708,34 @@ int main(int argc, const char** argv) operationResult = LZ4IO_decompressMultipleFilenames(prefs, inFileNames, ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION); else operationResult = DEFAULT_DECOMPRESSOR(prefs, input_filename, output_filename); - } else { /* compression is default action */ + } else if (mode == om_list){ + LZ4F_compFileInfo_t cfinfo; + if(!multiple_inputs){ + inFileNames[ifnIdx++] = input_filename; + } + DISPLAY("%16s\t%-20s\t%-20s\t%-10s\t%s\n","BlockChecksumFlag","Compressed", "Uncompressed", "Ratio", "Filename"); + for(i=0; i /* clock */ #include /* stat64 */ #include /* stat64 */ -#include "lz4io.h" #include "lz4.h" /* still required for legacy format */ #include "lz4hc.h" /* still required for legacy format */ #define LZ4F_STATIC_LINKING_ONLY #include "lz4frame.h" +#include "lz4io.h" /***************************** @@ -1265,3 +1265,41 @@ int LZ4IO_decompressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** i free(outFileName); return missingFiles + skippedFiles; } + +size_t LZ4IO_getCompressedFileInfo(const char* input_filename, LZ4F_compFileInfo_t* cfinfo){ + /* Get file size */ + stat_t statbuf; + if (!UTIL_getFileStat(input_filename, &statbuf)){ + EXM_THROW(60, "Can't stat file : %s", input_filename); + } + cfinfo->fileSize = statbuf.st_size; + /* Get basename without extension */ + const char *b = strrchr(input_filename, '/'); + if (b && b != input_filename){ + b++; + } else{ + b=input_filename; + } + const char *e = strrchr(b, '.'); + cfinfo->fileName = malloc( (e-b+1) * sizeof(char)); + strncpy(cfinfo->fileName, b, (e-b)); + cfinfo->fileName[e-b] = '\0'; + /* init */ + dRess_t ress; + LZ4F_errorCode_t const errorCode = LZ4F_createDecompressionContext(&ress.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; + /* Allocate Memory */ + ress.srcBuffer = malloc(LZ4IO_dBufferSize); + size_t readSize = LZ4F_HEADER_SIZE_MAX; + if (!fread(ress.srcBuffer, readSize, 1, finput)){ + EXM_THROW(30, "Error reading %s ", input_filename); + } + cfinfo->frameInfo = (LZ4F_frameInfo_t) LZ4F_INIT_FRAMEINFO; + LZ4F_getFrameInfo(ress.dCtx, &cfinfo->frameInfo, ress.srcBuffer, &readSize); + /* Close input/free resources */ + fclose(finput); + free(ress.srcBuffer); + return readSize; +} diff --git a/programs/lz4io.h b/programs/lz4io.h index 54d49be..bf1fa76 100644 --- a/programs/lz4io.h +++ b/programs/lz4io.h @@ -54,6 +54,14 @@ static const char nulmark[] = "/dev/null"; typedef struct LZ4IO_prefs_s LZ4IO_prefs_t; +typedef struct { + LZ4F_frameInfo_t frameInfo; + char* fileName; + unsigned long long fileSize; + double compressionRatio; +} LZ4F_compFileInfo_t; + + LZ4IO_prefs_t* LZ4IO_defaultPreferences(void); void LZ4IO_freePreferences(LZ4IO_prefs_t* const prefs); @@ -116,6 +124,9 @@ int LZ4IO_setSparseFile(LZ4IO_prefs_t* const prefs, int enable); /* Default setting : 0 == no content size present in frame header */ int LZ4IO_setContentSize(LZ4IO_prefs_t* const prefs, int enable); +/* */ +size_t LZ4IO_getCompressedFileInfo(const char* input_filename, LZ4F_compFileInfo_t* cfinfo); + /* Default setting : 0 == src file preserved */ void LZ4IO_setRemoveSrcFile(LZ4IO_prefs_t* const prefs, unsigned flag); -- 2.7.4