summaryrefslogtreecommitdiff
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 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)
/* Look for gzip header, set up for inflate or copy. state->have must be zero.
If this is the first time in, allocate required memory. state->how will be
- left unchanged if there is no more input data available, will be set to 1 if
- there is no gzip header and direct copying will be performed, or it will be
- set to 2 for decompression, and the gzip header will be skipped so that the
- next available input data is the raw deflate stream. If direct copying,
- then leftover input data from the input buffer will be copied to the output
- buffer. In that case, all further file reads will be directly to either the
- output buffer or a user buffer. If decompressing, the inflate state and the
- check value will be initialized. gz_head() will return 0 on success or -1
- on failure. Failures may include read errors or gzip header errors. */
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression, and the gzip header will be skipped so
+ that the next available input data is the raw deflate stream. If direct
+ copying, then leftover input data from the input buffer will be copied to
+ the output buffer. In that case, all further file reads will be directly to
+ either the output buffer or a user buffer. If decompressing, the inflate
+ state and the check value will be initialized. gz_head() will return 0 on
+ success or -1 on failure. Failures may include read errors or gzip header
+ errors. */
local int gz_head(state)
gz_statep state;
{
@@ -196,7 +197,8 @@ local int gz_head(state)
/* set up for decompression */
inflateReset(strm);
strm->adler = crc32(0L, Z_NULL, 0);
- state->how = 2;
+ state->how = GZIP;
+ state->direct = 0;
return 0;
}
else {
@@ -216,7 +218,8 @@ local int gz_head(state)
state->have += strm->avail_in;
strm->avail_in = 0;
}
- state->how = 1;
+ state->how = COPY;
+ state->direct = 1;
return 0;
}
@@ -224,7 +227,7 @@ local int gz_head(state)
If the end of the compressed data is reached, then verify the gzip trailer
check value and length (modulo 2^32). state->have and state->next are set
to point to the just decompressed data, and the crc is updated. If the
- trailer is verified, state->how is reset to zero to look for the next gzip
+ trailer is verified, state->how is reset to LOOK to look for the next gzip
stream or raw data, once state->have is depleted. Returns 0 on success, -1
on failure. Failures may include invalid compressed data or a failed gzip
trailer verification. */
@@ -284,7 +287,8 @@ local int gz_decomp(state)
gz_error(state, Z_DATA_ERROR, "incorrect length check");
return -1;
}
- state->how = 0; /* ready for next stream, once have is 0 */
+ state->how = LOOK; /* ready for next stream, once have is 0 (leave
+ state->direct unchanged to remember how) */
}
/* good decompression */
@@ -293,28 +297,28 @@ local int gz_decomp(state)
/* Make data and put in the output buffer. Assumes that state->have == 0.
Data is either copied from the input file or decompressed from the input
- file depending on state->how. If state->how is zero, then a gzip header is
+ file depending on state->how. If state->how is LOOK, then a gzip header is
looked for (and skipped if found) to determine wither to copy or decompress.
- Returns -1 on error, otherwise 0. gz_make() will leave state->have non-zero
- unless the end of the input file has been reached and all data has been
- processed. */
+ Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
+ or GZIP unless the end of the input file has been reached and all data has
+ been processed. */
local int gz_make(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
- if (state->how == 0) { /* look for gzip header */
+ if (state->how == LOOK) { /* look for gzip header */
if (gz_head(state) == -1)
return -1;
if (state->have) /* got some data from gz_head() */
return 0;
}
- if (state->how == 1) { /* straight copy */
+ if (state->how == COPY) { /* straight copy */
if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
return -1;
state->next = state->out;
}
- else if (state->how == 2) { /* decompress */
+ else if (state->how == GZIP) { /* decompress */
strm->avail_out = state->size << 1;
strm->next_out = state->out;
if (gz_decomp(state) == -1)
@@ -409,7 +413,7 @@ int ZEXPORT gzread(file, buf, len)
/* need output data -- for small len or new stream load up our output
buffer */
- else if (state->how == 0 || len < (state->size << 1)) {
+ else if (state->how == LOOK || len < (state->size << 1)) {
/* get more output, looking for header if required */
if (gz_make(state) == -1)
return -1;
@@ -419,13 +423,13 @@ int ZEXPORT gzread(file, buf, len)
}
/* large len -- read directly into user buffer */
- else if (state->how == 1) { /* read directly */
+ else if (state->how == COPY) { /* read directly */
if (gz_load(state, buf, len, &n) == -1)
return -1;
}
/* large len -- decompress directly into user buffer */
- else { /* state->how == 2 */
+ else { /* state->how == GZIP */
strm->avail_out = len;
strm->next_out = buf;
if (gz_decomp(state) == -1)
@@ -614,14 +618,20 @@ int ZEXPORT gzdirect(file)
if (state->mode != GZ_READ)
return 0;
- /* return true if reading without decompression */
- return state->how == 1;
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->how == LOOK && state->have == 0)
+ (void)gz_head(state);
+
+ /* return 1 if reading direct, 0 if decompressing a gzip stream */
+ return state->direct;
}
/* -- see zlib.h -- */
int ZEXPORT gzclose_r(file)
gzFile file;
{
+ int ret;
gz_statep state;
/* get internal structure */
@@ -640,9 +650,9 @@ int ZEXPORT gzclose_r(file)
free(state->in);
}
gz_error(state, Z_OK, NULL);
- close(state->fd);
+ ret = close(state->fd);
free(state);
- return Z_OK;
+ return ret ? Z_ERRNO : Z_OK;
}
#endif /* !OLD_GZIO */