jdk/src/share/native/java/util/zip/zlib-1.2.3/gzio.c
changeset 11303 5f48992867e6
parent 11302 a6305295d4d9
parent 11239 885050364691
child 11304 5d3d2bd1dfd1
equal deleted inserted replaced
11302:a6305295d4d9 11303:5f48992867e6
     1 /*
       
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.  Oracle designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Oracle in the LICENSE file that accompanied this code.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  */
       
    24 
       
    25 /* gzio.c -- IO on .gz files
       
    26  * Copyright (C) 1995-2005 Jean-loup Gailly.
       
    27  * For conditions of distribution and use, see copyright notice in zlib.h
       
    28  *
       
    29  * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
       
    30  */
       
    31 
       
    32 /* @(#) $Id$ */
       
    33 
       
    34 #include <stdio.h>
       
    35 
       
    36 #include "zutil.h"
       
    37 
       
    38 #ifdef NO_DEFLATE       /* for compatibility with old definition */
       
    39 #  define NO_GZCOMPRESS
       
    40 #endif
       
    41 
       
    42 #ifndef NO_DUMMY_DECL
       
    43 struct internal_state {int dummy;}; /* for buggy compilers */
       
    44 #endif
       
    45 
       
    46 #ifndef Z_BUFSIZE
       
    47 #  ifdef MAXSEG_64K
       
    48 #    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
       
    49 #  else
       
    50 #    define Z_BUFSIZE 16384
       
    51 #  endif
       
    52 #endif
       
    53 #ifndef Z_PRINTF_BUFSIZE
       
    54 #  define Z_PRINTF_BUFSIZE 4096
       
    55 #endif
       
    56 
       
    57 #ifdef __MVS__
       
    58 #  pragma map (fdopen , "\174\174FDOPEN")
       
    59    FILE *fdopen(int, const char *);
       
    60 #endif
       
    61 
       
    62 #ifndef STDC
       
    63 extern voidp  malloc OF((uInt size));
       
    64 extern void   free   OF((voidpf ptr));
       
    65 #endif
       
    66 
       
    67 #define ALLOC(size) malloc(size)
       
    68 #define TRYFREE(p) {if (p) free(p);}
       
    69 
       
    70 static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
       
    71 
       
    72 /* gzip flag byte */
       
    73 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
       
    74 #define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
       
    75 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
       
    76 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
       
    77 #define COMMENT      0x10 /* bit 4 set: file comment present */
       
    78 #define RESERVED     0xE0 /* bits 5..7: reserved */
       
    79 
       
    80 typedef struct gz_stream {
       
    81     z_stream stream;
       
    82     int      z_err;   /* error code for last stream operation */
       
    83     int      z_eof;   /* set if end of input file */
       
    84     FILE     *file;   /* .gz file */
       
    85     Byte     *inbuf;  /* input buffer */
       
    86     Byte     *outbuf; /* output buffer */
       
    87     uLong    crc;     /* crc32 of uncompressed data */
       
    88     char     *msg;    /* error message */
       
    89     char     *path;   /* path name for debugging only */
       
    90     int      transparent; /* 1 if input file is not a .gz file */
       
    91     char     mode;    /* 'w' or 'r' */
       
    92     z_off_t  start;   /* start of compressed data in file (header skipped) */
       
    93     z_off_t  in;      /* bytes into deflate or inflate */
       
    94     z_off_t  out;     /* bytes out of deflate or inflate */
       
    95     int      back;    /* one character push-back */
       
    96     int      last;    /* true if push-back is last character */
       
    97 } gz_stream;
       
    98 
       
    99 
       
   100 local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
       
   101 local int do_flush        OF((gzFile file, int flush));
       
   102 local int    get_byte     OF((gz_stream *s));
       
   103 local void   check_header OF((gz_stream *s));
       
   104 local int    destroy      OF((gz_stream *s));
       
   105 local void   putLong      OF((FILE *file, uLong x));
       
   106 local uLong  getLong      OF((gz_stream *s));
       
   107 
       
   108 /* ===========================================================================
       
   109      Opens a gzip (.gz) file for reading or writing. The mode parameter
       
   110    is as in fopen ("rb" or "wb"). The file is given either by file descriptor
       
   111    or path name (if fd == -1).
       
   112      gz_open returns NULL if the file could not be opened or if there was
       
   113    insufficient memory to allocate the (de)compression state; errno
       
   114    can be checked to distinguish the two cases (if errno is zero, the
       
   115    zlib error is Z_MEM_ERROR).
       
   116 */
       
   117 local gzFile gz_open (path, mode, fd)
       
   118     const char *path;
       
   119     const char *mode;
       
   120     int  fd;
       
   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(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(&(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(&(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 
       
   204     errno = 0;
       
   205     s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
       
   206 
       
   207     if (s->file == NULL) {
       
   208         return destroy(s), (gzFile)Z_NULL;
       
   209     }
       
   210     if (s->mode == 'w') {
       
   211         /* Write a very simple .gz header:
       
   212          */
       
   213         fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
       
   214              Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
       
   215         s->start = 10L;
       
   216         /* We use 10L instead of ftell(s->file) to because ftell causes an
       
   217          * fflush on some systems. This version of the library doesn't use
       
   218          * start anyway in write mode, so this initialization is not
       
   219          * necessary.
       
   220          */
       
   221     } else {
       
   222         check_header(s); /* skip the .gz header */
       
   223         s->start = ftell(s->file) - s->stream.avail_in;
       
   224     }
       
   225 
       
   226     return (gzFile)s;
       
   227 }
       
   228 
       
   229 /* ===========================================================================
       
   230      Opens a gzip (.gz) file for reading or writing.
       
   231 */
       
   232 gzFile ZEXPORT gzopen (path, mode)
       
   233     const char *path;
       
   234     const char *mode;
       
   235 {
       
   236     return gz_open (path, mode, -1);
       
   237 }
       
   238 
       
   239 /* ===========================================================================
       
   240      Associate a gzFile with the file descriptor fd. fd is not dup'ed here
       
   241    to mimic the behavio(u)r of fdopen.
       
   242 */
       
   243 gzFile ZEXPORT gzdopen (fd, mode)
       
   244     int fd;
       
   245     const char *mode;
       
   246 {
       
   247     char name[46];      /* allow for up to 128-bit integers */
       
   248 
       
   249     if (fd < 0) return (gzFile)Z_NULL;
       
   250     sprintf(name, "<fd:%d>", fd); /* for debugging */
       
   251 
       
   252     return gz_open (name, mode, fd);
       
   253 }
       
   254 
       
   255 /* ===========================================================================
       
   256  * Update the compression level and strategy
       
   257  */
       
   258 int ZEXPORT gzsetparams (file, level, strategy)
       
   259     gzFile file;
       
   260     int level;
       
   261     int strategy;
       
   262 {
       
   263     gz_stream *s = (gz_stream*)file;
       
   264 
       
   265     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   266 
       
   267     /* Make room to allow flushing */
       
   268     if (s->stream.avail_out == 0) {
       
   269 
       
   270         s->stream.next_out = s->outbuf;
       
   271         if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
       
   272             s->z_err = Z_ERRNO;
       
   273         }
       
   274         s->stream.avail_out = Z_BUFSIZE;
       
   275     }
       
   276 
       
   277     return deflateParams (&(s->stream), level, strategy);
       
   278 }
       
   279 
       
   280 /* ===========================================================================
       
   281      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
       
   282    for end of file.
       
   283    IN assertion: the stream s has been sucessfully opened for reading.
       
   284 */
       
   285 local int get_byte(s)
       
   286     gz_stream *s;
       
   287 {
       
   288     if (s->z_eof) return EOF;
       
   289     if (s->stream.avail_in == 0) {
       
   290         errno = 0;
       
   291         s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
       
   292         if (s->stream.avail_in == 0) {
       
   293             s->z_eof = 1;
       
   294             if (ferror(s->file)) s->z_err = Z_ERRNO;
       
   295             return EOF;
       
   296         }
       
   297         s->stream.next_in = s->inbuf;
       
   298     }
       
   299     s->stream.avail_in--;
       
   300     return *(s->stream.next_in)++;
       
   301 }
       
   302 
       
   303 /* ===========================================================================
       
   304       Check the gzip header of a gz_stream opened for reading. Set the stream
       
   305     mode to transparent if the gzip magic header is not present; set s->err
       
   306     to Z_DATA_ERROR if the magic header is present but the rest of the header
       
   307     is incorrect.
       
   308     IN assertion: the stream s has already been created sucessfully;
       
   309        s->stream.avail_in is zero for the first time, but may be non-zero
       
   310        for concatenated .gz files.
       
   311 */
       
   312 local void check_header(s)
       
   313     gz_stream *s;
       
   314 {
       
   315     int method; /* method byte */
       
   316     int flags;  /* flags byte */
       
   317     uInt len;
       
   318     int c;
       
   319 
       
   320     /* Assure two bytes in the buffer so we can peek ahead -- handle case
       
   321        where first byte of header is at the end of the buffer after the last
       
   322        gzip segment */
       
   323     len = s->stream.avail_in;
       
   324     if (len < 2) {
       
   325         if (len) s->inbuf[0] = s->stream.next_in[0];
       
   326         errno = 0;
       
   327         len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
       
   328         if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
       
   329         s->stream.avail_in += len;
       
   330         s->stream.next_in = s->inbuf;
       
   331         if (s->stream.avail_in < 2) {
       
   332             s->transparent = s->stream.avail_in;
       
   333             return;
       
   334         }
       
   335     }
       
   336 
       
   337     /* Peek ahead to check the gzip magic header */
       
   338     if (s->stream.next_in[0] != gz_magic[0] ||
       
   339         s->stream.next_in[1] != gz_magic[1]) {
       
   340         s->transparent = 1;
       
   341         return;
       
   342     }
       
   343     s->stream.avail_in -= 2;
       
   344     s->stream.next_in += 2;
       
   345 
       
   346     /* Check the rest of the gzip header */
       
   347     method = get_byte(s);
       
   348     flags = get_byte(s);
       
   349     if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
       
   350         s->z_err = Z_DATA_ERROR;
       
   351         return;
       
   352     }
       
   353 
       
   354     /* Discard time, xflags and OS code: */
       
   355     for (len = 0; len < 6; len++) (void)get_byte(s);
       
   356 
       
   357     if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
       
   358         len  =  (uInt)get_byte(s);
       
   359         len += ((uInt)get_byte(s))<<8;
       
   360         /* len is garbage if EOF but the loop below will quit anyway */
       
   361         while (len-- != 0 && get_byte(s) != EOF) ;
       
   362     }
       
   363     if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
       
   364         while ((c = get_byte(s)) != 0 && c != EOF) ;
       
   365     }
       
   366     if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
       
   367         while ((c = get_byte(s)) != 0 && c != EOF) ;
       
   368     }
       
   369     if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
       
   370         for (len = 0; len < 2; len++) (void)get_byte(s);
       
   371     }
       
   372     s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
       
   373 }
       
   374 
       
   375  /* ===========================================================================
       
   376  * Cleanup then free the given gz_stream. Return a zlib error code.
       
   377    Try freeing in the reverse order of allocations.
       
   378  */
       
   379 local int destroy (s)
       
   380     gz_stream *s;
       
   381 {
       
   382     int err = Z_OK;
       
   383 
       
   384     if (!s) return Z_STREAM_ERROR;
       
   385 
       
   386     TRYFREE(s->msg);
       
   387 
       
   388     if (s->stream.state != NULL) {
       
   389         if (s->mode == 'w') {
       
   390 #ifdef NO_GZCOMPRESS
       
   391             err = Z_STREAM_ERROR;
       
   392 #else
       
   393             err = deflateEnd(&(s->stream));
       
   394 #endif
       
   395         } else if (s->mode == 'r') {
       
   396             err = inflateEnd(&(s->stream));
       
   397         }
       
   398     }
       
   399     if (s->file != NULL && fclose(s->file)) {
       
   400 #ifdef ESPIPE
       
   401         if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
       
   402 #endif
       
   403             err = Z_ERRNO;
       
   404     }
       
   405     if (s->z_err < 0) err = s->z_err;
       
   406 
       
   407     TRYFREE(s->inbuf);
       
   408     TRYFREE(s->outbuf);
       
   409     TRYFREE(s->path);
       
   410     TRYFREE(s);
       
   411     return err;
       
   412 }
       
   413 
       
   414 /* ===========================================================================
       
   415      Reads the given number of uncompressed bytes from the compressed file.
       
   416    gzread returns the number of bytes actually read (0 for end of file).
       
   417 */
       
   418 int ZEXPORT gzread (file, buf, len)
       
   419     gzFile file;
       
   420     voidp buf;
       
   421     unsigned len;
       
   422 {
       
   423     gz_stream *s = (gz_stream*)file;
       
   424     Bytef *start = (Bytef*)buf; /* starting point for crc computation */
       
   425     Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
       
   426 
       
   427     if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
       
   428 
       
   429     if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
       
   430     if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
       
   431 
       
   432     next_out = (Byte*)buf;
       
   433     s->stream.next_out = (Bytef*)buf;
       
   434     s->stream.avail_out = len;
       
   435 
       
   436     if (s->stream.avail_out && s->back != EOF) {
       
   437         *next_out++ = s->back;
       
   438         s->stream.next_out++;
       
   439         s->stream.avail_out--;
       
   440         s->back = EOF;
       
   441         s->out++;
       
   442         start++;
       
   443         if (s->last) {
       
   444             s->z_err = Z_STREAM_END;
       
   445             return 1;
       
   446         }
       
   447     }
       
   448 
       
   449     while (s->stream.avail_out != 0) {
       
   450 
       
   451         if (s->transparent) {
       
   452             /* Copy first the lookahead bytes: */
       
   453             uInt n = s->stream.avail_in;
       
   454             if (n > s->stream.avail_out) n = s->stream.avail_out;
       
   455             if (n > 0) {
       
   456                 zmemcpy(s->stream.next_out, s->stream.next_in, n);
       
   457                 next_out += n;
       
   458                 s->stream.next_out = next_out;
       
   459                 s->stream.next_in   += n;
       
   460                 s->stream.avail_out -= n;
       
   461                 s->stream.avail_in  -= n;
       
   462             }
       
   463             if (s->stream.avail_out > 0) {
       
   464                 s->stream.avail_out -=
       
   465                     (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
       
   466             }
       
   467             len -= s->stream.avail_out;
       
   468             s->in  += len;
       
   469             s->out += len;
       
   470             if (len == 0) s->z_eof = 1;
       
   471             return (int)len;
       
   472         }
       
   473         if (s->stream.avail_in == 0 && !s->z_eof) {
       
   474 
       
   475             errno = 0;
       
   476             s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
       
   477             if (s->stream.avail_in == 0) {
       
   478                 s->z_eof = 1;
       
   479                 if (ferror(s->file)) {
       
   480                     s->z_err = Z_ERRNO;
       
   481                     break;
       
   482                 }
       
   483             }
       
   484             s->stream.next_in = s->inbuf;
       
   485         }
       
   486         s->in += s->stream.avail_in;
       
   487         s->out += s->stream.avail_out;
       
   488         s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
       
   489         s->in -= s->stream.avail_in;
       
   490         s->out -= s->stream.avail_out;
       
   491 
       
   492         if (s->z_err == Z_STREAM_END) {
       
   493             /* Check CRC and original size */
       
   494             s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
       
   495             start = s->stream.next_out;
       
   496 
       
   497             if (getLong(s) != s->crc) {
       
   498                 s->z_err = Z_DATA_ERROR;
       
   499             } else {
       
   500                 (void)getLong(s);
       
   501                 /* The uncompressed length returned by above getlong() may be
       
   502                  * different from s->out in case of concatenated .gz files.
       
   503                  * Check for such files:
       
   504                  */
       
   505                 check_header(s);
       
   506                 if (s->z_err == Z_OK) {
       
   507                     inflateReset(&(s->stream));
       
   508                     s->crc = crc32(0L, Z_NULL, 0);
       
   509                 }
       
   510             }
       
   511         }
       
   512         if (s->z_err != Z_OK || s->z_eof) break;
       
   513     }
       
   514     s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
       
   515 
       
   516     if (len == s->stream.avail_out &&
       
   517         (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
       
   518         return -1;
       
   519     return (int)(len - s->stream.avail_out);
       
   520 }
       
   521 
       
   522 
       
   523 /* ===========================================================================
       
   524       Reads one byte from the compressed file. gzgetc returns this byte
       
   525    or -1 in case of end of file or error.
       
   526 */
       
   527 int ZEXPORT gzgetc(file)
       
   528     gzFile file;
       
   529 {
       
   530     unsigned char c;
       
   531 
       
   532     return gzread(file, &c, 1) == 1 ? c : -1;
       
   533 }
       
   534 
       
   535 
       
   536 /* ===========================================================================
       
   537       Push one byte back onto the stream.
       
   538 */
       
   539 int ZEXPORT gzungetc(c, file)
       
   540     int c;
       
   541     gzFile file;
       
   542 {
       
   543     gz_stream *s = (gz_stream*)file;
       
   544 
       
   545     if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
       
   546     s->back = c;
       
   547     s->out--;
       
   548     s->last = (s->z_err == Z_STREAM_END);
       
   549     if (s->last) s->z_err = Z_OK;
       
   550     s->z_eof = 0;
       
   551     return c;
       
   552 }
       
   553 
       
   554 
       
   555 /* ===========================================================================
       
   556       Reads bytes from the compressed file until len-1 characters are
       
   557    read, or a newline character is read and transferred to buf, or an
       
   558    end-of-file condition is encountered.  The string is then terminated
       
   559    with a null character.
       
   560       gzgets returns buf, or Z_NULL in case of error.
       
   561 
       
   562       The current implementation is not optimized at all.
       
   563 */
       
   564 char * ZEXPORT gzgets(file, buf, len)
       
   565     gzFile file;
       
   566     char *buf;
       
   567     int len;
       
   568 {
       
   569     char *b = buf;
       
   570     if (buf == Z_NULL || len <= 0) return Z_NULL;
       
   571 
       
   572     while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
       
   573     *buf = '\0';
       
   574     return b == buf && len > 0 ? Z_NULL : b;
       
   575 }
       
   576 
       
   577 
       
   578 #ifndef NO_GZCOMPRESS
       
   579 /* ===========================================================================
       
   580      Writes the given number of uncompressed bytes into the compressed file.
       
   581    gzwrite returns the number of bytes actually written (0 in case of error).
       
   582 */
       
   583 int ZEXPORT gzwrite (file, buf, len)
       
   584     gzFile file;
       
   585     voidpc buf;
       
   586     unsigned len;
       
   587 {
       
   588     gz_stream *s = (gz_stream*)file;
       
   589 
       
   590     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   591 
       
   592     s->stream.next_in = (Bytef*)buf;
       
   593     s->stream.avail_in = len;
       
   594 
       
   595     while (s->stream.avail_in != 0) {
       
   596 
       
   597         if (s->stream.avail_out == 0) {
       
   598 
       
   599             s->stream.next_out = s->outbuf;
       
   600             if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
       
   601                 s->z_err = Z_ERRNO;
       
   602                 break;
       
   603             }
       
   604             s->stream.avail_out = Z_BUFSIZE;
       
   605         }
       
   606         s->in += s->stream.avail_in;
       
   607         s->out += s->stream.avail_out;
       
   608         s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
       
   609         s->in -= s->stream.avail_in;
       
   610         s->out -= s->stream.avail_out;
       
   611         if (s->z_err != Z_OK) break;
       
   612     }
       
   613     s->crc = crc32(s->crc, (const Bytef *)buf, len);
       
   614 
       
   615     return (int)(len - s->stream.avail_in);
       
   616 }
       
   617 
       
   618 
       
   619 /* ===========================================================================
       
   620      Converts, formats, and writes the args to the compressed file under
       
   621    control of the format string, as in fprintf. gzprintf returns the number of
       
   622    uncompressed bytes actually written (0 in case of error).
       
   623 */
       
   624 #ifdef STDC
       
   625 #include <stdarg.h>
       
   626 
       
   627 int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
       
   628 {
       
   629     char buf[Z_PRINTF_BUFSIZE];
       
   630     va_list va;
       
   631     int len;
       
   632 
       
   633     buf[sizeof(buf) - 1] = 0;
       
   634     va_start(va, format);
       
   635 #ifdef NO_vsnprintf
       
   636 #  ifdef HAS_vsprintf_void
       
   637     (void)vsprintf(buf, format, va);
       
   638     va_end(va);
       
   639     for (len = 0; len < sizeof(buf); len++)
       
   640         if (buf[len] == 0) break;
       
   641 #  else
       
   642     len = vsprintf(buf, format, va);
       
   643     va_end(va);
       
   644 #  endif
       
   645 #else
       
   646 #  ifdef HAS_vsnprintf_void
       
   647     (void)vsnprintf(buf, sizeof(buf), format, va);
       
   648     va_end(va);
       
   649     len = strlen(buf);
       
   650 #  else
       
   651     len = vsnprintf(buf, sizeof(buf), format, va);
       
   652     va_end(va);
       
   653 #  endif
       
   654 #endif
       
   655     if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
       
   656         return 0;
       
   657     return gzwrite(file, buf, (unsigned)len);
       
   658 }
       
   659 #else /* not ANSI C */
       
   660 
       
   661 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
       
   662                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
       
   663     gzFile file;
       
   664     const char *format;
       
   665     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
       
   666         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
       
   667 {
       
   668     char buf[Z_PRINTF_BUFSIZE];
       
   669     int len;
       
   670 
       
   671     buf[sizeof(buf) - 1] = 0;
       
   672 #ifdef NO_snprintf
       
   673 #  ifdef HAS_sprintf_void
       
   674     sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   675             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   676     for (len = 0; len < sizeof(buf); len++)
       
   677         if (buf[len] == 0) break;
       
   678 #  else
       
   679     len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   680                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   681 #  endif
       
   682 #else
       
   683 #  ifdef HAS_snprintf_void
       
   684     snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   685              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   686     len = strlen(buf);
       
   687 #  else
       
   688     len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
       
   689                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
       
   690 #  endif
       
   691 #endif
       
   692     if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
       
   693         return 0;
       
   694     return gzwrite(file, buf, len);
       
   695 }
       
   696 #endif
       
   697 
       
   698 /* ===========================================================================
       
   699       Writes c, converted to an unsigned char, into the compressed file.
       
   700    gzputc returns the value that was written, or -1 in case of error.
       
   701 */
       
   702 int ZEXPORT gzputc(file, c)
       
   703     gzFile file;
       
   704     int c;
       
   705 {
       
   706     unsigned char cc = (unsigned char) c; /* required for big endian systems */
       
   707 
       
   708     return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
       
   709 }
       
   710 
       
   711 
       
   712 /* ===========================================================================
       
   713       Writes the given null-terminated string to the compressed file, excluding
       
   714    the terminating null character.
       
   715       gzputs returns the number of characters written, or -1 in case of error.
       
   716 */
       
   717 int ZEXPORT gzputs(file, s)
       
   718     gzFile file;
       
   719     const char *s;
       
   720 {
       
   721     return gzwrite(file, (char*)s, (unsigned)strlen(s));
       
   722 }
       
   723 
       
   724 
       
   725 /* ===========================================================================
       
   726      Flushes all pending output into the compressed file. The parameter
       
   727    flush is as in the deflate() function.
       
   728 */
       
   729 local int do_flush (file, flush)
       
   730     gzFile file;
       
   731     int flush;
       
   732 {
       
   733     uInt len;
       
   734     int done = 0;
       
   735     gz_stream *s = (gz_stream*)file;
       
   736 
       
   737     if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
       
   738 
       
   739     s->stream.avail_in = 0; /* should be zero already anyway */
       
   740 
       
   741     for (;;) {
       
   742         len = Z_BUFSIZE - s->stream.avail_out;
       
   743 
       
   744         if (len != 0) {
       
   745             if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
       
   746                 s->z_err = Z_ERRNO;
       
   747                 return Z_ERRNO;
       
   748             }
       
   749             s->stream.next_out = s->outbuf;
       
   750             s->stream.avail_out = Z_BUFSIZE;
       
   751         }
       
   752         if (done) break;
       
   753         s->out += s->stream.avail_out;
       
   754         s->z_err = deflate(&(s->stream), flush);
       
   755         s->out -= s->stream.avail_out;
       
   756 
       
   757         /* Ignore the second of two consecutive flushes: */
       
   758         if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
       
   759 
       
   760         /* deflate has finished flushing only when it hasn't used up
       
   761          * all the available space in the output buffer:
       
   762          */
       
   763         done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
       
   764 
       
   765         if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
       
   766     }
       
   767     return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
       
   768 }
       
   769 
       
   770 int ZEXPORT gzflush (file, flush)
       
   771      gzFile file;
       
   772      int flush;
       
   773 {
       
   774     gz_stream *s = (gz_stream*)file;
       
   775     int err = do_flush (file, flush);
       
   776 
       
   777     if (err) return err;
       
   778     fflush(s->file);
       
   779     return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
       
   780 }
       
   781 #endif /* NO_GZCOMPRESS */
       
   782 
       
   783 /* ===========================================================================
       
   784       Sets the starting position for the next gzread or gzwrite on the given
       
   785    compressed file. The offset represents a number of bytes in the
       
   786       gzseek returns the resulting offset location as measured in bytes from
       
   787    the beginning of the uncompressed stream, or -1 in case of error.
       
   788       SEEK_END is not implemented, returns error.
       
   789       In this version of the library, gzseek can be extremely slow.
       
   790 */
       
   791 z_off_t ZEXPORT gzseek (file, offset, whence)
       
   792     gzFile file;
       
   793     z_off_t offset;
       
   794     int whence;
       
   795 {
       
   796     gz_stream *s = (gz_stream*)file;
       
   797 
       
   798     if (s == NULL || whence == SEEK_END ||
       
   799         s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
       
   800         return -1L;
       
   801     }
       
   802 
       
   803     if (s->mode == 'w') {
       
   804 #ifdef NO_GZCOMPRESS
       
   805         return -1L;
       
   806 #else
       
   807         if (whence == SEEK_SET) {
       
   808             offset -= s->in;
       
   809         }
       
   810         if (offset < 0) return -1L;
       
   811 
       
   812         /* At this point, offset is the number of zero bytes to write. */
       
   813         if (s->inbuf == Z_NULL) {
       
   814             s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
       
   815             if (s->inbuf == Z_NULL) return -1L;
       
   816             zmemzero(s->inbuf, Z_BUFSIZE);
       
   817         }
       
   818         while (offset > 0)  {
       
   819             uInt size = Z_BUFSIZE;
       
   820             if (offset < Z_BUFSIZE) size = (uInt)offset;
       
   821 
       
   822             size = gzwrite(file, s->inbuf, size);
       
   823             if (size == 0) return -1L;
       
   824 
       
   825             offset -= size;
       
   826         }
       
   827         return s->in;
       
   828 #endif
       
   829     }
       
   830     /* Rest of function is for reading only */
       
   831 
       
   832     /* compute absolute position */
       
   833     if (whence == SEEK_CUR) {
       
   834         offset += s->out;
       
   835     }
       
   836     if (offset < 0) return -1L;
       
   837 
       
   838     if (s->transparent) {
       
   839         /* map to fseek */
       
   840         s->back = EOF;
       
   841         s->stream.avail_in = 0;
       
   842         s->stream.next_in = s->inbuf;
       
   843         if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
       
   844 
       
   845         s->in = s->out = offset;
       
   846         return offset;
       
   847     }
       
   848 
       
   849     /* For a negative seek, rewind and use positive seek */
       
   850     if (offset >= s->out) {
       
   851         offset -= s->out;
       
   852     } else if (gzrewind(file) < 0) {
       
   853         return -1L;
       
   854     }
       
   855     /* offset is now the number of bytes to skip. */
       
   856 
       
   857     if (offset != 0 && s->outbuf == Z_NULL) {
       
   858         s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
       
   859         if (s->outbuf == Z_NULL) return -1L;
       
   860     }
       
   861     if (offset && s->back != EOF) {
       
   862         s->back = EOF;
       
   863         s->out++;
       
   864         offset--;
       
   865         if (s->last) s->z_err = Z_STREAM_END;
       
   866     }
       
   867     while (offset > 0)  {
       
   868         int size = Z_BUFSIZE;
       
   869         if (offset < Z_BUFSIZE) size = (int)offset;
       
   870 
       
   871         size = gzread(file, s->outbuf, (uInt)size);
       
   872         if (size <= 0) return -1L;
       
   873         offset -= size;
       
   874     }
       
   875     return s->out;
       
   876 }
       
   877 
       
   878 /* ===========================================================================
       
   879      Rewinds input file.
       
   880 */
       
   881 int ZEXPORT gzrewind (file)
       
   882     gzFile file;
       
   883 {
       
   884     gz_stream *s = (gz_stream*)file;
       
   885 
       
   886     if (s == NULL || s->mode != 'r') return -1;
       
   887 
       
   888     s->z_err = Z_OK;
       
   889     s->z_eof = 0;
       
   890     s->back = EOF;
       
   891     s->stream.avail_in = 0;
       
   892     s->stream.next_in = s->inbuf;
       
   893     s->crc = crc32(0L, Z_NULL, 0);
       
   894     if (!s->transparent) (void)inflateReset(&s->stream);
       
   895     s->in = 0;
       
   896     s->out = 0;
       
   897     return fseek(s->file, s->start, SEEK_SET);
       
   898 }
       
   899 
       
   900 /* ===========================================================================
       
   901      Returns the starting position for the next gzread or gzwrite on the
       
   902    given compressed file. This position represents a number of bytes in the
       
   903    uncompressed data stream.
       
   904 */
       
   905 z_off_t ZEXPORT gztell (file)
       
   906     gzFile file;
       
   907 {
       
   908     return gzseek(file, 0L, SEEK_CUR);
       
   909 }
       
   910 
       
   911 /* ===========================================================================
       
   912      Returns 1 when EOF has previously been detected reading the given
       
   913    input stream, otherwise zero.
       
   914 */
       
   915 int ZEXPORT gzeof (file)
       
   916     gzFile file;
       
   917 {
       
   918     gz_stream *s = (gz_stream*)file;
       
   919 
       
   920     /* With concatenated compressed files that can have embedded
       
   921      * crc trailers, z_eof is no longer the only/best indicator of EOF
       
   922      * on a gz_stream. Handle end-of-stream error explicitly here.
       
   923      */
       
   924     if (s == NULL || s->mode != 'r') return 0;
       
   925     if (s->z_eof) return 1;
       
   926     return s->z_err == Z_STREAM_END;
       
   927 }
       
   928 
       
   929 /* ===========================================================================
       
   930      Returns 1 if reading and doing so transparently, otherwise zero.
       
   931 */
       
   932 int ZEXPORT gzdirect (file)
       
   933     gzFile file;
       
   934 {
       
   935     gz_stream *s = (gz_stream*)file;
       
   936 
       
   937     if (s == NULL || s->mode != 'r') return 0;
       
   938     return s->transparent;
       
   939 }
       
   940 
       
   941 /* ===========================================================================
       
   942    Outputs a long in LSB order to the given file
       
   943 */
       
   944 local void putLong (file, x)
       
   945     FILE *file;
       
   946     uLong x;
       
   947 {
       
   948     int n;
       
   949     for (n = 0; n < 4; n++) {
       
   950         fputc((int)(x & 0xff), file);
       
   951         x >>= 8;
       
   952     }
       
   953 }
       
   954 
       
   955 /* ===========================================================================
       
   956    Reads a long in LSB order from the given gz_stream. Sets z_err in case
       
   957    of error.
       
   958 */
       
   959 local uLong getLong (s)
       
   960     gz_stream *s;
       
   961 {
       
   962     uLong x = (uLong)get_byte(s);
       
   963     int c;
       
   964 
       
   965     x += ((uLong)get_byte(s))<<8;
       
   966     x += ((uLong)get_byte(s))<<16;
       
   967     c = get_byte(s);
       
   968     if (c == EOF) s->z_err = Z_DATA_ERROR;
       
   969     x += ((uLong)c)<<24;
       
   970     return x;
       
   971 }
       
   972 
       
   973 /* ===========================================================================
       
   974      Flushes all pending output if necessary, closes the compressed file
       
   975    and deallocates all the (de)compression state.
       
   976 */
       
   977 int ZEXPORT gzclose (file)
       
   978     gzFile file;
       
   979 {
       
   980     gz_stream *s = (gz_stream*)file;
       
   981 
       
   982     if (s == NULL) return Z_STREAM_ERROR;
       
   983 
       
   984     if (s->mode == 'w') {
       
   985 #ifdef NO_GZCOMPRESS
       
   986         return Z_STREAM_ERROR;
       
   987 #else
       
   988         if (do_flush (file, Z_FINISH) != Z_OK)
       
   989             return destroy((gz_stream*)file);
       
   990 
       
   991         putLong (s->file, s->crc);
       
   992         putLong (s->file, (uLong)(s->in & 0xffffffff));
       
   993 #endif
       
   994     }
       
   995     return destroy((gz_stream*)file);
       
   996 }
       
   997 
       
   998 #ifdef STDC
       
   999 #  define zstrerror(errnum) strerror(errnum)
       
  1000 #else
       
  1001 #  define zstrerror(errnum) ""
       
  1002 #endif
       
  1003 
       
  1004 /* ===========================================================================
       
  1005      Returns the error message for the last error which occurred on the
       
  1006    given compressed file. errnum is set to zlib error number. If an
       
  1007    error occurred in the file system and not in the compression library,
       
  1008    errnum is set to Z_ERRNO and the application may consult errno
       
  1009    to get the exact error code.
       
  1010 */
       
  1011 const char * ZEXPORT gzerror (file, errnum)
       
  1012     gzFile file;
       
  1013     int *errnum;
       
  1014 {
       
  1015     char *m;
       
  1016     gz_stream *s = (gz_stream*)file;
       
  1017 
       
  1018     if (s == NULL) {
       
  1019         *errnum = Z_STREAM_ERROR;
       
  1020         return (const char*)ERR_MSG(Z_STREAM_ERROR);
       
  1021     }
       
  1022     *errnum = s->z_err;
       
  1023     if (*errnum == Z_OK) return (const char*)"";
       
  1024 
       
  1025     m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
       
  1026 
       
  1027     if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
       
  1028 
       
  1029     TRYFREE(s->msg);
       
  1030     s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
       
  1031     if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
       
  1032     strcpy(s->msg, s->path);
       
  1033     strcat(s->msg, ": ");
       
  1034     strcat(s->msg, m);
       
  1035     return (const char*)s->msg;
       
  1036 }
       
  1037 
       
  1038 /* ===========================================================================
       
  1039      Clear the error and end-of-file flags, and do the same for the real file.
       
  1040 */
       
  1041 void ZEXPORT gzclearerr (file)
       
  1042     gzFile file;
       
  1043 {
       
  1044     gz_stream *s = (gz_stream*)file;
       
  1045 
       
  1046     if (s == NULL) return;
       
  1047     if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
       
  1048     s->z_eof = 0;
       
  1049     clearerr(s->file);
       
  1050 }