stdlibs/libz/zlib/gzio.cpp
changeset 59 09fa7c3c5079
parent 52 bf6a71c50e42
child 63 a117ad66e027
equal deleted inserted replaced
52:bf6a71c50e42 59:09fa7c3c5079
     1 /* gzio.c -- IO on .gz files
       
     2  * Copyright (C) 1995-2005 Jean-loup Gailly.
       
     3  * For conditions of distribution and use, see copyright notice in zlib.h
       
     4  *
       
     5  * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
       
     6  */
       
     7 
       
     8 /* @(#) $Id: gzio.cpp,v 1.1.2.1 2008/08/14 15:26:57 e0222316 Exp $ */
       
     9 
       
    10 #include <stdio.h>
       
    11 #include "libzgzio.h"	/* libzgzio.h must be included BEFORE zutil.h, as its header guard is used in zutil.h */
       
    12 #include "zutil.h"
       
    13 
       
    14 #ifdef NO_DEFLATE       /* for compatibility with old definition */
       
    15 #  define NO_GZCOMPRESS
       
    16 #endif
       
    17 
       
    18 #ifndef NO_DUMMY_DECL
       
    19 struct internal_state {int dummy;}; /* for buggy compilers */
       
    20 #endif
       
    21 
       
    22 #ifndef Z_BUFSIZE
       
    23 #  ifdef MAXSEG_64K
       
    24 #    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
       
    25 #  else
       
    26 #    define Z_BUFSIZE 16384
       
    27 #  endif
       
    28 #endif
       
    29 #ifndef Z_PRINTF_BUFSIZE
       
    30 #  define Z_PRINTF_BUFSIZE 4096
       
    31 #endif
       
    32 
       
    33 #ifdef __MVS__
       
    34 #  pragma map (fdopen , "\174\174FDOPEN")
       
    35    FILE *fdopen(int, const char *);
       
    36 #endif
       
    37 
       
    38 #ifndef STDC
       
    39 extern voidp  malloc OF((uInt size));
       
    40 extern void   free   OF((voidpf ptr));
       
    41 #endif
       
    42 
       
    43 #define ALLOC(size) malloc(size)
       
    44 #define TRYFREE(p) {if (p) free(p);}
       
    45 
       
    46 static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
       
    47 
       
    48 /* gzip flag byte */
       
    49 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
       
    50 #define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
       
    51 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
       
    52 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
       
    53 #define COMMENT      0x10 /* bit 4 set: file comment present */
       
    54 #define RESERVED     0xE0 /* bits 5..7: reserved */
       
    55 
       
    56 typedef struct gz_stream {
       
    57     z_stream stream;
       
    58     int      z_err;   /* error code for last stream operation */
       
    59     int      z_eof;   /* set if end of input file */
       
    60     FILE     *file;   /* .gz file */
       
    61     Byte     *inbuf;  /* input buffer */
       
    62     Byte     *outbuf; /* output buffer */
       
    63     uLong    crc;     /* crc32 of uncompressed data */
       
    64     char     *msg;    /* error message */
       
    65     char     *path;   /* path name for debugging only */
       
    66     int      transparent; /* 1 if input file is not a .gz file */
       
    67     char     mode;    /* 'w' or 'r' */
       
    68     z_off_t  start;   /* start of compressed data in file (header skipped) */
       
    69     z_off_t  in;      /* bytes into deflate or inflate */
       
    70     z_off_t  out;     /* bytes out of deflate or inflate */
       
    71     int      back;    /* one character push-back */
       
    72     int      last;    /* true if push-back is last character */
       
    73 } gz_stream;
       
    74 
       
    75 #ifdef SYMBIAN_EZLIB_DEVICE
       
    76 /* This array is a copy of the one originally defined in zutil.cpp.  It is
       
    77    required here as zutil.cpp is now compiled seperately in libzcore.dll */
       
    78 const char * const z_errmsg[10] = {
       
    79 		"need dictionary",     /* Z_NEED_DICT       2  */
       
    80 		"stream end",          /* Z_STREAM_END      1  */
       
    81 		"",                    /* Z_OK              0  */
       
    82 		"file error",          /* Z_ERRNO         (-1) */
       
    83 		"stream error",        /* Z_STREAM_ERROR  (-2) */
       
    84 		"data error",          /* Z_DATA_ERROR    (-3) */
       
    85 		"insufficient memory", /* Z_MEM_ERROR     (-4) */
       
    86 		"buffer error",        /* Z_BUF_ERROR     (-5) */
       
    87 		"incompatible version",/* Z_VERSION_ERROR (-6) */
       
    88 ""};
       
    89 #endif /* SYMBIAN_EZLIB_DEVICE */
       
    90 
       
    91 local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
       
    92 local int do_flush        OF((gzFile file, int flush));
       
    93 local int    get_byte     OF((gz_stream *s));
       
    94 local void   check_header OF((gz_stream *s));
       
    95 local int    destroy      OF((gz_stream *s));
       
    96 local void   putLong      OF((FILE *file, uLong x));
       
    97 local uLong  getLong      OF((gz_stream *s));
       
    98 
       
    99 /* ===========================================================================
       
   100    Opens a gzip (.gz) file for reading or writing. The mode parameter
       
   101    is as in fopen ("rb" or "wb"). The file is given either by file descriptor
       
   102    or path name (if fd == -1).
       
   103    gz_open returns NULL if the file could not be opened or if there was
       
   104    insufficient memory to allocate the (de)compression state; errno
       
   105    can be checked to distinguish the two cases (if errno is zero, the
       
   106    zlib error is Z_MEM_ERROR).
       
   107 */
       
   108 #ifdef __SYMBIAN32__
       
   109 local gzFile gz_open (const char * path,const char *  mode, int fd)
       
   110 #else
       
   111 local gzFile gz_open (path, mode, fd)
       
   112     const char *path;
       
   113     const char *mode;
       
   114     int  fd;
       
   115 #endif /* __SYMBIAN32__ */
       
   116 
       
   117 {
       
   118     int err;
       
   119     int level = Z_DEFAULT_COMPRESSION; /* compression level */
       
   120     int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
       
   121     char *p = (char*)mode;
       
   122     gz_stream *s;
       
   123     char fmode[80]; /* copy of mode, without the compression level */
       
   124     char *m = fmode;
       
   125 
       
   126     if (!path || !mode) return Z_NULL;
       
   127 
       
   128     s = (gz_stream *)ALLOC(sizeof(gz_stream));
       
   129     if (!s) return Z_NULL;
       
   130 
       
   131     s->stream.zalloc = (alloc_func)0;
       
   132     s->stream.zfree = (free_func)0;
       
   133     s->stream.opaque = (voidpf)0;
       
   134     s->stream.next_in = s->inbuf = Z_NULL;
       
   135     s->stream.next_out = s->outbuf = Z_NULL;
       
   136     s->stream.avail_in = s->stream.avail_out = 0;
       
   137     s->file = NULL;
       
   138     s->z_err = Z_OK;
       
   139     s->z_eof = 0;
       
   140     s->in = 0;
       
   141     s->out = 0;
       
   142     s->back = EOF;
       
   143     s->crc = crc32_r(0L, Z_NULL, 0);
       
   144     s->msg = NULL;
       
   145     s->transparent = 0;
       
   146 
       
   147     s->path = (char*)ALLOC(strlen(path)+1);
       
   148     if (s->path == NULL) {
       
   149         return destroy(s), (gzFile)Z_NULL;
       
   150     }
       
   151     strcpy(s->path, path); /* do this early for debugging */
       
   152 
       
   153     s->mode = '\0';
       
   154     do {
       
   155         if (*p == 'r') s->mode = 'r';
       
   156         if (*p == 'w' || *p == 'a') s->mode = 'w';
       
   157         if (*p >= '0' && *p <= '9') {
       
   158             level = *p - '0';
       
   159         } else if (*p == 'f') {
       
   160           strategy = Z_FILTERED;
       
   161         } else if (*p == 'h') {
       
   162           strategy = Z_HUFFMAN_ONLY;
       
   163         } else if (*p == 'R') {
       
   164           strategy = Z_RLE;
       
   165         } else {
       
   166             *m++ = *p; /* copy the mode */
       
   167         }
       
   168     } while (*p++ && m != fmode + sizeof(fmode));
       
   169     if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
       
   170 
       
   171     if (s->mode == 'w') {
       
   172 #ifdef NO_GZCOMPRESS
       
   173         err = Z_STREAM_ERROR;
       
   174 #else
       
   175         err = deflateInit2_r(&(s->stream), level,
       
   176                            Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
       
   177         /* windowBits is passed < 0 to suppress zlib header */
       
   178 
       
   179         s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
       
   180 #endif
       
   181         if (err != Z_OK || s->outbuf == Z_NULL) {
       
   182             return destroy(s), (gzFile)Z_NULL;
       
   183         }
       
   184     } else {
       
   185         s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
       
   186 
       
   187         err = inflateInit2_r(&(s->stream), -MAX_WBITS);
       
   188         /* windowBits is passed < 0 to tell that there is no zlib header.
       
   189          * Note that in this case inflate *requires* an extra "dummy" byte
       
   190          * after the compressed stream in order to complete decompression and
       
   191          * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
       
   192          * present after the compressed stream.
       
   193          */
       
   194         if (err != Z_OK || s->inbuf == Z_NULL) {
       
   195             return destroy(s), (gzFile)Z_NULL;
       
   196         }
       
   197     }
       
   198     s->stream.avail_out = Z_BUFSIZE;
       
   199 
       
   200     errno = 0;
       
   201     s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
       
   202 
       
   203     if (s->file == NULL) {
       
   204         return destroy(s), (gzFile)Z_NULL;
       
   205     }
       
   206     if (s->mode == 'w') {
       
   207         /* Write a very simple .gz header:
       
   208          */
       
   209         fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
       
   210              Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
       
   211         s->start = 10L;
       
   212         /* We use 10L instead of ftell(s->file) to because ftell causes an
       
   213          * fflush on some systems. This version of the library doesn't use
       
   214          * start anyway in write mode, so this initialization is not
       
   215          * necessary.
       
   216          */
       
   217     } else {
       
   218         check_header(s); /* skip the .gz header */
       
   219         s->start = ftell(s->file) - s->stream.avail_in;
       
   220     }
       
   221 
       
   222     return (gzFile)s;
       
   223 }
       
   224 
       
   225 /* ===========================================================================
       
   226      Opens a gzip (.gz) file for reading or writing.
       
   227 */
       
   228 #ifdef __SYMBIAN32__
       
   229 gzFile gzopen_r (const char * path, const char * mode)
       
   230 #else
       
   231 gzFile ZEXPORT gzopen (path, mode)
       
   232     const char *path;
       
   233     const char *mode;
       
   234 #endif /* __SYMBIAN32__ */
       
   235 
       
   236 {
       
   237     return gz_open (path, mode, -1);
       
   238 }
       
   239 
       
   240 /* ===========================================================================
       
   241    Associate a gzFile with the file descriptor fd. fd is not dup'ed here
       
   242    to mimic the behavio(u)r of fdopen.
       
   243 */
       
   244 #ifdef __SYMBIAN32__
       
   245 gzFile gzdopen_r (int fd, const char *  mode)
       
   246 #else
       
   247 gzFile ZEXPORT gzdopen (fd, mode)
       
   248     int fd;
       
   249     const char *mode;
       
   250 #endif /* __SYMBIAN32__ */
       
   251 {
       
   252     char name[46];      /* allow for up to 128-bit integers */
       
   253 
       
   254     if (fd < 0) return (gzFile)Z_NULL;
       
   255     sprintf(name, "<fd:%d>", fd); /* for debugging */
       
   256 
       
   257     return gz_open (name, mode, fd);
       
   258 }
       
   259 
       
   260 /* ===========================================================================
       
   261  * Update the compression level and strategy
       
   262  */
       
   263 #ifdef __SYMBIAN32__
       
   264 int gzsetparams_r (gzFile file,int  level,int  strategy)	
       
   265 #else
       
   266 int ZEXPORT gzsetparams (file, level, strategy)
       
   267     gzFile file;
       
   268     int level;
       
   269     int strategy;
       
   270 #endif /* __SYMBIAN32__ */
       
   271 
       
   272 {
       
   273     gz_stream *s = (gz_stream*)file;
       
   274 
       
   275     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   276 
       
   277     /* Make room to allow flushing */
       
   278     if (s->stream.avail_out == 0) {
       
   279 
       
   280         s->stream.next_out = s->outbuf;
       
   281         if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
       
   282             s->z_err = Z_ERRNO;
       
   283         }
       
   284         s->stream.avail_out = Z_BUFSIZE;
       
   285     }
       
   286 
       
   287     return deflateParams_r (&(s->stream), level, strategy);
       
   288 }
       
   289 
       
   290 /* ===========================================================================
       
   291    Read a byte from a gz_stream; update next_in and avail_in. Return EOF
       
   292    for end of file.
       
   293    IN assertion: the stream s has been sucessfully opened for reading.
       
   294 */
       
   295 #ifdef __SYMBIAN32__
       
   296 local int get_byte (gz_stream *s)
       
   297 #else
       
   298 local int get_byte(s)
       
   299     gz_stream *s;
       
   300 #endif /* __SYMBIAN32__ */
       
   301 {
       
   302     if (s->z_eof) return EOF;
       
   303     if (s->stream.avail_in == 0) {
       
   304         errno = 0;
       
   305         s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
       
   306         if (s->stream.avail_in == 0) {
       
   307             s->z_eof = 1;
       
   308             if (ferror(s->file)) s->z_err = Z_ERRNO;
       
   309             return EOF;
       
   310         }
       
   311         s->stream.next_in = s->inbuf;
       
   312     }
       
   313     s->stream.avail_in--;
       
   314     return *(s->stream.next_in)++;
       
   315 }
       
   316 
       
   317 /* ===========================================================================
       
   318     Check the gzip header of a gz_stream opened for reading. Set the stream
       
   319     mode to transparent if the gzip magic header is not present; set s->err
       
   320     to Z_DATA_ERROR if the magic header is present but the rest of the header
       
   321     is incorrect.
       
   322     IN assertion: the stream s has already been created sucessfully;
       
   323     s->stream.avail_in is zero for the first time, but may be non-zero
       
   324     for concatenated .gz files.
       
   325 */
       
   326 #ifdef __SYMBIAN32__
       
   327 local void check_header (gz_stream * s)
       
   328 #else
       
   329 local void check_header(s)
       
   330     gz_stream *s;
       
   331 #endif /* __SYMBIAN32__ */
       
   332 {
       
   333     int method; /* method byte */
       
   334     int flags;  /* flags byte */
       
   335     uInt len;
       
   336     int c;
       
   337 
       
   338     /* Assure two bytes in the buffer so we can peek ahead -- handle case
       
   339        where first byte of header is at the end of the buffer after the last
       
   340        gzip segment */
       
   341     len = s->stream.avail_in;
       
   342     if (len < 2) {
       
   343         if (len) s->inbuf[0] = s->stream.next_in[0];
       
   344         errno = 0;
       
   345         len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
       
   346         if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
       
   347         s->stream.avail_in += len;
       
   348         s->stream.next_in = s->inbuf;
       
   349         if (s->stream.avail_in < 2) {
       
   350             s->transparent = s->stream.avail_in;
       
   351             return;
       
   352         }
       
   353     }
       
   354 
       
   355     /* Peek ahead to check the gzip magic header */
       
   356     if (s->stream.next_in[0] != gz_magic[0] ||
       
   357         s->stream.next_in[1] != gz_magic[1]) {
       
   358         s->transparent = 1;
       
   359         return;
       
   360     }
       
   361     s->stream.avail_in -= 2;
       
   362     s->stream.next_in += 2;
       
   363 
       
   364     /* Check the rest of the gzip header */
       
   365     method = get_byte(s);
       
   366     flags = get_byte(s);
       
   367     if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
       
   368         s->z_err = Z_DATA_ERROR;
       
   369         return;
       
   370     }
       
   371 
       
   372     /* Discard time, xflags and OS code: */
       
   373     for (len = 0; len < 6; len++) (void)get_byte(s);
       
   374 
       
   375     if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
       
   376         len  =  (uInt)get_byte(s);
       
   377         len += ((uInt)get_byte(s))<<8;
       
   378         /* len is garbage if EOF but the loop below will quit anyway */
       
   379         while (len-- != 0 && get_byte(s) != EOF) ;
       
   380     }
       
   381     if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
       
   382         while ((c = get_byte(s)) != 0 && c != EOF) ;
       
   383     }
       
   384     if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
       
   385         while ((c = get_byte(s)) != 0 && c != EOF) ;
       
   386     }
       
   387     if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
       
   388         for (len = 0; len < 2; len++) (void)get_byte(s);
       
   389     }
       
   390     s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
       
   391 }
       
   392 
       
   393  /* ===========================================================================
       
   394     Cleanup then free the given gz_stream. Return a zlib error code.
       
   395     Try freeing in the reverse order of allocations.
       
   396  */
       
   397 #ifdef __SYMBIAN32__ 
       
   398 local int destroy (gz_stream * s)
       
   399 #else
       
   400 local int destroy (s)
       
   401     gz_stream *s;
       
   402 #endif /* __SYMBIAN32__ */
       
   403 {
       
   404     int err = Z_OK;
       
   405 
       
   406     if (!s) return Z_STREAM_ERROR;
       
   407 
       
   408     TRYFREE(s->msg);
       
   409 
       
   410     if (s->stream.state != NULL) {
       
   411         if (s->mode == 'w') {
       
   412 #ifdef NO_GZCOMPRESS
       
   413             err = Z_STREAM_ERROR;
       
   414 #else
       
   415             err = deflateEnd_r(&(s->stream));
       
   416 #endif
       
   417         } else if (s->mode == 'r') {
       
   418             err = inflateEnd_r(&(s->stream));
       
   419         }
       
   420     }
       
   421     if (s->file != NULL && fclose(s->file)) {
       
   422 #ifdef ESPIPE
       
   423         if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
       
   424 #endif
       
   425             err = Z_ERRNO;
       
   426     }
       
   427     if (s->z_err < 0) err = s->z_err;
       
   428 
       
   429     TRYFREE(s->inbuf);
       
   430     TRYFREE(s->outbuf);
       
   431     TRYFREE(s->path);
       
   432     TRYFREE(s);
       
   433     return err;
       
   434 }
       
   435 
       
   436 /* ===========================================================================
       
   437    Reads the given number of uncompressed bytes from the compressed file.
       
   438    gzread returns the number of bytes actually read (0 for end of file).
       
   439 */
       
   440 #ifdef __SYMBIAN32__
       
   441 int gzread_r (gzFile file,voidp  buf,unsigned  len)
       
   442 #else
       
   443 int ZEXPORT gzread (file, buf, len)
       
   444     gzFile file;
       
   445     voidp buf;
       
   446     unsigned len;
       
   447 #endif /* __SYMBIAN32__ */
       
   448 {
       
   449     gz_stream *s = (gz_stream*)file;
       
   450     Bytef *start = (Bytef*)buf; /* starting point for crc computation */
       
   451     Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
       
   452 
       
   453     if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
       
   454 
       
   455     if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
       
   456     if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
       
   457 
       
   458     next_out = (Byte*)buf;
       
   459     s->stream.next_out = (Bytef*)buf;
       
   460     s->stream.avail_out = len;
       
   461 
       
   462     if (s->stream.avail_out && s->back != EOF) {
       
   463         *next_out++ = s->back;
       
   464         s->stream.next_out++;
       
   465         s->stream.avail_out--;
       
   466         s->back = EOF;
       
   467         s->out++;
       
   468         start++;
       
   469         if (s->last) {
       
   470             s->z_err = Z_STREAM_END;
       
   471             return 1;
       
   472         }
       
   473     }
       
   474 
       
   475     while (s->stream.avail_out != 0) {
       
   476 
       
   477         if (s->transparent) {
       
   478             /* Copy first the lookahead bytes: */
       
   479             uInt n = s->stream.avail_in;
       
   480             if (n > s->stream.avail_out) n = s->stream.avail_out;
       
   481             if (n > 0) {
       
   482                 zmemcpy(s->stream.next_out, s->stream.next_in, n);
       
   483                 next_out += n;
       
   484                 s->stream.next_out = next_out;
       
   485                 s->stream.next_in   += n;
       
   486                 s->stream.avail_out -= n;
       
   487                 s->stream.avail_in  -= n;
       
   488             }
       
   489             if (s->stream.avail_out > 0) {
       
   490                 s->stream.avail_out -=
       
   491                     (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
       
   492             }
       
   493             len -= s->stream.avail_out;
       
   494             s->in  += len;
       
   495             s->out += len;
       
   496             if (len == 0) s->z_eof = 1;
       
   497             return (int)len;
       
   498         }
       
   499         if (s->stream.avail_in == 0 && !s->z_eof) {
       
   500 
       
   501             errno = 0;
       
   502             s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
       
   503             if (s->stream.avail_in == 0) {
       
   504                 s->z_eof = 1;
       
   505                 if (ferror(s->file)) {
       
   506                     s->z_err = Z_ERRNO;
       
   507                     break;
       
   508                 }
       
   509             }
       
   510             s->stream.next_in = s->inbuf;
       
   511         }
       
   512         s->in += s->stream.avail_in;
       
   513         s->out += s->stream.avail_out;
       
   514         s->z_err = inflate_r(&(s->stream), Z_NO_FLUSH);
       
   515         s->in -= s->stream.avail_in;
       
   516         s->out -= s->stream.avail_out;
       
   517 
       
   518         if (s->z_err == Z_STREAM_END) {
       
   519             /* Check CRC and original size */
       
   520             s->crc = crc32_r(s->crc, start, (uInt)(s->stream.next_out - start));
       
   521             start = s->stream.next_out;
       
   522 
       
   523             if (getLong(s) != s->crc) {
       
   524                 s->z_err = Z_DATA_ERROR;
       
   525             } else {
       
   526                 (void)getLong(s);
       
   527                 /* The uncompressed length returned by above getlong() may be
       
   528                  * different from s->out in case of concatenated .gz files.
       
   529                  * Check for such files:
       
   530                  */
       
   531                 check_header(s);
       
   532                 if (s->z_err == Z_OK) {
       
   533                     inflateReset_r(&(s->stream));
       
   534                     s->crc = crc32_r(0L, Z_NULL, 0);
       
   535                 }
       
   536             }
       
   537         }
       
   538         if (s->z_err != Z_OK || s->z_eof) break;
       
   539     }
       
   540     s->crc = crc32_r(s->crc, start, (uInt)(s->stream.next_out - start));
       
   541 
       
   542     if (len == s->stream.avail_out &&
       
   543         (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
       
   544         return -1;
       
   545     return (int)(len - s->stream.avail_out);
       
   546 }
       
   547 
       
   548 
       
   549 /* ===========================================================================
       
   550    Reads one byte from the compressed file. gzgetc returns this byte
       
   551    or -1 in case of end of file or error.
       
   552 */
       
   553 #ifdef __SYMBIAN32__
       
   554 int gzgetc_r (gzFile file)
       
   555 #else
       
   556 int ZEXPORT gzgetc(file)
       
   557     gzFile file;
       
   558 #endif /* __SYMBIAN32__ */
       
   559 
       
   560 {
       
   561     unsigned char c;
       
   562 
       
   563     return gzread_r(file, &c, 1) == 1 ? c : -1;
       
   564 }
       
   565 
       
   566 
       
   567 /* ===========================================================================
       
   568    Push one byte back onto the stream.
       
   569 */
       
   570 #ifdef __SYMBIAN32__
       
   571 int gzungetc_r (int c,gzFile file)
       
   572 #else
       
   573 int ZEXPORT gzungetc(c, file)
       
   574     int c;
       
   575     gzFile file;
       
   576 #endif /* __SYMBIAN32__ */
       
   577 {
       
   578     gz_stream *s = (gz_stream*)file;
       
   579 
       
   580     if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
       
   581     s->back = c;
       
   582     s->out--;
       
   583     s->last = (s->z_err == Z_STREAM_END);
       
   584     if (s->last) s->z_err = Z_OK;
       
   585     s->z_eof = 0;
       
   586     return c;
       
   587 }
       
   588 
       
   589 
       
   590 /* ===========================================================================
       
   591    Reads bytes from the compressed file until len-1 characters are
       
   592    read, or a newline character is read and transferred to buf, or an
       
   593    end-of-file condition is encountered.  The string is then terminated
       
   594    with a null character.
       
   595    gzgets returns buf, or Z_NULL in case of error.
       
   596 
       
   597    The current implementation is not optimized at all.
       
   598 */
       
   599 #ifdef __SYMBIAN32__
       
   600 char * gzgets_r (gzFile file, char * buf, int len)
       
   601 #else
       
   602 char * ZEXPORT gzgets(file, buf, len)
       
   603     gzFile file;
       
   604     char *buf;
       
   605     int len;
       
   606 #endif /* __SYMBIAN32__ */
       
   607 {
       
   608     char *b = buf;
       
   609     if (buf == Z_NULL || len <= 0) return Z_NULL;
       
   610 
       
   611     while (--len > 0 && gzread_r(file, buf, 1) == 1 && *buf++ != '\n') ;
       
   612     *buf = '\0';
       
   613     return b == buf && len > 0 ? Z_NULL : b;
       
   614 }
       
   615 
       
   616 
       
   617 #ifndef NO_GZCOMPRESS
       
   618 /* ===========================================================================
       
   619    Writes the given number of uncompressed bytes into the compressed file.
       
   620    gzwrite returns the number of bytes actually written (0 in case of error).
       
   621 */
       
   622 #ifdef __SYMBIAN32__
       
   623 int gzwrite_r (gzFile file,voidpc  buf,unsigned len)	
       
   624 #else
       
   625 int ZEXPORT gzwrite (file, buf, len)
       
   626     gzFile file;
       
   627     voidpc buf;
       
   628     unsigned len;
       
   629 #endif /* __SYMBIAN32__ */
       
   630 {
       
   631     gz_stream *s = (gz_stream*)file;
       
   632 
       
   633     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   634 
       
   635     s->stream.next_in = (Bytef*)buf;
       
   636     s->stream.avail_in = len;
       
   637 
       
   638     while (s->stream.avail_in != 0) {
       
   639 
       
   640         if (s->stream.avail_out == 0) {
       
   641 
       
   642             s->stream.next_out = s->outbuf;
       
   643             if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
       
   644                 s->z_err = Z_ERRNO;
       
   645                 break;
       
   646             }
       
   647             s->stream.avail_out = Z_BUFSIZE;
       
   648         }
       
   649         s->in += s->stream.avail_in;
       
   650         s->out += s->stream.avail_out;
       
   651         s->z_err = deflate_r(&(s->stream), Z_NO_FLUSH);
       
   652         s->in -= s->stream.avail_in;
       
   653         s->out -= s->stream.avail_out;
       
   654         if (s->z_err != Z_OK) break;
       
   655     }
       
   656     s->crc = crc32_r(s->crc, (const Bytef *)buf, len);
       
   657 
       
   658     return (int)(len - s->stream.avail_in);
       
   659 }
       
   660 
       
   661 
       
   662 /* ===========================================================================
       
   663    Converts, formats, and writes the args to the compressed file under
       
   664    control of the format string, as in fprintf. gzprintf returns the number of
       
   665    uncompressed bytes actually written (0 in case of error).
       
   666 */
       
   667 #ifdef STDC
       
   668 #include <stdarg.h>
       
   669 
       
   670 #ifdef __SYMBIAN32__
       
   671 int gzprintf_r (gzFile file, const char *format, va_list va)
       
   672 #else
       
   673 int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
       
   674 #endif /* __SYMBIAN32__ */
       
   675 {
       
   676     int len;
       
   677 	int ret;
       
   678     
       
   679 #ifndef SYMBIAN_EZLIB_DEVICE
       
   680 	char buf[Z_PRINTF_BUFSIZE];
       
   681     buf[sizeof(buf) - 1] = 0;
       
   682 #else
       
   683 	char *buf = (char*)0;
       
   684     buf = (char*) ALLOC(Z_PRINTF_BUFSIZE * sizeof(char));
       
   685     if(!buf)
       
   686     	return 0;
       
   687     buf[Z_PRINTF_BUFSIZE - 1] = 0;
       
   688 #endif /* SYMBIAN_EZLIB_DEVICE */
       
   689     
       
   690 #ifdef NO_vsnprintf
       
   691 #  ifdef HAS_vsprintf_void
       
   692     (void)vsprintf(buf, format, va);
       
   693     va_end(va);
       
   694 #    ifndef SYMBIAN_EZLIB_DEVICE
       
   695        for (len = 0; len < sizeof(buf); len++)
       
   696 #	 else
       
   697 	   for (len = 0; len < Z_PRINTF_BUFSIZE; len++)
       
   698 #	 endif /* SYMBIAN_EZLIB_DEVICE */
       
   699         if (buf[len] == 0) break;
       
   700 #  else
       
   701     len = vsprintf(buf, format, va);
       
   702     va_end(va);
       
   703 #  endif
       
   704 #else
       
   705 #  ifdef HAS_vsnprintf_void
       
   706 #    ifndef SYMBIAN_EZLIB_DEVICE
       
   707        (void)vsnprintf(buf, sizeof(buf), format, va);
       
   708 #    else 
       
   709 	   (void)vsnprintf(buf, Z_PRINTF_BUFSIZE, format, va);
       
   710 #    endif /* SYMBIAN_EZLIB_DEVICE */
       
   711     va_end(va);
       
   712     len = strlen(buf);
       
   713 #  else
       
   714 #    ifndef SYMBIAN_EZLIB_DEVICE 
       
   715        len = vsnprintf(buf, sizeof(buf), format, va);
       
   716 #    else
       
   717 	   len = vsnprintf(buf, Z_PRINTF_BUFSIZE, format, va);
       
   718 #    endif /* SYMBIAN_EZLIB_DEVICE */
       
   719     va_end(va);
       
   720 #  endif
       
   721 #endif
       
   722 
       
   723 #ifndef SYMBIAN_EZLIB_DEVICE
       
   724     if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
       
   725     {
       
   726 #else
       
   727 	if (len <= 0 || len >= Z_PRINTF_BUFSIZE || buf[Z_PRINTF_BUFSIZE - 1] != 0)
       
   728 	{
       
   729 		free(buf);
       
   730 #endif /* SYMBIAN_EZLIB_DEVICE */
       
   731     	return 0;
       
   732     }
       
   733     ret = gzwrite_r(file, buf, (unsigned)len);
       
   734     
       
   735 #ifdef SYMBIAN_EZLIB_DEVICE
       
   736     free(buf);    
       
   737 #endif /* SYMBIAN_EZLIB_DEVICE */
       
   738     return ret; 
       
   739 }
       
   740 
       
   741 #else /* not ANSI C */
       
   742 
       
   743 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
       
   744                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
       
   745     gzFile file;
       
   746     const char *format;
       
   747     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
       
   748         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
       
   749 {
       
   750     char buf[Z_PRINTF_BUFSIZE];
       
   751     int len;
       
   752 
       
   753     buf[sizeof(buf) - 1] = 0;
       
   754 #ifdef NO_snprintf
       
   755 #  ifdef HAS_sprintf_void
       
   756     sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   757             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   758     for (len = 0; len < sizeof(buf); len++)
       
   759         if (buf[len] == 0) break;
       
   760 #  else
       
   761     len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   762                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   763 #  endif
       
   764 #else
       
   765 #  ifdef HAS_snprintf_void
       
   766     snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   767              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   768     len = strlen(buf);
       
   769 #  else
       
   770     len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   771                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   772 #  endif
       
   773 #endif
       
   774     if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
       
   775         return 0;
       
   776     return gzwrite(file, buf, len);
       
   777 }
       
   778 #endif
       
   779 
       
   780 /* ===========================================================================
       
   781    Writes c, converted to an unsigned char, into the compressed file.
       
   782    gzputc returns the value that was written, or -1 in case of error.
       
   783 */
       
   784 #ifdef __SYMBIAN32__
       
   785 int  gzputc_r (gzFile file,int  c)
       
   786 #else
       
   787 int ZEXPORT gzputc(file, c)
       
   788     gzFile file;
       
   789     int c;
       
   790 #endif /* __SYMBIAN32__ */
       
   791 {
       
   792     unsigned char cc = (unsigned char) c; /* required for big endian systems */
       
   793 
       
   794     return gzwrite_r(file, &cc, 1) == 1 ? (int)cc : -1;
       
   795 }
       
   796 
       
   797 
       
   798 /* ===========================================================================
       
   799    Writes the given null-terminated string to the compressed file, excluding
       
   800    the terminating null character.
       
   801    gzputs returns the number of characters written, or -1 in case of error.
       
   802 */
       
   803 #ifdef __SYMBIAN32__
       
   804 int  gzputs_r (gzFile file,  const char * s)
       
   805 #else
       
   806 int ZEXPORT gzputs(file, s)
       
   807     gzFile file;
       
   808     const char *s;
       
   809 #endif /* __SYMBIAN32__ */
       
   810 {
       
   811     return gzwrite_r(file, (char*)s, (unsigned)strlen(s));
       
   812 }
       
   813 
       
   814 
       
   815 /* ===========================================================================
       
   816    Flushes all pending output into the compressed file. The parameter
       
   817    flush is as in the deflate() function.
       
   818 */
       
   819 #ifdef __SYMBIAN32__
       
   820 local int do_flush (gzFile file,int  flush)
       
   821 #else
       
   822 local int do_flush (file, flush)
       
   823     gzFile file;
       
   824     int flush;
       
   825 #endif /* __SYMBIAN32__ */
       
   826 {
       
   827     uInt len;
       
   828     int done = 0;
       
   829     gz_stream *s = (gz_stream*)file;
       
   830 
       
   831     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   832 
       
   833     s->stream.avail_in = 0; /* should be zero already anyway */
       
   834 
       
   835     for (;;) {
       
   836         len = Z_BUFSIZE - s->stream.avail_out;
       
   837 
       
   838         if (len != 0) {
       
   839             if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
       
   840                 s->z_err = Z_ERRNO;
       
   841                 return Z_ERRNO;
       
   842             }
       
   843             s->stream.next_out = s->outbuf;
       
   844             s->stream.avail_out = Z_BUFSIZE;
       
   845         }
       
   846         if (done) break;
       
   847         s->out += s->stream.avail_out;
       
   848         s->z_err = deflate_r(&(s->stream), flush);
       
   849         s->out -= s->stream.avail_out;
       
   850 
       
   851         /* Ignore the second of two consecutive flushes: */
       
   852         if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
       
   853 
       
   854         /* deflate has finished flushing only when it hasn't used up
       
   855          * all the available space in the output buffer:
       
   856          */
       
   857         done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
       
   858 
       
   859         if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
       
   860     }
       
   861     return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
       
   862 }
       
   863 #ifdef __SYMBIAN32__
       
   864 int gzflush_r (gzFile file,int  flush)
       
   865 #else
       
   866 int ZEXPORT gzflush (file, flush)
       
   867      gzFile file;
       
   868      int flush;
       
   869 #endif /* __SYMBIAN32__ */
       
   870 {
       
   871     gz_stream *s = (gz_stream*)file;
       
   872     int err = do_flush (file, flush);
       
   873 
       
   874     if (err) return err;
       
   875     fflush(s->file);
       
   876     return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
       
   877 }
       
   878 #endif /* NO_GZCOMPRESS */
       
   879 
       
   880 /* ===========================================================================
       
   881    Sets the starting position for the next gzread or gzwrite on the given
       
   882    compressed file. The offset represents a number of bytes in the
       
   883    gzseek returns the resulting offset location as measured in bytes from
       
   884    the beginning of the uncompressed stream, or -1 in case of error.
       
   885    SEEK_END is not implemented, returns error.
       
   886    In this version of the library, gzseek can be extremely slow.
       
   887 */
       
   888 #ifdef __SYMBIAN32__
       
   889 z_off_t gzseek_r (gzFile file,z_off_t  offset,int whence)
       
   890 #else
       
   891 z_off_t ZEXPORT gzseek (file, offset, whence)
       
   892     gzFile file;
       
   893     z_off_t offset;
       
   894     int whence;
       
   895 #endif /* __SYMBIAN32__ */
       
   896 
       
   897 {
       
   898     gz_stream *s = (gz_stream*)file;
       
   899 
       
   900     if (s == NULL || whence == SEEK_END ||
       
   901         s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
       
   902         return -1L;
       
   903     }
       
   904 
       
   905     if (s->mode == 'w') {
       
   906 #ifdef NO_GZCOMPRESS
       
   907         return -1L;
       
   908 #else
       
   909         if (whence == SEEK_SET) {
       
   910             offset -= s->in;
       
   911         }
       
   912         if (offset < 0) return -1L;
       
   913 
       
   914         /* At this point, offset is the number of zero bytes to write. */
       
   915         if (s->inbuf == Z_NULL) {
       
   916             s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
       
   917             if (s->inbuf == Z_NULL) return -1L;
       
   918             zmemzero(s->inbuf, Z_BUFSIZE);
       
   919         }
       
   920         while (offset > 0)  {
       
   921             uInt size = Z_BUFSIZE;
       
   922             if (offset < Z_BUFSIZE) size = (uInt)offset;
       
   923 
       
   924             size = gzwrite_r(file, s->inbuf, size);
       
   925             if (size == 0) return -1L;
       
   926 
       
   927             offset -= size;
       
   928         }
       
   929         return s->in;
       
   930 #endif
       
   931     }
       
   932     /* Rest of function is for reading only */
       
   933 
       
   934     /* compute absolute position */
       
   935     if (whence == SEEK_CUR) {
       
   936         offset += s->out;
       
   937     }
       
   938     if (offset < 0) return -1L;
       
   939 
       
   940     if (s->transparent) {
       
   941         /* map to fseek */
       
   942         s->back = EOF;
       
   943         s->stream.avail_in = 0;
       
   944         s->stream.next_in = s->inbuf;
       
   945         if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
       
   946 
       
   947         s->in = s->out = offset;
       
   948         return offset;
       
   949     }
       
   950 
       
   951     /* For a negative seek, rewind and use positive seek */
       
   952     if (offset >= s->out) {
       
   953         offset -= s->out;
       
   954     } else if (gzrewind_r(file) < 0) {
       
   955         return -1L;
       
   956     }
       
   957     /* offset is now the number of bytes to skip. */
       
   958 
       
   959     if (offset != 0 && s->outbuf == Z_NULL) {
       
   960         s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
       
   961         if (s->outbuf == Z_NULL) return -1L;
       
   962     }
       
   963     if (offset && s->back != EOF) {
       
   964         s->back = EOF;
       
   965         s->out++;
       
   966         offset--;
       
   967         if (s->last) s->z_err = Z_STREAM_END;
       
   968     }
       
   969     while (offset > 0)  {
       
   970         int size = Z_BUFSIZE;
       
   971         if (offset < Z_BUFSIZE) size = (int)offset;
       
   972 
       
   973         size = gzread_r(file, s->outbuf, (uInt)size);
       
   974         if (size <= 0) return -1L;
       
   975         offset -= size;
       
   976     }
       
   977     return s->out;
       
   978 }
       
   979 
       
   980 /* ===========================================================================
       
   981      Rewinds input file.
       
   982 */
       
   983 #ifdef __SYMBIAN32__
       
   984 int  gzrewind_r (gzFile file)
       
   985 #else
       
   986 int ZEXPORT gzrewind (file)
       
   987     gzFile file;
       
   988 #endif /* __SYMBIAN32__ */
       
   989 {
       
   990     gz_stream *s = (gz_stream*)file;
       
   991 
       
   992     if (s == NULL || s->mode != 'r') return -1;
       
   993 
       
   994     s->z_err = Z_OK;
       
   995     s->z_eof = 0;
       
   996     s->back = EOF;
       
   997     s->stream.avail_in = 0;
       
   998     s->stream.next_in = s->inbuf;
       
   999     s->crc = crc32_r(0L, Z_NULL, 0);
       
  1000     if (!s->transparent) (void)inflateReset_r(&s->stream);
       
  1001     s->in = 0;
       
  1002     s->out = 0;
       
  1003     return fseek(s->file, s->start, SEEK_SET);
       
  1004 }
       
  1005 
       
  1006 /* ===========================================================================
       
  1007    Returns the starting position for the next gzread or gzwrite on the
       
  1008    given compressed file. This position represents a number of bytes in the
       
  1009    uncompressed data stream.
       
  1010 */
       
  1011 #ifdef __SYMBIAN32__
       
  1012 z_off_t gztell_r (gzFile file)
       
  1013 #else
       
  1014 z_off_t ZEXPORT gztell (file)
       
  1015     gzFile file;
       
  1016 #endif /* __SYMBIAN32__ */
       
  1017 {
       
  1018     return gzseek_r(file, 0L, SEEK_CUR);
       
  1019 }
       
  1020 
       
  1021 /* ===========================================================================
       
  1022    Returns 1 when EOF has previously been detected reading the given
       
  1023    input stream, otherwise zero.
       
  1024 */
       
  1025 #ifdef __SYMBIAN32__
       
  1026 int gzeof_r (gzFile file)
       
  1027 #else
       
  1028 int ZEXPORT gzeof (file)
       
  1029     gzFile file;
       
  1030 #endif /* __SYMBIAN32__ */
       
  1031 {
       
  1032     gz_stream *s = (gz_stream*)file;
       
  1033 
       
  1034     /* With concatenated compressed files that can have embedded
       
  1035      * crc trailers, z_eof is no longer the only/best indicator of EOF
       
  1036      * on a gz_stream. Handle end-of-stream error explicitly here.
       
  1037      */
       
  1038     if (s == NULL || s->mode != 'r') return 0;
       
  1039     if (s->z_eof) return 1;
       
  1040     return s->z_err == Z_STREAM_END;
       
  1041 }
       
  1042 
       
  1043 /* ===========================================================================
       
  1044    Returns 1 if reading and doing so transparently, otherwise zero.
       
  1045 */
       
  1046 #ifdef __SYMBIAN32__
       
  1047 int gzdirect_r (gzFile file)
       
  1048 #else
       
  1049 int ZEXPORT gzdirect (file)
       
  1050     gzFile file;
       
  1051 #endif /* __SYMBIAN32__ */
       
  1052 {
       
  1053     gz_stream *s = (gz_stream*)file;
       
  1054 
       
  1055     if (s == NULL || s->mode != 'r') return 0;
       
  1056     return s->transparent;
       
  1057 }
       
  1058 
       
  1059 /* ===========================================================================
       
  1060    Outputs a long in LSB order to the given file
       
  1061 */
       
  1062 #ifdef __SYMBIAN32__
       
  1063 local void putLong (FILE * file,uLong  x)
       
  1064 #else
       
  1065 local void putLong (file, x)
       
  1066     FILE *file;
       
  1067     uLong x;
       
  1068 #endif /* __SYMBIAN32__ */
       
  1069 {
       
  1070     int n;
       
  1071     for (n = 0; n < 4; n++) {
       
  1072         fputc((int)(x & 0xff), file);
       
  1073         x >>= 8;
       
  1074     }
       
  1075 }
       
  1076 
       
  1077 /* ===========================================================================
       
  1078    Reads a long in LSB order from the given gz_stream. Sets z_err in case
       
  1079    of error.
       
  1080 */
       
  1081 #ifdef __SYMBIAN32__
       
  1082 local uLong getLong (gz_stream * s)
       
  1083 #else
       
  1084 local uLong getLong (s)
       
  1085     gz_stream *s;
       
  1086 #endif /* __SYMBIAN32__ */
       
  1087 {
       
  1088     uLong x = (uLong)get_byte(s);
       
  1089     int c;
       
  1090 
       
  1091     x += ((uLong)get_byte(s))<<8;
       
  1092     x += ((uLong)get_byte(s))<<16;
       
  1093     c = get_byte(s);
       
  1094     if (c == EOF) s->z_err = Z_DATA_ERROR;
       
  1095     x += ((uLong)c)<<24;
       
  1096     return x;
       
  1097 }
       
  1098 
       
  1099 /* ===========================================================================
       
  1100    Flushes all pending output if necessary, closes the compressed file
       
  1101    and deallocates all the (de)compression state.
       
  1102 */
       
  1103 #ifdef __SYMBIAN32__
       
  1104 int gzclose_r(gzFile file)
       
  1105 #else
       
  1106 int ZEXPORT gzclose (file)
       
  1107     gzFile file;
       
  1108 #endif /* __SYMBIAN32__ */
       
  1109 {
       
  1110     gz_stream *s = (gz_stream*)file;
       
  1111 
       
  1112     if (s == NULL) return Z_STREAM_ERROR;
       
  1113 
       
  1114     if (s->mode == 'w') {
       
  1115 #ifdef NO_GZCOMPRESS
       
  1116         return Z_STREAM_ERROR;
       
  1117 #else
       
  1118         if (do_flush (file, Z_FINISH) != Z_OK)
       
  1119             return destroy((gz_stream*)file);
       
  1120 
       
  1121         putLong (s->file, s->crc);
       
  1122         putLong (s->file, (uLong)(s->in & 0xffffffff));
       
  1123 #endif
       
  1124     }
       
  1125     return destroy((gz_stream*)file);
       
  1126 }
       
  1127 
       
  1128 #ifdef STDC
       
  1129 #  define zstrerror(errnum) strerror(errnum)
       
  1130 #else
       
  1131 #  define zstrerror(errnum) ""
       
  1132 #endif
       
  1133 
       
  1134 /* ===========================================================================
       
  1135    Returns the error message for the last error which occurred on the
       
  1136    given compressed file. errnum is set to zlib error number. If an
       
  1137    error occurred in the file system and not in the compression library,
       
  1138    errnum is set to Z_ERRNO and the application may consult errno
       
  1139    to get the exact error code.
       
  1140 */
       
  1141 #ifdef __SYMBIAN32__
       
  1142 const char *  gzerror_r (gzFile file, int *  errnum)
       
  1143 #else
       
  1144 const char * ZEXPORT gzerror (file, errnum)
       
  1145     gzFile file;
       
  1146     int *errnum;
       
  1147 #endif /* __SYMBIAN32__ */
       
  1148 {
       
  1149     char *m;
       
  1150     gz_stream *s = (gz_stream*)file;
       
  1151 
       
  1152     if (s == NULL) {
       
  1153         *errnum = Z_STREAM_ERROR;
       
  1154         return (const char*)ERR_MSG(Z_STREAM_ERROR);
       
  1155     }
       
  1156     *errnum = s->z_err;
       
  1157     if (*errnum == Z_OK) return (const char*)"";
       
  1158 
       
  1159     m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
       
  1160 
       
  1161     if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
       
  1162 
       
  1163     TRYFREE(s->msg);
       
  1164     s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
       
  1165     if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
       
  1166     strcpy(s->msg, s->path);
       
  1167     strcat(s->msg, ": ");
       
  1168     strcat(s->msg, m);
       
  1169     return (const char*)s->msg;
       
  1170 }
       
  1171 
       
  1172 /* ===========================================================================
       
  1173    Clear the error and end-of-file flags, and do the same for the real file.
       
  1174 */
       
  1175 #ifdef __SYMBIAN32__
       
  1176 void gzclearerr_r (gzFile file)
       
  1177 #else
       
  1178 void ZEXPORT gzclearerr (file)
       
  1179     gzFile file;
       
  1180 #endif /* __SYMBIAN32__ */
       
  1181 {
       
  1182     gz_stream *s = (gz_stream*)file;
       
  1183 
       
  1184     if (s == NULL) return;
       
  1185     if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
       
  1186     s->z_eof = 0;
       
  1187     clearerr(s->file);
       
  1188 }
       
  1189 
       
  1190 
       
  1191