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_compression.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>     // printf
   13 #include <stdlib.h>    // free
   14 #include <string.h>    // memset, strcat, strlen
   15 #include <zstd.h>      // presumes zstd library is installed
   16 #include "common.h"    // Helper functions, CHECK(), and CHECK_ZSTD()
   17 
   18 static void compressFile_orDie(const char* fname, const char* outName, int cLevel,
   19                                int nbThreads)
   20 {
   21     fprintf (stderr, "Starting compression of %s with level %d, using %d threads\n",
   22              fname, cLevel, nbThreads);
   23 
   24     /* Open the input and output files. */
   25     FILE* const fin  = fopen_orDie(fname, "rb");
   26     FILE* const fout = fopen_orDie(outName, "wb");
   27     /* Create the input and output buffers.
   28      * They may be any size, but we recommend using these functions to size them.
   29      * Performance will only suffer significantly for very tiny buffers.
   30      */
   31     size_t const buffInSize = ZSTD_CStreamInSize();
   32     void*  const buffIn  = malloc_orDie(buffInSize);
   33     size_t const buffOutSize = ZSTD_CStreamOutSize();
   34     void*  const buffOut = malloc_orDie(buffOutSize);
   35 
   36     /* Create the context. */
   37     ZSTD_CCtx* const cctx = ZSTD_createCCtx();
   38     CHECK(cctx != NULL, "ZSTD_createCCtx() failed!");
   39 
   40     /* Set any parameters you want.
   41      * Here we set the compression level, and enable the checksum.
   42      */
   43     CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel) );
   44     CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) );
   45     ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads);
   46 
   47     /* This loop read from the input file, compresses that entire chunk,
   48      * and writes all output produced to the output file.
   49      */
   50     size_t const toRead = buffInSize;
   51     for (;;) {
   52         size_t read = fread_orDie(buffIn, toRead, fin);
   53         /* Select the flush mode.
   54          * If the read may not be finished (read == toRead) we use
   55          * ZSTD_e_continue. If this is the last chunk, we use ZSTD_e_end.
   56          * Zstd optimizes the case where the first flush mode is ZSTD_e_end,
   57          * since it knows it is compressing the entire source in one pass.
   58          */
   59         int const lastChunk = (read < toRead);
   60         ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
   61         /* Set the input buffer to what we just read.
   62          * We compress until the input buffer is empty, each time flushing the
   63          * output.
   64          */
   65         ZSTD_inBuffer input = { buffIn, read, 0 };
   66         int finished;
   67         do {
   68             /* Compress into the output buffer and write all of the output to
   69              * the file so we can reuse the buffer next iteration.
   70              */
   71             ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
   72             size_t const remaining = ZSTD_compressStream2(cctx, &output , &input, mode);
   73             CHECK_ZSTD(remaining);
   74             fwrite_orDie(buffOut, output.pos, fout);
   75             /* If we're on the last chunk we're finished when zstd returns 0,
   76              * which means its consumed all the input AND finished the frame.
   77              * Otherwise, we're finished when we've consumed all the input.
   78              */
   79             finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
   80         } while (!finished);
   81         CHECK(input.pos == input.size,
   82               "Impossible: zstd only returns 0 when the input is completely consumed!");
   83 
   84         if (lastChunk) {
   85             break;
   86         }
   87     }
   88 
   89     ZSTD_freeCCtx(cctx);
   90     fclose_orDie(fout);
   91     fclose_orDie(fin);
   92     free(buffIn);
   93     free(buffOut);
   94 }
   95 
   96 
   97 static char* createOutFilename_orDie(const char* filename)
   98 {
   99     size_t const inL = strlen(filename);
  100     size_t const outL = inL + 5;
  101     void* const outSpace = malloc_orDie(outL);
  102     memset(outSpace, 0, outL);
  103     strcat(outSpace, filename);
  104     strcat(outSpace, ".zst");
  105     return (char*)outSpace;
  106 }
  107 
  108 int main(int argc, const char** argv)
  109 {
  110     const char* const exeName = argv[0];
  111 
  112     if (argc < 2) {
  113         printf("wrong arguments\n");
  114         printf("usage:\n");
  115         printf("%s FILE [LEVEL] [THREADS]\n", exeName);
  116         return 1;
  117     }
  118 
  119     int cLevel = 1;
  120     int nbThreads = 4;
  121 
  122     if (argc >= 3) {
  123       cLevel = atoi (argv[2]);
  124       CHECK(cLevel != 0, "can't parse LEVEL!");
  125     }
  126 
  127     if (argc >= 4) {
  128       nbThreads = atoi (argv[3]);
  129       CHECK(nbThreads != 0, "can't parse THREADS!");
  130     }
  131 
  132     const char* const inFilename = argv[1];
  133 
  134     char* const outFilename = createOutFilename_orDie(inFilename);
  135     compressFile_orDie(inFilename, outFilename, cLevel, nbThreads);
  136 
  137     free(outFilename);   /* not strictly required, since program execution stops there,
  138                           * but some static analyzer may complain otherwise */
  139     return 0;
  140 }

Cache object: 89f682c5145d828fd8cd940445297456


[ 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.