fixed lz4 -m -c
authorYann Collet <cyan@fb.com>
Fri, 12 Apr 2019 22:17:48 +0000 (15:17 -0700)
committerYann Collet <cyan@fb.com>
Fri, 12 Apr 2019 22:17:48 +0000 (15:17 -0700)
can compress multiple files into stdout

programs/lz4cli.c
programs/lz4io.c
programs/lz4io.h
tests/Makefile

index 9a7aeb4..8bd7042 100644 (file)
@@ -711,7 +711,7 @@ int main(int argc, const char** argv)
             LZ4IO_compressFilename_Legacy(prefs, input_filename, output_filename, cLevel);
         } else {
             if (multiple_inputs)
-                operationResult = LZ4IO_compressMultipleFilenames(prefs, inFileNames, ifnIdx, LZ4_EXTENSION, cLevel);
+                operationResult = LZ4IO_compressMultipleFilenames(prefs, inFileNames, ifnIdx, !strcmp(output_filename,stdoutmark) ? stdoutmark : LZ4_EXTENSION, cLevel);
             else
                 operationResult = DEFAULT_COMPRESSOR(prefs, input_filename, output_filename, cLevel);
         }
index 6bb6c48..bf412da 100644 (file)
@@ -121,8 +121,8 @@ struct LZ4IO_prefs_s {
   int contentSizeFlag;
   int useDictionary;
   unsigned favorDecSpeed;
-  char const* dictionaryFilename;
-  U32 removeSrcFile;
+  const char* dictionaryFilename;
+  int removeSrcFile;
 };
 
 /**************************************
@@ -323,11 +323,12 @@ static FILE* LZ4IO_openSrcFile(const char* srcFileName)
 }
 
 /** FIO_openDstFile() :
- * condition : `dstFileName` must be non-NULL.
+ *  condition : `dstFileName` must be non-NULL.
  * @result : FILE* to `dstFileName`, or NULL if it fails */
 static FILE* LZ4IO_openDstFile(LZ4IO_prefs_t* const prefs, const char* dstFileName)
 {
     FILE* f;
+    assert(dstFileName != NULL);
 
     if (!strcmp (dstFileName, stdoutmark)) {
         DISPLAYLEVEL(4,"Using stdout for output\n");
@@ -595,7 +596,10 @@ static void LZ4IO_freeCResources(cRess_t ress)
  * result : 0 : compression completed correctly
  *          1 : missing or pb opening srcFileName
  */
-static int LZ4IO_compressFilename_extRess(LZ4IO_prefs_t* const io_prefs, cRess_t ress, const char* srcFileName, const char* dstFileName, int compressionLevel)
+static int
+LZ4IO_compressFilename_extRess(LZ4IO_prefs_t* const io_prefs, cRess_t ress,
+                               const char* srcFileName, const char* dstFileName,
+                               int compressionLevel)
 {
     unsigned long long filesize = 0;
     unsigned long long compressedfilesize = 0;
@@ -691,9 +695,9 @@ static int LZ4IO_compressFilename_extRess(LZ4IO_prefs_t* const io_prefs, cRess_t
         compressedfilesize += headerSize;
     }
 
-    /* Release files */
+    /* Release file handlers */
     fclose (srcFile);
-    fclose (dstFile);
+    if (strcmp(dstFileName,stdoutmark)) fclose (dstFile);   /* do not close stdout */
 
     /* Copy owner, file permissions and modification time */
     {   stat_t statbuf;
@@ -744,7 +748,10 @@ int LZ4IO_compressFilename(LZ4IO_prefs_t* const prefs, const char* srcFileName,
 
 
 #define FNSPACE 30
-int LZ4IO_compressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** inFileNamesTable, int ifntSize, const char* suffix, int compressionLevel)
+int LZ4IO_compressMultipleFilenames(LZ4IO_prefs_t* const prefs,
+                              const char** inFileNamesTable, int ifntSize,
+                              const char* suffix,
+                              int compressionLevel)
 {
     int i;
     int missed_files = 0;
@@ -759,11 +766,21 @@ int LZ4IO_compressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** inF
     /* loop on each file */
     for (i=0; i<ifntSize; i++) {
         size_t const ifnSize = strlen(inFileNamesTable[i]);
-        if (ofnSize <= ifnSize+suffixSize+1) { free(dstFileName); ofnSize = ifnSize + 20; dstFileName = (char*)malloc(ofnSize); if (dstFileName==NULL) { LZ4IO_freeCResources(ress); return ifntSize; } }
+        if (ofnSize <= ifnSize+suffixSize+1) {
+            free(dstFileName);
+            ofnSize = ifnSize + 20;
+            dstFileName = (char*)malloc(ofnSize);
+            if (dstFileName==NULL) {
+                LZ4IO_freeCResources(ress);
+                return ifntSize;
+        }   }
         strcpy(dstFileName, inFileNamesTable[i]);
         strcat(dstFileName, suffix);
 
-        missed_files += LZ4IO_compressFilename_extRess(prefs, ress, inFileNamesTable[i], dstFileName, compressionLevel);
+        missed_files += LZ4IO_compressFilename_extRess(prefs, ress,
+            inFileNamesTable[i],
+            !strcmp(suffix,stdoutmark) ? stdoutmark : dstFileName,
+            compressionLevel);
     }
 
     /* Close & Free */
@@ -778,13 +795,14 @@ int LZ4IO_compressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** inF
 /* ********************** LZ4 file-stream Decompression **************** */
 /* ********************************************************************* */
 
+/* It's presumed that s points to a memory space of size >= 4 */
 static unsigned LZ4IO_readLE32 (const void* s)
 {
     const unsigned char* const srcPtr = (const unsigned char*)s;
     unsigned value32 = srcPtr[0];
-    value32 += (srcPtr[1]<<8);
-    value32 += (srcPtr[2]<<16);
-    value32 += ((unsigned)srcPtr[3])<<24;
+    value32 += (unsigned)srcPtr[1] <<  8;
+    value32 += (unsigned)srcPtr[2] << 16;
+    value32 += (unsigned)srcPtr[3] << 24;
     return value32;
 }
 
index 0c28784..54d49be 100644 (file)
@@ -57,13 +57,16 @@ typedef struct LZ4IO_prefs_s LZ4IO_prefs_t;
 LZ4IO_prefs_t* LZ4IO_defaultPreferences(void);
 void LZ4IO_freePreferences(LZ4IO_prefs_t* const prefs);
 
+
 /* ************************************************** */
 /* ****************** Functions ********************* */
 /* ************************************************** */
 
+/* if output_filename == stdoutmark, writes to stdout */
 int LZ4IO_compressFilename(LZ4IO_prefs_t* const prefs, const char* input_filename, const char* output_filename, int compressionlevel);
 int LZ4IO_decompressFilename(LZ4IO_prefs_t* const prefs, const char* input_filename, const char* output_filename);
 
+/* if suffix == stdoutmark, writes to stdout */
 int LZ4IO_compressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** inFileNamesTable, int ifntSize, const char* suffix, int compressionlevel);
 int LZ4IO_decompressMultipleFilenames(LZ4IO_prefs_t* const prefs, const char** inFileNamesTable, int ifntSize, const char* suffix);
 
index 8e154f7..8442ab8 100644 (file)
@@ -232,11 +232,20 @@ test-lz4-multiple: lz4 datagen
        @./datagen -s2 -g100K > tmp-tlm2 2> $(VOID)
        @./datagen -s3 -g1M   > tmp-tlm3 2> $(VOID)
        $(LZ4) -f -m tmp-tlm*
-       ls -ls tmp-tlm*
+       test -f tmp-tlm1.lz4
+       test -f tmp-tlm2.lz4
+       test -f tmp-tlm3.lz4
        @$(RM) tmp-tlm1 tmp-tlm2 tmp-tlm3
        $(LZ4) -df -m tmp-tlm*.lz4
-       ls -ls tmp-tlm*
-       $(LZ4) -f -m tmp-tlm1 notHere tmp-tlm2; echo $$?
+       test -f tmp-tlm1
+       test -f tmp-tlm2
+       test -f tmp-tlm3
+       cat tmp-tlm1.lz4 tmp-tlm2.lz4 tmp-tlm3.lz4 > tmp-tlm-concat1
+       $(RM) *.lz4
+       $(LZ4) -f -m tmp-tlm* -c > tmp-tlm-concat2
+       test ! -f tmp-tlm1.lz4  # must not create .lz4 artefact
+       sdiff tmp-tlm-concat1 tmp-tlm-concat2  # must be equivalent
+       ! $(LZ4) -f -m tmp-tlm1 notHere tmp-tlm2  # must fail : notHere not present
        @$(RM) tmp-tlm*
 
 test-lz4-basic: lz4 datagen unlz4 lz4cat