12569963fSbluhm /* example.c -- usage example of the zlib compression library
22569963fSbluhm * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
32569963fSbluhm * For conditions of distribution and use, see copyright notice in zlib.h
42569963fSbluhm */
52569963fSbluhm
6*b0b511c0Stb /* @(#) $Id: example.c,v 1.3 2023/11/18 22:40:14 tb Exp $ */
72569963fSbluhm
82569963fSbluhm #include "zlib.h"
92569963fSbluhm #include <stdio.h>
102569963fSbluhm
112569963fSbluhm #ifdef STDC
122569963fSbluhm # include <string.h>
132569963fSbluhm # include <stdlib.h>
142569963fSbluhm #endif
152569963fSbluhm
162569963fSbluhm #if defined(VMS) || defined(RISCOS)
172569963fSbluhm # define TESTFILE "foo-gz"
182569963fSbluhm #else
192569963fSbluhm # define TESTFILE "foo.gz"
202569963fSbluhm #endif
212569963fSbluhm
222569963fSbluhm #define CHECK_ERR(err, msg) { \
232569963fSbluhm if (err != Z_OK) { \
242569963fSbluhm fprintf(stderr, "%s error: %d\n", msg, err); \
252569963fSbluhm exit(1); \
262569963fSbluhm } \
272569963fSbluhm }
282569963fSbluhm
292569963fSbluhm static z_const char hello[] = "hello, hello!";
302569963fSbluhm /* "hello world" would be more standard, but the repeated "hello"
312569963fSbluhm * stresses the compression code better, sorry...
322569963fSbluhm */
332569963fSbluhm
342569963fSbluhm static const char dictionary[] = "hello";
352569963fSbluhm static uLong dictId; /* Adler32 value of the dictionary */
362569963fSbluhm
372569963fSbluhm #ifdef Z_SOLO
382569963fSbluhm
myalloc(void * q,unsigned n,unsigned m)39*b0b511c0Stb static void *myalloc(void *q, unsigned n, unsigned m) {
402569963fSbluhm (void)q;
412569963fSbluhm return calloc(n, m);
422569963fSbluhm }
432569963fSbluhm
myfree(void * q,void * p)44*b0b511c0Stb static void myfree(void *q, void *p) {
452569963fSbluhm (void)q;
462569963fSbluhm free(p);
472569963fSbluhm }
482569963fSbluhm
492569963fSbluhm static alloc_func zalloc = myalloc;
502569963fSbluhm static free_func zfree = myfree;
512569963fSbluhm
522569963fSbluhm #else /* !Z_SOLO */
532569963fSbluhm
542569963fSbluhm static alloc_func zalloc = (alloc_func)0;
552569963fSbluhm static free_func zfree = (free_func)0;
562569963fSbluhm
572569963fSbluhm /* ===========================================================================
582569963fSbluhm * Test compress() and uncompress()
592569963fSbluhm */
test_compress(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)60*b0b511c0Stb static void test_compress(Byte *compr, uLong comprLen, Byte *uncompr,
61*b0b511c0Stb uLong uncomprLen) {
622569963fSbluhm int err;
632569963fSbluhm uLong len = (uLong)strlen(hello)+1;
642569963fSbluhm
652569963fSbluhm err = compress(compr, &comprLen, (const Bytef*)hello, len);
662569963fSbluhm CHECK_ERR(err, "compress");
672569963fSbluhm
682569963fSbluhm strcpy((char*)uncompr, "garbage");
692569963fSbluhm
702569963fSbluhm err = uncompress(uncompr, &uncomprLen, compr, comprLen);
712569963fSbluhm CHECK_ERR(err, "uncompress");
722569963fSbluhm
732569963fSbluhm if (strcmp((char*)uncompr, hello)) {
742569963fSbluhm fprintf(stderr, "bad uncompress\n");
752569963fSbluhm exit(1);
762569963fSbluhm } else {
772569963fSbluhm printf("uncompress(): %s\n", (char *)uncompr);
782569963fSbluhm }
792569963fSbluhm }
802569963fSbluhm
812569963fSbluhm /* ===========================================================================
822569963fSbluhm * Test read/write of .gz files
832569963fSbluhm */
test_gzio(const char * fname,Byte * uncompr,uLong uncomprLen)84*b0b511c0Stb static void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) {
852569963fSbluhm #ifdef NO_GZCOMPRESS
862569963fSbluhm fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
872569963fSbluhm #else
882569963fSbluhm int err;
892569963fSbluhm int len = (int)strlen(hello)+1;
902569963fSbluhm gzFile file;
912569963fSbluhm z_off_t pos;
922569963fSbluhm
932569963fSbluhm file = gzopen(fname, "wb");
942569963fSbluhm if (file == NULL) {
952569963fSbluhm fprintf(stderr, "gzopen error\n");
962569963fSbluhm exit(1);
972569963fSbluhm }
982569963fSbluhm gzputc(file, 'h');
992569963fSbluhm if (gzputs(file, "ello") != 4) {
1002569963fSbluhm fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
1012569963fSbluhm exit(1);
1022569963fSbluhm }
1032569963fSbluhm if (gzprintf(file, ", %s!", "hello") != 8) {
1042569963fSbluhm fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
1052569963fSbluhm exit(1);
1062569963fSbluhm }
1072569963fSbluhm gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
1082569963fSbluhm gzclose(file);
1092569963fSbluhm
1102569963fSbluhm file = gzopen(fname, "rb");
1112569963fSbluhm if (file == NULL) {
1122569963fSbluhm fprintf(stderr, "gzopen error\n");
1132569963fSbluhm exit(1);
1142569963fSbluhm }
1152569963fSbluhm strcpy((char*)uncompr, "garbage");
1162569963fSbluhm
1172569963fSbluhm if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
1182569963fSbluhm fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
1192569963fSbluhm exit(1);
1202569963fSbluhm }
1212569963fSbluhm if (strcmp((char*)uncompr, hello)) {
1222569963fSbluhm fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
1232569963fSbluhm exit(1);
1242569963fSbluhm } else {
1252569963fSbluhm printf("gzread(): %s\n", (char*)uncompr);
1262569963fSbluhm }
1272569963fSbluhm
1282569963fSbluhm pos = gzseek(file, -8L, SEEK_CUR);
1292569963fSbluhm if (pos != 6 || gztell(file) != pos) {
1302569963fSbluhm fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
1312569963fSbluhm (long)pos, (long)gztell(file));
1322569963fSbluhm exit(1);
1332569963fSbluhm }
1342569963fSbluhm
1352569963fSbluhm if (gzgetc(file) != ' ') {
1362569963fSbluhm fprintf(stderr, "gzgetc error\n");
1372569963fSbluhm exit(1);
1382569963fSbluhm }
1392569963fSbluhm
1402569963fSbluhm if (gzungetc(' ', file) != ' ') {
1412569963fSbluhm fprintf(stderr, "gzungetc error\n");
1422569963fSbluhm exit(1);
1432569963fSbluhm }
1442569963fSbluhm
1452569963fSbluhm gzgets(file, (char*)uncompr, (int)uncomprLen);
1462569963fSbluhm if (strlen((char*)uncompr) != 7) { /* " hello!" */
1472569963fSbluhm fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
1482569963fSbluhm exit(1);
1492569963fSbluhm }
1502569963fSbluhm if (strcmp((char*)uncompr, hello + 6)) {
1512569963fSbluhm fprintf(stderr, "bad gzgets after gzseek\n");
1522569963fSbluhm exit(1);
1532569963fSbluhm } else {
1542569963fSbluhm printf("gzgets() after gzseek: %s\n", (char*)uncompr);
1552569963fSbluhm }
1562569963fSbluhm
1572569963fSbluhm gzclose(file);
1582569963fSbluhm #endif
1592569963fSbluhm }
1602569963fSbluhm
1612569963fSbluhm #endif /* Z_SOLO */
1622569963fSbluhm
1632569963fSbluhm /* ===========================================================================
1642569963fSbluhm * Test deflate() with small buffers
1652569963fSbluhm */
test_deflate(Byte * compr,uLong comprLen)166*b0b511c0Stb static void test_deflate(Byte *compr, uLong comprLen) {
1672569963fSbluhm z_stream c_stream; /* compression stream */
1682569963fSbluhm int err;
1692569963fSbluhm uLong len = (uLong)strlen(hello)+1;
1702569963fSbluhm
1712569963fSbluhm c_stream.zalloc = zalloc;
1722569963fSbluhm c_stream.zfree = zfree;
1732569963fSbluhm c_stream.opaque = (voidpf)0;
1742569963fSbluhm
1752569963fSbluhm err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
1762569963fSbluhm CHECK_ERR(err, "deflateInit");
1772569963fSbluhm
1782569963fSbluhm c_stream.next_in = (z_const unsigned char *)hello;
1792569963fSbluhm c_stream.next_out = compr;
1802569963fSbluhm
1812569963fSbluhm while (c_stream.total_in != len && c_stream.total_out < comprLen) {
1822569963fSbluhm c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
1832569963fSbluhm err = deflate(&c_stream, Z_NO_FLUSH);
1842569963fSbluhm CHECK_ERR(err, "deflate");
1852569963fSbluhm }
1862569963fSbluhm /* Finish the stream, still forcing small buffers: */
1872569963fSbluhm for (;;) {
1882569963fSbluhm c_stream.avail_out = 1;
1892569963fSbluhm err = deflate(&c_stream, Z_FINISH);
1902569963fSbluhm if (err == Z_STREAM_END) break;
1912569963fSbluhm CHECK_ERR(err, "deflate");
1922569963fSbluhm }
1932569963fSbluhm
1942569963fSbluhm err = deflateEnd(&c_stream);
1952569963fSbluhm CHECK_ERR(err, "deflateEnd");
1962569963fSbluhm }
1972569963fSbluhm
1982569963fSbluhm /* ===========================================================================
1992569963fSbluhm * Test inflate() with small buffers
2002569963fSbluhm */
test_inflate(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)201*b0b511c0Stb static void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
202*b0b511c0Stb uLong uncomprLen) {
2032569963fSbluhm int err;
2042569963fSbluhm z_stream d_stream; /* decompression stream */
2052569963fSbluhm
2062569963fSbluhm strcpy((char*)uncompr, "garbage");
2072569963fSbluhm
2082569963fSbluhm d_stream.zalloc = zalloc;
2092569963fSbluhm d_stream.zfree = zfree;
2102569963fSbluhm d_stream.opaque = (voidpf)0;
2112569963fSbluhm
2122569963fSbluhm d_stream.next_in = compr;
2132569963fSbluhm d_stream.avail_in = 0;
2142569963fSbluhm d_stream.next_out = uncompr;
2152569963fSbluhm
2162569963fSbluhm err = inflateInit(&d_stream);
2172569963fSbluhm CHECK_ERR(err, "inflateInit");
2182569963fSbluhm
2192569963fSbluhm while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
2202569963fSbluhm d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
2212569963fSbluhm err = inflate(&d_stream, Z_NO_FLUSH);
2222569963fSbluhm if (err == Z_STREAM_END) break;
2232569963fSbluhm CHECK_ERR(err, "inflate");
2242569963fSbluhm }
2252569963fSbluhm
2262569963fSbluhm err = inflateEnd(&d_stream);
2272569963fSbluhm CHECK_ERR(err, "inflateEnd");
2282569963fSbluhm
2292569963fSbluhm if (strcmp((char*)uncompr, hello)) {
2302569963fSbluhm fprintf(stderr, "bad inflate\n");
2312569963fSbluhm exit(1);
2322569963fSbluhm } else {
2332569963fSbluhm printf("inflate(): %s\n", (char *)uncompr);
2342569963fSbluhm }
2352569963fSbluhm }
2362569963fSbluhm
2372569963fSbluhm /* ===========================================================================
2382569963fSbluhm * Test deflate() with large buffers and dynamic change of compression level
2392569963fSbluhm */
test_large_deflate(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)240*b0b511c0Stb static void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr,
241*b0b511c0Stb uLong uncomprLen) {
2422569963fSbluhm z_stream c_stream; /* compression stream */
2432569963fSbluhm int err;
2442569963fSbluhm
2452569963fSbluhm c_stream.zalloc = zalloc;
2462569963fSbluhm c_stream.zfree = zfree;
2472569963fSbluhm c_stream.opaque = (voidpf)0;
2482569963fSbluhm
2492569963fSbluhm err = deflateInit(&c_stream, Z_BEST_SPEED);
2502569963fSbluhm CHECK_ERR(err, "deflateInit");
2512569963fSbluhm
2522569963fSbluhm c_stream.next_out = compr;
2532569963fSbluhm c_stream.avail_out = (uInt)comprLen;
2542569963fSbluhm
2552569963fSbluhm /* At this point, uncompr is still mostly zeroes, so it should compress
2562569963fSbluhm * very well:
2572569963fSbluhm */
2582569963fSbluhm c_stream.next_in = uncompr;
2592569963fSbluhm c_stream.avail_in = (uInt)uncomprLen;
2602569963fSbluhm err = deflate(&c_stream, Z_NO_FLUSH);
2612569963fSbluhm CHECK_ERR(err, "deflate");
2622569963fSbluhm if (c_stream.avail_in != 0) {
2632569963fSbluhm fprintf(stderr, "deflate not greedy\n");
2642569963fSbluhm exit(1);
2652569963fSbluhm }
2662569963fSbluhm
2672569963fSbluhm /* Feed in already compressed data and switch to no compression: */
2682569963fSbluhm deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
2692569963fSbluhm c_stream.next_in = compr;
270*b0b511c0Stb c_stream.avail_in = (uInt)uncomprLen/2;
2712569963fSbluhm err = deflate(&c_stream, Z_NO_FLUSH);
2722569963fSbluhm CHECK_ERR(err, "deflate");
2732569963fSbluhm
2742569963fSbluhm /* Switch back to compressing mode: */
2752569963fSbluhm deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
2762569963fSbluhm c_stream.next_in = uncompr;
2772569963fSbluhm c_stream.avail_in = (uInt)uncomprLen;
2782569963fSbluhm err = deflate(&c_stream, Z_NO_FLUSH);
2792569963fSbluhm CHECK_ERR(err, "deflate");
2802569963fSbluhm
2812569963fSbluhm err = deflate(&c_stream, Z_FINISH);
2822569963fSbluhm if (err != Z_STREAM_END) {
2832569963fSbluhm fprintf(stderr, "deflate should report Z_STREAM_END\n");
2842569963fSbluhm exit(1);
2852569963fSbluhm }
2862569963fSbluhm err = deflateEnd(&c_stream);
2872569963fSbluhm CHECK_ERR(err, "deflateEnd");
2882569963fSbluhm }
2892569963fSbluhm
2902569963fSbluhm /* ===========================================================================
2912569963fSbluhm * Test inflate() with large buffers
2922569963fSbluhm */
test_large_inflate(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)293*b0b511c0Stb static void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
294*b0b511c0Stb uLong uncomprLen) {
2952569963fSbluhm int err;
2962569963fSbluhm z_stream d_stream; /* decompression stream */
2972569963fSbluhm
2982569963fSbluhm strcpy((char*)uncompr, "garbage");
2992569963fSbluhm
3002569963fSbluhm d_stream.zalloc = zalloc;
3012569963fSbluhm d_stream.zfree = zfree;
3022569963fSbluhm d_stream.opaque = (voidpf)0;
3032569963fSbluhm
3042569963fSbluhm d_stream.next_in = compr;
3052569963fSbluhm d_stream.avail_in = (uInt)comprLen;
3062569963fSbluhm
3072569963fSbluhm err = inflateInit(&d_stream);
3082569963fSbluhm CHECK_ERR(err, "inflateInit");
3092569963fSbluhm
3102569963fSbluhm for (;;) {
3112569963fSbluhm d_stream.next_out = uncompr; /* discard the output */
3122569963fSbluhm d_stream.avail_out = (uInt)uncomprLen;
3132569963fSbluhm err = inflate(&d_stream, Z_NO_FLUSH);
3142569963fSbluhm if (err == Z_STREAM_END) break;
3152569963fSbluhm CHECK_ERR(err, "large inflate");
3162569963fSbluhm }
3172569963fSbluhm
3182569963fSbluhm err = inflateEnd(&d_stream);
3192569963fSbluhm CHECK_ERR(err, "inflateEnd");
3202569963fSbluhm
321*b0b511c0Stb if (d_stream.total_out != 2*uncomprLen + uncomprLen/2) {
3222569963fSbluhm fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
3232569963fSbluhm exit(1);
3242569963fSbluhm } else {
3252569963fSbluhm printf("large_inflate(): OK\n");
3262569963fSbluhm }
3272569963fSbluhm }
3282569963fSbluhm
3292569963fSbluhm /* ===========================================================================
3302569963fSbluhm * Test deflate() with full flush
3312569963fSbluhm */
test_flush(Byte * compr,uLong * comprLen)332*b0b511c0Stb static void test_flush(Byte *compr, uLong *comprLen) {
3332569963fSbluhm z_stream c_stream; /* compression stream */
3342569963fSbluhm int err;
3352569963fSbluhm uInt len = (uInt)strlen(hello)+1;
3362569963fSbluhm
3372569963fSbluhm c_stream.zalloc = zalloc;
3382569963fSbluhm c_stream.zfree = zfree;
3392569963fSbluhm c_stream.opaque = (voidpf)0;
3402569963fSbluhm
3412569963fSbluhm err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
3422569963fSbluhm CHECK_ERR(err, "deflateInit");
3432569963fSbluhm
3442569963fSbluhm c_stream.next_in = (z_const unsigned char *)hello;
3452569963fSbluhm c_stream.next_out = compr;
3462569963fSbluhm c_stream.avail_in = 3;
3472569963fSbluhm c_stream.avail_out = (uInt)*comprLen;
3482569963fSbluhm err = deflate(&c_stream, Z_FULL_FLUSH);
3492569963fSbluhm CHECK_ERR(err, "deflate");
3502569963fSbluhm
3512569963fSbluhm compr[3]++; /* force an error in first compressed block */
3522569963fSbluhm c_stream.avail_in = len - 3;
3532569963fSbluhm
3542569963fSbluhm err = deflate(&c_stream, Z_FINISH);
3552569963fSbluhm if (err != Z_STREAM_END) {
3562569963fSbluhm CHECK_ERR(err, "deflate");
3572569963fSbluhm }
3582569963fSbluhm err = deflateEnd(&c_stream);
3592569963fSbluhm CHECK_ERR(err, "deflateEnd");
3602569963fSbluhm
3612569963fSbluhm *comprLen = c_stream.total_out;
3622569963fSbluhm }
3632569963fSbluhm
3642569963fSbluhm /* ===========================================================================
3652569963fSbluhm * Test inflateSync()
3662569963fSbluhm */
test_sync(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)367*b0b511c0Stb static void test_sync(Byte *compr, uLong comprLen, Byte *uncompr,
368*b0b511c0Stb uLong uncomprLen) {
3692569963fSbluhm int err;
3702569963fSbluhm z_stream d_stream; /* decompression stream */
3712569963fSbluhm
3722569963fSbluhm strcpy((char*)uncompr, "garbage");
3732569963fSbluhm
3742569963fSbluhm d_stream.zalloc = zalloc;
3752569963fSbluhm d_stream.zfree = zfree;
3762569963fSbluhm d_stream.opaque = (voidpf)0;
3772569963fSbluhm
3782569963fSbluhm d_stream.next_in = compr;
3792569963fSbluhm d_stream.avail_in = 2; /* just read the zlib header */
3802569963fSbluhm
3812569963fSbluhm err = inflateInit(&d_stream);
3822569963fSbluhm CHECK_ERR(err, "inflateInit");
3832569963fSbluhm
3842569963fSbluhm d_stream.next_out = uncompr;
3852569963fSbluhm d_stream.avail_out = (uInt)uncomprLen;
3862569963fSbluhm
3872569963fSbluhm err = inflate(&d_stream, Z_NO_FLUSH);
3882569963fSbluhm CHECK_ERR(err, "inflate");
3892569963fSbluhm
3902569963fSbluhm d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
3912569963fSbluhm err = inflateSync(&d_stream); /* but skip the damaged part */
3922569963fSbluhm CHECK_ERR(err, "inflateSync");
3932569963fSbluhm
3942569963fSbluhm err = inflate(&d_stream, Z_FINISH);
3956e97c859Stb if (err != Z_STREAM_END) {
3966e97c859Stb fprintf(stderr, "inflate should report Z_STREAM_END\n");
3972569963fSbluhm exit(1);
3982569963fSbluhm }
3992569963fSbluhm err = inflateEnd(&d_stream);
4002569963fSbluhm CHECK_ERR(err, "inflateEnd");
4012569963fSbluhm
4022569963fSbluhm printf("after inflateSync(): hel%s\n", (char *)uncompr);
4032569963fSbluhm }
4042569963fSbluhm
4052569963fSbluhm /* ===========================================================================
4062569963fSbluhm * Test deflate() with preset dictionary
4072569963fSbluhm */
test_dict_deflate(Byte * compr,uLong comprLen)408*b0b511c0Stb static void test_dict_deflate(Byte *compr, uLong comprLen) {
4092569963fSbluhm z_stream c_stream; /* compression stream */
4102569963fSbluhm int err;
4112569963fSbluhm
4122569963fSbluhm c_stream.zalloc = zalloc;
4132569963fSbluhm c_stream.zfree = zfree;
4142569963fSbluhm c_stream.opaque = (voidpf)0;
4152569963fSbluhm
4162569963fSbluhm err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
4172569963fSbluhm CHECK_ERR(err, "deflateInit");
4182569963fSbluhm
4192569963fSbluhm err = deflateSetDictionary(&c_stream,
4202569963fSbluhm (const Bytef*)dictionary, (int)sizeof(dictionary));
4212569963fSbluhm CHECK_ERR(err, "deflateSetDictionary");
4222569963fSbluhm
4232569963fSbluhm dictId = c_stream.adler;
4242569963fSbluhm c_stream.next_out = compr;
4252569963fSbluhm c_stream.avail_out = (uInt)comprLen;
4262569963fSbluhm
4272569963fSbluhm c_stream.next_in = (z_const unsigned char *)hello;
4282569963fSbluhm c_stream.avail_in = (uInt)strlen(hello)+1;
4292569963fSbluhm
4302569963fSbluhm err = deflate(&c_stream, Z_FINISH);
4312569963fSbluhm if (err != Z_STREAM_END) {
4322569963fSbluhm fprintf(stderr, "deflate should report Z_STREAM_END\n");
4332569963fSbluhm exit(1);
4342569963fSbluhm }
4352569963fSbluhm err = deflateEnd(&c_stream);
4362569963fSbluhm CHECK_ERR(err, "deflateEnd");
4372569963fSbluhm }
4382569963fSbluhm
4392569963fSbluhm /* ===========================================================================
4402569963fSbluhm * Test inflate() with a preset dictionary
4412569963fSbluhm */
test_dict_inflate(Byte * compr,uLong comprLen,Byte * uncompr,uLong uncomprLen)442*b0b511c0Stb static void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
443*b0b511c0Stb uLong uncomprLen) {
4442569963fSbluhm int err;
4452569963fSbluhm z_stream d_stream; /* decompression stream */
4462569963fSbluhm
4472569963fSbluhm strcpy((char*)uncompr, "garbage");
4482569963fSbluhm
4492569963fSbluhm d_stream.zalloc = zalloc;
4502569963fSbluhm d_stream.zfree = zfree;
4512569963fSbluhm d_stream.opaque = (voidpf)0;
4522569963fSbluhm
4532569963fSbluhm d_stream.next_in = compr;
4542569963fSbluhm d_stream.avail_in = (uInt)comprLen;
4552569963fSbluhm
4562569963fSbluhm err = inflateInit(&d_stream);
4572569963fSbluhm CHECK_ERR(err, "inflateInit");
4582569963fSbluhm
4592569963fSbluhm d_stream.next_out = uncompr;
4602569963fSbluhm d_stream.avail_out = (uInt)uncomprLen;
4612569963fSbluhm
4622569963fSbluhm for (;;) {
4632569963fSbluhm err = inflate(&d_stream, Z_NO_FLUSH);
4642569963fSbluhm if (err == Z_STREAM_END) break;
4652569963fSbluhm if (err == Z_NEED_DICT) {
4662569963fSbluhm if (d_stream.adler != dictId) {
4672569963fSbluhm fprintf(stderr, "unexpected dictionary");
4682569963fSbluhm exit(1);
4692569963fSbluhm }
4702569963fSbluhm err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
4712569963fSbluhm (int)sizeof(dictionary));
4722569963fSbluhm }
4732569963fSbluhm CHECK_ERR(err, "inflate with dict");
4742569963fSbluhm }
4752569963fSbluhm
4762569963fSbluhm err = inflateEnd(&d_stream);
4772569963fSbluhm CHECK_ERR(err, "inflateEnd");
4782569963fSbluhm
4792569963fSbluhm if (strcmp((char*)uncompr, hello)) {
4802569963fSbluhm fprintf(stderr, "bad inflate with dict\n");
4812569963fSbluhm exit(1);
4822569963fSbluhm } else {
4832569963fSbluhm printf("inflate with dictionary: %s\n", (char *)uncompr);
4842569963fSbluhm }
4852569963fSbluhm }
4862569963fSbluhm
4872569963fSbluhm /* ===========================================================================
4882569963fSbluhm * Usage: example [output.gz [input.gz]]
4892569963fSbluhm */
4902569963fSbluhm
main(int argc,char * argv[])491*b0b511c0Stb int main(int argc, char *argv[]) {
4922569963fSbluhm Byte *compr, *uncompr;
493*b0b511c0Stb uLong uncomprLen = 20000;
494*b0b511c0Stb uLong comprLen = 3 * uncomprLen;
4952569963fSbluhm static const char* myVersion = ZLIB_VERSION;
4962569963fSbluhm
4972569963fSbluhm if (zlibVersion()[0] != myVersion[0]) {
4982569963fSbluhm fprintf(stderr, "incompatible zlib version\n");
4992569963fSbluhm exit(1);
5002569963fSbluhm
5012569963fSbluhm } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
502*b0b511c0Stb fprintf(stderr, "warning: different zlib version linked: %s\n",
503*b0b511c0Stb zlibVersion());
5042569963fSbluhm }
5052569963fSbluhm
5062569963fSbluhm printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
5072569963fSbluhm ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
5082569963fSbluhm
5092569963fSbluhm compr = (Byte*)calloc((uInt)comprLen, 1);
5102569963fSbluhm uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
5112569963fSbluhm /* compr and uncompr are cleared to avoid reading uninitialized
5122569963fSbluhm * data and to ensure that uncompr compresses well.
5132569963fSbluhm */
5142569963fSbluhm if (compr == Z_NULL || uncompr == Z_NULL) {
5152569963fSbluhm printf("out of memory\n");
5162569963fSbluhm exit(1);
5172569963fSbluhm }
5182569963fSbluhm
5192569963fSbluhm #ifdef Z_SOLO
5202569963fSbluhm (void)argc;
5212569963fSbluhm (void)argv;
5222569963fSbluhm #else
5232569963fSbluhm test_compress(compr, comprLen, uncompr, uncomprLen);
5242569963fSbluhm
5252569963fSbluhm test_gzio((argc > 1 ? argv[1] : TESTFILE),
5262569963fSbluhm uncompr, uncomprLen);
5272569963fSbluhm #endif
5282569963fSbluhm
5292569963fSbluhm test_deflate(compr, comprLen);
5302569963fSbluhm test_inflate(compr, comprLen, uncompr, uncomprLen);
5312569963fSbluhm
5322569963fSbluhm test_large_deflate(compr, comprLen, uncompr, uncomprLen);
5332569963fSbluhm test_large_inflate(compr, comprLen, uncompr, uncomprLen);
5342569963fSbluhm
5352569963fSbluhm test_flush(compr, &comprLen);
5362569963fSbluhm test_sync(compr, comprLen, uncompr, uncomprLen);
537*b0b511c0Stb comprLen = 3 * uncomprLen;
5382569963fSbluhm
5392569963fSbluhm test_dict_deflate(compr, comprLen);
5402569963fSbluhm test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
5412569963fSbluhm
5422569963fSbluhm free(compr);
5432569963fSbluhm free(uncompr);
5442569963fSbluhm
5452569963fSbluhm return 0;
5462569963fSbluhm }
547