1 /* example.c contains minimal changes required to be compiled with zlibWrapper:
2 * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h"
3 * - test_flush() and test_sync() use functions not supported by zlibWrapper
4 therefore they are disabled while zstd compression is turned on */
6 /* example.c -- usage example of the zlib compression library
9 Copyright (c) 1995-2006, 2011 Jean-loup Gailly
11 This software is provided 'as-is', without any express or implied
12 warranty. In no event will the authors be held liable for any damages
13 arising from the use of this software.
15 Permission is granted to anyone to use this software for any purpose,
16 including commercial applications, and to alter it and redistribute it
17 freely, subject to the following restrictions:
19 1. The origin of this software must not be misrepresented; you must not
20 claim that you wrote the original software. If you use this software
21 in a product, an acknowledgement in the product documentation would be
22 appreciated but is not required.
23 2. Altered source versions must be plainly marked as such, and must not be
24 misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source distribution.
30 #include "zstd_zlibwrapper.h"
38 #if defined(VMS) || defined(RISCOS)
39 # define TESTFILE "foo-gz"
41 # define TESTFILE "foo.gz"
44 #define CHECK_ERR(err, msg) { \
46 fprintf(stderr, "%s error: %d\n", msg, err); \
51 z_const char hello[] = "hello, hello! I said hello, hello!";
52 /* "hello world" would be more standard, but the repeated "hello"
53 * stresses the compression code better, sorry...
56 const char dictionary[] = "hello, hello!";
57 uLong dictId; /* Adler32 value of the dictionary */
59 void test_deflate _Z_OF((Byte *compr, uLong comprLen));
60 void test_inflate _Z_OF((Byte *compr, uLong comprLen,
61 Byte *uncompr, uLong uncomprLen));
62 void test_large_deflate _Z_OF((Byte *compr, uLong comprLen,
63 Byte *uncompr, uLong uncomprLen));
64 void test_large_inflate _Z_OF((Byte *compr, uLong comprLen,
65 Byte *uncompr, uLong uncomprLen));
66 void test_flush _Z_OF((Byte *compr, uLong *comprLen));
67 void test_sync _Z_OF((Byte *compr, uLong comprLen,
68 Byte *uncompr, uLong uncomprLen));
69 void test_dict_deflate _Z_OF((Byte *compr, uLong comprLen));
70 void test_dict_inflate _Z_OF((Byte *compr, uLong comprLen,
71 Byte *uncompr, uLong uncomprLen));
72 int main _Z_OF((int argc, char *argv[]));
77 void *myalloc _Z_OF((void *, unsigned, unsigned));
78 void myfree _Z_OF((void *, void *));
80 void *myalloc(void *q, unsigned n, unsigned m)
82 void *buf = calloc(n, m);
84 /* printf("myalloc %p n=%d m=%d\n", buf, n, m); */
88 void myfree(void *q, void *p)
90 /* printf("myfree %p\n", p); */
95 static alloc_func zalloc = myalloc;
96 static free_func zfree = myfree;
100 static alloc_func zalloc = (alloc_func)0;
101 static free_func zfree = (free_func)0;
103 void test_compress _Z_OF((Byte *compr, uLong comprLen,
104 Byte *uncompr, uLong uncomprLen));
105 void test_gzio _Z_OF((const char *fname,
106 Byte *uncompr, uLong uncomprLen));
108 /* ===========================================================================
109 * Test compress() and uncompress()
111 void test_compress(Byte *compr, uLong comprLen, Byte *uncompr,
114 uLong len = (uLong)strlen(hello)+1;
116 err = compress(compr, &comprLen, (const Bytef*)hello, len);
117 CHECK_ERR(err, "compress");
119 strcpy((char*)uncompr, "garbage");
121 err = uncompress(uncompr, &uncomprLen, compr, comprLen);
122 CHECK_ERR(err, "uncompress");
124 if (strcmp((char*)uncompr, hello)) {
125 fprintf(stderr, "bad uncompress\n");
128 printf("uncompress(): %s\n", (char *)uncompr);
132 /* ===========================================================================
133 * Test read/write of .gz files
135 void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) {
137 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
140 int len = (int)strlen(hello)+1;
144 file = gzopen(fname, "wb");
146 fprintf(stderr, "gzopen error\n");
150 if (gzputs(file, "ello") != 4) {
151 fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
154 if (gzprintf(file, ", %s! I said hello, hello!", "hello") != 8+21) {
155 fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
158 gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
161 file = gzopen(fname, "rb");
163 fprintf(stderr, "gzopen error\n");
166 strcpy((char*)uncompr, "garbage");
168 if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
169 fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
172 if (strcmp((char*)uncompr, hello)) {
173 fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
176 printf("gzread(): %s\n", (char*)uncompr);
179 pos = gzseek(file, -8L, SEEK_CUR);
180 if (pos != 6+21 || gztell(file) != pos) {
181 fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
182 (long)pos, (long)gztell(file));
186 if (gzgetc(file) != ' ') {
187 fprintf(stderr, "gzgetc error\n");
191 if (gzungetc(' ', file) != ' ') {
192 fprintf(stderr, "gzungetc error\n");
196 gzgets(file, (char*)uncompr, (int)uncomprLen);
197 if (strlen((char*)uncompr) != 7) { /* " hello!" */
198 fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
201 if (strcmp((char*)uncompr, hello + 6+21)) {
202 fprintf(stderr, "bad gzgets after gzseek\n");
205 printf("gzgets() after gzseek: %s\n", (char*)uncompr);
214 /* ===========================================================================
215 * Test deflate() with small buffers
217 void test_deflate(Byte *compr, uLong comprLen) {
218 z_stream c_stream; /* compression stream */
220 uLong len = (uLong)strlen(hello)+1;
222 c_stream.zalloc = zalloc;
223 c_stream.zfree = zfree;
224 c_stream.opaque = (voidpf)0;
226 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
227 CHECK_ERR(err, "deflateInit");
229 c_stream.next_in = (z_const unsigned char *)hello;
230 c_stream.next_out = compr;
232 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
233 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
234 err = deflate(&c_stream, Z_NO_FLUSH);
235 CHECK_ERR(err, "deflate");
237 /* Finish the stream, still forcing small buffers: */
239 c_stream.avail_out = 1;
240 err = deflate(&c_stream, Z_FINISH);
241 if (err == Z_STREAM_END) break;
242 CHECK_ERR(err, "deflate");
245 err = deflateEnd(&c_stream);
246 CHECK_ERR(err, "deflateEnd");
249 /* ===========================================================================
250 * Test inflate() with small buffers
252 void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
255 z_stream d_stream; /* decompression stream */
257 strcpy((char*)uncompr, "garbage");
259 d_stream.zalloc = zalloc;
260 d_stream.zfree = zfree;
261 d_stream.opaque = (voidpf)0;
263 d_stream.next_in = compr;
264 d_stream.avail_in = 0;
265 d_stream.next_out = uncompr;
267 err = inflateInit(&d_stream);
268 CHECK_ERR(err, "inflateInit");
270 while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
271 d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
272 err = inflate(&d_stream, Z_NO_FLUSH);
273 if (err == Z_STREAM_END) break;
274 CHECK_ERR(err, "inflate");
277 err = inflateEnd(&d_stream);
278 CHECK_ERR(err, "inflateEnd");
280 if (strcmp((char*)uncompr, hello)) {
281 fprintf(stderr, "bad inflate\n");
284 printf("inflate(): %s\n", (char *)uncompr);
288 /* ===========================================================================
289 * Test deflate() with large buffers and dynamic change of compression level
291 void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr,
293 z_stream c_stream; /* compression stream */
296 c_stream.zalloc = zalloc;
297 c_stream.zfree = zfree;
298 c_stream.opaque = (voidpf)0;
300 err = deflateInit(&c_stream, Z_BEST_SPEED);
301 CHECK_ERR(err, "deflateInit");
303 c_stream.next_out = compr;
304 c_stream.avail_out = (uInt)comprLen;
306 /* At this point, uncompr is still mostly zeroes, so it should compress
309 c_stream.next_in = uncompr;
310 c_stream.avail_in = (uInt)uncomprLen;
311 err = deflate(&c_stream, Z_NO_FLUSH);
312 CHECK_ERR(err, "deflate");
313 if (c_stream.avail_in != 0) {
314 fprintf(stderr, "deflate not greedy\n");
318 /* Feed in already compressed data and switch to no compression: */
319 deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
320 c_stream.next_in = compr;
321 c_stream.avail_in = (uInt)comprLen/2;
322 err = deflate(&c_stream, Z_NO_FLUSH);
323 CHECK_ERR(err, "deflate");
325 /* Switch back to compressing mode: */
326 deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
327 c_stream.next_in = uncompr;
328 c_stream.avail_in = (uInt)uncomprLen;
329 err = deflate(&c_stream, Z_NO_FLUSH);
330 CHECK_ERR(err, "deflate");
332 err = deflate(&c_stream, Z_FINISH);
333 if (err != Z_STREAM_END) {
334 fprintf(stderr, "deflate should report Z_STREAM_END\n");
337 err = deflateEnd(&c_stream);
338 CHECK_ERR(err, "deflateEnd");
341 /* ===========================================================================
342 * Test inflate() with large buffers
344 void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
347 z_stream d_stream; /* decompression stream */
349 strcpy((char*)uncompr, "garbage");
351 d_stream.zalloc = zalloc;
352 d_stream.zfree = zfree;
353 d_stream.opaque = (voidpf)0;
355 d_stream.next_in = compr;
356 d_stream.avail_in = (uInt)comprLen;
358 err = inflateInit(&d_stream);
359 CHECK_ERR(err, "inflateInit");
362 d_stream.next_out = uncompr; /* discard the output */
363 d_stream.avail_out = (uInt)uncomprLen;
364 err = inflate(&d_stream, Z_NO_FLUSH);
365 if (err == Z_STREAM_END) break;
366 CHECK_ERR(err, "large inflate");
369 err = inflateEnd(&d_stream);
370 CHECK_ERR(err, "inflateEnd");
372 if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
373 fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
376 printf("large_inflate(): OK\n");
380 /* ===========================================================================
381 * Test deflate() with full flush
383 void test_flush(Byte *compr, uLong *comprLen) {
384 z_stream c_stream; /* compression stream */
386 uInt len = (uInt)strlen(hello)+1;
388 c_stream.zalloc = zalloc;
389 c_stream.zfree = zfree;
390 c_stream.opaque = (voidpf)0;
392 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
393 CHECK_ERR(err, "deflateInit");
395 c_stream.next_in = (z_const unsigned char *)hello;
396 c_stream.next_out = compr;
397 c_stream.avail_in = 3;
398 c_stream.avail_out = (uInt)*comprLen;
399 err = deflate(&c_stream, Z_FULL_FLUSH);
400 CHECK_ERR(err, "deflate");
402 compr[3]++; /* force an error in first compressed block */
403 c_stream.avail_in = len - 3;
405 err = deflate(&c_stream, Z_FINISH);
406 if (err != Z_STREAM_END) {
407 CHECK_ERR(err, "deflate");
409 err = deflateEnd(&c_stream);
410 CHECK_ERR(err, "deflateEnd");
412 *comprLen = c_stream.total_out;
415 /* ===========================================================================
418 void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) {
420 z_stream d_stream; /* decompression stream */
422 strcpy((char*)uncompr, "garbage");
424 d_stream.zalloc = zalloc;
425 d_stream.zfree = zfree;
426 d_stream.opaque = (voidpf)0;
428 d_stream.next_in = compr;
429 d_stream.avail_in = 2; /* just read the zlib header */
431 err = inflateInit(&d_stream);
432 CHECK_ERR(err, "inflateInit");
434 d_stream.next_out = uncompr;
435 d_stream.avail_out = (uInt)uncomprLen;
437 inflate(&d_stream, Z_NO_FLUSH);
438 CHECK_ERR(err, "inflate");
440 d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
441 err = inflateSync(&d_stream); /* but skip the damaged part */
442 CHECK_ERR(err, "inflateSync");
444 err = inflate(&d_stream, Z_FINISH);
445 if (err != Z_DATA_ERROR) {
446 fprintf(stderr, "inflate should report DATA_ERROR\n");
447 /* Because of incorrect adler32 */
450 err = inflateEnd(&d_stream);
451 CHECK_ERR(err, "inflateEnd");
453 printf("after inflateSync(): hel%s\n", (char *)uncompr);
456 /* ===========================================================================
457 * Test deflate() with preset dictionary
459 void test_dict_deflate(Byte *compr, uLong comprLen) {
460 z_stream c_stream; /* compression stream */
463 c_stream.zalloc = zalloc;
464 c_stream.zfree = zfree;
465 c_stream.opaque = (voidpf)0;
467 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
468 CHECK_ERR(err, "deflateInit");
470 err = deflateSetDictionary(&c_stream,
471 (const Bytef*)dictionary, (int)sizeof(dictionary));
472 CHECK_ERR(err, "deflateSetDictionary");
474 dictId = c_stream.adler;
475 c_stream.next_out = compr;
476 c_stream.avail_out = (uInt)comprLen;
478 c_stream.next_in = (z_const unsigned char *)hello;
479 c_stream.avail_in = (uInt)strlen(hello)+1;
481 err = deflate(&c_stream, Z_FINISH);
482 if (err != Z_STREAM_END) {
483 fprintf(stderr, "deflate should report Z_STREAM_END\n");
486 err = deflateEnd(&c_stream);
487 CHECK_ERR(err, "deflateEnd");
490 /* ===========================================================================
491 * Test inflate() with a preset dictionary
493 void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
496 z_stream d_stream; /* decompression stream */
498 strcpy((char*)uncompr, "garbage");
500 d_stream.zalloc = zalloc;
501 d_stream.zfree = zfree;
502 d_stream.opaque = (voidpf)0;
504 d_stream.next_in = compr;
505 d_stream.avail_in = (uInt)comprLen;
507 err = inflateInit(&d_stream);
508 CHECK_ERR(err, "inflateInit");
510 d_stream.next_out = uncompr;
511 d_stream.avail_out = (uInt)uncomprLen;
514 err = inflate(&d_stream, Z_NO_FLUSH);
515 if (err == Z_STREAM_END) break;
516 if (err == Z_NEED_DICT) {
517 if (d_stream.adler != dictId) {
518 fprintf(stderr, "unexpected dictionary");
521 err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
522 (int)sizeof(dictionary));
524 CHECK_ERR(err, "inflate with dict");
527 err = inflateEnd(&d_stream);
528 CHECK_ERR(err, "inflateEnd");
530 if (strcmp((char*)uncompr, hello)) {
531 fprintf(stderr, "bad inflate with dict\n");
534 printf("inflate with dictionary: %s\n", (char *)uncompr);
538 /* ===========================================================================
539 * Usage: example [output.gz [input.gz]]
542 int main(int argc, char *argv[]) {
543 Byte *compr, *uncompr;
544 uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
545 uLong uncomprLen = comprLen;
546 static const char* myVersion = ZLIB_VERSION;
548 if (zlibVersion()[0] != myVersion[0]) {
549 fprintf(stderr, "incompatible zlib version\n");
552 } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
553 fprintf(stderr, "warning: different zlib version\n");
556 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
557 ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
558 if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion());
560 compr = (Byte*)calloc((uInt)comprLen, 1);
561 uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
562 /* compr and uncompr are cleared to avoid reading uninitialized
563 * data and to ensure that uncompr compresses well.
565 if (compr == Z_NULL || uncompr == Z_NULL) {
566 printf("out of memory\n");
571 argc = strlen(argv[0]);
573 test_compress(compr, comprLen, uncompr, uncomprLen);
575 test_gzio((argc > 1 ? argv[1] : TESTFILE),
576 uncompr, uncomprLen);
579 test_deflate(compr, comprLen);
580 test_inflate(compr, comprLen, uncompr, uncomprLen);
582 test_large_deflate(compr, comprLen, uncompr, uncomprLen);
583 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
585 if (!ZWRAP_isUsingZSTDcompression()) {
586 test_flush(compr, &comprLen);
587 test_sync(compr, comprLen, uncompr, uncomprLen);
589 comprLen = uncomprLen;
591 test_dict_deflate(compr, comprLen);
592 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);