sourcepawn/compiler/zlib/gzio.c
branchsourcemod-1.1.0
changeset 2283 03a67e41afbc
parent 1951 c7b4237fff50
child 2287 017a725c9d17
     1.1 --- a/sourcepawn/compiler/zlib/gzio.c	Fri Mar 28 06:21:34 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1026 +0,0 @@
     1.4 -/* gzio.c -- IO on .gz files
     1.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
     1.6 - * For conditions of distribution and use, see copyright notice in zlib.h
     1.7 - *
     1.8 - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
     1.9 - */
    1.10 -
    1.11 -/* @(#) $Id$ */
    1.12 -
    1.13 -#include <stdio.h>
    1.14 -
    1.15 -#include "zutil.h"
    1.16 -
    1.17 -#ifdef NO_DEFLATE       /* for compatibility with old definition */
    1.18 -#  define NO_GZCOMPRESS
    1.19 -#endif
    1.20 -
    1.21 -#ifndef NO_DUMMY_DECL
    1.22 -struct internal_state {int dummy;}; /* for buggy compilers */
    1.23 -#endif
    1.24 -
    1.25 -#ifndef Z_BUFSIZE
    1.26 -#  ifdef MAXSEG_64K
    1.27 -#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
    1.28 -#  else
    1.29 -#    define Z_BUFSIZE 16384
    1.30 -#  endif
    1.31 -#endif
    1.32 -#ifndef Z_PRINTF_BUFSIZE
    1.33 -#  define Z_PRINTF_BUFSIZE 4096
    1.34 -#endif
    1.35 -
    1.36 -#ifdef __MVS__
    1.37 -#  pragma map (fdopen , "\174\174FDOPEN")
    1.38 -   FILE *fdopen(int, const char *);
    1.39 -#endif
    1.40 -
    1.41 -#ifndef STDC
    1.42 -extern voidp  malloc OF((uInt size));
    1.43 -extern void   free   OF((voidpf ptr));
    1.44 -#endif
    1.45 -
    1.46 -#define ALLOC(size) malloc(size)
    1.47 -#define TRYFREE(p) {if (p) free(p);}
    1.48 -
    1.49 -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
    1.50 -
    1.51 -/* gzip flag byte */
    1.52 -#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
    1.53 -#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
    1.54 -#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
    1.55 -#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
    1.56 -#define COMMENT      0x10 /* bit 4 set: file comment present */
    1.57 -#define RESERVED     0xE0 /* bits 5..7: reserved */
    1.58 -
    1.59 -typedef struct gz_stream {
    1.60 -    z_stream stream;
    1.61 -    int      z_err;   /* error code for last stream operation */
    1.62 -    int      z_eof;   /* set if end of input file */
    1.63 -    FILE     *file;   /* .gz file */
    1.64 -    Byte     *inbuf;  /* input buffer */
    1.65 -    Byte     *outbuf; /* output buffer */
    1.66 -    uLong    crc;     /* crc32 of uncompressed data */
    1.67 -    char     *msg;    /* error message */
    1.68 -    char     *path;   /* path name for debugging only */
    1.69 -    int      transparent; /* 1 if input file is not a .gz file */
    1.70 -    char     mode;    /* 'w' or 'r' */
    1.71 -    z_off_t  start;   /* start of compressed data in file (header skipped) */
    1.72 -    z_off_t  in;      /* bytes into deflate or inflate */
    1.73 -    z_off_t  out;     /* bytes out of deflate or inflate */
    1.74 -    int      back;    /* one character push-back */
    1.75 -    int      last;    /* true if push-back is last character */
    1.76 -} gz_stream;
    1.77 -
    1.78 -
    1.79 -local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
    1.80 -local int do_flush        OF((gzFile file, int flush));
    1.81 -local int    get_byte     OF((gz_stream *s));
    1.82 -local void   check_header OF((gz_stream *s));
    1.83 -local int    destroy      OF((gz_stream *s));
    1.84 -local void   putLong      OF((FILE *file, uLong x));
    1.85 -local uLong  getLong      OF((gz_stream *s));
    1.86 -
    1.87 -/* ===========================================================================
    1.88 -     Opens a gzip (.gz) file for reading or writing. The mode parameter
    1.89 -   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
    1.90 -   or path name (if fd == -1).
    1.91 -     gz_open returns NULL if the file could not be opened or if there was
    1.92 -   insufficient memory to allocate the (de)compression state; errno
    1.93 -   can be checked to distinguish the two cases (if errno is zero, the
    1.94 -   zlib error is Z_MEM_ERROR).
    1.95 -*/
    1.96 -local gzFile gz_open (path, mode, fd)
    1.97 -    const char *path;
    1.98 -    const char *mode;
    1.99 -    int  fd;
   1.100 -{
   1.101 -    int err;
   1.102 -    int level = Z_DEFAULT_COMPRESSION; /* compression level */
   1.103 -    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
   1.104 -    char *p = (char*)mode;
   1.105 -    gz_stream *s;
   1.106 -    char fmode[80]; /* copy of mode, without the compression level */
   1.107 -    char *m = fmode;
   1.108 -
   1.109 -    if (!path || !mode) return Z_NULL;
   1.110 -
   1.111 -    s = (gz_stream *)ALLOC(sizeof(gz_stream));
   1.112 -    if (!s) return Z_NULL;
   1.113 -
   1.114 -    s->stream.zalloc = (alloc_func)0;
   1.115 -    s->stream.zfree = (free_func)0;
   1.116 -    s->stream.opaque = (voidpf)0;
   1.117 -    s->stream.next_in = s->inbuf = Z_NULL;
   1.118 -    s->stream.next_out = s->outbuf = Z_NULL;
   1.119 -    s->stream.avail_in = s->stream.avail_out = 0;
   1.120 -    s->file = NULL;
   1.121 -    s->z_err = Z_OK;
   1.122 -    s->z_eof = 0;
   1.123 -    s->in = 0;
   1.124 -    s->out = 0;
   1.125 -    s->back = EOF;
   1.126 -    s->crc = crc32(0L, Z_NULL, 0);
   1.127 -    s->msg = NULL;
   1.128 -    s->transparent = 0;
   1.129 -
   1.130 -    s->path = (char*)ALLOC(strlen(path)+1);
   1.131 -    if (s->path == NULL) {
   1.132 -        return destroy(s), (gzFile)Z_NULL;
   1.133 -    }
   1.134 -    strcpy(s->path, path); /* do this early for debugging */
   1.135 -
   1.136 -    s->mode = '\0';
   1.137 -    do {
   1.138 -        if (*p == 'r') s->mode = 'r';
   1.139 -        if (*p == 'w' || *p == 'a') s->mode = 'w';
   1.140 -        if (*p >= '0' && *p <= '9') {
   1.141 -            level = *p - '0';
   1.142 -        } else if (*p == 'f') {
   1.143 -          strategy = Z_FILTERED;
   1.144 -        } else if (*p == 'h') {
   1.145 -          strategy = Z_HUFFMAN_ONLY;
   1.146 -        } else if (*p == 'R') {
   1.147 -          strategy = Z_RLE;
   1.148 -        } else {
   1.149 -            *m++ = *p; /* copy the mode */
   1.150 -        }
   1.151 -    } while (*p++ && m != fmode + sizeof(fmode));
   1.152 -    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
   1.153 -
   1.154 -    if (s->mode == 'w') {
   1.155 -#ifdef NO_GZCOMPRESS
   1.156 -        err = Z_STREAM_ERROR;
   1.157 -#else
   1.158 -        err = deflateInit2(&(s->stream), level,
   1.159 -                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
   1.160 -        /* windowBits is passed < 0 to suppress zlib header */
   1.161 -
   1.162 -        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
   1.163 -#endif
   1.164 -        if (err != Z_OK || s->outbuf == Z_NULL) {
   1.165 -            return destroy(s), (gzFile)Z_NULL;
   1.166 -        }
   1.167 -    } else {
   1.168 -        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
   1.169 -
   1.170 -        err = inflateInit2(&(s->stream), -MAX_WBITS);
   1.171 -        /* windowBits is passed < 0 to tell that there is no zlib header.
   1.172 -         * Note that in this case inflate *requires* an extra "dummy" byte
   1.173 -         * after the compressed stream in order to complete decompression and
   1.174 -         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
   1.175 -         * present after the compressed stream.
   1.176 -         */
   1.177 -        if (err != Z_OK || s->inbuf == Z_NULL) {
   1.178 -            return destroy(s), (gzFile)Z_NULL;
   1.179 -        }
   1.180 -    }
   1.181 -    s->stream.avail_out = Z_BUFSIZE;
   1.182 -
   1.183 -    errno = 0;
   1.184 -    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
   1.185 -
   1.186 -    if (s->file == NULL) {
   1.187 -        return destroy(s), (gzFile)Z_NULL;
   1.188 -    }
   1.189 -    if (s->mode == 'w') {
   1.190 -        /* Write a very simple .gz header:
   1.191 -         */
   1.192 -        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
   1.193 -             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
   1.194 -        s->start = 10L;
   1.195 -        /* We use 10L instead of ftell(s->file) to because ftell causes an
   1.196 -         * fflush on some systems. This version of the library doesn't use
   1.197 -         * start anyway in write mode, so this initialization is not
   1.198 -         * necessary.
   1.199 -         */
   1.200 -    } else {
   1.201 -        check_header(s); /* skip the .gz header */
   1.202 -        s->start = ftell(s->file) - s->stream.avail_in;
   1.203 -    }
   1.204 -
   1.205 -    return (gzFile)s;
   1.206 -}
   1.207 -
   1.208 -/* ===========================================================================
   1.209 -     Opens a gzip (.gz) file for reading or writing.
   1.210 -*/
   1.211 -gzFile ZEXPORT gzopen (path, mode)
   1.212 -    const char *path;
   1.213 -    const char *mode;
   1.214 -{
   1.215 -    return gz_open (path, mode, -1);
   1.216 -}
   1.217 -
   1.218 -/* ===========================================================================
   1.219 -     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
   1.220 -   to mimic the behavio(u)r of fdopen.
   1.221 -*/
   1.222 -gzFile ZEXPORT gzdopen (fd, mode)
   1.223 -    int fd;
   1.224 -    const char *mode;
   1.225 -{
   1.226 -    char name[46];      /* allow for up to 128-bit integers */
   1.227 -
   1.228 -    if (fd < 0) return (gzFile)Z_NULL;
   1.229 -    sprintf(name, "<fd:%d>", fd); /* for debugging */
   1.230 -
   1.231 -    return gz_open (name, mode, fd);
   1.232 -}
   1.233 -
   1.234 -/* ===========================================================================
   1.235 - * Update the compression level and strategy
   1.236 - */
   1.237 -int ZEXPORT gzsetparams (file, level, strategy)
   1.238 -    gzFile file;
   1.239 -    int level;
   1.240 -    int strategy;
   1.241 -{
   1.242 -    gz_stream *s = (gz_stream*)file;
   1.243 -
   1.244 -    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
   1.245 -
   1.246 -    /* Make room to allow flushing */
   1.247 -    if (s->stream.avail_out == 0) {
   1.248 -
   1.249 -        s->stream.next_out = s->outbuf;
   1.250 -        if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
   1.251 -            s->z_err = Z_ERRNO;
   1.252 -        }
   1.253 -        s->stream.avail_out = Z_BUFSIZE;
   1.254 -    }
   1.255 -
   1.256 -    return deflateParams (&(s->stream), level, strategy);
   1.257 -}
   1.258 -
   1.259 -/* ===========================================================================
   1.260 -     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
   1.261 -   for end of file.
   1.262 -   IN assertion: the stream s has been sucessfully opened for reading.
   1.263 -*/
   1.264 -local int get_byte(s)
   1.265 -    gz_stream *s;
   1.266 -{
   1.267 -    if (s->z_eof) return EOF;
   1.268 -    if (s->stream.avail_in == 0) {
   1.269 -        errno = 0;
   1.270 -        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
   1.271 -        if (s->stream.avail_in == 0) {
   1.272 -            s->z_eof = 1;
   1.273 -            if (ferror(s->file)) s->z_err = Z_ERRNO;
   1.274 -            return EOF;
   1.275 -        }
   1.276 -        s->stream.next_in = s->inbuf;
   1.277 -    }
   1.278 -    s->stream.avail_in--;
   1.279 -    return *(s->stream.next_in)++;
   1.280 -}
   1.281 -
   1.282 -/* ===========================================================================
   1.283 -      Check the gzip header of a gz_stream opened for reading. Set the stream
   1.284 -    mode to transparent if the gzip magic header is not present; set s->err
   1.285 -    to Z_DATA_ERROR if the magic header is present but the rest of the header
   1.286 -    is incorrect.
   1.287 -    IN assertion: the stream s has already been created sucessfully;
   1.288 -       s->stream.avail_in is zero for the first time, but may be non-zero
   1.289 -       for concatenated .gz files.
   1.290 -*/
   1.291 -local void check_header(s)
   1.292 -    gz_stream *s;
   1.293 -{
   1.294 -    int method; /* method byte */
   1.295 -    int flags;  /* flags byte */
   1.296 -    uInt len;
   1.297 -    int c;
   1.298 -
   1.299 -    /* Assure two bytes in the buffer so we can peek ahead -- handle case
   1.300 -       where first byte of header is at the end of the buffer after the last
   1.301 -       gzip segment */
   1.302 -    len = s->stream.avail_in;
   1.303 -    if (len < 2) {
   1.304 -        if (len) s->inbuf[0] = s->stream.next_in[0];
   1.305 -        errno = 0;
   1.306 -        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
   1.307 -        if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
   1.308 -        s->stream.avail_in += len;
   1.309 -        s->stream.next_in = s->inbuf;
   1.310 -        if (s->stream.avail_in < 2) {
   1.311 -            s->transparent = s->stream.avail_in;
   1.312 -            return;
   1.313 -        }
   1.314 -    }
   1.315 -
   1.316 -    /* Peek ahead to check the gzip magic header */
   1.317 -    if (s->stream.next_in[0] != gz_magic[0] ||
   1.318 -        s->stream.next_in[1] != gz_magic[1]) {
   1.319 -        s->transparent = 1;
   1.320 -        return;
   1.321 -    }
   1.322 -    s->stream.avail_in -= 2;
   1.323 -    s->stream.next_in += 2;
   1.324 -
   1.325 -    /* Check the rest of the gzip header */
   1.326 -    method = get_byte(s);
   1.327 -    flags = get_byte(s);
   1.328 -    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
   1.329 -        s->z_err = Z_DATA_ERROR;
   1.330 -        return;
   1.331 -    }
   1.332 -
   1.333 -    /* Discard time, xflags and OS code: */
   1.334 -    for (len = 0; len < 6; len++) (void)get_byte(s);
   1.335 -
   1.336 -    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
   1.337 -        len  =  (uInt)get_byte(s);
   1.338 -        len += ((uInt)get_byte(s))<<8;
   1.339 -        /* len is garbage if EOF but the loop below will quit anyway */
   1.340 -        while (len-- != 0 && get_byte(s) != EOF) ;
   1.341 -    }
   1.342 -    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
   1.343 -        while ((c = get_byte(s)) != 0 && c != EOF) ;
   1.344 -    }
   1.345 -    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
   1.346 -        while ((c = get_byte(s)) != 0 && c != EOF) ;
   1.347 -    }
   1.348 -    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
   1.349 -        for (len = 0; len < 2; len++) (void)get_byte(s);
   1.350 -    }
   1.351 -    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
   1.352 -}
   1.353 -
   1.354 - /* ===========================================================================
   1.355 - * Cleanup then free the given gz_stream. Return a zlib error code.
   1.356 -   Try freeing in the reverse order of allocations.
   1.357 - */
   1.358 -local int destroy (s)
   1.359 -    gz_stream *s;
   1.360 -{
   1.361 -    int err = Z_OK;
   1.362 -
   1.363 -    if (!s) return Z_STREAM_ERROR;
   1.364 -
   1.365 -    TRYFREE(s->msg);
   1.366 -
   1.367 -    if (s->stream.state != NULL) {
   1.368 -        if (s->mode == 'w') {
   1.369 -#ifdef NO_GZCOMPRESS
   1.370 -            err = Z_STREAM_ERROR;
   1.371 -#else
   1.372 -            err = deflateEnd(&(s->stream));
   1.373 -#endif
   1.374 -        } else if (s->mode == 'r') {
   1.375 -            err = inflateEnd(&(s->stream));
   1.376 -        }
   1.377 -    }
   1.378 -    if (s->file != NULL && fclose(s->file)) {
   1.379 -#ifdef ESPIPE
   1.380 -        if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
   1.381 -#endif
   1.382 -            err = Z_ERRNO;
   1.383 -    }
   1.384 -    if (s->z_err < 0) err = s->z_err;
   1.385 -
   1.386 -    TRYFREE(s->inbuf);
   1.387 -    TRYFREE(s->outbuf);
   1.388 -    TRYFREE(s->path);
   1.389 -    TRYFREE(s);
   1.390 -    return err;
   1.391 -}
   1.392 -
   1.393 -/* ===========================================================================
   1.394 -     Reads the given number of uncompressed bytes from the compressed file.
   1.395 -   gzread returns the number of bytes actually read (0 for end of file).
   1.396 -*/
   1.397 -int ZEXPORT gzread (file, buf, len)
   1.398 -    gzFile file;
   1.399 -    voidp buf;
   1.400 -    unsigned len;
   1.401 -{
   1.402 -    gz_stream *s = (gz_stream*)file;
   1.403 -    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
   1.404 -    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
   1.405 -
   1.406 -    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
   1.407 -
   1.408 -    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
   1.409 -    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
   1.410 -
   1.411 -    next_out = (Byte*)buf;
   1.412 -    s->stream.next_out = (Bytef*)buf;
   1.413 -    s->stream.avail_out = len;
   1.414 -
   1.415 -    if (s->stream.avail_out && s->back != EOF) {
   1.416 -        *next_out++ = s->back;
   1.417 -        s->stream.next_out++;
   1.418 -        s->stream.avail_out--;
   1.419 -        s->back = EOF;
   1.420 -        s->out++;
   1.421 -        start++;
   1.422 -        if (s->last) {
   1.423 -            s->z_err = Z_STREAM_END;
   1.424 -            return 1;
   1.425 -        }
   1.426 -    }
   1.427 -
   1.428 -    while (s->stream.avail_out != 0) {
   1.429 -
   1.430 -        if (s->transparent) {
   1.431 -            /* Copy first the lookahead bytes: */
   1.432 -            uInt n = s->stream.avail_in;
   1.433 -            if (n > s->stream.avail_out) n = s->stream.avail_out;
   1.434 -            if (n > 0) {
   1.435 -                zmemcpy(s->stream.next_out, s->stream.next_in, n);
   1.436 -                next_out += n;
   1.437 -                s->stream.next_out = next_out;
   1.438 -                s->stream.next_in   += n;
   1.439 -                s->stream.avail_out -= n;
   1.440 -                s->stream.avail_in  -= n;
   1.441 -            }
   1.442 -            if (s->stream.avail_out > 0) {
   1.443 -                s->stream.avail_out -=
   1.444 -                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
   1.445 -            }
   1.446 -            len -= s->stream.avail_out;
   1.447 -            s->in  += len;
   1.448 -            s->out += len;
   1.449 -            if (len == 0) s->z_eof = 1;
   1.450 -            return (int)len;
   1.451 -        }
   1.452 -        if (s->stream.avail_in == 0 && !s->z_eof) {
   1.453 -
   1.454 -            errno = 0;
   1.455 -            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
   1.456 -            if (s->stream.avail_in == 0) {
   1.457 -                s->z_eof = 1;
   1.458 -                if (ferror(s->file)) {
   1.459 -                    s->z_err = Z_ERRNO;
   1.460 -                    break;
   1.461 -                }
   1.462 -            }
   1.463 -            s->stream.next_in = s->inbuf;
   1.464 -        }
   1.465 -        s->in += s->stream.avail_in;
   1.466 -        s->out += s->stream.avail_out;
   1.467 -        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
   1.468 -        s->in -= s->stream.avail_in;
   1.469 -        s->out -= s->stream.avail_out;
   1.470 -
   1.471 -        if (s->z_err == Z_STREAM_END) {
   1.472 -            /* Check CRC and original size */
   1.473 -            s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
   1.474 -            start = s->stream.next_out;
   1.475 -
   1.476 -            if (getLong(s) != s->crc) {
   1.477 -                s->z_err = Z_DATA_ERROR;
   1.478 -            } else {
   1.479 -                (void)getLong(s);
   1.480 -                /* The uncompressed length returned by above getlong() may be
   1.481 -                 * different from s->out in case of concatenated .gz files.
   1.482 -                 * Check for such files:
   1.483 -                 */
   1.484 -                check_header(s);
   1.485 -                if (s->z_err == Z_OK) {
   1.486 -                    inflateReset(&(s->stream));
   1.487 -                    s->crc = crc32(0L, Z_NULL, 0);
   1.488 -                }
   1.489 -            }
   1.490 -        }
   1.491 -        if (s->z_err != Z_OK || s->z_eof) break;
   1.492 -    }
   1.493 -    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
   1.494 -
   1.495 -    if (len == s->stream.avail_out &&
   1.496 -        (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
   1.497 -        return -1;
   1.498 -    return (int)(len - s->stream.avail_out);
   1.499 -}
   1.500 -
   1.501 -
   1.502 -/* ===========================================================================
   1.503 -      Reads one byte from the compressed file. gzgetc returns this byte
   1.504 -   or -1 in case of end of file or error.
   1.505 -*/
   1.506 -int ZEXPORT gzgetc(file)
   1.507 -    gzFile file;
   1.508 -{
   1.509 -    unsigned char c;
   1.510 -
   1.511 -    return gzread(file, &c, 1) == 1 ? c : -1;
   1.512 -}
   1.513 -
   1.514 -
   1.515 -/* ===========================================================================
   1.516 -      Push one byte back onto the stream.
   1.517 -*/
   1.518 -int ZEXPORT gzungetc(c, file)
   1.519 -    int c;
   1.520 -    gzFile file;
   1.521 -{
   1.522 -    gz_stream *s = (gz_stream*)file;
   1.523 -
   1.524 -    if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
   1.525 -    s->back = c;
   1.526 -    s->out--;
   1.527 -    s->last = (s->z_err == Z_STREAM_END);
   1.528 -    if (s->last) s->z_err = Z_OK;
   1.529 -    s->z_eof = 0;
   1.530 -    return c;
   1.531 -}
   1.532 -
   1.533 -
   1.534 -/* ===========================================================================
   1.535 -      Reads bytes from the compressed file until len-1 characters are
   1.536 -   read, or a newline character is read and transferred to buf, or an
   1.537 -   end-of-file condition is encountered.  The string is then terminated
   1.538 -   with a null character.
   1.539 -      gzgets returns buf, or Z_NULL in case of error.
   1.540 -
   1.541 -      The current implementation is not optimized at all.
   1.542 -*/
   1.543 -char * ZEXPORT gzgets(file, buf, len)
   1.544 -    gzFile file;
   1.545 -    char *buf;
   1.546 -    int len;
   1.547 -{
   1.548 -    char *b = buf;
   1.549 -    if (buf == Z_NULL || len <= 0) return Z_NULL;
   1.550 -
   1.551 -    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
   1.552 -    *buf = '\0';
   1.553 -    return b == buf && len > 0 ? Z_NULL : b;
   1.554 -}
   1.555 -
   1.556 -
   1.557 -#ifndef NO_GZCOMPRESS
   1.558 -/* ===========================================================================
   1.559 -     Writes the given number of uncompressed bytes into the compressed file.
   1.560 -   gzwrite returns the number of bytes actually written (0 in case of error).
   1.561 -*/
   1.562 -int ZEXPORT gzwrite (file, buf, len)
   1.563 -    gzFile file;
   1.564 -    voidpc buf;
   1.565 -    unsigned len;
   1.566 -{
   1.567 -    gz_stream *s = (gz_stream*)file;
   1.568 -
   1.569 -    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
   1.570 -
   1.571 -    s->stream.next_in = (Bytef*)buf;
   1.572 -    s->stream.avail_in = len;
   1.573 -
   1.574 -    while (s->stream.avail_in != 0) {
   1.575 -
   1.576 -        if (s->stream.avail_out == 0) {
   1.577 -
   1.578 -            s->stream.next_out = s->outbuf;
   1.579 -            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
   1.580 -                s->z_err = Z_ERRNO;
   1.581 -                break;
   1.582 -            }
   1.583 -            s->stream.avail_out = Z_BUFSIZE;
   1.584 -        }
   1.585 -        s->in += s->stream.avail_in;
   1.586 -        s->out += s->stream.avail_out;
   1.587 -        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
   1.588 -        s->in -= s->stream.avail_in;
   1.589 -        s->out -= s->stream.avail_out;
   1.590 -        if (s->z_err != Z_OK) break;
   1.591 -    }
   1.592 -    s->crc = crc32(s->crc, (const Bytef *)buf, len);
   1.593 -
   1.594 -    return (int)(len - s->stream.avail_in);
   1.595 -}
   1.596 -
   1.597 -
   1.598 -/* ===========================================================================
   1.599 -     Converts, formats, and writes the args to the compressed file under
   1.600 -   control of the format string, as in fprintf. gzprintf returns the number of
   1.601 -   uncompressed bytes actually written (0 in case of error).
   1.602 -*/
   1.603 -#ifdef STDC
   1.604 -#include <stdarg.h>
   1.605 -
   1.606 -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
   1.607 -{
   1.608 -    char buf[Z_PRINTF_BUFSIZE];
   1.609 -    va_list va;
   1.610 -    int len;
   1.611 -
   1.612 -    buf[sizeof(buf) - 1] = 0;
   1.613 -    va_start(va, format);
   1.614 -#ifdef NO_vsnprintf
   1.615 -#  ifdef HAS_vsprintf_void
   1.616 -    (void)vsprintf(buf, format, va);
   1.617 -    va_end(va);
   1.618 -    for (len = 0; len < sizeof(buf); len++)
   1.619 -        if (buf[len] == 0) break;
   1.620 -#  else
   1.621 -    len = vsprintf(buf, format, va);
   1.622 -    va_end(va);
   1.623 -#  endif
   1.624 -#else
   1.625 -#  ifdef HAS_vsnprintf_void
   1.626 -    (void)vsnprintf(buf, sizeof(buf), format, va);
   1.627 -    va_end(va);
   1.628 -    len = strlen(buf);
   1.629 -#  else
   1.630 -    len = vsnprintf(buf, sizeof(buf), format, va);
   1.631 -    va_end(va);
   1.632 -#  endif
   1.633 -#endif
   1.634 -    if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
   1.635 -        return 0;
   1.636 -    return gzwrite(file, buf, (unsigned)len);
   1.637 -}
   1.638 -#else /* not ANSI C */
   1.639 -
   1.640 -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
   1.641 -                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
   1.642 -    gzFile file;
   1.643 -    const char *format;
   1.644 -    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
   1.645 -        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
   1.646 -{
   1.647 -    char buf[Z_PRINTF_BUFSIZE];
   1.648 -    int len;
   1.649 -
   1.650 -    buf[sizeof(buf) - 1] = 0;
   1.651 -#ifdef NO_snprintf
   1.652 -#  ifdef HAS_sprintf_void
   1.653 -    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
   1.654 -            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
   1.655 -    for (len = 0; len < sizeof(buf); len++)
   1.656 -        if (buf[len] == 0) break;
   1.657 -#  else
   1.658 -    len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
   1.659 -                a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
   1.660 -#  endif
   1.661 -#else
   1.662 -#  ifdef HAS_snprintf_void
   1.663 -    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
   1.664 -             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
   1.665 -    len = strlen(buf);
   1.666 -#  else
   1.667 -    len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
   1.668 -                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
   1.669 -#  endif
   1.670 -#endif
   1.671 -    if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
   1.672 -        return 0;
   1.673 -    return gzwrite(file, buf, len);
   1.674 -}
   1.675 -#endif
   1.676 -
   1.677 -/* ===========================================================================
   1.678 -      Writes c, converted to an unsigned char, into the compressed file.
   1.679 -   gzputc returns the value that was written, or -1 in case of error.
   1.680 -*/
   1.681 -int ZEXPORT gzputc(file, c)
   1.682 -    gzFile file;
   1.683 -    int c;
   1.684 -{
   1.685 -    unsigned char cc = (unsigned char) c; /* required for big endian systems */
   1.686 -
   1.687 -    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
   1.688 -}
   1.689 -
   1.690 -
   1.691 -/* ===========================================================================
   1.692 -      Writes the given null-terminated string to the compressed file, excluding
   1.693 -   the terminating null character.
   1.694 -      gzputs returns the number of characters written, or -1 in case of error.
   1.695 -*/
   1.696 -int ZEXPORT gzputs(file, s)
   1.697 -    gzFile file;
   1.698 -    const char *s;
   1.699 -{
   1.700 -    return gzwrite(file, (char*)s, (unsigned)strlen(s));
   1.701 -}
   1.702 -
   1.703 -
   1.704 -/* ===========================================================================
   1.705 -     Flushes all pending output into the compressed file. The parameter
   1.706 -   flush is as in the deflate() function.
   1.707 -*/
   1.708 -local int do_flush (file, flush)
   1.709 -    gzFile file;
   1.710 -    int flush;
   1.711 -{
   1.712 -    uInt len;
   1.713 -    int done = 0;
   1.714 -    gz_stream *s = (gz_stream*)file;
   1.715 -
   1.716 -    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
   1.717 -
   1.718 -    s->stream.avail_in = 0; /* should be zero already anyway */
   1.719 -
   1.720 -    for (;;) {
   1.721 -        len = Z_BUFSIZE - s->stream.avail_out;
   1.722 -
   1.723 -        if (len != 0) {
   1.724 -            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
   1.725 -                s->z_err = Z_ERRNO;
   1.726 -                return Z_ERRNO;
   1.727 -            }
   1.728 -            s->stream.next_out = s->outbuf;
   1.729 -            s->stream.avail_out = Z_BUFSIZE;
   1.730 -        }
   1.731 -        if (done) break;
   1.732 -        s->out += s->stream.avail_out;
   1.733 -        s->z_err = deflate(&(s->stream), flush);
   1.734 -        s->out -= s->stream.avail_out;
   1.735 -
   1.736 -        /* Ignore the second of two consecutive flushes: */
   1.737 -        if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
   1.738 -
   1.739 -        /* deflate has finished flushing only when it hasn't used up
   1.740 -         * all the available space in the output buffer:
   1.741 -         */
   1.742 -        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
   1.743 -
   1.744 -        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
   1.745 -    }
   1.746 -    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
   1.747 -}
   1.748 -
   1.749 -int ZEXPORT gzflush (file, flush)
   1.750 -     gzFile file;
   1.751 -     int flush;
   1.752 -{
   1.753 -    gz_stream *s = (gz_stream*)file;
   1.754 -    int err = do_flush (file, flush);
   1.755 -
   1.756 -    if (err) return err;
   1.757 -    fflush(s->file);
   1.758 -    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
   1.759 -}
   1.760 -#endif /* NO_GZCOMPRESS */
   1.761 -
   1.762 -/* ===========================================================================
   1.763 -      Sets the starting position for the next gzread or gzwrite on the given
   1.764 -   compressed file. The offset represents a number of bytes in the
   1.765 -      gzseek returns the resulting offset location as measured in bytes from
   1.766 -   the beginning of the uncompressed stream, or -1 in case of error.
   1.767 -      SEEK_END is not implemented, returns error.
   1.768 -      In this version of the library, gzseek can be extremely slow.
   1.769 -*/
   1.770 -z_off_t ZEXPORT gzseek (file, offset, whence)
   1.771 -    gzFile file;
   1.772 -    z_off_t offset;
   1.773 -    int whence;
   1.774 -{
   1.775 -    gz_stream *s = (gz_stream*)file;
   1.776 -
   1.777 -    if (s == NULL || whence == SEEK_END ||
   1.778 -        s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
   1.779 -        return -1L;
   1.780 -    }
   1.781 -
   1.782 -    if (s->mode == 'w') {
   1.783 -#ifdef NO_GZCOMPRESS
   1.784 -        return -1L;
   1.785 -#else
   1.786 -        if (whence == SEEK_SET) {
   1.787 -            offset -= s->in;
   1.788 -        }
   1.789 -        if (offset < 0) return -1L;
   1.790 -
   1.791 -        /* At this point, offset is the number of zero bytes to write. */
   1.792 -        if (s->inbuf == Z_NULL) {
   1.793 -            s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
   1.794 -            if (s->inbuf == Z_NULL) return -1L;
   1.795 -            zmemzero(s->inbuf, Z_BUFSIZE);
   1.796 -        }
   1.797 -        while (offset > 0)  {
   1.798 -            uInt size = Z_BUFSIZE;
   1.799 -            if (offset < Z_BUFSIZE) size = (uInt)offset;
   1.800 -
   1.801 -            size = gzwrite(file, s->inbuf, size);
   1.802 -            if (size == 0) return -1L;
   1.803 -
   1.804 -            offset -= size;
   1.805 -        }
   1.806 -        return s->in;
   1.807 -#endif
   1.808 -    }
   1.809 -    /* Rest of function is for reading only */
   1.810 -
   1.811 -    /* compute absolute position */
   1.812 -    if (whence == SEEK_CUR) {
   1.813 -        offset += s->out;
   1.814 -    }
   1.815 -    if (offset < 0) return -1L;
   1.816 -
   1.817 -    if (s->transparent) {
   1.818 -        /* map to fseek */
   1.819 -        s->back = EOF;
   1.820 -        s->stream.avail_in = 0;
   1.821 -        s->stream.next_in = s->inbuf;
   1.822 -        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
   1.823 -
   1.824 -        s->in = s->out = offset;
   1.825 -        return offset;
   1.826 -    }
   1.827 -
   1.828 -    /* For a negative seek, rewind and use positive seek */
   1.829 -    if (offset >= s->out) {
   1.830 -        offset -= s->out;
   1.831 -    } else if (gzrewind(file) < 0) {
   1.832 -        return -1L;
   1.833 -    }
   1.834 -    /* offset is now the number of bytes to skip. */
   1.835 -
   1.836 -    if (offset != 0 && s->outbuf == Z_NULL) {
   1.837 -        s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
   1.838 -        if (s->outbuf == Z_NULL) return -1L;
   1.839 -    }
   1.840 -    if (offset && s->back != EOF) {
   1.841 -        s->back = EOF;
   1.842 -        s->out++;
   1.843 -        offset--;
   1.844 -        if (s->last) s->z_err = Z_STREAM_END;
   1.845 -    }
   1.846 -    while (offset > 0)  {
   1.847 -        int size = Z_BUFSIZE;
   1.848 -        if (offset < Z_BUFSIZE) size = (int)offset;
   1.849 -
   1.850 -        size = gzread(file, s->outbuf, (uInt)size);
   1.851 -        if (size <= 0) return -1L;
   1.852 -        offset -= size;
   1.853 -    }
   1.854 -    return s->out;
   1.855 -}
   1.856 -
   1.857 -/* ===========================================================================
   1.858 -     Rewinds input file.
   1.859 -*/
   1.860 -int ZEXPORT gzrewind (file)
   1.861 -    gzFile file;
   1.862 -{
   1.863 -    gz_stream *s = (gz_stream*)file;
   1.864 -
   1.865 -    if (s == NULL || s->mode != 'r') return -1;
   1.866 -
   1.867 -    s->z_err = Z_OK;
   1.868 -    s->z_eof = 0;
   1.869 -    s->back = EOF;
   1.870 -    s->stream.avail_in = 0;
   1.871 -    s->stream.next_in = s->inbuf;
   1.872 -    s->crc = crc32(0L, Z_NULL, 0);
   1.873 -    if (!s->transparent) (void)inflateReset(&s->stream);
   1.874 -    s->in = 0;
   1.875 -    s->out = 0;
   1.876 -    return fseek(s->file, s->start, SEEK_SET);
   1.877 -}
   1.878 -
   1.879 -/* ===========================================================================
   1.880 -     Returns the starting position for the next gzread or gzwrite on the
   1.881 -   given compressed file. This position represents a number of bytes in the
   1.882 -   uncompressed data stream.
   1.883 -*/
   1.884 -z_off_t ZEXPORT gztell (file)
   1.885 -    gzFile file;
   1.886 -{
   1.887 -    return gzseek(file, 0L, SEEK_CUR);
   1.888 -}
   1.889 -
   1.890 -/* ===========================================================================
   1.891 -     Returns 1 when EOF has previously been detected reading the given
   1.892 -   input stream, otherwise zero.
   1.893 -*/
   1.894 -int ZEXPORT gzeof (file)
   1.895 -    gzFile file;
   1.896 -{
   1.897 -    gz_stream *s = (gz_stream*)file;
   1.898 -
   1.899 -    /* With concatenated compressed files that can have embedded
   1.900 -     * crc trailers, z_eof is no longer the only/best indicator of EOF
   1.901 -     * on a gz_stream. Handle end-of-stream error explicitly here.
   1.902 -     */
   1.903 -    if (s == NULL || s->mode != 'r') return 0;
   1.904 -    if (s->z_eof) return 1;
   1.905 -    return s->z_err == Z_STREAM_END;
   1.906 -}
   1.907 -
   1.908 -/* ===========================================================================
   1.909 -     Returns 1 if reading and doing so transparently, otherwise zero.
   1.910 -*/
   1.911 -int ZEXPORT gzdirect (file)
   1.912 -    gzFile file;
   1.913 -{
   1.914 -    gz_stream *s = (gz_stream*)file;
   1.915 -
   1.916 -    if (s == NULL || s->mode != 'r') return 0;
   1.917 -    return s->transparent;
   1.918 -}
   1.919 -
   1.920 -/* ===========================================================================
   1.921 -   Outputs a long in LSB order to the given file
   1.922 -*/
   1.923 -local void putLong (file, x)
   1.924 -    FILE *file;
   1.925 -    uLong x;
   1.926 -{
   1.927 -    int n;
   1.928 -    for (n = 0; n < 4; n++) {
   1.929 -        fputc((int)(x & 0xff), file);
   1.930 -        x >>= 8;
   1.931 -    }
   1.932 -}
   1.933 -
   1.934 -/* ===========================================================================
   1.935 -   Reads a long in LSB order from the given gz_stream. Sets z_err in case
   1.936 -   of error.
   1.937 -*/
   1.938 -local uLong getLong (s)
   1.939 -    gz_stream *s;
   1.940 -{
   1.941 -    uLong x = (uLong)get_byte(s);
   1.942 -    int c;
   1.943 -
   1.944 -    x += ((uLong)get_byte(s))<<8;
   1.945 -    x += ((uLong)get_byte(s))<<16;
   1.946 -    c = get_byte(s);
   1.947 -    if (c == EOF) s->z_err = Z_DATA_ERROR;
   1.948 -    x += ((uLong)c)<<24;
   1.949 -    return x;
   1.950 -}
   1.951 -
   1.952 -/* ===========================================================================
   1.953 -     Flushes all pending output if necessary, closes the compressed file
   1.954 -   and deallocates all the (de)compression state.
   1.955 -*/
   1.956 -int ZEXPORT gzclose (file)
   1.957 -    gzFile file;
   1.958 -{
   1.959 -    gz_stream *s = (gz_stream*)file;
   1.960 -
   1.961 -    if (s == NULL) return Z_STREAM_ERROR;
   1.962 -
   1.963 -    if (s->mode == 'w') {
   1.964 -#ifdef NO_GZCOMPRESS
   1.965 -        return Z_STREAM_ERROR;
   1.966 -#else
   1.967 -        if (do_flush (file, Z_FINISH) != Z_OK)
   1.968 -            return destroy((gz_stream*)file);
   1.969 -
   1.970 -        putLong (s->file, s->crc);
   1.971 -        putLong (s->file, (uLong)(s->in & 0xffffffff));
   1.972 -#endif
   1.973 -    }
   1.974 -    return destroy((gz_stream*)file);
   1.975 -}
   1.976 -
   1.977 -#ifdef STDC
   1.978 -#  define zstrerror(errnum) strerror(errnum)
   1.979 -#else
   1.980 -#  define zstrerror(errnum) ""
   1.981 -#endif
   1.982 -
   1.983 -/* ===========================================================================
   1.984 -     Returns the error message for the last error which occurred on the
   1.985 -   given compressed file. errnum is set to zlib error number. If an
   1.986 -   error occurred in the file system and not in the compression library,
   1.987 -   errnum is set to Z_ERRNO and the application may consult errno
   1.988 -   to get the exact error code.
   1.989 -*/
   1.990 -const char * ZEXPORT gzerror (file, errnum)
   1.991 -    gzFile file;
   1.992 -    int *errnum;
   1.993 -{
   1.994 -    char *m;
   1.995 -    gz_stream *s = (gz_stream*)file;
   1.996 -
   1.997 -    if (s == NULL) {
   1.998 -        *errnum = Z_STREAM_ERROR;
   1.999 -        return (const char*)ERR_MSG(Z_STREAM_ERROR);
  1.1000 -    }
  1.1001 -    *errnum = s->z_err;
  1.1002 -    if (*errnum == Z_OK) return (const char*)"";
  1.1003 -
  1.1004 -    m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
  1.1005 -
  1.1006 -    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
  1.1007 -
  1.1008 -    TRYFREE(s->msg);
  1.1009 -    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
  1.1010 -    if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
  1.1011 -    strcpy(s->msg, s->path);
  1.1012 -    strcat(s->msg, ": ");
  1.1013 -    strcat(s->msg, m);
  1.1014 -    return (const char*)s->msg;
  1.1015 -}
  1.1016 -
  1.1017 -/* ===========================================================================
  1.1018 -     Clear the error and end-of-file flags, and do the same for the real file.
  1.1019 -*/
  1.1020 -void ZEXPORT gzclearerr (file)
  1.1021 -    gzFile file;
  1.1022 -{
  1.1023 -    gz_stream *s = (gz_stream*)file;
  1.1024 -
  1.1025 -    if (s == NULL) return;
  1.1026 -    if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
  1.1027 -    s->z_eof = 0;
  1.1028 -    clearerr(s->file);
  1.1029 -}