]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
improved and fixed --list command, original patches by @ib (#772)
authorYann Collet <cyan@fb.com>
Fri, 18 Aug 2017 22:57:53 +0000 (15:57 -0700)
committerYann Collet <cyan@fb.com>
Fri, 18 Aug 2017 22:57:53 +0000 (15:57 -0700)
accepts all skippable frame identifiers.
display in MB or KB, depending on frame size.
fixed combination of skippable and zstd frames.

NEWS
programs/fileio.c

diff --git a/NEWS b/NEWS
index b3c2613feef0caa2ee592f52797eb14a0ff56f38..641551d9f289cdde76666057886ce758cc893744 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 v1.3.1
 perf: substantially decreased memory usage in Multi-threading mode, thanks to reports by Tino Reichardt
 perf: Multi-threading supports up to 256 threads. Cap at 256 when more are requested (#760)
+cli : improved and fixed --list command, by @ib (#772)
 build: fix Visual compilation for non x86/x64 targets, reported by Greg Slazinski (#718)
 API exp : breaking change : ZSTD_getframeHeader() provides more information
 API exp : breaking change : pinned down values of error codes
index e729e37eca9313249ca2eb2ed740bd65bf10b77b..e6fa61f621a825d53909efd270fda420e2e2d456 100644 (file)
@@ -947,6 +947,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){
         return 3;
     }
     info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName);
+
     /* begin analyzing frame */
     for ( ; ; ) {
         BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
@@ -966,37 +967,31 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){
                 break;
             }
         }
-        {
-            U32 const magicNumber = MEM_readLE32(headerBuffer);
+        {   U32 const magicNumber = MEM_readLE32(headerBuffer);
+            /* Zstandard frame */
             if (magicNumber == ZSTD_MAGICNUMBER) {
                 U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead);
                 if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) {
                     info->decompUnavailable = 1;
-                }
-                else {
+                } else {
                     info->decompressedSize += frameContentSize;
                 }
-                {
-                    /* move to the end of the frame header */
-                    size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead);
+                /* move to the end of the frame header */
+                {   size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead);
                     if (ZSTD_isError(headerSize)) {
                         DISPLAY("Error: could not determine frame header size\n");
                         detectError = 1;
                         break;
                     }
-                    {
-                        int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR);
+                    {   int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR);
                         if (ret != 0) {
                             DISPLAY("Error: could not move to end of frame header\n");
                             detectError = 1;
                             break;
-                        }
-                    }
-                }
+                }   }   }
 
                 /* skip the rest of the blocks in the frame */
-                {
-                    int lastBlock = 0;
+                {   int lastBlock = 0;
                     do {
                         BYTE blockHeaderBuffer[3];
                         U32 blockHeader;
@@ -1009,24 +1004,20 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){
                         }
                         blockHeader = MEM_readLE24(blockHeaderBuffer);
                         lastBlock = blockHeader & 1;
-                        blockSize = blockHeader >> 3;
-                        {
-                            int const ret = fseek(srcFile, blockSize, SEEK_CUR);
+                        blockSize = blockHeader >> 3;  /* Warning : does not work when block is RLE type */
+                        {   int const ret = fseek(srcFile, blockSize, SEEK_CUR);
                             if (ret != 0) {
                                 DISPLAY("Error: could not skip to end of block\n");
                                 detectError = 1;
                                 break;
-                            }
-                        }
+                        }   }
                     } while (lastBlock != 1);
 
-                    if (detectError) {
-                        break;
-                    }
+                    if (detectError) break;
                 }
-                {
-                    /* check if checksum is used */
-                    BYTE const frameHeaderDescriptor = headerBuffer[4];
+
+                /* check if checksum is used */
+                {   BYTE const frameHeaderDescriptor = headerBuffer[4];
                     int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2;
                     if (contentChecksumFlag) {
                         int const ret = fseek(srcFile, 4, SEEK_CUR);
@@ -1035,64 +1026,60 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){
                             DISPLAY("Error: could not skip past checksum\n");
                             detectError = 1;
                             break;
-                        }
-                    }
-                }
+                }   }   }
                 info->numActualFrames++;
             }
