Dependencies:   emwin_lib

Fork of DMemWin by Embedded Artists

Committer:
destinyXfate
Date:
Thu Jun 02 04:55:08 2016 +0000
Revision:
4:20387dbf7ecf
Parent:
2:0e2ef1edf01b
;

Who changed what in which revision?

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