]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Added "dictionary decompression" example
authorYann Collet <yann.collet.73@gmail.com>
Thu, 7 Jul 2016 12:08:00 +0000 (14:08 +0200)
committerYann Collet <yann.collet.73@gmail.com>
Thu, 7 Jul 2016 12:08:00 +0000 (14:08 +0200)
examples/README.md [new file with mode: 0644]
examples/dictionary_decompression.c [new file with mode: 0644]
lib/.gitignore [new file with mode: 0644]

diff --git a/examples/README.md b/examples/README.md
new file mode 100644 (file)
index 0000000..a3d5931
--- /dev/null
@@ -0,0 +1,7 @@
+Zstandard library : usage examples
+==================================
+
+- [Dictionary decompression](dictionary_decompression.c)
+  Decompress multiple files using the same dictionary.
+  Compatible with Legacy modes.
+  Introduces usage of : `ZSTD_createDDict()` and `ZSTD_decompress_usingDDict()`
diff --git a/examples/dictionary_decompression.c b/examples/dictionary_decompression.c
new file mode 100644 (file)
index 0000000..e307bea
--- /dev/null
@@ -0,0 +1,112 @@
+#include <stdlib.h>    // exit
+#include <stdio.h>     // printf
+#include <string.h>    // strerror
+#include <errno.h>     // errno
+#include <sys/stat.h>  // stat
+#include <zstd.h>
+
+
+static off_t fsizeX(const char *filename)
+{
+    struct stat st;
+    if (stat(filename, &st) == 0) return st.st_size;
+    /* error */
+    printf("stat: %s : %s \n", filename, strerror(errno));
+    exit(1);
+}
+
+static FILE* fopenX(const char *filename, const char *instruction)
+{
+    FILE* const inFile = fopen(filename, instruction);
+    if (inFile) return inFile;
+    /* error */
+    printf("fopen: %s : %s \n", filename, strerror(errno));
+    exit(2);
+}
+
+static void* mallocX(size_t size)
+{
+    void* const buff = malloc(size);
+    if (buff) return buff;
+    /* error */
+    printf("malloc: %s \n", strerror(errno));
+    exit(3);
+}
+
+static void* loadFileX(const char* fileName, size_t* size)
+{
+    off_t const buffSize = fsizeX(fileName);
+    FILE* const inFile = fopenX(fileName, "rb");
+    void* const buffer = mallocX(buffSize);
+    size_t const readSize = fread(buffer, 1, buffSize, inFile);
+    if (readSize != (size_t)buffSize) {
+        printf("fread: %s : %s \n", fileName, strerror(errno));
+        exit(4);
+    }
+    fclose(inFile);
+    *size = buffSize;
+    return buffer;
+}
+
+
+static const ZSTD_DDict* createDict(const char* dictFileName)
+{
+    size_t dictSize;
+    void* const dictBuffer = loadFileX(dictFileName, &dictSize);
+    const ZSTD_DDict* const ddict = ZSTD_createDDict(dictBuffer, dictSize);
+    free(dictBuffer);
+    return ddict;
+}
+
+
+/* prototype declared here, as it currently is part of experimental section */
+unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+
+static void decompress(const char* fname, const ZSTD_DDict* ddict)
+{
+    size_t cSize;
+    void* const cBuff = loadFileX(fname, &cSize);
+    unsigned long long const rSize = ZSTD_getDecompressedSize(cBuff, cSize);
+    if (rSize==0) {
+        printf("%s : original size unknown \n", fname);
+        exit(5);
+    }
+    void* const rBuff = mallocX(rSize);
+
+    ZSTD_DCtx* const dctx = ZSTD_createDCtx();
+    size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, cBuff, cSize, ddict);
+
+    if (dSize != rSize) {
+        printf("error decoding %s : %s \n", fname, ZSTD_getErrorName(dSize));
+        exit(7);
+    }
+
+    /* success */
+    printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize);
+
+    ZSTD_freeDCtx(dctx);
+    free(rBuff);
+    free(cBuff);
+}
+
+
+int main(int argc, const char** argv)
+{
+    const char* const exeName = argv[0];
+
+    if (argc<3) {
+        printf("wrong arguments\n");
+        printf("usage:\n");
+        printf("%s [FILES] dictionary\n", exeName);
+        return 1;
+    }
+
+    /* load dictionary only once */
+    const char* const dictName = argv[argc-1];
+    const ZSTD_DDict* const dictPtr = createDict(dictName);
+
+    int u;
+    for (u=1; u<argc-1; u++) decompress(argv[u], dictPtr);
+
+    printf("All %u files decoded. \n", argc-2);
+}
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644 (file)
index 0000000..b43a854
--- /dev/null
@@ -0,0 +1,2 @@
+# make install artefact
+libzstd.pc