xref: /netbsd-src/external/bsd/zstd/dist/zlibWrapper/examples/example.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1*3117ece4Schristos /* example.c contains minimal changes required to be compiled with zlibWrapper:
2*3117ece4Schristos  * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h"
3*3117ece4Schristos  * - test_flush() and test_sync() use functions not supported by zlibWrapper
4*3117ece4Schristos      therefore they are disabled while zstd compression is turned on     */
5*3117ece4Schristos 
6*3117ece4Schristos /* example.c -- usage example of the zlib compression library
7*3117ece4Schristos  */
8*3117ece4Schristos /*
9*3117ece4Schristos   Copyright (c) 1995-2006, 2011 Jean-loup Gailly
10*3117ece4Schristos 
11*3117ece4Schristos  This software is provided 'as-is', without any express or implied
12*3117ece4Schristos  warranty. In no event will the authors be held liable for any damages
13*3117ece4Schristos  arising from the use of this software.
14*3117ece4Schristos 
15*3117ece4Schristos  Permission is granted to anyone to use this software for any purpose,
16*3117ece4Schristos  including commercial applications, and to alter it and redistribute it
17*3117ece4Schristos  freely, subject to the following restrictions:
18*3117ece4Schristos 
19*3117ece4Schristos  1. The origin of this software must not be misrepresented; you must not
20*3117ece4Schristos     claim that you wrote the original software. If you use this software
21*3117ece4Schristos     in a product, an acknowledgement in the product documentation would be
22*3117ece4Schristos     appreciated but is not required.
23*3117ece4Schristos  2. Altered source versions must be plainly marked as such, and must not be
24*3117ece4Schristos     misrepresented as being the original software.
25*3117ece4Schristos  3. This notice may not be removed or altered from any source distribution.
26*3117ece4Schristos  */
27*3117ece4Schristos 
28*3117ece4Schristos /* @(#) $Id: example.c,v 1.1.1.1 2024/10/27 22:44:15 christos Exp $ */
29*3117ece4Schristos 
30*3117ece4Schristos #include "zstd_zlibwrapper.h"
31*3117ece4Schristos #include <stdio.h>
32*3117ece4Schristos 
33*3117ece4Schristos #ifdef STDC
34*3117ece4Schristos #  include <string.h>
35*3117ece4Schristos #  include <stdlib.h>
36*3117ece4Schristos #endif
37*3117ece4Schristos 
38*3117ece4Schristos #if defined(VMS) || defined(RISCOS)
39*3117ece4Schristos #  define TESTFILE "foo-gz"
40*3117ece4Schristos #else
41*3117ece4Schristos #  define TESTFILE "foo.gz"
42*3117ece4Schristos #endif
43*3117ece4Schristos 
44*3117ece4Schristos #define CHECK_ERR(err, msg) { \
45*3117ece4Schristos     if (err != Z_OK) { \
46*3117ece4Schristos         fprintf(stderr, "%s error: %d\n", msg, err); \
47*3117ece4Schristos         exit(1); \
48*3117ece4Schristos     } \
49*3117ece4Schristos }
50*3117ece4Schristos 
51*3117ece4Schristos z_const char hello[] = "hello, hello! I said hello, hello!";
52*3117ece4Schristos /* "hello world" would be more standard, but the repeated "hello"
53*3117ece4Schristos  * stresses the compression code better, sorry...
54*3117ece4Schristos  */
55*3117ece4Schristos 
56*3117ece4Schristos const char dictionary[] = "hello, hello!";
57*3117ece4Schristos uLong dictId; /* Adler32 value of the dictionary */
58*3117ece4Schristos 
59*3117ece4Schristos void test_deflate       _Z_OF((Byte *compr, uLong comprLen));
60*3117ece4Schristos void test_inflate       _Z_OF((Byte *compr, uLong comprLen,
61*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
62*3117ece4Schristos void test_large_deflate _Z_OF((Byte *compr, uLong comprLen,
63*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
64*3117ece4Schristos void test_large_inflate _Z_OF((Byte *compr, uLong comprLen,
65*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
66*3117ece4Schristos void test_flush         _Z_OF((Byte *compr, uLong *comprLen));
67*3117ece4Schristos void test_sync          _Z_OF((Byte *compr, uLong comprLen,
68*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
69*3117ece4Schristos void test_dict_deflate  _Z_OF((Byte *compr, uLong comprLen));
70*3117ece4Schristos void test_dict_inflate  _Z_OF((Byte *compr, uLong comprLen,
71*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
72*3117ece4Schristos int  main               _Z_OF((int argc, char *argv[]));
73*3117ece4Schristos 
74*3117ece4Schristos 
75*3117ece4Schristos #ifdef Z_SOLO
76*3117ece4Schristos 
77*3117ece4Schristos void *myalloc _Z_OF((void *, unsigned, unsigned));
78*3117ece4Schristos void myfree _Z_OF((void *, void *));
79*3117ece4Schristos 
80*3117ece4Schristos void *myalloc(void *q, unsigned n, unsigned m)
81*3117ece4Schristos {
82*3117ece4Schristos     void *buf = calloc(n, m);
83*3117ece4Schristos     q = Z_NULL;
84*3117ece4Schristos   /*  printf("myalloc %p n=%d m=%d\n", buf, n, m); */
85*3117ece4Schristos     return buf;
86*3117ece4Schristos }
87*3117ece4Schristos 
88*3117ece4Schristos void myfree(void *q, void *p)
89*3117ece4Schristos {
90*3117ece4Schristos   /*  printf("myfree %p\n", p); */
91*3117ece4Schristos     q = Z_NULL;
92*3117ece4Schristos     free(p);
93*3117ece4Schristos }
94*3117ece4Schristos 
95*3117ece4Schristos static alloc_func zalloc = myalloc;
96*3117ece4Schristos static free_func zfree = myfree;
97*3117ece4Schristos 
98*3117ece4Schristos #else /* !Z_SOLO */
99*3117ece4Schristos 
100*3117ece4Schristos static alloc_func zalloc = (alloc_func)0;
101*3117ece4Schristos static free_func zfree = (free_func)0;
102*3117ece4Schristos 
103*3117ece4Schristos void test_compress      _Z_OF((Byte *compr, uLong comprLen,
104*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
105*3117ece4Schristos void test_gzio          _Z_OF((const char *fname,
106*3117ece4Schristos                             Byte *uncompr, uLong uncomprLen));
107*3117ece4Schristos 
108*3117ece4Schristos /* ===========================================================================
109*3117ece4Schristos  * Test compress() and uncompress()
110*3117ece4Schristos  */
111*3117ece4Schristos void test_compress(Byte *compr, uLong comprLen, Byte *uncompr,
112*3117ece4Schristos                    uLong uncomprLen) {
113*3117ece4Schristos     int err;
114*3117ece4Schristos     uLong len = (uLong)strlen(hello)+1;
115*3117ece4Schristos 
116*3117ece4Schristos     err = compress(compr, &comprLen, (const Bytef*)hello, len);
117*3117ece4Schristos     CHECK_ERR(err, "compress");
118*3117ece4Schristos 
119*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
120*3117ece4Schristos 
121*3117ece4Schristos     err = uncompress(uncompr, &uncomprLen, compr, comprLen);
122*3117ece4Schristos     CHECK_ERR(err, "uncompress");
123*3117ece4Schristos 
124*3117ece4Schristos     if (strcmp((char*)uncompr, hello)) {
125*3117ece4Schristos         fprintf(stderr, "bad uncompress\n");
126*3117ece4Schristos         exit(1);
127*3117ece4Schristos     } else {
128*3117ece4Schristos         printf("uncompress(): %s\n", (char *)uncompr);
129*3117ece4Schristos     }
130*3117ece4Schristos }
131*3117ece4Schristos 
132*3117ece4Schristos /* ===========================================================================
133*3117ece4Schristos  * Test read/write of .gz files
134*3117ece4Schristos  */
135*3117ece4Schristos void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) {
136*3117ece4Schristos #ifdef NO_GZCOMPRESS
137*3117ece4Schristos     fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
138*3117ece4Schristos #else
139*3117ece4Schristos     int err;
140*3117ece4Schristos     int len = (int)strlen(hello)+1;
141*3117ece4Schristos     gzFile file;
142*3117ece4Schristos     z_off_t pos;
143*3117ece4Schristos 
144*3117ece4Schristos     file = gzopen(fname, "wb");
145*3117ece4Schristos     if (file == NULL) {
146*3117ece4Schristos         fprintf(stderr, "gzopen error\n");
147*3117ece4Schristos         exit(1);
148*3117ece4Schristos     }
149*3117ece4Schristos     gzputc(file, 'h');
150*3117ece4Schristos     if (gzputs(file, "ello") != 4) {
151*3117ece4Schristos         fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
152*3117ece4Schristos         exit(1);
153*3117ece4Schristos     }
154*3117ece4Schristos     if (gzprintf(file, ", %s! I said hello, hello!", "hello") != 8+21) {
155*3117ece4Schristos         fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
156*3117ece4Schristos         exit(1);
157*3117ece4Schristos     }
158*3117ece4Schristos     gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
159*3117ece4Schristos     gzclose(file);
160*3117ece4Schristos 
161*3117ece4Schristos     file = gzopen(fname, "rb");
162*3117ece4Schristos     if (file == NULL) {
163*3117ece4Schristos         fprintf(stderr, "gzopen error\n");
164*3117ece4Schristos         exit(1);
165*3117ece4Schristos     }
166*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
167*3117ece4Schristos 
168*3117ece4Schristos     if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
169*3117ece4Schristos         fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
170*3117ece4Schristos         exit(1);
171*3117ece4Schristos     }
172*3117ece4Schristos     if (strcmp((char*)uncompr, hello)) {
173*3117ece4Schristos         fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
174*3117ece4Schristos         exit(1);
175*3117ece4Schristos     } else {
176*3117ece4Schristos         printf("gzread(): %s\n", (char*)uncompr);
177*3117ece4Schristos     }
178*3117ece4Schristos 
179*3117ece4Schristos     pos = gzseek(file, -8L, SEEK_CUR);
180*3117ece4Schristos     if (pos != 6+21 || gztell(file) != pos) {
181*3117ece4Schristos         fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
182*3117ece4Schristos                 (long)pos, (long)gztell(file));
183*3117ece4Schristos         exit(1);
184*3117ece4Schristos     }
185*3117ece4Schristos 
186*3117ece4Schristos     if (gzgetc(file) != ' ') {
187*3117ece4Schristos         fprintf(stderr, "gzgetc error\n");
188*3117ece4Schristos         exit(1);
189*3117ece4Schristos     }
190*3117ece4Schristos 
191*3117ece4Schristos     if (gzungetc(' ', file) != ' ') {
192*3117ece4Schristos         fprintf(stderr, "gzungetc error\n");
193*3117ece4Schristos         exit(1);
194*3117ece4Schristos     }
195*3117ece4Schristos 
196*3117ece4Schristos     gzgets(file, (char*)uncompr, (int)uncomprLen);
197*3117ece4Schristos     if (strlen((char*)uncompr) != 7) { /* " hello!" */
198*3117ece4Schristos         fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
199*3117ece4Schristos         exit(1);
200*3117ece4Schristos     }
201*3117ece4Schristos     if (strcmp((char*)uncompr, hello + 6+21)) {
202*3117ece4Schristos         fprintf(stderr, "bad gzgets after gzseek\n");
203*3117ece4Schristos         exit(1);
204*3117ece4Schristos     } else {
205*3117ece4Schristos         printf("gzgets() after gzseek: %s\n", (char*)uncompr);
206*3117ece4Schristos     }
207*3117ece4Schristos 
208*3117ece4Schristos     gzclose(file);
209*3117ece4Schristos #endif
210*3117ece4Schristos }
211*3117ece4Schristos 
212*3117ece4Schristos #endif /* Z_SOLO */
213*3117ece4Schristos 
214*3117ece4Schristos /* ===========================================================================
215*3117ece4Schristos  * Test deflate() with small buffers
216*3117ece4Schristos  */
217*3117ece4Schristos void test_deflate(Byte *compr, uLong comprLen) {
218*3117ece4Schristos     z_stream c_stream; /* compression stream */
219*3117ece4Schristos     int err;
220*3117ece4Schristos     uLong len = (uLong)strlen(hello)+1;
221*3117ece4Schristos 
222*3117ece4Schristos     c_stream.zalloc = zalloc;
223*3117ece4Schristos     c_stream.zfree = zfree;
224*3117ece4Schristos     c_stream.opaque = (voidpf)0;
225*3117ece4Schristos 
226*3117ece4Schristos     err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
227*3117ece4Schristos     CHECK_ERR(err, "deflateInit");
228*3117ece4Schristos 
229*3117ece4Schristos     c_stream.next_in  = (z_const unsigned char *)hello;
230*3117ece4Schristos     c_stream.next_out = compr;
231*3117ece4Schristos 
232*3117ece4Schristos     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
233*3117ece4Schristos         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
234*3117ece4Schristos         err = deflate(&c_stream, Z_NO_FLUSH);
235*3117ece4Schristos         CHECK_ERR(err, "deflate");
236*3117ece4Schristos     }
237*3117ece4Schristos     /* Finish the stream, still forcing small buffers: */
238*3117ece4Schristos     for (;;) {
239*3117ece4Schristos         c_stream.avail_out = 1;
240*3117ece4Schristos         err = deflate(&c_stream, Z_FINISH);
241*3117ece4Schristos         if (err == Z_STREAM_END) break;
242*3117ece4Schristos         CHECK_ERR(err, "deflate");
243*3117ece4Schristos     }
244*3117ece4Schristos 
245*3117ece4Schristos     err = deflateEnd(&c_stream);
246*3117ece4Schristos     CHECK_ERR(err, "deflateEnd");
247*3117ece4Schristos }
248*3117ece4Schristos 
249*3117ece4Schristos /* ===========================================================================
250*3117ece4Schristos  * Test inflate() with small buffers
251*3117ece4Schristos  */
252*3117ece4Schristos void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
253*3117ece4Schristos                   uLong uncomprLen) {
254*3117ece4Schristos     int err;
255*3117ece4Schristos     z_stream d_stream; /* decompression stream */
256*3117ece4Schristos 
257*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
258*3117ece4Schristos 
259*3117ece4Schristos     d_stream.zalloc = zalloc;
260*3117ece4Schristos     d_stream.zfree = zfree;
261*3117ece4Schristos     d_stream.opaque = (voidpf)0;
262*3117ece4Schristos 
263*3117ece4Schristos     d_stream.next_in  = compr;
264*3117ece4Schristos     d_stream.avail_in = 0;
265*3117ece4Schristos     d_stream.next_out = uncompr;
266*3117ece4Schristos 
267*3117ece4Schristos     err = inflateInit(&d_stream);
268*3117ece4Schristos     CHECK_ERR(err, "inflateInit");
269*3117ece4Schristos 
270*3117ece4Schristos     while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
271*3117ece4Schristos         d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
272*3117ece4Schristos         err = inflate(&d_stream, Z_NO_FLUSH);
273*3117ece4Schristos         if (err == Z_STREAM_END) break;
274*3117ece4Schristos         CHECK_ERR(err, "inflate");
275*3117ece4Schristos     }
276*3117ece4Schristos 
277*3117ece4Schristos     err = inflateEnd(&d_stream);
278*3117ece4Schristos     CHECK_ERR(err, "inflateEnd");
279*3117ece4Schristos 
280*3117ece4Schristos     if (strcmp((char*)uncompr, hello)) {
281*3117ece4Schristos         fprintf(stderr, "bad inflate\n");
282*3117ece4Schristos         exit(1);
283*3117ece4Schristos     } else {
284*3117ece4Schristos         printf("inflate(): %s\n", (char *)uncompr);
285*3117ece4Schristos     }
286*3117ece4Schristos }
287*3117ece4Schristos 
288*3117ece4Schristos /* ===========================================================================
289*3117ece4Schristos  * Test deflate() with large buffers and dynamic change of compression level
290*3117ece4Schristos  */
291*3117ece4Schristos void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr,
292*3117ece4Schristos                         uLong uncomprLen) {
293*3117ece4Schristos     z_stream c_stream; /* compression stream */
294*3117ece4Schristos     int err;
295*3117ece4Schristos 
296*3117ece4Schristos     c_stream.zalloc = zalloc;
297*3117ece4Schristos     c_stream.zfree = zfree;
298*3117ece4Schristos     c_stream.opaque = (voidpf)0;
299*3117ece4Schristos 
300*3117ece4Schristos     err = deflateInit(&c_stream, Z_BEST_SPEED);
301*3117ece4Schristos     CHECK_ERR(err, "deflateInit");
302*3117ece4Schristos 
303*3117ece4Schristos     c_stream.next_out = compr;
304*3117ece4Schristos     c_stream.avail_out = (uInt)comprLen;
305*3117ece4Schristos 
306*3117ece4Schristos     /* At this point, uncompr is still mostly zeroes, so it should compress
307*3117ece4Schristos      * very well:
308*3117ece4Schristos      */
309*3117ece4Schristos     c_stream.next_in = uncompr;
310*3117ece4Schristos     c_stream.avail_in = (uInt)uncomprLen;
311*3117ece4Schristos     err = deflate(&c_stream, Z_NO_FLUSH);
312*3117ece4Schristos     CHECK_ERR(err, "deflate");
313*3117ece4Schristos     if (c_stream.avail_in != 0) {
314*3117ece4Schristos         fprintf(stderr, "deflate not greedy\n");
315*3117ece4Schristos         exit(1);
316*3117ece4Schristos     }
317*3117ece4Schristos 
318*3117ece4Schristos     /* Feed in already compressed data and switch to no compression: */
319*3117ece4Schristos     deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
320*3117ece4Schristos     c_stream.next_in = compr;
321*3117ece4Schristos     c_stream.avail_in = (uInt)comprLen/2;
322*3117ece4Schristos     err = deflate(&c_stream, Z_NO_FLUSH);
323*3117ece4Schristos     CHECK_ERR(err, "deflate");
324*3117ece4Schristos 
325*3117ece4Schristos     /* Switch back to compressing mode: */
326*3117ece4Schristos     deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
327*3117ece4Schristos     c_stream.next_in = uncompr;
328*3117ece4Schristos     c_stream.avail_in = (uInt)uncomprLen;
329*3117ece4Schristos     err = deflate(&c_stream, Z_NO_FLUSH);
330*3117ece4Schristos     CHECK_ERR(err, "deflate");
331*3117ece4Schristos 
332*3117ece4Schristos     err = deflate(&c_stream, Z_FINISH);
333*3117ece4Schristos     if (err != Z_STREAM_END) {
334*3117ece4Schristos         fprintf(stderr, "deflate should report Z_STREAM_END\n");
335*3117ece4Schristos         exit(1);
336*3117ece4Schristos     }
337*3117ece4Schristos     err = deflateEnd(&c_stream);
338*3117ece4Schristos     CHECK_ERR(err, "deflateEnd");
339*3117ece4Schristos }
340*3117ece4Schristos 
341*3117ece4Schristos /* ===========================================================================
342*3117ece4Schristos  * Test inflate() with large buffers
343*3117ece4Schristos  */
344*3117ece4Schristos void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
345*3117ece4Schristos                         uLong uncomprLen) {
346*3117ece4Schristos     int err;
347*3117ece4Schristos     z_stream d_stream; /* decompression stream */
348*3117ece4Schristos 
349*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
350*3117ece4Schristos 
351*3117ece4Schristos     d_stream.zalloc = zalloc;
352*3117ece4Schristos     d_stream.zfree = zfree;
353*3117ece4Schristos     d_stream.opaque = (voidpf)0;
354*3117ece4Schristos 
355*3117ece4Schristos     d_stream.next_in  = compr;
356*3117ece4Schristos     d_stream.avail_in = (uInt)comprLen;
357*3117ece4Schristos 
358*3117ece4Schristos     err = inflateInit(&d_stream);
359*3117ece4Schristos     CHECK_ERR(err, "inflateInit");
360*3117ece4Schristos 
361*3117ece4Schristos     for (;;) {
362*3117ece4Schristos         d_stream.next_out = uncompr;            /* discard the output */
363*3117ece4Schristos         d_stream.avail_out = (uInt)uncomprLen;
364*3117ece4Schristos         err = inflate(&d_stream, Z_NO_FLUSH);
365*3117ece4Schristos         if (err == Z_STREAM_END) break;
366*3117ece4Schristos         CHECK_ERR(err, "large inflate");
367*3117ece4Schristos     }
368*3117ece4Schristos 
369*3117ece4Schristos     err = inflateEnd(&d_stream);
370*3117ece4Schristos     CHECK_ERR(err, "inflateEnd");
371*3117ece4Schristos 
372*3117ece4Schristos     if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
373*3117ece4Schristos         fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
374*3117ece4Schristos         exit(1);
375*3117ece4Schristos     } else {
376*3117ece4Schristos         printf("large_inflate(): OK\n");
377*3117ece4Schristos     }
378*3117ece4Schristos }
379*3117ece4Schristos 
380*3117ece4Schristos /* ===========================================================================
381*3117ece4Schristos  * Test deflate() with full flush
382*3117ece4Schristos  */
383*3117ece4Schristos void test_flush(Byte *compr, uLong *comprLen) {
384*3117ece4Schristos     z_stream c_stream; /* compression stream */
385*3117ece4Schristos     int err;
386*3117ece4Schristos     uInt len = (uInt)strlen(hello)+1;
387*3117ece4Schristos 
388*3117ece4Schristos     c_stream.zalloc = zalloc;
389*3117ece4Schristos     c_stream.zfree = zfree;
390*3117ece4Schristos     c_stream.opaque = (voidpf)0;
391*3117ece4Schristos 
392*3117ece4Schristos     err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
393*3117ece4Schristos     CHECK_ERR(err, "deflateInit");
394*3117ece4Schristos 
395*3117ece4Schristos     c_stream.next_in  = (z_const unsigned char *)hello;
396*3117ece4Schristos     c_stream.next_out = compr;
397*3117ece4Schristos     c_stream.avail_in = 3;
398*3117ece4Schristos     c_stream.avail_out = (uInt)*comprLen;
399*3117ece4Schristos     err = deflate(&c_stream, Z_FULL_FLUSH);
400*3117ece4Schristos     CHECK_ERR(err, "deflate");
401*3117ece4Schristos 
402*3117ece4Schristos     compr[3]++; /* force an error in first compressed block */
403*3117ece4Schristos     c_stream.avail_in = len - 3;
404*3117ece4Schristos 
405*3117ece4Schristos     err = deflate(&c_stream, Z_FINISH);
406*3117ece4Schristos     if (err != Z_STREAM_END) {
407*3117ece4Schristos         CHECK_ERR(err, "deflate");
408*3117ece4Schristos     }
409*3117ece4Schristos     err = deflateEnd(&c_stream);
410*3117ece4Schristos     CHECK_ERR(err, "deflateEnd");
411*3117ece4Schristos 
412*3117ece4Schristos     *comprLen = c_stream.total_out;
413*3117ece4Schristos }
414*3117ece4Schristos 
415*3117ece4Schristos /* ===========================================================================
416*3117ece4Schristos  * Test inflateSync()
417*3117ece4Schristos  */
418*3117ece4Schristos void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) {
419*3117ece4Schristos     int err;
420*3117ece4Schristos     z_stream d_stream; /* decompression stream */
421*3117ece4Schristos 
422*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
423*3117ece4Schristos 
424*3117ece4Schristos     d_stream.zalloc = zalloc;
425*3117ece4Schristos     d_stream.zfree = zfree;
426*3117ece4Schristos     d_stream.opaque = (voidpf)0;
427*3117ece4Schristos 
428*3117ece4Schristos     d_stream.next_in  = compr;
429*3117ece4Schristos     d_stream.avail_in = 2; /* just read the zlib header */
430*3117ece4Schristos 
431*3117ece4Schristos     err = inflateInit(&d_stream);
432*3117ece4Schristos     CHECK_ERR(err, "inflateInit");
433*3117ece4Schristos 
434*3117ece4Schristos     d_stream.next_out = uncompr;
435*3117ece4Schristos     d_stream.avail_out = (uInt)uncomprLen;
436*3117ece4Schristos 
437*3117ece4Schristos     inflate(&d_stream, Z_NO_FLUSH);
438*3117ece4Schristos     CHECK_ERR(err, "inflate");
439*3117ece4Schristos 
440*3117ece4Schristos     d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
441*3117ece4Schristos     err = inflateSync(&d_stream);           /* but skip the damaged part */
442*3117ece4Schristos     CHECK_ERR(err, "inflateSync");
443*3117ece4Schristos 
444*3117ece4Schristos     err = inflate(&d_stream, Z_FINISH);
445*3117ece4Schristos     if (err != Z_DATA_ERROR) {
446*3117ece4Schristos         fprintf(stderr, "inflate should report DATA_ERROR\n");
447*3117ece4Schristos         /* Because of incorrect adler32 */
448*3117ece4Schristos         exit(1);
449*3117ece4Schristos     }
450*3117ece4Schristos     err = inflateEnd(&d_stream);
451*3117ece4Schristos     CHECK_ERR(err, "inflateEnd");
452*3117ece4Schristos 
453*3117ece4Schristos     printf("after inflateSync(): hel%s\n", (char *)uncompr);
454*3117ece4Schristos }
455*3117ece4Schristos 
456*3117ece4Schristos /* ===========================================================================
457*3117ece4Schristos  * Test deflate() with preset dictionary
458*3117ece4Schristos  */
459*3117ece4Schristos void test_dict_deflate(Byte *compr, uLong comprLen) {
460*3117ece4Schristos     z_stream c_stream; /* compression stream */
461*3117ece4Schristos     int err;
462*3117ece4Schristos 
463*3117ece4Schristos     c_stream.zalloc = zalloc;
464*3117ece4Schristos     c_stream.zfree = zfree;
465*3117ece4Schristos     c_stream.opaque = (voidpf)0;
466*3117ece4Schristos 
467*3117ece4Schristos     err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
468*3117ece4Schristos     CHECK_ERR(err, "deflateInit");
469*3117ece4Schristos 
470*3117ece4Schristos     err = deflateSetDictionary(&c_stream,
471*3117ece4Schristos                 (const Bytef*)dictionary, (int)sizeof(dictionary));
472*3117ece4Schristos     CHECK_ERR(err, "deflateSetDictionary");
473*3117ece4Schristos 
474*3117ece4Schristos     dictId = c_stream.adler;
475*3117ece4Schristos     c_stream.next_out = compr;
476*3117ece4Schristos     c_stream.avail_out = (uInt)comprLen;
477*3117ece4Schristos 
478*3117ece4Schristos     c_stream.next_in = (z_const unsigned char *)hello;
479*3117ece4Schristos     c_stream.avail_in = (uInt)strlen(hello)+1;
480*3117ece4Schristos 
481*3117ece4Schristos     err = deflate(&c_stream, Z_FINISH);
482*3117ece4Schristos     if (err != Z_STREAM_END) {
483*3117ece4Schristos         fprintf(stderr, "deflate should report Z_STREAM_END\n");
484*3117ece4Schristos         exit(1);
485*3117ece4Schristos     }
486*3117ece4Schristos     err = deflateEnd(&c_stream);
487*3117ece4Schristos     CHECK_ERR(err, "deflateEnd");
488*3117ece4Schristos }
489*3117ece4Schristos 
490*3117ece4Schristos /* ===========================================================================
491*3117ece4Schristos  * Test inflate() with a preset dictionary
492*3117ece4Schristos  */
493*3117ece4Schristos void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
494*3117ece4Schristos                        uLong uncomprLen) {
495*3117ece4Schristos     int err;
496*3117ece4Schristos     z_stream d_stream; /* decompression stream */
497*3117ece4Schristos 
498*3117ece4Schristos     strcpy((char*)uncompr, "garbage");
499*3117ece4Schristos 
500*3117ece4Schristos     d_stream.zalloc = zalloc;
501*3117ece4Schristos     d_stream.zfree = zfree;
502*3117ece4Schristos     d_stream.opaque = (voidpf)0;
503*3117ece4Schristos 
504*3117ece4Schristos     d_stream.next_in  = compr;
505*3117ece4Schristos     d_stream.avail_in = (uInt)comprLen;
506*3117ece4Schristos 
507*3117ece4Schristos     err = inflateInit(&d_stream);
508*3117ece4Schristos     CHECK_ERR(err, "inflateInit");
509*3117ece4Schristos 
510*3117ece4Schristos     d_stream.next_out = uncompr;
511*3117ece4Schristos     d_stream.avail_out = (uInt)uncomprLen;
512*3117ece4Schristos 
513*3117ece4Schristos     for (;;) {
514*3117ece4Schristos         err = inflate(&d_stream, Z_NO_FLUSH);
515*3117ece4Schristos         if (err == Z_STREAM_END) break;
516*3117ece4Schristos         if (err == Z_NEED_DICT) {
517*3117ece4Schristos             if (d_stream.adler != dictId) {
518*3117ece4Schristos                 fprintf(stderr, "unexpected dictionary");
519*3117ece4Schristos                 exit(1);
520*3117ece4Schristos             }
521*3117ece4Schristos             err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
522*3117ece4Schristos                                        (int)sizeof(dictionary));
523*3117ece4Schristos         }
524*3117ece4Schristos         CHECK_ERR(err, "inflate with dict");
525*3117ece4Schristos     }
526*3117ece4Schristos 
527*3117ece4Schristos     err = inflateEnd(&d_stream);
528*3117ece4Schristos     CHECK_ERR(err, "inflateEnd");
529*3117ece4Schristos 
530*3117ece4Schristos     if (strcmp((char*)uncompr, hello)) {
531*3117ece4Schristos         fprintf(stderr, "bad inflate with dict\n");
532*3117ece4Schristos         exit(1);
533*3117ece4Schristos     } else {
534*3117ece4Schristos         printf("inflate with dictionary: %s\n", (char *)uncompr);
535*3117ece4Schristos     }
536*3117ece4Schristos }
537*3117ece4Schristos 
538*3117ece4Schristos /* ===========================================================================
539*3117ece4Schristos  * Usage:  example [output.gz  [input.gz]]
540*3117ece4Schristos  */
541*3117ece4Schristos 
542*3117ece4Schristos int main(int argc, char *argv[]) {
543*3117ece4Schristos     Byte *compr, *uncompr;
544*3117ece4Schristos     uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
545*3117ece4Schristos     uLong uncomprLen = comprLen;
546*3117ece4Schristos     static const char* myVersion = ZLIB_VERSION;
547*3117ece4Schristos 
548*3117ece4Schristos     if (zlibVersion()[0] != myVersion[0]) {
549*3117ece4Schristos         fprintf(stderr, "incompatible zlib version\n");
550*3117ece4Schristos         exit(1);
551*3117ece4Schristos 
552*3117ece4Schristos     } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
553*3117ece4Schristos         fprintf(stderr, "warning: different zlib version\n");
554*3117ece4Schristos     }
555*3117ece4Schristos 
556*3117ece4Schristos     printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
557*3117ece4Schristos             ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
558*3117ece4Schristos     if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion());
559*3117ece4Schristos 
560*3117ece4Schristos     compr    = (Byte*)calloc((uInt)comprLen, 1);
561*3117ece4Schristos     uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
562*3117ece4Schristos     /* compr and uncompr are cleared to avoid reading uninitialized
563*3117ece4Schristos      * data and to ensure that uncompr compresses well.
564*3117ece4Schristos      */
565*3117ece4Schristos     if (compr == Z_NULL || uncompr == Z_NULL) {
566*3117ece4Schristos         printf("out of memory\n");
567*3117ece4Schristos         exit(1);
568*3117ece4Schristos     }
569*3117ece4Schristos 
570*3117ece4Schristos #ifdef Z_SOLO
571*3117ece4Schristos     argc = strlen(argv[0]);
572*3117ece4Schristos #else
573*3117ece4Schristos     test_compress(compr, comprLen, uncompr, uncomprLen);
574*3117ece4Schristos 
575*3117ece4Schristos     test_gzio((argc > 1 ? argv[1] : TESTFILE),
576*3117ece4Schristos           uncompr, uncomprLen);
577*3117ece4Schristos #endif
578*3117ece4Schristos 
579*3117ece4Schristos     test_deflate(compr, comprLen);
580*3117ece4Schristos     test_inflate(compr, comprLen, uncompr, uncomprLen);
581*3117ece4Schristos 
582*3117ece4Schristos     test_large_deflate(compr, comprLen, uncompr, uncomprLen);
583*3117ece4Schristos     test_large_inflate(compr, comprLen, uncompr, uncomprLen);
584*3117ece4Schristos 
585*3117ece4Schristos     if (!ZWRAP_isUsingZSTDcompression()) {
586*3117ece4Schristos         test_flush(compr, &comprLen);
587*3117ece4Schristos         test_sync(compr, comprLen, uncompr, uncomprLen);
588*3117ece4Schristos     }
589*3117ece4Schristos     comprLen = uncomprLen;
590*3117ece4Schristos 
591*3117ece4Schristos     test_dict_deflate(compr, comprLen);
592*3117ece4Schristos     test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
593*3117ece4Schristos 
594*3117ece4Schristos     free(compr);
595*3117ece4Schristos     free(uncompr);
596*3117ece4Schristos 
597*3117ece4Schristos     return 0;
598*3117ece4Schristos }
599