diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:27:08 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:27:08 -0700 |
commit | 7df877eccdd826e94df53215f65dee639428e83f (patch) | |
tree | 11ed5070798961e28a4c69d9272ecaada500abc3 /gzread.c | |
parent | dc5a43ebfadb6b775f6e64bfeb5a461c66acb394 (diff) | |
download | zlib-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.c | 64 |
1 files changed, 37 insertions, 27 deletions
@@ -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. */ | ||
104 | local int gz_head(state) | 105 | local 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. */ |
301 | local int gz_make(state) | 305 | local 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 -- */ |
622 | int ZEXPORT gzclose_r(file) | 631 | int 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 */ |