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