diff options
Diffstat (limited to '')
| -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 */ |
