The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/zstd/examples/streaming_decompression.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) Yann Collet, Facebook, Inc.
    3  * All rights reserved.
    4  *
    5  * This source code is licensed under both the BSD-style license (found in the
    6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
    7  * in the COPYING file in the root directory of this source tree).
    8  * You may select, at your option, one of the above-listed licenses.
    9  */
   10 
   11 
   12 #include <stdio.h>     // fprintf
   13 #include <stdlib.h>    // free
   14 #include <zstd.h>      // presumes zstd library is installed
   15 #include "common.h"    // Helper functions, CHECK(), and CHECK_ZSTD()
   16 
   17 static void decompressFile_orDie(const char* fname)
   18 {
   19     FILE* const fin  = fopen_orDie(fname, "rb");
   20     size_t const buffInSize = ZSTD_DStreamInSize();
   21     void*  const buffIn  = malloc_orDie(buffInSize);
   22     FILE* const fout = stdout;
   23     size_t const buffOutSize = ZSTD_DStreamOutSize();  /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */
   24     void*  const buffOut = malloc_orDie(buffOutSize);
   25 
   26     ZSTD_DCtx* const dctx = ZSTD_createDCtx();
   27     CHECK(dctx != NULL, "ZSTD_createDCtx() failed!");
   28 
   29     /* This loop assumes that the input file is one or more concatenated zstd
   30      * streams. This example won't work if there is trailing non-zstd data at
   31      * the end, but streaming decompression in general handles this case.
   32      * ZSTD_decompressStream() returns 0 exactly when the frame is completed,
   33      * and doesn't consume input after the frame.
   34      */
   35     size_t const toRead = buffInSize;
   36     size_t read;
   37     size_t lastRet = 0;
   38     int isEmpty = 1;
   39     while ( (read = fread_orDie(buffIn, toRead, fin)) ) {
   40         isEmpty = 0;
   41         ZSTD_inBuffer input = { buffIn, read, 0 };
   42         /* Given a valid frame, zstd won't consume the last byte of the frame
   43          * until it has flushed all of the decompressed data of the frame.
   44          * Therefore, instead of checking if the return code is 0, we can
   45          * decompress just check if input.pos < input.size.
   46          */
   47         while (input.pos < input.size) {
   48             ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
   49             /* The return code is zero if the frame is complete, but there may
   50              * be multiple frames concatenated together. Zstd will automatically
   51              * reset the context when a frame is complete. Still, calling
   52              * ZSTD_DCtx_reset() can be useful to reset the context to a clean
   53              * state, for instance if the last decompression call returned an
   54              * error.
   55              */
   56             size_t const ret = ZSTD_decompressStream(dctx, &output , &input);
   57             CHECK_ZSTD(ret);
   58             fwrite_orDie(buffOut, output.pos, fout);
   59             lastRet = ret;
   60         }
   61     }
   62 
   63     if (isEmpty) {
   64         fprintf(stderr, "input is empty\n");
   65         exit(1);
   66     }
   67 
   68     if (lastRet != 0) {
   69         /* The last return value from ZSTD_decompressStream did not end on a
   70          * frame, but we reached the end of the file! We assume this is an
   71          * error, and the input was truncated.
   72          */
   73         fprintf(stderr, "EOF before end of stream: %zu\n", lastRet);
   74         exit(1);
   75     }
   76 
   77     ZSTD_freeDCtx(dctx);
   78     fclose_orDie(fin);
   79     fclose_orDie(fout);
   80     free(buffIn);
   81     free(buffOut);
   82 }
   83 
   84 
   85 int main(int argc, const char** argv)
   86 {
   87     const char* const exeName = argv[0];
   88 
   89     if (argc!=2) {
   90         fprintf(stderr, "wrong arguments\n");
   91         fprintf(stderr, "usage:\n");
   92         fprintf(stderr, "%s FILE\n", exeName);
   93         return 1;
   94     }
   95 
   96     const char* const inFilename = argv[1];
   97 
   98     decompressFile_orDie(inFilename);
   99     return 0;
  100 }

Cache object: 1cad3c408e8bf7a9e015110b6fb3df0e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.