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