diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
commit | bdde4e09d21edff02ea5093b7f6eccbf166b272f (patch) | |
tree | a64632a98a6bea6e5df864d6e5b6f2e51ea69c1c /gzio.c | |
parent | 1c71d8b13b54f91ddec361d3053ecce26e6ff761 (diff) | |
download | zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.gz zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.bz2 zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.zip |
zlib 0.92v0.92
Diffstat (limited to 'gzio.c')
-rw-r--r-- | gzio.c | 284 |
1 files changed, 142 insertions, 142 deletions
@@ -3,7 +3,7 @@ | |||
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
6 | /* $Id: gzio.c,v 1.7 1995/05/02 12:22:08 jloup Exp $ */ | 6 | /* $Id: gzio.c,v 1.8 1995/05/03 17:27:09 jloup Exp $ */ |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | 9 | ||
@@ -68,13 +68,13 @@ local int destroy (s) | |||
68 | 68 | ||
69 | if (s->stream.state != NULL) { | 69 | if (s->stream.state != NULL) { |
70 | if (s->mode == 'w') { | 70 | if (s->mode == 'w') { |
71 | err = deflateEnd(&(s->stream)); | 71 | err = deflateEnd(&(s->stream)); |
72 | } else if (s->mode == 'r') { | 72 | } else if (s->mode == 'r') { |
73 | err = inflateEnd(&(s->stream)); | 73 | err = inflateEnd(&(s->stream)); |
74 | } | 74 | } |
75 | } | 75 | } |
76 | if (s->file != NULL && fclose(s->file)) { | 76 | if (s->file != NULL && fclose(s->file)) { |
77 | err = Z_ERRNO; | 77 | err = Z_ERRNO; |
78 | } | 78 | } |
79 | if (s->z_err < 0) err = s->z_err; | 79 | if (s->z_err < 0) err = s->z_err; |
80 | zcfree((voidp)0, s); | 80 | zcfree((voidp)0, s); |
@@ -115,34 +115,34 @@ local gzFile gz_open (path, mode, fd) | |||
115 | 115 | ||
116 | s->path = (char*)ALLOC(strlen(path)+1); | 116 | s->path = (char*)ALLOC(strlen(path)+1); |
117 | if (s->path == NULL) { | 117 | if (s->path == NULL) { |
118 | return destroy(s), (gzFile)Z_NULL; | 118 | return destroy(s), (gzFile)Z_NULL; |
119 | } | 119 | } |
120 | strcpy(s->path, path); /* do this early for debugging */ | 120 | strcpy(s->path, path); /* do this early for debugging */ |
121 | 121 | ||
122 | s->mode = '\0'; | 122 | s->mode = '\0'; |
123 | do { | 123 | do { |
124 | if (*p == 'r') s->mode = 'r'; | 124 | if (*p == 'r') s->mode = 'r'; |
125 | if (*p == 'w') s->mode = 'w'; | 125 | if (*p == 'w') s->mode = 'w'; |
126 | } while (*p++); | 126 | } while (*p++); |
127 | if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; | 127 | if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; |
128 | 128 | ||
129 | if (s->mode == 'w') { | 129 | if (s->mode == 'w') { |
130 | err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION, | 130 | err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION, |
131 | DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); | 131 | DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); |
132 | /* windowBits is passed < 0 to suppress zlib header */ | 132 | /* windowBits is passed < 0 to suppress zlib header */ |
133 | 133 | ||
134 | s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE); | 134 | s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE); |
135 | 135 | ||
136 | if (err != Z_OK || s->outbuf == Z_NULL) { | 136 | if (err != Z_OK || s->outbuf == Z_NULL) { |
137 | return destroy(s), (gzFile)Z_NULL; | 137 | return destroy(s), (gzFile)Z_NULL; |
138 | } | 138 | } |
139 | } else { | 139 | } else { |
140 | err = inflateInit2(&(s->stream), -MAX_WBITS); | 140 | err = inflateInit2(&(s->stream), -MAX_WBITS); |
141 | s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE); | 141 | s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE); |
142 | 142 | ||
143 | if (err != Z_OK || s->inbuf == Z_NULL) { | 143 | if (err != Z_OK || s->inbuf == Z_NULL) { |
144 | return destroy(s), (gzFile)Z_NULL; | 144 | return destroy(s), (gzFile)Z_NULL; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | s->stream.avail_out = Z_BUFSIZE; | 147 | s->stream.avail_out = Z_BUFSIZE; |
148 | 148 | ||
@@ -150,55 +150,55 @@ local gzFile gz_open (path, mode, fd) | |||
150 | s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode); | 150 | s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode); |
151 | 151 | ||
152 | if (s->file == NULL) { | 152 | if (s->file == NULL) { |
153 | return destroy(s), (gzFile)Z_NULL; | 153 | return destroy(s), (gzFile)Z_NULL; |
154 | } | 154 | } |
155 | if (s->mode == 'w') { | 155 | if (s->mode == 'w') { |
156 | /* Write a very simple .gz header: | 156 | /* Write a very simple .gz header: |
157 | */ | 157 | */ |
158 | fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2, | 158 | fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2, |
159 | DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); | 159 | DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); |
160 | } else { | 160 | } else { |
161 | /* Check and skip the header: | 161 | /* Check and skip the header: |
162 | */ | 162 | */ |
163 | Byte c1 = 0, c2 = 0; | 163 | Byte c1 = 0, c2 = 0; |
164 | Byte method = 0; | 164 | Byte method = 0; |
165 | Byte flags = 0; | 165 | Byte flags = 0; |
166 | Byte xflags = 0; | 166 | Byte xflags = 0; |
167 | Byte time[4]; | 167 | Byte time[4]; |
168 | Byte osCode; | 168 | Byte osCode; |
169 | int c; | 169 | int c; |
170 | 170 | ||
171 | s->stream.avail_in = fread(s->inbuf, 1, 2, s->file); | 171 | s->stream.avail_in = fread(s->inbuf, 1, 2, s->file); |
172 | if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1 | 172 | if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1 |
173 | || s->inbuf[1] != GZ_MAGIC_2) { | 173 | || s->inbuf[1] != GZ_MAGIC_2) { |
174 | s->transparent = 1; | 174 | s->transparent = 1; |
175 | return (gzFile)s; | 175 | return (gzFile)s; |
176 | } | 176 | } |
177 | s->stream.avail_in = 0; | 177 | s->stream.avail_in = 0; |
178 | fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode); | 178 | fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode); |
179 | 179 | ||
180 | if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) { | 180 | if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) { |
181 | s->z_err = Z_DATA_ERROR; | 181 | s->z_err = Z_DATA_ERROR; |
182 | return (gzFile)s; | 182 | return (gzFile)s; |
183 | } | 183 | } |
184 | if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ | 184 | if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ |
185 | long len; | 185 | long len; |
186 | fscanf(s->file, "%c%c", &c1, &c2); | 186 | fscanf(s->file, "%c%c", &c1, &c2); |
187 | len = c1 + ((long)c2<<8); | 187 | len = c1 + ((long)c2<<8); |
188 | fseek(s->file, len, SEEK_CUR); | 188 | fseek(s->file, len, SEEK_CUR); |
189 | } | 189 | } |
190 | if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ | 190 | if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ |
191 | while ((c = getc(s->file)) != 0 && c != EOF) ; | 191 | while ((c = getc(s->file)) != 0 && c != EOF) ; |
192 | } | 192 | } |
193 | if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ | 193 | if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ |
194 | while ((c = getc(s->file)) != 0 && c != EOF) ; | 194 | while ((c = getc(s->file)) != 0 && c != EOF) ; |
195 | } | 195 | } |
196 | if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ | 196 | if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ |
197 | fscanf(s->file, "%c%c", &c1, &c2); | 197 | fscanf(s->file, "%c%c", &c1, &c2); |
198 | } | 198 | } |
199 | if (feof(s->file)) { | 199 | if (feof(s->file)) { |
200 | s->z_err = Z_DATA_ERROR; | 200 | s->z_err = Z_DATA_ERROR; |
201 | } | 201 | } |
202 | } | 202 | } |
203 | return (gzFile)s; | 203 | return (gzFile)s; |
204 | } | 204 | } |
@@ -240,16 +240,16 @@ int gzread (file, buf, len) | |||
240 | if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; | 240 | if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; |
241 | 241 | ||
242 | if (s->transparent) { | 242 | if (s->transparent) { |
243 | unsigned n = 0; | 243 | unsigned n = 0; |
244 | Byte *b = (Byte*)buf; | 244 | Byte *b = (Byte*)buf; |
245 | /* Copy the first two (non-magic) bytes if not done already */ | 245 | /* Copy the first two (non-magic) bytes if not done already */ |
246 | while (s->stream.avail_in > 0 && len > 0) { | 246 | while (s->stream.avail_in > 0 && len > 0) { |
247 | *b++ = *s->stream.next_in++; | 247 | *b++ = *s->stream.next_in++; |
248 | s->stream.avail_in--; | 248 | s->stream.avail_in--; |
249 | len--; n++; | 249 | len--; n++; |
250 | } | 250 | } |
251 | if (len == 0) return n; | 251 | if (len == 0) return n; |
252 | return n + fread(b, 1, len, s->file); | 252 | return n + fread(b, 1, len, s->file); |
253 | } | 253 | } |
254 | if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */ | 254 | if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */ |
255 | if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */ | 255 | if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */ |
@@ -259,24 +259,24 @@ int gzread (file, buf, len) | |||
259 | 259 | ||
260 | while (s->stream.avail_out != 0) { | 260 | while (s->stream.avail_out != 0) { |
261 | 261 | ||
262 | if (s->stream.avail_in == 0 && !s->z_eof) { | 262 | if (s->stream.avail_in == 0 && !s->z_eof) { |
263 | 263 | ||
264 | errno = 0; | 264 | errno = 0; |
265 | s->stream.avail_in = | 265 | s->stream.avail_in = |
266 | fread(s->inbuf, 1, Z_BUFSIZE, s->file); | 266 | fread(s->inbuf, 1, Z_BUFSIZE, s->file); |
267 | if (s->stream.avail_in == 0) { | 267 | if (s->stream.avail_in == 0) { |
268 | s->z_eof = 1; | 268 | s->z_eof = 1; |
269 | } else if (s->stream.avail_in == (uInt)EOF) { | 269 | } else if (s->stream.avail_in == (uInt)EOF) { |
270 | s->stream.avail_in = 0; | 270 | s->stream.avail_in = 0; |
271 | s->z_eof = 1; | 271 | s->z_eof = 1; |
272 | s->z_err = Z_ERRNO; | 272 | s->z_err = Z_ERRNO; |
273 | break; | 273 | break; |
274 | } | 274 | } |
275 | s->stream.next_in = s->inbuf; | 275 | s->stream.next_in = s->inbuf; |
276 | } | 276 | } |
277 | s->z_err = inflate(&(s->stream), Z_NO_FLUSH); | 277 | s->z_err = inflate(&(s->stream), Z_NO_FLUSH); |
278 | 278 | ||
279 | if (s->z_err == Z_STREAM_END || | 279 | if (s->z_err == Z_STREAM_END || |
280 | s->z_err != Z_OK || s->z_eof) break; | 280 | s->z_err != Z_OK || s->z_eof) break; |
281 | } | 281 | } |
282 | len -= s->stream.avail_out; | 282 | len -= s->stream.avail_out; |
@@ -302,18 +302,18 @@ int gzwrite (file, buf, len) | |||
302 | 302 | ||
303 | while (s->stream.avail_in != 0) { | 303 | while (s->stream.avail_in != 0) { |
304 | 304 | ||
305 | if (s->stream.avail_out == 0) { | 305 | if (s->stream.avail_out == 0) { |
306 | 306 | ||
307 | s->stream.next_out = s->outbuf; | 307 | s->stream.next_out = s->outbuf; |
308 | if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { | 308 | if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { |
309 | s->z_err = Z_ERRNO; | 309 | s->z_err = Z_ERRNO; |
310 | break; | 310 | break; |
311 | } | 311 | } |
312 | s->stream.avail_out = Z_BUFSIZE; | 312 | s->stream.avail_out = Z_BUFSIZE; |
313 | } | 313 | } |
314 | s->z_err = deflate(&(s->stream), Z_NO_FLUSH); | 314 | s->z_err = deflate(&(s->stream), Z_NO_FLUSH); |
315 | 315 | ||
316 | if (s->z_err != Z_OK) break; | 316 | if (s->z_err != Z_OK) break; |
317 | } | 317 | } |
318 | s->crc = crc32(s->crc, buf, len); | 318 | s->crc = crc32(s->crc, buf, len); |
319 | 319 | ||
@@ -339,25 +339,25 @@ int gzflush (file, flush) | |||
339 | s->stream.avail_in = 0; /* should be zero already anyway */ | 339 | s->stream.avail_in = 0; /* should be zero already anyway */ |
340 | 340 | ||
341 | for (;;) { | 341 | for (;;) { |
342 | len = Z_BUFSIZE - s->stream.avail_out; | 342 | len = Z_BUFSIZE - s->stream.avail_out; |
343 | 343 | ||
344 | if (len != 0) { | 344 | if (len != 0) { |
345 | if (fwrite(s->outbuf, 1, len, s->file) != len) { | 345 | if (fwrite(s->outbuf, 1, len, s->file) != len) { |
346 | s->z_err = Z_ERRNO; | 346 | s->z_err = Z_ERRNO; |
347 | return Z_ERRNO; | 347 | return Z_ERRNO; |
348 | } | 348 | } |
349 | s->stream.next_out = s->outbuf; | 349 | s->stream.next_out = s->outbuf; |
350 | s->stream.avail_out = Z_BUFSIZE; | 350 | s->stream.avail_out = Z_BUFSIZE; |
351 | } | 351 | } |
352 | if (done) break; | 352 | if (done) break; |
353 | s->z_err = deflate(&(s->stream), flush); | 353 | s->z_err = deflate(&(s->stream), flush); |
354 | 354 | ||
355 | /* deflate has finished flushing only when it hasn't used up | 355 | /* deflate has finished flushing only when it hasn't used up |
356 | * all the available space in the output buffer: | 356 | * all the available space in the output buffer: |
357 | */ | 357 | */ |
358 | done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); | 358 | done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); |
359 | 359 | ||
360 | if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; | 360 | if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; |
361 | } | 361 | } |
362 | return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; | 362 | return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; |
363 | } | 363 | } |
@@ -371,8 +371,8 @@ local void putLong (file, x) | |||
371 | { | 371 | { |
372 | int n; | 372 | int n; |
373 | for (n = 0; n < 4; n++) { | 373 | for (n = 0; n < 4; n++) { |
374 | fputc((int)(x & 0xff), file); | 374 | fputc((int)(x & 0xff), file); |
375 | x >>= 8; | 375 | x >>= 8; |
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
@@ -386,8 +386,8 @@ local uLong getLong (buf) | |||
386 | Byte *p = buf+4; | 386 | Byte *p = buf+4; |
387 | 387 | ||
388 | do { | 388 | do { |
389 | x <<= 8; | 389 | x <<= 8; |
390 | x |= *--p; | 390 | x |= *--p; |
391 | } while (p != buf); | 391 | } while (p != buf); |
392 | return x; | 392 | return x; |
393 | } | 393 | } |
@@ -406,31 +406,31 @@ int gzclose (file) | |||
406 | if (s == NULL) return Z_STREAM_ERROR; | 406 | if (s == NULL) return Z_STREAM_ERROR; |
407 | 407 | ||
408 | if (s->mode == 'w') { | 408 | if (s->mode == 'w') { |
409 | err = gzflush (file, Z_FINISH); | 409 | err = gzflush (file, Z_FINISH); |
410 | if (err != Z_OK) return destroy(file); | 410 | if (err != Z_OK) return destroy(file); |
411 | 411 | ||
412 | putLong (s->file, s->crc); | 412 | putLong (s->file, s->crc); |
413 | putLong (s->file, s->stream.total_in); | 413 | putLong (s->file, s->stream.total_in); |
414 | 414 | ||
415 | } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) { | 415 | } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) { |
416 | 416 | ||
417 | /* slide CRC and original size if they are at the end of inbuf */ | 417 | /* slide CRC and original size if they are at the end of inbuf */ |
418 | if ((n = s->stream.avail_in) < 8 && !s->z_eof) { | 418 | if ((n = s->stream.avail_in) < 8 && !s->z_eof) { |
419 | Byte *p = s->inbuf; | 419 | Byte *p = s->inbuf; |
420 | Byte *q = s->stream.next_in; | 420 | Byte *q = s->stream.next_in; |
421 | while (n--) { *p++ = *q++; }; | 421 | while (n--) { *p++ = *q++; }; |
422 | 422 | ||
423 | n = s->stream.avail_in; | 423 | n = s->stream.avail_in; |
424 | n += fread(p, 1, 8, s->file); | 424 | n += fread(p, 1, 8, s->file); |
425 | s->stream.next_in = s->inbuf; | 425 | s->stream.next_in = s->inbuf; |
426 | } | 426 | } |
427 | /* check CRC and original size */ | 427 | /* check CRC and original size */ |
428 | if (n < 8 || | 428 | if (n < 8 || |
429 | getLong(s->stream.next_in) != s->crc || | 429 | getLong(s->stream.next_in) != s->crc || |
430 | getLong(s->stream.next_in + 4) != s->stream.total_out) { | 430 | getLong(s->stream.next_in + 4) != s->stream.total_out) { |
431 | 431 | ||
432 | s->z_err = Z_DATA_ERROR; | 432 | s->z_err = Z_DATA_ERROR; |
433 | } | 433 | } |
434 | } | 434 | } |
435 | return destroy(file); | 435 | return destroy(file); |
436 | } | 436 | } |
@@ -450,8 +450,8 @@ char* gzerror (file, errnum) | |||
450 | gz_stream *s = (gz_stream*)file; | 450 | gz_stream *s = (gz_stream*)file; |
451 | 451 | ||
452 | if (s == NULL) { | 452 | if (s == NULL) { |
453 | *errnum = Z_STREAM_ERROR; | 453 | *errnum = Z_STREAM_ERROR; |
454 | return z_errmsg[1-Z_STREAM_ERROR]; | 454 | return z_errmsg[1-Z_STREAM_ERROR]; |
455 | } | 455 | } |
456 | *errnum = s->z_err; | 456 | *errnum = s->z_err; |
457 | if (*errnum == Z_OK) return ""; | 457 | if (*errnum == Z_OK) return ""; |