1 /* example.c -- usage example of the zlib compression library
2  * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include "zbuild.h"
7 #ifdef ZLIB_COMPAT
8 #  include "zlib.h"
9 #else
10 #  include "zlib-ng.h"
11 #endif
12 #include "deflate.h"
13 
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <inttypes.h>
17 
18 #define TESTFILE "foo.gz"
19 
20 static const char hello[] = "hello, hello!";
21 /* "hello world" would be more standard, but the repeated "hello"
22  * stresses the compression code better, sorry...
23  */
24 
25 static const char dictionary[] = "hello";
26 static unsigned long dictId = 0; /* Adler32 value of the dictionary */
27 
28 /* Maximum dictionary size, according to inflateGetDictionary() description. */
29 #define MAX_DICTIONARY_SIZE 32768
30 
31 
32 void test_compress      (unsigned char *compr, z_size_t comprLen,unsigned char *uncompr, z_size_t uncomprLen);
33 void test_gzio          (const char *fname, unsigned char *uncompr, z_size_t uncomprLen);
34 void test_deflate       (unsigned char *compr, size_t comprLen);
35 void test_inflate       (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
36 void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params);
37 void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
38 void test_flush         (unsigned char *compr, z_size_t *comprLen);
39 void test_sync          (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
40 void test_dict_deflate  (unsigned char *compr, size_t comprLen);
41 void test_dict_inflate  (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
42 int  main               (int argc, char *argv[]);
43 
44 
45 static alloc_func zalloc = NULL;
46 static free_func zfree = NULL;
47 
48 /* ===========================================================================
49  * Display error message and exit
50  */
error(const char * format,...)51 void error(const char *format, ...) {
52     va_list va;
53 
54     va_start(va, format);
55     vfprintf(stderr, format, va);
56     va_end(va);
57 
58     exit(1);
59 }
60 
61 #define CHECK_ERR(err, msg) { \
62     if (err != Z_OK) \
63         error("%s error: %d\n", msg, err); \
64 }
65 
66 /* ===========================================================================
67  * Test compress() and uncompress()
68  */
test_compress(unsigned char * compr,z_size_t comprLen,unsigned char * uncompr,z_size_t uncomprLen)69 void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncompr, z_size_t uncomprLen) {
70     int err;
71     size_t len = strlen(hello)+1;
72 
73     err = PREFIX(compress)(compr, &comprLen, (const unsigned char*)hello, (z_size_t)len);
74     CHECK_ERR(err, "compress");
75 
76     strcpy((char*)uncompr, "garbage");
77 
78     err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen);
79     CHECK_ERR(err, "uncompress");
80 
81     if (strcmp((char*)uncompr, hello))
82         error("bad uncompress\n");
83     else
84         printf("uncompress(): %s\n", (char *)uncompr);
85 }
86 
87 /* ===========================================================================
88  * Test read/write of .gz files
89  */
test_gzio(const char * fname,unsigned char * uncompr,z_size_t uncomprLen)90 void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) {
91 #ifdef NO_GZCOMPRESS
92     fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
93 #else
94     int err;
95     size_t read;
96     size_t len = strlen(hello)+1;
97     gzFile file;
98     z_off64_t pos;
99     z_off64_t comprLen;
100 
101     /* Write gz file with test data */
102     file = PREFIX(gzopen)(fname, "wb");
103     if (file == NULL)
104         error("gzopen error\n");
105     /* Write hello, hello! using gzputs and gzprintf */
106     PREFIX(gzputc)(file, 'h');
107     if (PREFIX(gzputs)(file, "ello") != 4)
108         error("gzputs err: %s\n", PREFIX(gzerror)(file, &err));
109     if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8)
110         error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err));
111     /* Write string null-teriminator using gzseek */
112     if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0)
113         error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file));
114     /* Write hello, hello! using gzfwrite using best compression level */
115     if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK)
116         error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err));
117     if (PREFIX(gzfwrite)(hello, len, 1, file) == 0)
118         error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err));
119     /* Flush compressed bytes to file */
120     if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK)
121         error("gzflush err: %s\n", PREFIX(gzerror)(file, &err));
122     comprLen = PREFIX(gzoffset)(file);
123     if (comprLen <= 0)
124         error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err));
125     PREFIX(gzclose)(file);
126 
127     /* Open gz file we previously wrote */
128     file = PREFIX(gzopen)(fname, "rb");
129     if (file == NULL)
130         error("gzopen error\n");
131 
132     /* Read uncompressed data - hello, hello! string twice */
133     strcpy((char*)uncompr, "garbages");
134     if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len))
135         error("gzread err: %s\n", PREFIX(gzerror)(file, &err));
136     if (strcmp((char*)uncompr, hello))
137         error("bad gzread: %s\n", (char*)uncompr);
138     else
139         printf("gzread(): %s\n", (char*)uncompr);
140     /* Check position at the end of the gz file */
141     if (PREFIX(gzeof)(file) != 1)
142         error("gzeof err: not reporting end of stream\n");
143 
144     /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
145     pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
146     if (pos != 6 || PREFIX(gztell)(file) != pos)
147         error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
148     if (PREFIX(gzgetc)(file) != ' ')
149         error("gzgetc error\n");
150     if (PREFIX(gzungetc)(' ', file) != ' ')
151         error("gzungetc error\n");
152     /* Read first hello, hello! string with gzgets */
153     strcpy((char*)uncompr, "garbages");
154     PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen);
155     if (strlen((char*)uncompr) != 7) /* " hello!" */
156         error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err));
157     if (strcmp((char*)uncompr, hello + 6))
158         error("bad gzgets after gzseek\n");
159     else
160         printf("gzgets() after gzseek: %s\n", (char*)uncompr);
161     /* Seek to second hello, hello! string */
162     pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
163     if (pos != 14 || PREFIX(gztell)(file) != pos)
164         error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
165     /* Check position not at end of file */
166     if (PREFIX(gzeof)(file) != 0)
167         error("gzeof err: reporting end of stream\n");
168     /* Read first hello, hello! string with gzfread */
169     strcpy((char*)uncompr, "garbages");
170     read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file);
171     if (strcmp((const char *)uncompr, hello) != 0)
172         error("bad gzgets\n");
173     else
174         printf("gzgets(): %s\n", (char*)uncompr);
175     pos = PREFIX(gzoffset)(file);
176     if (pos < 0 || pos != (comprLen + 10))
177         error("gzoffset err: wrong offset at end\n");
178     /* Trigger an error and clear it with gzclearerr */
179     PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
180     PREFIX(gzerror)(file, &err);
181     if (err == 0)
182         error("gzerror err: no error returned\n");
183     PREFIX(gzclearerr)(file);
184     PREFIX(gzerror)(file, &err);
185     if (err != 0)
186         error("gzclearerr err: not zero %d\n", err);
187 
188     PREFIX(gzclose)(file);
189 
190     if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR)
191         error("gzclose unexpected return when handle null\n");
192     Z_UNUSED(read);
193 #endif
194 }
195 
196 /* ===========================================================================
197  * Test deflate() with small buffers
198  */
test_deflate(unsigned char * compr,size_t comprLen)199 void test_deflate(unsigned char *compr, size_t comprLen) {
200     PREFIX3(stream) c_stream; /* compression stream */
201     int err;
202     size_t len = strlen(hello)+1;
203 
204     c_stream.zalloc = zalloc;
205     c_stream.zfree = zfree;
206     c_stream.opaque = (void *)0;
207     c_stream.total_in = 0;
208     c_stream.total_out = 0;
209 
210     err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
211     CHECK_ERR(err, "deflateInit");
212 
213     c_stream.next_in  = (z_const unsigned char *)hello;
214     c_stream.next_out = compr;
215 
216     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
217         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
218         err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
219         CHECK_ERR(err, "deflate");
220     }
221     /* Finish the stream, still forcing small buffers: */
222     for (;;) {
223         c_stream.avail_out = 1;
224         err = PREFIX(deflate)(&c_stream, Z_FINISH);
225         if (err == Z_STREAM_END) break;
226         CHECK_ERR(err, "deflate");
227     }
228 
229     err = PREFIX(deflateEnd)(&c_stream);
230     CHECK_ERR(err, "deflateEnd");
231 }
232 
233 /* ===========================================================================
234  * Test inflate() with small buffers
235  */
test_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)236 void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
237     int err;
238     PREFIX3(stream) d_stream; /* decompression stream */
239 
240     strcpy((char*)uncompr, "garbage");
241 
242     d_stream.zalloc = zalloc;
243     d_stream.zfree = zfree;
244     d_stream.opaque = (void *)0;
245 
246     d_stream.next_in  = compr;
247     d_stream.avail_in = 0;
248     d_stream.next_out = uncompr;
249     d_stream.total_in = 0;
250     d_stream.total_out = 0;
251 
252     err = PREFIX(inflateInit)(&d_stream);
253     CHECK_ERR(err, "inflateInit");
254 
255     while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
256         d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
257         err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
258         if (err == Z_STREAM_END) break;
259         CHECK_ERR(err, "inflate");
260     }
261 
262     err = PREFIX(inflateEnd)(&d_stream);
263     CHECK_ERR(err, "inflateEnd");
264 
265     if (strcmp((char*)uncompr, hello))
266         error("bad inflate\n");
267     else
268         printf("inflate(): %s\n", (char *)uncompr);
269 }
270 
271 static unsigned int diff;
272 
273 /* ===========================================================================
274  * Test deflate() with large buffers and dynamic change of compression level
275  */
test_large_deflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen,int zng_params)276 void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) {
277     PREFIX3(stream) c_stream; /* compression stream */
278     int err;
279 #ifndef ZLIB_COMPAT
280     int level = -1;
281     int strategy = -1;
282     zng_deflate_param_value params[2];
283 
284     params[0].param = Z_DEFLATE_LEVEL;
285     params[0].buf = &level;
286     params[0].size = sizeof(level);
287 
288     params[1].param = Z_DEFLATE_STRATEGY;
289     params[1].buf = &strategy;
290     params[1].size = sizeof(strategy);
291 #endif
292 
293     c_stream.zalloc = zalloc;
294     c_stream.zfree = zfree;
295     c_stream.opaque = (void *)0;
296 
297     err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED);
298     CHECK_ERR(err, "deflateInit");
299 
300     c_stream.next_out = compr;
301     c_stream.avail_out = (unsigned int)comprLen;
302 
303     /* At this point, uncompr is still mostly zeroes, so it should compress
304      * very well:
305      */
306     c_stream.next_in = uncompr;
307     c_stream.avail_in = (unsigned int)uncomprLen;
308     err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
309     CHECK_ERR(err, "deflate");
310     if (c_stream.avail_in != 0)
311         error("deflate not greedy\n");
312 
313     /* Feed in already compressed data and switch to no compression: */
314     if (zng_params) {
315 #ifndef ZLIB_COMPAT
316         zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
317         if (level != Z_BEST_SPEED)
318             error("Expected compression level Z_BEST_SPEED, got %d\n", level);
319         if (strategy != Z_DEFAULT_STRATEGY)
320             error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
321         level = Z_NO_COMPRESSION;
322         strategy = Z_DEFAULT_STRATEGY;
323         zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
324 #else
325         error("test_large_deflate() called with zng_params=1 in compat mode\n");
326 #endif
327     } else {
328         PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
329     }
330     c_stream.next_in = compr;
331     diff = (unsigned int)(c_stream.next_out - compr);
332     c_stream.avail_in = diff;
333     err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
334     CHECK_ERR(err, "deflate");
335 
336     /* Switch back to compressing mode: */
337     if (zng_params) {
338 #ifndef ZLIB_COMPAT
339         level = -1;
340         strategy = -1;
341         zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
342         if (level != Z_NO_COMPRESSION)
343             error("Expected compression level Z_NO_COMPRESSION, got %d\n", level);
344         if (strategy != Z_DEFAULT_STRATEGY)
345             error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
346         level = Z_BEST_COMPRESSION;
347         strategy = Z_FILTERED;
348         zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
349 #else
350         error("test_large_deflate() called with zng_params=1 in compat mode\n");
351 #endif
352     } else {
353         PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
354     }
355     c_stream.next_in = uncompr;
356     c_stream.avail_in = (unsigned int)uncomprLen;
357     err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
358     CHECK_ERR(err, "deflate");
359 
360     err = PREFIX(deflate)(&c_stream, Z_FINISH);
361     if (err != Z_STREAM_END)
362         error("deflate should report Z_STREAM_END\n");
363     err = PREFIX(deflateEnd)(&c_stream);
364     CHECK_ERR(err, "deflateEnd");
365 }
366 
367 /* ===========================================================================
368  * Test inflate() with large buffers
369  */
test_large_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)370 void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
371     int err;
372     PREFIX3(stream) d_stream; /* decompression stream */
373 
374     strcpy((char*)uncompr, "garbage");
375 
376     d_stream.zalloc = zalloc;
377     d_stream.zfree = zfree;
378     d_stream.opaque = (void *)0;
379 
380     d_stream.next_in  = compr;
381     d_stream.avail_in = (unsigned int)comprLen;
382     d_stream.total_in = 0;
383     d_stream.total_out = 0;
384 
385     err = PREFIX(inflateInit)(&d_stream);
386     CHECK_ERR(err, "inflateInit");
387 
388     for (;;) {
389         d_stream.next_out = uncompr;            /* discard the output */
390         d_stream.avail_out = (unsigned int)uncomprLen;
391         err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
392         if (err == Z_STREAM_END) break;
393         CHECK_ERR(err, "large inflate");
394     }
395 
396     err = PREFIX(inflateEnd)(&d_stream);
397     CHECK_ERR(err, "inflateEnd");
398 
399     if (d_stream.total_out != 2*uncomprLen + diff)
400         error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
401     else
402         printf("large_inflate(): OK\n");
403 }
404 
405 /* ===========================================================================
406  * Test deflate() with full flush
407  */
test_flush(unsigned char * compr,z_size_t * comprLen)408 void test_flush(unsigned char *compr, z_size_t *comprLen) {
409     PREFIX3(stream) c_stream; /* compression stream */
410     int err;
411     unsigned int len = (unsigned int)strlen(hello)+1;
412 
413     c_stream.zalloc = zalloc;
414     c_stream.zfree = zfree;
415     c_stream.opaque = (void *)0;
416 
417     err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
418     CHECK_ERR(err, "deflateInit");
419 
420     c_stream.next_in  = (z_const unsigned char *)hello;
421     c_stream.next_out = compr;
422     c_stream.avail_in = 3;
423     c_stream.avail_out = (unsigned int)*comprLen;
424     err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
425     CHECK_ERR(err, "deflate");
426 
427     compr[3]++; /* force an error in first compressed block */
428     c_stream.avail_in = len - 3;
429 
430     err = PREFIX(deflate)(&c_stream, Z_FINISH);
431     if (err != Z_STREAM_END) {
432         CHECK_ERR(err, "deflate");
433     }
434     err = PREFIX(deflateEnd)(&c_stream);
435     CHECK_ERR(err, "deflateEnd");
436 
437     *comprLen = (z_size_t)c_stream.total_out;
438 }
439 
440 /* ===========================================================================
441  * Test inflateSync()
442  */
test_sync(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)443 void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
444     int err;
445     PREFIX3(stream) d_stream; /* decompression stream */
446 
447     strcpy((char*)uncompr, "garbage");
448 
449     d_stream.zalloc = zalloc;
450     d_stream.zfree = zfree;
451     d_stream.opaque = (void *)0;
452 
453     d_stream.next_in  = compr;
454     d_stream.avail_in = 2; /* just read the zlib header */
455 
456     err = PREFIX(inflateInit)(&d_stream);
457     CHECK_ERR(err, "inflateInit");
458 
459     d_stream.next_out = uncompr;
460     d_stream.avail_out = (unsigned int)uncomprLen;
461 
462     err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
463     CHECK_ERR(err, "inflate");
464 
465     d_stream.avail_in = (unsigned int)comprLen-2;   /* read all compressed data */
466     err = PREFIX(inflateSync)(&d_stream);           /* but skip the damaged part */
467     CHECK_ERR(err, "inflateSync");
468 
469     err = PREFIX(inflate)(&d_stream, Z_FINISH);
470     if (err != Z_STREAM_END)
471         error("inflate should report Z_STREAM_END\n");
472     err = PREFIX(inflateEnd)(&d_stream);
473     CHECK_ERR(err, "inflateEnd");
474 
475     printf("after inflateSync(): hel%s\n", (char *)uncompr);
476 }
477 
478 /* ===========================================================================
479  * Test deflate() with preset dictionary
480  */
test_dict_deflate(unsigned char * compr,size_t comprLen)481 void test_dict_deflate(unsigned char *compr, size_t comprLen) {
482     PREFIX3(stream) c_stream; /* compression stream */
483     int err;
484 
485     c_stream.zalloc = zalloc;
486     c_stream.zfree = zfree;
487     c_stream.opaque = (void *)0;
488     c_stream.adler = 0;
489 
490     err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
491     CHECK_ERR(err, "deflateInit");
492 
493     err = PREFIX(deflateSetDictionary)(&c_stream,
494                 (const unsigned char*)dictionary, (int)sizeof(dictionary));
495     CHECK_ERR(err, "deflateSetDictionary");
496 
497     dictId = c_stream.adler;
498     c_stream.next_out = compr;
499     c_stream.avail_out = (unsigned int)comprLen;
500 
501     c_stream.next_in = (z_const unsigned char *)hello;
502     c_stream.avail_in = (unsigned int)strlen(hello)+1;
503 
504     err = PREFIX(deflate)(&c_stream, Z_FINISH);
505     if (err != Z_STREAM_END)
506         error("deflate should report Z_STREAM_END\n");
507     err = PREFIX(deflateEnd)(&c_stream);
508     CHECK_ERR(err, "deflateEnd");
509 }
510 
511 /* ===========================================================================
512  * Test inflate() with a preset dictionary
513  */
test_dict_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)514 void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
515     int err;
516     uint8_t check_dictionary[MAX_DICTIONARY_SIZE];
517     uint32_t check_dictionary_len = 0;
518     PREFIX3(stream) d_stream; /* decompression stream */
519 
520     strcpy((char*)uncompr, "garbage garbage garbage");
521 
522     d_stream.zalloc = zalloc;
523     d_stream.zfree = zfree;
524     d_stream.opaque = (void *)0;
525     d_stream.adler = 0;
526     d_stream.next_in  = compr;
527     d_stream.avail_in = (unsigned int)comprLen;
528 
529     err = PREFIX(inflateInit)(&d_stream);
530     CHECK_ERR(err, "inflateInit");
531 
532     d_stream.next_out = uncompr;
533     d_stream.avail_out = (unsigned int)uncomprLen;
534 
535     for (;;) {
536         err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
537         if (err == Z_STREAM_END) break;
538         if (err == Z_NEED_DICT) {
539             if (d_stream.adler != dictId)
540                 error("unexpected dictionary");
541             err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary,
542                                        (int)sizeof(dictionary));
543         }
544         CHECK_ERR(err, "inflate with dict");
545     }
546 
547     err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len);
548     CHECK_ERR(err, "inflateGetDictionary");
549 #ifndef S390_DFLTCC_INFLATE
550     if (check_dictionary_len < sizeof(dictionary))
551         error("bad dictionary length\n");
552 #endif
553 
554     err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len);
555     CHECK_ERR(err, "inflateGetDictionary");
556 #ifndef S390_DFLTCC_INFLATE
557     if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0)
558         error("bad dictionary\n");
559 #endif
560 
561     err = PREFIX(inflateEnd)(&d_stream);
562     CHECK_ERR(err, "inflateEnd");
563 
564     if (strncmp((char*)uncompr, hello, sizeof(hello)))
565         error("bad inflate with dict\n");
566     else
567         printf("inflate with dictionary: %s\n", (char *)uncompr);
568 }
569 
570 /* ===========================================================================
571  * Test deflateBound() with small buffers
572  */
test_deflate_bound(void)573 void test_deflate_bound(void) {
574     PREFIX3(stream) c_stream; /* compression stream */
575     int err;
576     unsigned int len = (unsigned int)strlen(hello)+1;
577     int estimateLen = 0;
578     unsigned char *outBuf = NULL;
579 
580     c_stream.zalloc = zalloc;
581     c_stream.zfree = zfree;
582     c_stream.opaque = (voidpf)0;
583     c_stream.avail_in = len;
584     c_stream.next_in = (z_const unsigned char *)hello;
585     c_stream.avail_out = 0;
586     c_stream.next_out = outBuf;
587 
588     err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
589     CHECK_ERR(err, "deflateInit");
590 
591     /* calculate actual output length and update structure */
592     estimateLen = PREFIX(deflateBound)(&c_stream, len);
593     outBuf = malloc(estimateLen);
594 
595     if (outBuf != NULL) {
596         /* update zlib configuration */
597         c_stream.avail_out = estimateLen;
598         c_stream.next_out = outBuf;
599 
600         /* do the compression */
601         err = PREFIX(deflate)(&c_stream, Z_FINISH);
602         if (err == Z_STREAM_END) {
603             printf("deflateBound(): OK\n");
604         } else {
605             CHECK_ERR(err, "deflate");
606         }
607     }
608 
609     err = PREFIX(deflateEnd)(&c_stream);
610     CHECK_ERR(err, "deflateEnd");
611 
612     free(outBuf);
613 }
614 
615 /* ===========================================================================
616  * Test deflateCopy() with small buffers
617  */
test_deflate_copy(unsigned char * compr,size_t comprLen)618 void test_deflate_copy(unsigned char *compr, size_t comprLen) {
619     PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */
620     int err;
621     size_t len = strlen(hello)+1;
622 
623     memset(&c_stream, 0, sizeof(c_stream));
624 
625     c_stream.zalloc = zalloc;
626     c_stream.zfree = zfree;
627     c_stream.opaque = (voidpf)0;
628 
629     err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
630     CHECK_ERR(err, "deflateInit");
631 
632     c_stream.next_in = (z_const unsigned char *)hello;
633     c_stream.next_out = compr;
634 
635     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
636         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
637         err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
638         CHECK_ERR(err, "deflate");
639     }
640 
641     /* Finish the stream, still forcing small buffers: */
642     for (;;) {
643         c_stream.avail_out = 1;
644         err = PREFIX(deflate)(&c_stream, Z_FINISH);
645         if (err == Z_STREAM_END) break;
646         CHECK_ERR(err, "deflate");
647     }
648 
649     err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream);
650     CHECK_ERR(err, "deflate_copy");
651 
652     if (c_stream.state->status == c_stream_copy.state->status) {
653         printf("deflate_copy(): OK\n");
654     }
655 
656     err = PREFIX(deflateEnd)(&c_stream);
657     CHECK_ERR(err, "deflateEnd original");
658 
659     err = PREFIX(deflateEnd)(&c_stream_copy);
660     CHECK_ERR(err, "deflateEnd copy");
661 }
662 
663 /* ===========================================================================
664  * Test deflateGetDictionary() with small buffers
665  */
test_deflate_get_dict(unsigned char * compr,size_t comprLen)666 void test_deflate_get_dict(unsigned char *compr, size_t comprLen) {
667     PREFIX3(stream) c_stream; /* compression stream */
668     int err;
669     unsigned char *dictNew = NULL;
670     unsigned int *dictLen;
671 
672     c_stream.zalloc = zalloc;
673     c_stream.zfree = zfree;
674     c_stream.opaque = (voidpf)0;
675 
676     err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
677     CHECK_ERR(err, "deflateInit");
678 
679     c_stream.next_out = compr;
680     c_stream.avail_out = (uInt)comprLen;
681 
682     c_stream.next_in = (z_const unsigned char *)hello;
683     c_stream.avail_in = (unsigned int)strlen(hello)+1;
684 
685     err = PREFIX(deflate)(&c_stream, Z_FINISH);
686 
687     if (err != Z_STREAM_END)
688         error("deflate should report Z_STREAM_END\n");
689 
690     dictNew = calloc(256, 1);
691     dictLen = (unsigned int *)calloc(4, 1);
692     err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen);
693 
694     CHECK_ERR(err, "deflateGetDictionary");
695     if (err == Z_OK) {
696         printf("deflateGetDictionary(): %s\n", dictNew);
697     }
698 
699     err = PREFIX(deflateEnd)(&c_stream);
700     CHECK_ERR(err, "deflateEnd");
701 
702     free(dictNew);
703     free(dictLen);
704 }
705 
706 /* ===========================================================================
707  * Test deflatePending() with small buffers
708  */
test_deflate_pending(unsigned char * compr,size_t comprLen)709 void test_deflate_pending(unsigned char *compr, size_t comprLen) {
710     PREFIX3(stream) c_stream; /* compression stream */
711     int err;
712     int *bits = calloc(256, 1);
713     unsigned *ped = calloc(256, 1);
714     size_t len = strlen(hello)+1;
715 
716 
717     c_stream.zalloc = zalloc;
718     c_stream.zfree = zfree;
719     c_stream.opaque = (voidpf)0;
720 
721     err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
722     CHECK_ERR(err, "deflateInit");
723 
724     c_stream.next_in = (z_const unsigned char *)hello;
725     c_stream.next_out = compr;
726 
727     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
728         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
729         err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
730         CHECK_ERR(err, "deflate");
731     }
732 
733     err = PREFIX(deflatePending)(&c_stream, ped, bits);
734     CHECK_ERR(err, "deflatePending");
735 
736     if (*bits >= 0 && *bits <= 7) {
737         printf("deflatePending(): OK\n");
738     } else {
739         printf("deflatePending(): error\n");
740     }
741 
742     /* Finish the stream, still forcing small buffers: */
743     for (;;) {
744         c_stream.avail_out = 1;
745         err = PREFIX(deflate)(&c_stream, Z_FINISH);
746         if (err == Z_STREAM_END) break;
747         CHECK_ERR(err, "deflate");
748     }
749 
750     err = PREFIX(deflateEnd)(&c_stream);
751     CHECK_ERR(err, "deflateEnd");
752 
753     free(bits);
754     free(ped);
755 }
756 
757 /* ===========================================================================
758  * Test deflatePrime() wrapping gzip around deflate stream
759  */
test_deflate_prime(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)760 void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
761     PREFIX3(stream) c_stream; /* compression stream */
762     PREFIX3(stream) d_stream; /* decompression stream */
763     int err;
764     size_t len = strlen(hello)+1;
765     uint32_t crc = 0;
766 
767 
768     c_stream.zalloc = zalloc;
769     c_stream.zfree = zfree;
770     c_stream.opaque = (voidpf)0;
771 
772     /* Raw deflate windowBits is -15 */
773     err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
774     CHECK_ERR(err, "deflateInit2");
775 
776     /* Gzip magic number */
777     err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f);
778     CHECK_ERR(err, "deflatePrime");
779     /* Gzip compression method (deflate) */
780     err = PREFIX(deflatePrime)(&c_stream, 8, 0x08);
781     CHECK_ERR(err, "deflatePrime");
782     /* Gzip flags (one byte, using two odd bit calls) */
783     err = PREFIX(deflatePrime)(&c_stream, 3, 0x0);
784     CHECK_ERR(err, "deflatePrime");
785     err = PREFIX(deflatePrime)(&c_stream, 5, 0x0);
786     CHECK_ERR(err, "deflatePrime");
787     /* Gzip modified time */
788     err = PREFIX(deflatePrime)(&c_stream, 32, 0x0);
789     CHECK_ERR(err, "deflatePrime");
790     /* Gzip extra flags */
791     err = PREFIX(deflatePrime)(&c_stream, 8, 0x0);
792     CHECK_ERR(err, "deflatePrime");
793     /* Gzip operating system */
794     err = PREFIX(deflatePrime)(&c_stream, 8, 255);
795     CHECK_ERR(err, "deflatePrime");
796 
797     c_stream.next_in = (z_const unsigned char *)hello;
798     c_stream.avail_in = (uint32_t)len;
799     c_stream.next_out = compr;
800     c_stream.avail_out = (uint32_t)comprLen;
801 
802     err = PREFIX(deflate)(&c_stream, Z_FINISH);
803     if (err != Z_STREAM_END)
804         CHECK_ERR(err, "deflate");
805 
806     /* Gzip uncompressed data crc32 */
807     crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len);
808     err = PREFIX(deflatePrime)(&c_stream, 32, crc);
809     CHECK_ERR(err, "deflatePrime");
810     /* Gzip uncompressed data length */
811     err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)len);
812     CHECK_ERR(err, "deflatePrime");
813 
814     err = PREFIX(deflateEnd)(&c_stream);
815     CHECK_ERR(err, "deflateEnd");
816 
817     d_stream.zalloc = zalloc;
818     d_stream.zfree = zfree;
819     d_stream.opaque = (void *)0;
820 
821     d_stream.next_in  = compr;
822     d_stream.avail_in = (uint32_t)c_stream.total_out;
823     d_stream.next_out = uncompr;
824     d_stream.avail_out = (uint32_t)uncomprLen;
825     d_stream.total_in = 0;
826     d_stream.total_out = 0;
827 
828     /* Inflate with gzip header */
829     err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32);
830     CHECK_ERR(err, "inflateInit");
831 
832     err = PREFIX(inflate)(&d_stream, Z_FINISH);
833     if (err != Z_BUF_ERROR) {
834         CHECK_ERR(err, "inflate");
835     }
836 
837     err = PREFIX(inflateEnd)(&d_stream);
838     CHECK_ERR(err, "inflateEnd");
839 
840     if (strcmp((const char *)uncompr, hello) != 0)
841         error("bad deflatePrime\n");
842     if (err == Z_OK)
843         printf("deflatePrime(): OK\n");
844 }
845 
846 /* ===========================================================================
847  * Test deflateSetHeader() with small buffers
848  */
test_deflate_set_header(unsigned char * compr,size_t comprLen)849 void test_deflate_set_header(unsigned char *compr, size_t comprLen) {
850     PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header)));
851     PREFIX3(stream) c_stream; /* compression stream */
852     int err;
853     size_t len = strlen(hello)+1;
854 
855 
856     if (head == NULL)
857         error("out of memory\n");
858 
859     c_stream.zalloc = zalloc;
860     c_stream.zfree = zfree;
861     c_stream.opaque = (voidpf)0;
862 
863     /* gzip */
864     err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
865     CHECK_ERR(err, "deflateInit2");
866 
867     head->text = 1;
868     head->comment = (uint8_t *)"comment";
869     head->name = (uint8_t *)"name";
870     head->hcrc = 1;
871     head->extra = (uint8_t *)"extra";
872     head->extra_len = (uint32_t)strlen((const char *)head->extra);
873 
874     err = PREFIX(deflateSetHeader)(&c_stream, head);
875     CHECK_ERR(err, "deflateSetHeader");
876     if (err == Z_OK) {
877         printf("deflateSetHeader(): OK\n");
878     }
879     PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen);
880 
881     c_stream.next_in  = (unsigned char *)hello;
882     c_stream.next_out = compr;
883 
884     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
885         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
886         err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
887         CHECK_ERR(err, "deflate");
888     }
889 
890     /* Finish the stream, still forcing small buffers: */
891     for (;;) {
892         c_stream.avail_out = 1;
893         err = PREFIX(deflate)(&c_stream, Z_FINISH);
894         if (err == Z_STREAM_END) break;
895         CHECK_ERR(err, "deflate");
896     }
897 
898     err = PREFIX(deflateEnd)(&c_stream);
899     CHECK_ERR(err, "deflateEnd");
900 
901     free(head);
902 }
903 
904 /* ===========================================================================
905  * Test deflateTune() with small buffers
906  */
test_deflate_tune(unsigned char * compr,size_t comprLen)907 void test_deflate_tune(unsigned char *compr, size_t comprLen) {
908     PREFIX3(stream) c_stream; /* compression stream */
909     int err;
910     int good_length = 3;
911     int max_lazy = 5;
912     int nice_length = 18;
913     int max_chain = 6;
914     size_t len = strlen(hello)+1;
915 
916 
917     c_stream.zalloc = zalloc;
918     c_stream.zfree = zfree;
919     c_stream.opaque = (voidpf)0;
920 
921     err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
922     CHECK_ERR(err, "deflateInit");
923 
924     err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain);
925     CHECK_ERR(err, "deflateTune");
926     if (err == Z_OK) {
927         printf("deflateTune(): OK\n");
928     }
929 
930     c_stream.next_in = (z_const unsigned char *)hello;
931     c_stream.next_out = compr;
932 
933     while (c_stream.total_in != len && c_stream.total_out < comprLen) {
934         c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
935         err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
936         CHECK_ERR(err, "deflate");
937     }
938 
939     /* Finish the stream, still forcing small buffers: */
940     for (;;) {
941         c_stream.avail_out = 1;
942         err = PREFIX(deflate)(&c_stream, Z_FINISH);
943         if (err == Z_STREAM_END) break;
944         CHECK_ERR(err, "deflate");
945     }
946 
947     err = PREFIX(deflateEnd)(&c_stream);
948     CHECK_ERR(err, "deflateEnd");
949 }
950 
951 /* ===========================================================================
952  * Usage:  example [output.gz  [input.gz]]
953  */
main(int argc,char * argv[])954 int main(int argc, char *argv[]) {
955     unsigned char *compr, *uncompr;
956     z_size_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
957     z_size_t uncomprLen = comprLen;
958     static const char* myVersion = PREFIX2(VERSION);
959 
960     if (zVersion()[0] != myVersion[0]) {
961         fprintf(stderr, "incompatible zlib version\n");
962         exit(1);
963 
964     } else if (strcmp(zVersion(), PREFIX2(VERSION)) != 0) {
965         fprintf(stderr, "warning: different zlib version\n");
966     }
967 
968     printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n",
969             ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)());
970 
971     compr    = (unsigned char*)calloc((unsigned int)comprLen, 1);
972     uncompr  = (unsigned char*)calloc((unsigned int)uncomprLen, 1);
973     /* compr and uncompr are cleared to avoid reading uninitialized
974      * data and to ensure that uncompr compresses well.
975      */
976     if (compr == NULL || uncompr == NULL)
977         error("out of memory\n");
978 
979     test_compress(compr, comprLen, uncompr, uncomprLen);
980 
981     test_gzio((argc > 1 ? argv[1] : TESTFILE),
982               uncompr, uncomprLen);
983 
984     test_deflate(compr, comprLen);
985     test_inflate(compr, comprLen, uncompr, uncomprLen);
986 
987     test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0);
988     test_large_inflate(compr, comprLen, uncompr, uncomprLen);
989 
990 #ifndef ZLIB_COMPAT
991     test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1);
992     test_large_inflate(compr, comprLen, uncompr, uncomprLen);
993 #endif
994 
995     test_flush(compr, &comprLen);
996     test_sync(compr, comprLen, uncompr, uncomprLen);
997     comprLen = uncomprLen;
998 
999     test_dict_deflate(compr, comprLen);
1000     test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
1001 
1002     test_deflate_bound();
1003     test_deflate_copy(compr, comprLen);
1004     test_deflate_get_dict(compr, comprLen);
1005     test_deflate_set_header(compr, comprLen);
1006     test_deflate_tune(compr, comprLen);
1007     test_deflate_pending(compr, comprLen);
1008     test_deflate_prime(compr, comprLen, uncompr, uncomprLen);
1009 
1010     free(compr);
1011     free(uncompr);
1012 
1013     return 0;
1014 }
1015