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