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