Previous 199869 Revisions Next

r23790 Wednesday 19th June, 2013 at 12:09:13 UTC by Oliver Stöneberg
removed unused exmaples from zlib folder (nw)
[src/lib/zlib]example.c minigzip.c

trunk/src/lib/zlib/minigzip.c
r23789r23790
1/* minigzip.c -- simulate gzip using the zlib compression library
2 * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/*
7 * minigzip is a minimal implementation of the gzip utility. This is
8 * only an example of using zlib and isn't meant to replace the
9 * full-featured gzip. No attempt is made to deal with file systems
10 * limiting names to 14 or 8+3 characters, etc... Error checking is
11 * very limited. So use minigzip only for testing; use gzip for the
12 * real thing. On MSDOS, use only on file names without extension
13 * or in pipe mode.
14 */
15
16/* @(#) $Id$ */
17
18#include "zlib.h"
19#include <stdio.h>
20
21#ifdef STDC
22#  include <string.h>
23#  include <stdlib.h>
24#endif
25
26#ifdef USE_MMAP
27#  include <sys/types.h>
28#  include <sys/mman.h>
29#  include <sys/stat.h>
30#endif
31
32#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
33#  include <fcntl.h>
34#  include <io.h>
35#  ifdef UNDER_CE
36#    include <stdlib.h>
37#  endif
38#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
39#else
40#  define SET_BINARY_MODE(file)
41#endif
42
43#ifdef VMS
44#  define unlink delete
45#  define GZ_SUFFIX "-gz"
46#endif
47#ifdef RISCOS
48#  define unlink remove
49#  define GZ_SUFFIX "-gz"
50#  define fileno(file) file->__file
51#endif
52#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
53#  include <unix.h> /* for fileno */
54#endif
55
56#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
57#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
58   extern int unlink OF((const char *));
59#endif
60#endif
61
62#if defined(UNDER_CE)
63#  include <windows.h>
64#  define perror(s) pwinerror(s)
65
66/* Map the Windows error number in ERROR to a locale-dependent error
67   message string and return a pointer to it.  Typically, the values
68   for ERROR come from GetLastError.
69
70   The string pointed to shall not be modified by the application,
71   but may be overwritten by a subsequent call to strwinerror
72
73   The strwinerror function does not change the current setting
74   of GetLastError.  */
75
76static char *strwinerror (error)
77      DWORD error;
78{
79   static char buf[1024];
80
81   wchar_t *msgbuf;
82   DWORD lasterr = GetLastError();
83   DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
84      | FORMAT_MESSAGE_ALLOCATE_BUFFER,
85      NULL,
86      error,
87      0, /* Default language */
88      (LPVOID)&msgbuf,
89      0,
90      NULL);
91   if (chars != 0) {
92      /* If there is an \r\n appended, zap it.  */
93      if (chars >= 2
94         && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
95         chars -= 2;
96         msgbuf[chars] = 0;
97      }
98
99      if (chars > sizeof (buf) - 1) {
100         chars = sizeof (buf) - 1;
101         msgbuf[chars] = 0;
102      }
103
104      wcstombs(buf, msgbuf, chars + 1);
105      LocalFree(msgbuf);
106   }
107   else {
108      sprintf(buf, "unknown win32 error (%ld)", error);
109   }
110
111   SetLastError(lasterr);
112   return buf;
113}
114
115static void pwinerror (s)
116   const char *s;
117{
118   if (s && *s)
119      fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
120   else
121      fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
122}
123
124#endif /* UNDER_CE */
125
126#ifndef GZ_SUFFIX
127#  define GZ_SUFFIX ".gz"
128#endif
129#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
130
131#define BUFLEN      16384
132#define MAX_NAME_LEN 1024
133
134#ifdef MAXSEG_64K
135#  define local static
136   /* Needed for systems with limitation on stack size. */
137#else
138#  define local
139#endif
140
141#ifdef Z_SOLO
142/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
143
144#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
145#  include <unistd.h>       /* for unlink() */
146#endif
147
148void *myalloc OF((void *, unsigned, unsigned));
149void myfree OF((void *, void *));
150
151void *myalloc(q, n, m)
152   void *q;
153   unsigned n, m;
154{
155   q = Z_NULL;
156   return calloc(n, m);
157}
158
159void myfree(q, p)
160   void *q, *p;
161{
162   q = Z_NULL;
163   free(p);
164}
165
166typedef struct gzFile_s {
167   FILE *file;
168   int write;
169   int err;
170   char *msg;
171   z_stream strm;
172} *gzFile;
173
174gzFile gzopen OF((const char *, const char *));
175gzFile gzdopen OF((int, const char *));
176gzFile gz_open OF((const char *, int, const char *));
177
178gzFile gzopen(path, mode)
179const char *path;
180const char *mode;
181{
182   return gz_open(path, -1, mode);
183}
184
185gzFile gzdopen(fd, mode)
186int fd;
187const char *mode;
188{
189   return gz_open(NULL, fd, mode);
190}
191
192gzFile gz_open(path, fd, mode)
193   const char *path;
194   int fd;
195   const char *mode;
196{
197   gzFile gz;
198   int ret;
199
200   gz = malloc(sizeof(struct gzFile_s));
201   if (gz == NULL)
202      return NULL;
203   gz->write = strchr(mode, 'w') != NULL;
204   gz->strm.zalloc = myalloc;
205   gz->strm.zfree = myfree;
206   gz->strm.opaque = Z_NULL;
207   if (gz->write)
208      ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
209   else {
210      gz->strm.next_in = 0;
211      gz->strm.avail_in = Z_NULL;
212      ret = inflateInit2(&(gz->strm), 15 + 16);
213   }
214   if (ret != Z_OK) {
215      free(gz);
216      return NULL;
217   }
218   gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
219                        fopen(path, gz->write ? "wb" : "rb");
220   if (gz->file == NULL) {
221      gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
222      free(gz);
223      return NULL;
224   }
225   gz->err = 0;
226   gz->msg = "";
227   return gz;
228}
229
230int gzwrite OF((gzFile, const void *, unsigned));
231
232int gzwrite(gz, buf, len)
233   gzFile gz;
234   const void *buf;
235   unsigned len;
236{
237   z_stream *strm;
238   unsigned char out[BUFLEN];
239
240   if (gz == NULL || !gz->write)
241      return 0;
242   strm = &(gz->strm);
243   strm->next_in = (void *)buf;
244   strm->avail_in = len;
245   do {
246      strm->next_out = out;
247      strm->avail_out = BUFLEN;
248      (void)deflate(strm, Z_NO_FLUSH);
249      fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
250   } while (strm->avail_out == 0);
251   return len;
252}
253
254int gzread OF((gzFile, void *, unsigned));
255
256int gzread(gz, buf, len)
257   gzFile gz;
258   void *buf;
259   unsigned len;
260{
261   int ret;
262   unsigned got;
263   unsigned char in[1];
264   z_stream *strm;
265
266   if (gz == NULL || gz->write)
267      return 0;
268   if (gz->err)
269      return 0;
270   strm = &(gz->strm);
271   strm->next_out = (void *)buf;
272   strm->avail_out = len;
273   do {
274      got = fread(in, 1, 1, gz->file);
275      if (got == 0)
276         break;
277      strm->next_in = in;
278      strm->avail_in = 1;
279      ret = inflate(strm, Z_NO_FLUSH);
280      if (ret == Z_DATA_ERROR) {
281         gz->err = Z_DATA_ERROR;
282         gz->msg = strm->msg;
283         return 0;
284      }
285      if (ret == Z_STREAM_END)
286         inflateReset(strm);
287   } while (strm->avail_out);
288   return len - strm->avail_out;
289}
290
291int gzclose OF((gzFile));
292
293int gzclose(gz)
294   gzFile gz;
295{
296   z_stream *strm;
297   unsigned char out[BUFLEN];
298
299   if (gz == NULL)
300      return Z_STREAM_ERROR;
301   strm = &(gz->strm);
302   if (gz->write) {
303      strm->next_in = Z_NULL;
304      strm->avail_in = 0;
305      do {
306         strm->next_out = out;
307         strm->avail_out = BUFLEN;
308         (void)deflate(strm, Z_FINISH);
309         fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
310      } while (strm->avail_out == 0);
311      deflateEnd(strm);
312   }
313   else
314      inflateEnd(strm);
315   fclose(gz->file);
316   free(gz);
317   return Z_OK;
318}
319
320const char *gzerror OF((gzFile, int *));
321
322const char *gzerror(gz, err)
323   gzFile gz;
324   int *err;
325{
326   *err = gz->err;
327   return gz->msg;
328}
329
330#endif
331
332char *prog;
333
334void error            OF((const char *msg));
335void gz_compress      OF((FILE   *in, gzFile out));
336#ifdef USE_MMAP
337int  gz_compress_mmap OF((FILE   *in, gzFile out));
338#endif
339void gz_uncompress    OF((gzFile in, FILE   *out));
340void file_compress    OF((char  *file, char *mode));
341void file_uncompress  OF((char  *file));
342int  main             OF((int argc, char *argv[]));
343
344/* ===========================================================================
345 * Display error message and exit
346 */
347void error(msg)
348   const char *msg;
349{
350   fprintf(stderr, "%s: %s\n", prog, msg);
351   exit(1);
352}
353
354/* ===========================================================================
355 * Compress input to output then close both files.
356 */
357
358void gz_compress(in, out)
359   FILE   *in;
360   gzFile out;
361{
362   local char buf[BUFLEN];
363   int len;
364   int err;
365
366#ifdef USE_MMAP
367   /* Try first compressing with mmap. If mmap fails (minigzip used in a
368    * pipe), use the normal fread loop.
369    */
370   if (gz_compress_mmap(in, out) == Z_OK) return;
371#endif
372   for (;;) {
373      len = (int)fread(buf, 1, sizeof(buf), in);
374      if (ferror(in)) {
375         perror("fread");
376         exit(1);
377      }
378      if (len == 0) break;
379
380      if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
381   }
382   fclose(in);
383   if (gzclose(out) != Z_OK) error("failed gzclose");
384}
385
386#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
387
388/* Try compressing the input file at once using mmap. Return Z_OK if
389 * if success, Z_ERRNO otherwise.
390 */
391int gz_compress_mmap(in, out)
392   FILE   *in;
393   gzFile out;
394{
395   int len;
396   int err;
397   int ifd = fileno(in);
398   caddr_t buf;    /* mmap'ed buffer for the entire input file */
399   off_t buf_len;  /* length of the input file */
400   struct stat sb;
401
402   /* Determine the size of the file, needed for mmap: */
403   if (fstat(ifd, &sb) < 0) return Z_ERRNO;
404   buf_len = sb.st_size;
405   if (buf_len <= 0) return Z_ERRNO;
406
407   /* Now do the actual mmap: */
408   buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
409   if (buf == (caddr_t)(-1)) return Z_ERRNO;
410
411   /* Compress the whole file at once: */
412   len = gzwrite(out, (char *)buf, (unsigned)buf_len);
413
414   if (len != (int)buf_len) error(gzerror(out, &err));
415
416   munmap(buf, buf_len);
417   fclose(in);
418   if (gzclose(out) != Z_OK) error("failed gzclose");
419   return Z_OK;
420}
421#endif /* USE_MMAP */
422
423/* ===========================================================================
424 * Uncompress input to output then close both files.
425 */
426void gz_uncompress(in, out)
427   gzFile in;
428   FILE   *out;
429{
430   local char buf[BUFLEN];
431   int len;
432   int err;
433
434   for (;;) {
435      len = gzread(in, buf, sizeof(buf));
436      if (len < 0) error (gzerror(in, &err));
437      if (len == 0) break;
438
439      if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
440         error("failed fwrite");
441      }
442   }
443   if (fclose(out)) error("failed fclose");
444
445   if (gzclose(in) != Z_OK) error("failed gzclose");
446}
447
448
449/* ===========================================================================
450 * Compress the given file: create a corresponding .gz file and remove the
451 * original.
452 */
453void file_compress(file, mode)
454   char  *file;
455   char  *mode;
456{
457   local char outfile[MAX_NAME_LEN];
458   FILE  *in;
459   gzFile out;
460
461   if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
462      fprintf(stderr, "%s: filename too long\n", prog);
463      exit(1);
464   }
465
466   strcpy(outfile, file);
467   strcat(outfile, GZ_SUFFIX);
468
469   in = fopen(file, "rb");
470   if (in == NULL) {
471      perror(file);
472      exit(1);
473   }
474   out = gzopen(outfile, mode);
475   if (out == NULL) {
476      fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
477      exit(1);
478   }
479   gz_compress(in, out);
480
481   unlink(file);
482}
483
484
485/* ===========================================================================
486 * Uncompress the given file and remove the original.
487 */
488void file_uncompress(file)
489   char  *file;
490{
491   local char buf[MAX_NAME_LEN];
492   char *infile, *outfile;
493   FILE  *out;
494   gzFile in;
495   size_t len = strlen(file);
496
497   if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
498      fprintf(stderr, "%s: filename too long\n", prog);
499      exit(1);
500   }
501
502   strcpy(buf, file);
503
504   if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
505      infile = file;
506      outfile = buf;
507      outfile[len-3] = '\0';
508   } else {
509      outfile = file;
510      infile = buf;
511      strcat(infile, GZ_SUFFIX);
512   }
513   in = gzopen(infile, "rb");
514   if (in == NULL) {
515      fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
516      exit(1);
517   }
518   out = fopen(outfile, "wb");
519   if (out == NULL) {
520      perror(file);
521      exit(1);
522   }
523
524   gz_uncompress(in, out);
525
526   unlink(infile);
527}
528
529
530/* ===========================================================================
531 * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
532 *   -c : write to standard output
533 *   -d : decompress
534 *   -f : compress with Z_FILTERED
535 *   -h : compress with Z_HUFFMAN_ONLY
536 *   -r : compress with Z_RLE
537 *   -1 to -9 : compression level
538 */
539
540int main(argc, argv)
541   int argc;
542   char *argv[];
543{
544   int copyout = 0;
545   int uncompr = 0;
546   gzFile file;
547   char *bname, outmode[20];
548
549   strcpy(outmode, "wb6 ");
550
551   prog = argv[0];
552   bname = strrchr(argv[0], '/');
553   if (bname)
554      bname++;
555   else
556      bname = argv[0];
557   argc--, argv++;
558
559   if (!strcmp(bname, "gunzip"))
560      uncompr = 1;
561   else if (!strcmp(bname, "zcat"))
562      copyout = uncompr = 1;
563
564   while (argc > 0) {
565      if (strcmp(*argv, "-c") == 0)
566      copyout = 1;
567      else if (strcmp(*argv, "-d") == 0)
568      uncompr = 1;
569      else if (strcmp(*argv, "-f") == 0)
570      outmode[3] = 'f';
571      else if (strcmp(*argv, "-h") == 0)
572      outmode[3] = 'h';
573      else if (strcmp(*argv, "-r") == 0)
574      outmode[3] = 'R';
575      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
576            (*argv)[2] == 0)
577      outmode[2] = (*argv)[1];
578      else
579      break;
580      argc--, argv++;
581   }
582   if (outmode[3] == ' ')
583      outmode[3] = 0;
584   if (argc == 0) {
585      SET_BINARY_MODE(stdin);
586      SET_BINARY_MODE(stdout);
587      if (uncompr) {
588         file = gzdopen(fileno(stdin), "rb");
589         if (file == NULL) error("can't gzdopen stdin");
590         gz_uncompress(file, stdout);
591      } else {
592         file = gzdopen(fileno(stdout), outmode);
593         if (file == NULL) error("can't gzdopen stdout");
594         gz_compress(stdin, file);
595      }
596   } else {
597      if (copyout) {
598         SET_BINARY_MODE(stdout);
599      }
600      do {
601         if (uncompr) {
602            if (copyout) {
603               file = gzopen(*argv, "rb");
604               if (file == NULL)
605                  fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
606               else
607                  gz_uncompress(file, stdout);
608            } else {
609               file_uncompress(*argv);
610            }
611         } else {
612            if (copyout) {
613               FILE * in = fopen(*argv, "rb");
614
615               if (in == NULL) {
616                  perror(*argv);
617               } else {
618                  file = gzdopen(fileno(stdout), outmode);
619                  if (file == NULL) error("can't gzdopen stdout");
620
621                  gz_compress(in, file);
622               }
623
624            } else {
625               file_compress(*argv, outmode);
626            }
627         }
628      } while (argv++, --argc);
629   }
630   return 0;
631}
trunk/src/lib/zlib/example.c
r23789r23790
1/* example.c -- usage example of the zlib compression library
2 * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* @(#) $Id$ */
7
8#include "zlib.h"
9#include <stdio.h>
10
11#ifdef STDC
12#  include <string.h>
13#  include <stdlib.h>
14#endif
15
16#if defined(VMS) || defined(RISCOS)
17#  define TESTFILE "foo-gz"
18#else
19#  define TESTFILE "foo.gz"
20#endif
21
22#define CHECK_ERR(err, msg) { \
23   if (err != Z_OK) { \
24      fprintf(stderr, "%s error: %d\n", msg, err); \
25      exit(1); \
26   } \
27}
28
29const char hello[] = "hello, hello!";
30/* "hello world" would be more standard, but the repeated "hello"
31 * stresses the compression code better, sorry...
32 */
33
34const char dictionary[] = "hello";
35uLong dictId; /* Adler32 value of the dictionary */
36
37void test_deflate       OF((Byte *compr, uLong comprLen));
38void test_inflate       OF((Byte *compr, uLong comprLen,
39                     Byte *uncompr, uLong uncomprLen));
40void test_large_deflate OF((Byte *compr, uLong comprLen,
41                     Byte *uncompr, uLong uncomprLen));
42void test_large_inflate OF((Byte *compr, uLong comprLen,
43                     Byte *uncompr, uLong uncomprLen));
44void test_flush         OF((Byte *compr, uLong *comprLen));
45void test_sync          OF((Byte *compr, uLong comprLen,
46                     Byte *uncompr, uLong uncomprLen));
47void test_dict_deflate  OF((Byte *compr, uLong comprLen));
48void test_dict_inflate  OF((Byte *compr, uLong comprLen,
49                     Byte *uncompr, uLong uncomprLen));
50int  main               OF((int argc, char *argv[]));
51
52
53#ifdef Z_SOLO
54
55void *myalloc OF((void *, unsigned, unsigned));
56void myfree OF((void *, void *));
57
58void *myalloc(q, n, m)
59   void *q;
60   unsigned n, m;
61{
62   q = Z_NULL;
63   return calloc(n, m);
64}
65
66void myfree(void *q, void *p)
67{
68   q = Z_NULL;
69   free(p);
70}
71
72static alloc_func zalloc = myalloc;
73static free_func zfree = myfree;
74
75#else /* !Z_SOLO */
76
77static alloc_func zalloc = (alloc_func)0;
78static free_func zfree = (free_func)0;
79
80void test_compress      OF((Byte *compr, uLong comprLen,
81                     Byte *uncompr, uLong uncomprLen));
82void test_gzio          OF((const char *fname,
83                     Byte *uncompr, uLong uncomprLen));
84
85/* ===========================================================================
86 * Test compress() and uncompress()
87 */
88void test_compress(compr, comprLen, uncompr, uncomprLen)
89   Byte *compr, *uncompr;
90   uLong comprLen, uncomprLen;
91{
92   int err;
93   uLong len = (uLong)strlen(hello)+1;
94
95   err = compress(compr, &comprLen, (const Bytef*)hello, len);
96   CHECK_ERR(err, "compress");
97
98   strcpy((char*)uncompr, "garbage");
99
100   err = uncompress(uncompr, &uncomprLen, compr, comprLen);
101   CHECK_ERR(err, "uncompress");
102
103   if (strcmp((char*)uncompr, hello)) {
104      fprintf(stderr, "bad uncompress\n");
105      exit(1);
106   } else {
107      printf("uncompress(): %s\n", (char *)uncompr);
108   }
109}
110
111/* ===========================================================================
112 * Test read/write of .gz files
113 */
114void test_gzio(fname, uncompr, uncomprLen)
115   const char *fname; /* compressed file name */
116   Byte *uncompr;
117   uLong uncomprLen;
118{
119#ifdef NO_GZCOMPRESS
120   fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
121#else
122   int err;
123   int len = (int)strlen(hello)+1;
124   gzFile file;
125   z_off_t pos;
126
127   file = gzopen(fname, "wb");
128   if (file == NULL) {
129      fprintf(stderr, "gzopen error\n");
130      exit(1);
131   }
132   gzputc(file, 'h');
133   if (gzputs(file, "ello") != 4) {
134      fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
135      exit(1);
136   }
137   if (gzprintf(file, ", %s!", "hello") != 8) {
138      fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
139      exit(1);
140   }
141   gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
142   gzclose(file);
143
144   file = gzopen(fname, "rb");
145   if (file == NULL) {
146      fprintf(stderr, "gzopen error\n");
147      exit(1);
148   }
149   strcpy((char*)uncompr, "garbage");
150
151   if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
152      fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
153      exit(1);
154   }
155   if (strcmp((char*)uncompr, hello)) {
156      fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
157      exit(1);
158   } else {
159      printf("gzread(): %s\n", (char*)uncompr);
160   }
161
162   pos = gzseek(file, -8L, SEEK_CUR);
163   if (pos != 6 || gztell(file) != pos) {
164      fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
165            (long)pos, (long)gztell(file));
166      exit(1);
167   }
168
169   if (gzgetc(file) != ' ') {
170      fprintf(stderr, "gzgetc error\n");
171      exit(1);
172   }
173
174   if (gzungetc(' ', file) != ' ') {
175      fprintf(stderr, "gzungetc error\n");
176      exit(1);
177   }
178
179   gzgets(file, (char*)uncompr, (int)uncomprLen);
180   if (strlen((char*)uncompr) != 7) { /* " hello!" */
181      fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
182      exit(1);
183   }
184   if (strcmp((char*)uncompr, hello + 6)) {
185      fprintf(stderr, "bad gzgets after gzseek\n");
186      exit(1);
187   } else {
188      printf("gzgets() after gzseek: %s\n", (char*)uncompr);
189   }
190
191   gzclose(file);
192#endif
193}
194
195#endif /* Z_SOLO */
196
197/* ===========================================================================
198 * Test deflate() with small buffers
199 */
200void test_deflate(compr, comprLen)
201   Byte *compr;
202   uLong comprLen;
203{
204   z_stream c_stream; /* compression stream */
205   int err;
206   uLong len = (uLong)strlen(hello)+1;
207
208   c_stream.zalloc = zalloc;
209   c_stream.zfree = zfree;
210   c_stream.opaque = (voidpf)0;
211
212   err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
213   CHECK_ERR(err, "deflateInit");
214
215   c_stream.next_in  = (Bytef*)hello;
216   c_stream.next_out = compr;
217
218   while (c_stream.total_in != len && c_stream.total_out < comprLen) {
219      c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
220      err = deflate(&c_stream, Z_NO_FLUSH);
221      CHECK_ERR(err, "deflate");
222   }
223   /* Finish the stream, still forcing small buffers: */
224   for (;;) {
225      c_stream.avail_out = 1;
226      err = deflate(&c_stream, Z_FINISH);
227      if (err == Z_STREAM_END) break;
228      CHECK_ERR(err, "deflate");
229   }
230
231   err = deflateEnd(&c_stream);
232   CHECK_ERR(err, "deflateEnd");
233}
234
235/* ===========================================================================
236 * Test inflate() with small buffers
237 */
238void test_inflate(compr, comprLen, uncompr, uncomprLen)
239   Byte *compr, *uncompr;
240   uLong comprLen, uncomprLen;
241{
242   int err;
243   z_stream d_stream; /* decompression stream */
244
245   strcpy((char*)uncompr, "garbage");
246
247   d_stream.zalloc = zalloc;
248   d_stream.zfree = zfree;
249   d_stream.opaque = (voidpf)0;
250
251   d_stream.next_in  = compr;
252   d_stream.avail_in = 0;
253   d_stream.next_out = uncompr;
254
255   err = inflateInit(&d_stream);
256   CHECK_ERR(err, "inflateInit");
257
258   while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
259      d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
260      err = inflate(&d_stream, Z_NO_FLUSH);
261      if (err == Z_STREAM_END) break;
262      CHECK_ERR(err, "inflate");
263   }
264
265   err = inflateEnd(&d_stream);
266   CHECK_ERR(err, "inflateEnd");
267
268   if (strcmp((char*)uncompr, hello)) {
269      fprintf(stderr, "bad inflate\n");
270      exit(1);
271   } else {
272      printf("inflate(): %s\n", (char *)uncompr);
273   }
274}
275
276/* ===========================================================================
277 * Test deflate() with large buffers and dynamic change of compression level
278 */
279void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
280   Byte *compr, *uncompr;
281   uLong comprLen, uncomprLen;
282{
283   z_stream c_stream; /* compression stream */
284   int err;
285
286   c_stream.zalloc = zalloc;
287   c_stream.zfree = zfree;
288   c_stream.opaque = (voidpf)0;
289
290   err = deflateInit(&c_stream, Z_BEST_SPEED);
291   CHECK_ERR(err, "deflateInit");
292
293   c_stream.next_out = compr;
294   c_stream.avail_out = (uInt)comprLen;
295
296   /* At this point, uncompr is still mostly zeroes, so it should compress
297    * very well:
298    */
299   c_stream.next_in = uncompr;
300   c_stream.avail_in = (uInt)uncomprLen;
301   err = deflate(&c_stream, Z_NO_FLUSH);
302   CHECK_ERR(err, "deflate");
303   if (c_stream.avail_in != 0) {
304      fprintf(stderr, "deflate not greedy\n");
305      exit(1);
306   }
307
308   /* Feed in already compressed data and switch to no compression: */
309   deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
310   c_stream.next_in = compr;
311   c_stream.avail_in = (uInt)comprLen/2;
312   err = deflate(&c_stream, Z_NO_FLUSH);
313   CHECK_ERR(err, "deflate");
314
315   /* Switch back to compressing mode: */
316   deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
317   c_stream.next_in = uncompr;
318   c_stream.avail_in = (uInt)uncomprLen;
319   err = deflate(&c_stream, Z_NO_FLUSH);
320   CHECK_ERR(err, "deflate");
321
322   err = deflate(&c_stream, Z_FINISH);
323   if (err != Z_STREAM_END) {
324      fprintf(stderr, "deflate should report Z_STREAM_END\n");
325      exit(1);
326   }
327   err = deflateEnd(&c_stream);
328   CHECK_ERR(err, "deflateEnd");
329}
330
331/* ===========================================================================
332 * Test inflate() with large buffers
333 */
334void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
335   Byte *compr, *uncompr;
336   uLong comprLen, uncomprLen;
337{
338   int err;
339   z_stream d_stream; /* decompression stream */
340
341   strcpy((char*)uncompr, "garbage");
342
343   d_stream.zalloc = zalloc;
344   d_stream.zfree = zfree;
345   d_stream.opaque = (voidpf)0;
346
347   d_stream.next_in  = compr;
348   d_stream.avail_in = (uInt)comprLen;
349
350   err = inflateInit(&d_stream);
351   CHECK_ERR(err, "inflateInit");
352
353   for (;;) {
354      d_stream.next_out = uncompr;            /* discard the output */
355      d_stream.avail_out = (uInt)uncomprLen;
356      err = inflate(&d_stream, Z_NO_FLUSH);
357      if (err == Z_STREAM_END) break;
358      CHECK_ERR(err, "large inflate");
359   }
360
361   err = inflateEnd(&d_stream);
362   CHECK_ERR(err, "inflateEnd");
363
364   if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
365      fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
366      exit(1);
367   } else {
368      printf("large_inflate(): OK\n");
369   }
370}
371
372/* ===========================================================================
373 * Test deflate() with full flush
374 */
375void test_flush(compr, comprLen)
376   Byte *compr;
377   uLong *comprLen;
378{
379   z_stream c_stream; /* compression stream */
380   int err;
381   uInt len = (uInt)strlen(hello)+1;
382
383   c_stream.zalloc = zalloc;
384   c_stream.zfree = zfree;
385   c_stream.opaque = (voidpf)0;
386
387   err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
388   CHECK_ERR(err, "deflateInit");
389
390   c_stream.next_in  = (Bytef*)hello;
391   c_stream.next_out = compr;
392   c_stream.avail_in = 3;
393   c_stream.avail_out = (uInt)*comprLen;
394   err = deflate(&c_stream, Z_FULL_FLUSH);
395   CHECK_ERR(err, "deflate");
396
397   compr[3]++; /* force an error in first compressed block */
398   c_stream.avail_in = len - 3;
399
400   err = deflate(&c_stream, Z_FINISH);
401   if (err != Z_STREAM_END) {
402      CHECK_ERR(err, "deflate");
403   }
404   err = deflateEnd(&c_stream);
405   CHECK_ERR(err, "deflateEnd");
406
407   *comprLen = c_stream.total_out;
408}
409
410/* ===========================================================================
411 * Test inflateSync()
412 */
413void test_sync(compr, comprLen, uncompr, uncomprLen)
414   Byte *compr, *uncompr;
415   uLong comprLen, uncomprLen;
416{
417   int err;
418   z_stream d_stream; /* decompression stream */
419
420   strcpy((char*)uncompr, "garbage");
421
422   d_stream.zalloc = zalloc;
423   d_stream.zfree = zfree;
424   d_stream.opaque = (voidpf)0;
425
426   d_stream.next_in  = compr;
427   d_stream.avail_in = 2; /* just read the zlib header */
428
429   err = inflateInit(&d_stream);
430   CHECK_ERR(err, "inflateInit");
431
432   d_stream.next_out = uncompr;
433   d_stream.avail_out = (uInt)uncomprLen;
434
435   inflate(&d_stream, Z_NO_FLUSH);
436   CHECK_ERR(err, "inflate");
437
438   d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
439   err = inflateSync(&d_stream);           /* but skip the damaged part */
440   CHECK_ERR(err, "inflateSync");
441
442   err = inflate(&d_stream, Z_FINISH);
443   if (err != Z_DATA_ERROR) {
444      fprintf(stderr, "inflate should report DATA_ERROR\n");
445      /* Because of incorrect adler32 */
446      exit(1);
447   }
448   err = inflateEnd(&d_stream);
449   CHECK_ERR(err, "inflateEnd");
450
451   printf("after inflateSync(): hel%s\n", (char *)uncompr);
452}
453
454/* ===========================================================================
455 * Test deflate() with preset dictionary
456 */
457void test_dict_deflate(compr, comprLen)
458   Byte *compr;
459   uLong comprLen;
460{
461   z_stream c_stream; /* compression stream */
462   int err;
463
464   c_stream.zalloc = zalloc;
465   c_stream.zfree = zfree;
466   c_stream.opaque = (voidpf)0;
467
468   err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
469   CHECK_ERR(err, "deflateInit");
470
471   err = deflateSetDictionary(&c_stream,
472            (const Bytef*)dictionary, (int)sizeof(dictionary));
473   CHECK_ERR(err, "deflateSetDictionary");
474
475   dictId = c_stream.adler;
476   c_stream.next_out = compr;
477   c_stream.avail_out = (uInt)comprLen;
478
479   c_stream.next_in = (Bytef*)hello;
480   c_stream.avail_in = (uInt)strlen(hello)+1;
481
482   err = deflate(&c_stream, Z_FINISH);
483   if (err != Z_STREAM_END) {
484      fprintf(stderr, "deflate should report Z_STREAM_END\n");
485      exit(1);
486   }
487   err = deflateEnd(&c_stream);
488   CHECK_ERR(err, "deflateEnd");
489}
490
491/* ===========================================================================
492 * Test inflate() with a preset dictionary
493 */
494void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
495   Byte *compr, *uncompr;
496   uLong comprLen, uncomprLen;
497{
498   int err;
499   z_stream d_stream; /* decompression stream */
500
501   strcpy((char*)uncompr, "garbage");
502
503   d_stream.zalloc = zalloc;
504   d_stream.zfree = zfree;
505   d_stream.opaque = (voidpf)0;
506
507   d_stream.next_in  = compr;
508   d_stream.avail_in = (uInt)comprLen;
509
510   err = inflateInit(&d_stream);
511   CHECK_ERR(err, "inflateInit");
512
513   d_stream.next_out = uncompr;
514   d_stream.avail_out = (uInt)uncomprLen;
515
516   for (;;) {
517      err = inflate(&d_stream, Z_NO_FLUSH);
518      if (err == Z_STREAM_END) break;
519      if (err == Z_NEED_DICT) {
520         if (d_stream.adler != dictId) {
521            fprintf(stderr, "unexpected dictionary");
522            exit(1);
523         }
524         err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
525                              (int)sizeof(dictionary));
526      }
527      CHECK_ERR(err, "inflate with dict");
528   }
529
530   err = inflateEnd(&d_stream);
531   CHECK_ERR(err, "inflateEnd");
532
533   if (strcmp((char*)uncompr, hello)) {
534      fprintf(stderr, "bad inflate with dict\n");
535      exit(1);
536   } else {
537      printf("inflate with dictionary: %s\n", (char *)uncompr);
538   }
539}
540
541/* ===========================================================================
542 * Usage:  example [output.gz  [input.gz]]
543 */
544
545int main(argc, argv)
546   int argc;
547   char *argv[];
548{
549   Byte *compr, *uncompr;
550   uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
551   uLong uncomprLen = comprLen;
552   static const char* myVersion = ZLIB_VERSION;
553
554   if (zlibVersion()[0] != myVersion[0]) {
555      fprintf(stderr, "incompatible zlib version\n");
556      exit(1);
557
558   } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
559      fprintf(stderr, "warning: different zlib version\n");
560   }
561
562   printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
563         ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
564
565   compr    = (Byte*)calloc((uInt)comprLen, 1);
566   uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
567   /* compr and uncompr are cleared to avoid reading uninitialized
568    * data and to ensure that uncompr compresses well.
569    */
570   if (compr == Z_NULL || uncompr == Z_NULL) {
571      printf("out of memory\n");
572      exit(1);
573   }
574
575#ifdef Z_SOLO
576   argc = strlen(argv[0]);
577#else
578   test_compress(compr, comprLen, uncompr, uncomprLen);
579
580   test_gzio((argc > 1 ? argv[1] : TESTFILE),
581            uncompr, uncomprLen);
582#endif
583
584   test_deflate(compr, comprLen);
585   test_inflate(compr, comprLen, uncompr, uncomprLen);
586
587   test_large_deflate(compr, comprLen, uncompr, uncomprLen);
588   test_large_inflate(compr, comprLen, uncompr, uncomprLen);
589
590   test_flush(compr, &comprLen);
591   test_sync(compr, comprLen, uncompr, uncomprLen);
592   comprLen = uncomprLen;
593
594   test_dict_deflate(compr, comprLen);
595   test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
596
597   free(compr);
598   free(uncompr);
599
600   return 0;
601}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team