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