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