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