Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/zstd/examples/multiple_streaming_compression.c
48249 views
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
/* The objective of this example is to show of to compress multiple successive files
13
* while preserving memory management.
14
* All structures and buffers will be created only once,
15
* and shared across all compression operations */
16
17
#include <stdio.h> // printf
18
#include <stdlib.h> // free
19
#include <string.h> // memset, strcat
20
#include <zstd.h> // presumes zstd library is installed
21
#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD()
22
23
typedef struct {
24
void* buffIn;
25
void* buffOut;
26
size_t buffInSize;
27
size_t buffOutSize;
28
ZSTD_CCtx* cctx;
29
} resources;
30
31
static resources createResources_orDie(int cLevel)
32
{
33
resources ress;
34
ress.buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */
35
ress.buffOutSize= ZSTD_CStreamOutSize(); /* can always flush a full block */
36
ress.buffIn = malloc_orDie(ress.buffInSize);
37
ress.buffOut= malloc_orDie(ress.buffOutSize);
38
ress.cctx = ZSTD_createCCtx();
39
CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!");
40
41
/* Set any compression parameters you want here.
42
* They will persist for every compression operation.
43
* Here we set the compression level, and enable the checksum.
44
*/
45
CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, cLevel) );
46
CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_checksumFlag, 1) );
47
return ress;
48
}
49
50
static void freeResources(resources ress)
51
{
52
ZSTD_freeCCtx(ress.cctx);
53
free(ress.buffIn);
54
free(ress.buffOut);
55
}
56
57
static void compressFile_orDie(resources ress, const char* fname, const char* outName)
58
{
59
// Open the input and output files.
60
FILE* const fin = fopen_orDie(fname, "rb");
61
FILE* const fout = fopen_orDie(outName, "wb");
62
63
/* Reset the context to a clean state to start a new compression operation.
64
* The parameters are sticky, so we keep the compression level and extra
65
* parameters that we set in createResources_orDie().
66
*/
67
CHECK_ZSTD( ZSTD_CCtx_reset(ress.cctx, ZSTD_reset_session_only) );
68
69
size_t const toRead = ress.buffInSize;
70
size_t read;
71
while ( (read = fread_orDie(ress.buffIn, toRead, fin)) ) {
72
/* This loop is the same as streaming_compression.c.
73
* See that file for detailed comments.
74
*/
75
int const lastChunk = (read < toRead);
76
ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
77
78
ZSTD_inBuffer input = { ress.buffIn, read, 0 };
79
int finished;
80
do {
81
ZSTD_outBuffer output = { ress.buffOut, ress.buffOutSize, 0 };
82
size_t const remaining = ZSTD_compressStream2(ress.cctx, &output, &input, mode);
83
CHECK_ZSTD(remaining);
84
fwrite_orDie(ress.buffOut, output.pos, fout);
85
finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
86
} while (!finished);
87
CHECK(input.pos == input.size,
88
"Impossible: zstd only returns 0 when the input is completely consumed!");
89
}
90
91
fclose_orDie(fout);
92
fclose_orDie(fin);
93
}
94
95
int main(int argc, const char** argv)
96
{
97
const char* const exeName = argv[0];
98
99
if (argc<2) {
100
printf("wrong arguments\n");
101
printf("usage:\n");
102
printf("%s FILE(s)\n", exeName);
103
return 1;
104
}
105
106
int const cLevel = 7;
107
resources const ress = createResources_orDie(cLevel);
108
void* ofnBuffer = NULL;
109
size_t ofnbSize = 0;
110
111
int argNb;
112
for (argNb = 1; argNb < argc; argNb++) {
113
const char* const ifn = argv[argNb];
114
size_t const ifnSize = strlen(ifn);
115
size_t const ofnSize = ifnSize + 5;
116
if (ofnbSize <= ofnSize) {
117
ofnbSize = ofnSize + 16;
118
free(ofnBuffer);
119
ofnBuffer = malloc_orDie(ofnbSize);
120
}
121
memset(ofnBuffer, 0, ofnSize);
122
strcat(ofnBuffer, ifn);
123
strcat(ofnBuffer, ".zst");
124
compressFile_orDie(ress, ifn, ofnBuffer);
125
}
126
127
freeResources(ress);
128
free(ofnBuffer);
129
130
printf("compressed %i files \n", argc-1);
131
132
return 0;
133
}
134
135