-            else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) {
-                BYTE frameSizeBuffer[4];
-                size_t const readBytes = fread(frameSizeBuffer, 1, 4, srcFile);
-                if (readBytes != 4) {
-                    DISPLAY("There was an error reading skippable frame size");
+            /* Skippable frame */
+            else if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+                U32 const frameSize = MEM_readLE32(headerBuffer + 4);
+                long const seek = -numBytesRead + 8 + frameSize;
+                int const ret = LONG_SEEK(srcFile, seek, SEEK_CUR);
+                if (ret != 0) {
+                    DISPLAY("Error: could not find end of skippable frame\n");
                     detectError = 1;
                     break;
                 }
-                {
-                    U32 const frameSize = MEM_readLE32(frameSizeBuffer);
-                    int const ret = LONG_SEEK(srcFile, frameSize, SEEK_CUR);
-                    if (ret != 0) {
-                        DISPLAY("Error: could not find end of skippable frame\n");
-                        detectError = 1;
-                        break;
-                    }
-                }
                 info->numSkippableFrames++;
             }
+            /* unknown content */
             else {
                 detectError = 2;
                 break;
             }
         }
-    }
+    }  /* end analyzing frame */
     fclose(srcFile);
     return detectError;
 }
 
 static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){
-    double const compressedSizeMB = (double)info->compressedSize/(1 MB);
-    double const decompressedSizeMB = (double)info->decompressedSize/(1 MB);
+    unsigned const unit = info->compressedSize < (1 MB) ? (1 KB) : (1 MB);
+    const char* const unitStr = info->compressedSize < (1 MB) ? "KB" : "MB";
+    double const compressedSizeUnit = (double)info->compressedSize / unit;
+    double const decompressedSizeUnit = (double)info->decompressedSize / unit;
     double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/info->compressedSize;
     const char* const checkString = (info->usesCheck ? "XXH64" : "None");
     if (displayLevel <= 2) {
         if (!info->decompUnavailable) {
             DISPLAYOUT("Skippable  Non-Skippable  Compressed  Uncompressed  Ratio  Check  Filename\n");
-            DISPLAYOUT("%9d  %13d  %7.2f MB  %9.2f MB  %5.3f  %5s  %s\n",
-                    info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB,
+            DISPLAYOUT("%9d  %13d  %7.2f %2s  %9.2f %2s  %5.3f  %5s  %s\n",
+                    info->numSkippableFrames, info->numActualFrames,
+                    compressedSizeUnit, unitStr, decompressedSizeUnit, unitStr,
                     ratio, checkString, inFileName);
-        }
-        else {
+        } else {
             DISPLAYOUT("Skippable  Non-Skippable  Compressed  Check  Filename\n");
             DISPLAYOUT("%9d  %13d  %7.2f MB  %5s  %s\n",
-                    info->numSkippableFrames, info->numActualFrames, compressedSizeMB, checkString, inFileName);
+                    info->numSkippableFrames, info->numActualFrames,
+                    compressedSizeUnit, checkString, inFileName);
         }
-    }
-    else{
+    } else {
         DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames);
         DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames);
-        DISPLAYOUT("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize);
+        DISPLAYOUT("Compressed Size: %.2f %2s (%llu B)\n",
+                    compressedSizeUnit, unitStr, info->compressedSize);
         if (!info->decompUnavailable) {
-            DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize);
+            DISPLAYOUT("Decompressed Size: %.2f %2s (%llu B)\n",
+                    decompressedSizeUnit, unitStr, info->decompressedSize);
             DISPLAYOUT("Ratio: %.4f\n", ratio);
         }
         DISPLAYOUT("Check: %s\n", checkString);