aboutsummaryrefslogtreecommitdiff
path: root/gzread.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:27:08 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:27:08 -0700
commit7df877eccdd826e94df53215f65dee639428e83f (patch)
tree11ed5070798961e28a4c69d9272ecaada500abc3 /gzread.c
parentdc5a43ebfadb6b775f6e64bfeb5a461c66acb394 (diff)
downloadzlib-7df877eccdd826e94df53215f65dee639428e83f.tar.gz
zlib-7df877eccdd826e94df53215f65dee639428e83f.tar.bz2
zlib-7df877eccdd826e94df53215f65dee639428e83f.zip
zlib 1.2.3.7v1.2.3.7
Diffstat (limited to 'gzread.c')
-rw-r--r--gzread.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/gzread.c b/gzread.c
index 74bdc7b..74322ca 100644
--- a/gzread.c
+++ b/gzread.c
@@ -92,15 +92,16 @@ local int gz_next4(state, ret)
92 92
93/* Look for gzip header, set up for inflate or copy. state->have must be zero. 93/* Look for gzip header, set up for inflate or copy. state->have must be zero.
94 If this is the first time in, allocate required memory. state->how will be 94 If this is the first time in, allocate required memory. state->how will be
95 left unchanged if there is no more input data available, will be set to 1 if 95 left unchanged if there is no more input data available, will be set to COPY
96 there is no gzip header and direct copying will be performed, or it will be 96 if there is no gzip header and direct copying will be performed, or it will
97 set to 2 for decompression, and the gzip header will be skipped so that the 97 be set to GZIP for decompression, and the gzip header will be skipped so
98 next available input data is the raw deflate stream. If direct copying, 98 that the next available input data is the raw deflate stream. If direct
99 then leftover input data from the input buffer will be copied to the output 99 copying, then leftover input data from the input buffer will be copied to
100 buffer. In that case, all further file reads will be directly to either the 100 the output buffer. In that case, all further file reads will be directly to
101 output buffer or a user buffer. If decompressing, the inflate state and the 101 either the output buffer or a user buffer. If decompressing, the inflate
102 check value will be initialized. gz_head() will return 0 on success or -1 102 state and the check value will be initialized. gz_head() will return 0 on
103 on failure. Failures may include read errors or gzip header errors. */ 103 success or -1 on failure. Failures may include read errors or gzip header
104 errors. */
104local int gz_head(state) 105local int gz_head(state)
105 gz_statep state; 106 gz_statep state;
106{ 107{
@@ -196,7 +197,8 @@ local int gz_head(state)
196 /* set up for decompression */ 197 /* set up for decompression */
197 inflateReset(strm); 198 inflateReset(strm);
198 strm->adler = crc32(0L, Z_NULL, 0); 199 strm->adler = crc32(0L, Z_NULL, 0);
199 state->how = 2; 200 state->how = GZIP;
201 state->direct = 0;
200 return 0; 202 return 0;
201 } 203 }
202 else { 204 else {
@@ -216,7 +218,8 @@ local int gz_head(state)
216 state->have += strm->avail_in; 218 state->have += strm->avail_in;
217 strm->avail_in = 0; 219 strm->avail_in = 0;
218 } 220 }
219 state->how = 1; 221 state->how = COPY;
222 state->direct = 1;
220 return 0; 223 return 0;
221} 224}
222 225
@@ -224,7 +227,7 @@ local int gz_head(state)
224 If the end of the compressed data is reached, then verify the gzip trailer 227 If the end of the compressed data is reached, then verify the gzip trailer
225 check value and length (modulo 2^32). state->have and state->next are set 228 check value and length (modulo 2^32). state->have and state->next are set
226 to point to the just decompressed data, and the crc is updated. If the 229 to point to the just decompressed data, and the crc is updated. If the
227 trailer is verified, state->how is reset to zero to look for the next gzip 230 trailer is verified, state->how is reset to LOOK to look for the next gzip
228 stream or raw data, once state->have is depleted. Returns 0 on success, -1 231 stream or raw data, once state->have is depleted. Returns 0 on success, -1
229 on failure. Failures may include invalid compressed data or a failed gzip 232 on failure. Failures may include invalid compressed data or a failed gzip
230 trailer verification. */ 233 trailer verification. */
@@ -284,7 +287,8 @@ local int gz_decomp(state)
284 gz_error(state, Z_DATA_ERROR, "incorrect length check"); 287 gz_error(state, Z_DATA_ERROR, "incorrect length check");
285 return -1; 288 return -1;
286 } 289 }
287 state->how = 0; /* ready for next stream, once have is 0 */ 290 state->how = LOOK; /* ready for next stream, once have is 0 (leave
291 state->direct unchanged to remember how) */
288 } 292 }
289 293
290 /* good decompression */ 294 /* good decompression */
@@ -293,28 +297,28 @@ local int gz_decomp(state)
293 297
294/* Make data and put in the output buffer. Assumes that state->have == 0. 298/* Make data and put in the output buffer. Assumes that state->have == 0.
295 Data is either copied from the input file or decompressed from the input 299 Data is either copied from the input file or decompressed from the input
296 file depending on state->how. If state->how is zero, then a gzip header is 300 file depending on state->how. If state->how is LOOK, then a gzip header is
297 looked for (and skipped if found) to determine wither to copy or decompress. 301 looked for (and skipped if found) to determine wither to copy or decompress.
298 Returns -1 on error, otherwise 0. gz_make() will leave state->have non-zero 302 Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
299 unless the end of the input file has been reached and all data has been 303 or GZIP unless the end of the input file has been reached and all data has
300 processed. */ 304 been processed. */
301local int gz_make(state) 305local int gz_make(state)
302 gz_statep state; 306 gz_statep state;
303{ 307{
304 z_streamp strm = &(state->strm); 308 z_streamp strm = &(state->strm);
305 309
306 if (state->how == 0) { /* look for gzip header */ 310 if (state->how == LOOK) { /* look for gzip header */
307 if (gz_head(state) == -1) 311 if (gz_head(state) == -1)
308 return -1; 312 return -1;
309 if (state->have) /* got some data from gz_head() */ 313 if (state->have) /* got some data from gz_head() */
310 return 0; 314 return 0;
311 } 315 }
312 if (state->how == 1) { /* straight copy */ 316 if (state->how == COPY) { /* straight copy */
313 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) 317 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
314 return -1; 318 return -1;
315 state->next = state->out; 319 state->next = state->out;
316 } 320 }
317 else if (state->how == 2) { /* decompress */ 321 else if (state->how == GZIP) { /* decompress */
318 strm->avail_out = state->size << 1; 322 strm->avail_out = state->size << 1;
319 strm->next_out = state->out; 323 strm->next_out = state->out;
320 if (gz_decomp(state) == -1) 324 if (gz_decomp(state) == -1)
@@ -409,7 +413,7 @@ int ZEXPORT gzread(file, buf, len)
409 413
410 /* need output data -- for small len or new stream load up our output 414 /* need output data -- for small len or new stream load up our output
411 buffer */ 415 buffer */
412 else if (state->how == 0 || len < (state->size << 1)) { 416 else if (state->how == LOOK || len < (state->size << 1)) {
413 /* get more output, looking for header if required */ 417 /* get more output, looking for header if required */
414 if (gz_make(state) == -1) 418 if (gz_make(state) == -1)
415 return -1; 419 return -1;
@@ -419,13 +423,13 @@ int ZEXPORT gzread(file, buf, len)
419 } 423 }
420 424
421 /* large len -- read directly into user buffer */ 425 /* large len -- read directly into user buffer */
422 else if (state->how == 1) { /* read directly */ 426 else if (state->how == COPY) { /* read directly */
423 if (gz_load(state, buf, len, &n) == -1) 427 if (gz_load(state, buf, len, &n) == -1)
424 return -1; 428 return -1;
425 } 429 }
426 430
427 /* large len -- decompress directly into user buffer */ 431 /* large len -- decompress directly into user buffer */
428 else { /* state->how == 2 */ 432 else { /* state->how == GZIP */
429 strm->avail_out = len; 433 strm->avail_out = len;
430 strm->next_out = buf; 434 strm->next_out = buf;
431 if (gz_decomp(state) == -1) 435 if (gz_decomp(state) == -1)
@@ -614,14 +618,20 @@ int ZEXPORT gzdirect(file)
614 if (state->mode != GZ_READ) 618 if (state->mode != GZ_READ)
615 return 0; 619 return 0;
616 620
617 /* return true if reading without decompression */ 621 /* if the state is not known, but we can find out, then do so (this is
618 return state->how == 1; 622 mainly for right after a gzopen() or gzdopen()) */
623 if (state->how == LOOK && state->have == 0)
624 (void)gz_head(state);
625
626 /* return 1 if reading direct, 0 if decompressing a gzip stream */
627 return state->direct;
619} 628}
620 629
621/* -- see zlib.h -- */ 630/* -- see zlib.h -- */
622int ZEXPORT gzclose_r(file) 631int ZEXPORT gzclose_r(file)
623 gzFile file; 632 gzFile file;
624{ 633{
634 int ret;
625 gz_statep state; 635 gz_statep state;
626 636
627 /* get internal structure */ 637 /* get internal structure */
@@ -640,9 +650,9 @@ int ZEXPORT gzclose_r(file)
640 free(state->in); 650 free(state->in);
641 } 651 }
642 gz_error(state, Z_OK, NULL); 652 gz_error(state, Z_OK, NULL);
643 close(state->fd); 653 ret = close(state->fd);
644 free(state); 654 free(state);
645 return Z_OK; 655 return ret ? Z_ERRNO : Z_OK;
646} 656}
647 657
648#endif /* !OLD_GZIO */ 658#endif /* !OLD_GZIO */