Path: blob/main/sys/contrib/zstd/examples/multiple_streaming_compression.c
48249 views
/*1* Copyright (c) Yann Collet, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under both the BSD-style license (found in the5* LICENSE file in the root directory of this source tree) and the GPLv2 (found6* in the COPYING file in the root directory of this source tree).7* You may select, at your option, one of the above-listed licenses.8*/91011/* The objective of this example is to show of to compress multiple successive files12* while preserving memory management.13* All structures and buffers will be created only once,14* and shared across all compression operations */1516#include <stdio.h> // printf17#include <stdlib.h> // free18#include <string.h> // memset, strcat19#include <zstd.h> // presumes zstd library is installed20#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD()2122typedef struct {23void* buffIn;24void* buffOut;25size_t buffInSize;26size_t buffOutSize;27ZSTD_CCtx* cctx;28} resources;2930static resources createResources_orDie(int cLevel)31{32resources ress;33ress.buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */34ress.buffOutSize= ZSTD_CStreamOutSize(); /* can always flush a full block */35ress.buffIn = malloc_orDie(ress.buffInSize);36ress.buffOut= malloc_orDie(ress.buffOutSize);37ress.cctx = ZSTD_createCCtx();38CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!");3940/* Set any compression parameters you want here.41* They will persist for every compression operation.42* Here we set the compression level, and enable the checksum.43*/44CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, cLevel) );45CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_checksumFlag, 1) );46return ress;47}4849static void freeResources(resources ress)50{51ZSTD_freeCCtx(ress.cctx);52free(ress.buffIn);53free(ress.buffOut);54}5556static void compressFile_orDie(resources ress, const char* fname, const char* outName)57{58// Open the input and output files.59FILE* const fin = fopen_orDie(fname, "rb");60FILE* const fout = fopen_orDie(outName, "wb");6162/* Reset the context to a clean state to start a new compression operation.63* The parameters are sticky, so we keep the compression level and extra64* parameters that we set in createResources_orDie().65*/66CHECK_ZSTD( ZSTD_CCtx_reset(ress.cctx, ZSTD_reset_session_only) );6768size_t const toRead = ress.buffInSize;69size_t read;70while ( (read = fread_orDie(ress.buffIn, toRead, fin)) ) {71/* This loop is the same as streaming_compression.c.72* See that file for detailed comments.73*/74int const lastChunk = (read < toRead);75ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;7677ZSTD_inBuffer input = { ress.buffIn, read, 0 };78int finished;79do {80ZSTD_outBuffer output = { ress.buffOut, ress.buffOutSize, 0 };81size_t const remaining = ZSTD_compressStream2(ress.cctx, &output, &input, mode);82CHECK_ZSTD(remaining);83fwrite_orDie(ress.buffOut, output.pos, fout);84finished = lastChunk ? (remaining == 0) : (input.pos == input.size);85} while (!finished);86CHECK(input.pos == input.size,87"Impossible: zstd only returns 0 when the input is completely consumed!");88}8990fclose_orDie(fout);91fclose_orDie(fin);92}9394int main(int argc, const char** argv)95{96const char* const exeName = argv[0];9798if (argc<2) {99printf("wrong arguments\n");100printf("usage:\n");101printf("%s FILE(s)\n", exeName);102return 1;103}104105int const cLevel = 7;106resources const ress = createResources_orDie(cLevel);107void* ofnBuffer = NULL;108size_t ofnbSize = 0;109110int argNb;111for (argNb = 1; argNb < argc; argNb++) {112const char* const ifn = argv[argNb];113size_t const ifnSize = strlen(ifn);114size_t const ofnSize = ifnSize + 5;115if (ofnbSize <= ofnSize) {116ofnbSize = ofnSize + 16;117free(ofnBuffer);118ofnBuffer = malloc_orDie(ofnbSize);119}120memset(ofnBuffer, 0, ofnSize);121strcat(ofnBuffer, ifn);122strcat(ofnBuffer, ".zst");123compressFile_orDie(ress, ifn, ofnBuffer);124}125126freeResources(ress);127free(ofnBuffer);128129printf("compressed %i files \n", argc-1);130131return 0;132}133134135