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