FR #598 Improve initial design, test mallocs, support C90.
authorgabrielstedman <gabriwinter@gmail.com>
Sun, 21 Apr 2019 16:43:57 +0000 (17:43 +0100)
committergabrielstedman <gabriwinter@gmail.com>
Sun, 21 Apr 2019 17:20:40 +0000 (18:20 +0100)
programs/lz4.1.md
programs/lz4cli.c
programs/lz4io.c
programs/lz4io.h

index 10449a0..7db9f19 100644 (file)
@@ -114,6 +114,11 @@ only the latest one will be applied.
 * `-b#`:
   Benchmark mode, using `#` compression level.
 
+* `--list`:
+  List mode.
+  Lists information about .lz4 files. 
+  Useful if compressed with --content-size flag.
+
 ### Operation modifiers
 
 * `-#`:
@@ -161,6 +166,7 @@ only the latest one will be applied.
   Multiple input files.
   Compressed file names will be appended a `.lz4` suffix.
   This mode also reduces notification level.
+  Can also be used to list multiple files.
   `lz4 -m` has a behavior equivalent to `gzip -k`
   (it preserves source files by default).
 
index 54d93f1..23c4be7 100644 (file)
@@ -142,7 +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( "--list  : lists information about .lz4 files. 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);
@@ -709,31 +709,11 @@ int main(int argc, const char** argv)
         else
             operationResult = DEFAULT_DECOMPRESSOR(prefs, input_filename, output_filename);
     } 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(unsigned int j=0; j<ifnIdx; j++){
-            /* Get file info */
-            if (!LZ4IO_getCompressedFileInfo(inFileNames[j], &cfinfo)){
-                DISPLAYLEVEL(1, "Failed to get frame info.\n");
-                if (!multiple_inputs){
-                    return 1;
-                }
-                continue;
-            }
-            if(cfinfo.frameInfo.contentSize){
-                double 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);
-            }
-            free(cfinfo.fileName);
-        }
-        free(inFileNames);
-        return 0;
+        operationResult = LZ4IO_getCompressedFilesInfo(inFileNames, ifnIdx);
+        inFileNames=NULL;
     } else {
        /* compression is default action */
         if (legacy_format) {
index e62e56f..2e38d2f 100644 (file)
@@ -1266,40 +1266,86 @@ int LZ4IO_decompressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** i
     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);
+int LZ4IO_getCompressedFilesInfo(const char** inFileNames, const size_t ifnIdx){
+  size_t idx;
+  int op_result=0;
+  LZ4F_compFileInfo_t cfinfo = (LZ4F_compFileInfo_t) LZ4F_INIT_FILEINFO;
+  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 */
+    op_result&=LZ4IO_getCompressedFileInfo(inFileNames[idx], &cfinfo);
+    if (op_result != 0){
+        DISPLAYLEVEL(1, "Failed to get frame info for file %s\n", inFileNames[idx]);
+        if (ifnIdx < 2){
+            return 1;
+        }
+        continue;
     }
-    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;
+    if(cfinfo.frameInfo.contentSize){
+        DISPLAY("%-16d\t%-20llu\t%-20llu\t%-8.4f\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize,cfinfo.frameInfo.contentSize, cfinfo.ratio, cfinfo.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);
+    else{
+        DISPLAY("%-16d\t%-20llu\t%-20s\t%-10s\t%s\n",cfinfo.frameInfo.blockChecksumFlag,cfinfo.fileSize, "-", "-", cfinfo.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;
+  }
+  return op_result;
+}
+
+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 0;
+  *cfinfo = (LZ4F_compFileInfo_t) LZ4F_INIT_FILEINFO;
+  /* Get file size */
+  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 */
+  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 = malloc( (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);
+  }
+  // cfinfo->frameInfo = (LZ4F_frameInfo_t) LZ4F_INIT_FRAMEINFO;
+  LZ4F_getFrameInfo(ress.dCtx, &cfinfo->frameInfo, ress.srcBuffer, &readSize);
+  if(cfinfo->frameInfo.contentSize){
+    cfinfo->ratio = (double)cfinfo->fileSize / cfinfo->frameInfo.contentSize;
+  } else {
+    cfinfo->ratio = -1;
+  }
+
+  /* Close input/free resources */
+  fclose(finput);
+  free(ress.srcBuffer);
+  return 0;
 }
index bf1fa76..707f233 100644 (file)
@@ -56,11 +56,12 @@ typedef struct LZ4IO_prefs_s LZ4IO_prefs_t;
 
 typedef struct {
   LZ4F_frameInfo_t frameInfo;
-  char* fileName;
+  const char* fileName;
   unsigned long long fileSize;
-  double compressionRatio;
+  double ratio;
 } LZ4F_compFileInfo_t;
 
+#define LZ4F_INIT_FILEINFO   { (LZ4F_frameInfo_t) LZ4F_INIT_FRAMEINFO, NULL, 0ULL, -1.f }
 
 LZ4IO_prefs_t* LZ4IO_defaultPreferences(void);
 void LZ4IO_freePreferences(LZ4IO_prefs_t* const prefs);
@@ -124,8 +125,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);
+int LZ4IO_getCompressedFilesInfo(const char** inFileNames,const size_t ifnIdx);
+
+int 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);