gzread.c updated to zlib 1.2.11
This commit is contained in:
parent
7f82aad187
commit
5735fd74ee
@ -1,9 +1,9 @@
|
||||
/* gzread.c contains minimal changes required to be compiled with zlibWrapper:
|
||||
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
|
||||
|
||||
/* gzread.c -- zlib functions for reading gzip files
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
|
||||
* For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
|
||||
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
|
||||
|
||||
/* gzread.c -- zlib functions for reading gzip files
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
@ -15,9 +15,10 @@ local int gz_look OF((gz_statep));
|
||||
local int gz_decomp OF((gz_statep));
|
||||
local int gz_fetch OF((gz_statep));
|
||||
local int gz_skip OF((gz_statep, z_off64_t));
|
||||
local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
|
||||
|
||||
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||||
state->fd, and update state->eof, state->err, and state->msg as appropriate.
|
||||
state.state->fd, and update state.state->eof, state.state->err, and state.state->msg as appropriate.
|
||||
This function needs to loop on read(), since read() is not guaranteed to
|
||||
read the number of bytes requested, depending on the type of descriptor. */
|
||||
local int gz_load(state, buf, len, have)
|
||||
@ -27,13 +28,17 @@ local int gz_load(state, buf, len, have)
|
||||
unsigned *have;
|
||||
{
|
||||
int ret;
|
||||
unsigned get, max = ((unsigned)-1 >> 2) + 1;
|
||||
|
||||
*have = 0;
|
||||
do {
|
||||
ret = (int)read(state.state->fd, buf + *have, len - *have);
|
||||
get = len - *have;
|
||||
if (get > max)
|
||||
get = max;
|
||||
ret = read(state.state->fd, buf + *have, get);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
*have += ret;
|
||||
*have += (unsigned)ret;
|
||||
} while (*have < len);
|
||||
if (ret < 0) {
|
||||
gz_error(state, Z_ERRNO, zstrerror());
|
||||
@ -77,8 +82,8 @@ local int gz_avail(state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
|
||||
If this is the first time in, allocate required memory. state->how will be
|
||||
/* Look for gzip header, set up for inflate or copy. state.state->x.have must be 0.
|
||||
If this is the first time in, allocate required memory. state.state->how will be
|
||||
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. If direct copying, then leftover input
|
||||
@ -97,10 +102,8 @@ local int gz_look(state)
|
||||
state.state->in = (unsigned char *)malloc(state.state->want);
|
||||
state.state->out = (unsigned char *)malloc(state.state->want << 1);
|
||||
if (state.state->in == NULL || state.state->out == NULL) {
|
||||
if (state.state->out != NULL)
|
||||
free(state.state->out);
|
||||
if (state.state->in != NULL)
|
||||
free(state.state->in);
|
||||
free(state.state->out);
|
||||
free(state.state->in);
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
@ -136,7 +139,6 @@ local int gz_look(state)
|
||||
file -- for here we assume that if a gzip file is being written, then
|
||||
the header will be written in a single operation, so that reading a
|
||||
single byte is sufficient indication that it is not a gzip file) */
|
||||
//printf("strm->next_in[0]=%d strm->next_in[1]=%d\n", strm->next_in[0], strm->next_in[1]);
|
||||
if (strm->avail_in > 1 &&
|
||||
((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */
|
||||
|| (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { /* zstd header */
|
||||
@ -170,9 +172,9 @@ local int gz_look(state)
|
||||
}
|
||||
|
||||
/* Decompress from input to the provided next_out and avail_out in the state.
|
||||
On return, state->x.have and state->x.next point to the just decompressed
|
||||
data. If the gzip stream completes, state->how is reset to LOOK to look for
|
||||
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
|
||||
On return, state.state->x.have and state.state->x.next point to the just decompressed
|
||||
data. If the gzip stream completes, state.state->how is reset to LOOK to look for
|
||||
the next gzip stream or raw data, once state.state->x.have is depleted. Returns 0
|
||||
on success, -1 on failure. */
|
||||
local int gz_decomp(state)
|
||||
gz_statep state;
|
||||
@ -222,11 +224,11 @@ local int gz_decomp(state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
|
||||
/* Fetch data and put it in the output buffer. Assumes state.state->x.have is 0.
|
||||
Data is either copied from the input file or decompressed from the input
|
||||
file depending on state->how. If state->how is LOOK, then a gzip header is
|
||||
file depending on state.state->how. If state.state->how is LOOK, then a gzip header is
|
||||
looked for to determine whether to copy or decompress. Returns -1 on error,
|
||||
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
|
||||
otherwise 0. gz_fetch() will leave state.state->how as COPY or GZIP unless the
|
||||
end of the input file has been reached and all data has been processed. */
|
||||
local int gz_fetch(state)
|
||||
gz_statep state;
|
||||
@ -289,33 +291,17 @@ local int gz_skip(state, len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzread(file, buf, len)
|
||||
gzFile file;
|
||||
voidp buf;
|
||||
unsigned len;
|
||||
{
|
||||
unsigned got, n;
|
||||
/* Read len bytes into buf from file, or less than len up to the end of the
|
||||
input. Return the number of bytes read. If zero is returned, either the
|
||||
end of file was reached, or there was an error. state.state->err must be
|
||||
consulted in that case to determine which. */
|
||||
local z_size_t gz_read(state, buf, len)
|
||||
gz_statep state;
|
||||
z_streamp strm;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
strm = &(state.state->strm);
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state.state->mode != GZ_READ ||
|
||||
(state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* since an int is returned, make sure len fits in one, otherwise return
|
||||
with an error (this avoids the flaw in the interface) */
|
||||
if ((int)len < 0) {
|
||||
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||
return -1;
|
||||
}
|
||||
voidp buf;
|
||||
z_size_t len;
|
||||
{
|
||||
z_size_t got;
|
||||
unsigned n;
|
||||
|
||||
/* if len is zero, avoid unnecessary operations */
|
||||
if (len == 0)
|
||||
@ -325,32 +311,38 @@ int ZEXPORT gzread(file, buf, len)
|
||||
if (state.state->seek) {
|
||||
state.state->seek = 0;
|
||||
if (gz_skip(state, state.state->skip) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get len bytes to buf, or less than len if at the end */
|
||||
got = 0;
|
||||
do {
|
||||
/* set n to the maximum amount of len that fits in an unsigned int */
|
||||
n = -1;
|
||||
if (n > len)
|
||||
n = len;
|
||||
|
||||
/* first just try copying data from the output buffer */
|
||||
if (state.state->x.have) {
|
||||
n = state.state->x.have > len ? len : state.state->x.have;
|
||||
if (state.state->x.have < n)
|
||||
n = state.state->x.have;
|
||||
memcpy(buf, state.state->x.next, n);
|
||||
state.state->x.next += n;
|
||||
state.state->x.have -= n;
|
||||
}
|
||||
|
||||
/* output buffer empty -- return if we're at the end of the input */
|
||||
else if (state.state->eof && strm->avail_in == 0) {
|
||||
else if (state.state->eof && state.state->strm.avail_in == 0) {
|
||||
state.state->past = 1; /* tried to read past end */
|
||||
break;
|
||||
}
|
||||
|
||||
/* need output data -- for small len or new stream load up our output
|
||||
buffer */
|
||||
else if (state.state->how == LOOK || len < (state.state->size << 1)) {
|
||||
else if (state.state->how == LOOK || n < (state.state->size << 1)) {
|
||||
/* get more output, looking for header if required */
|
||||
if (gz_fetch(state) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
continue; /* no progress yet -- go back to copy above */
|
||||
/* the copy above assures that we will leave with space in the
|
||||
output buffer, allowing at least one gzungetc() to succeed */
|
||||
@ -358,16 +350,16 @@ int ZEXPORT gzread(file, buf, len)
|
||||
|
||||
/* large len -- read directly into user buffer */
|
||||
else if (state.state->how == COPY) { /* read directly */
|
||||
if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
|
||||
return -1;
|
||||
if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* large len -- decompress directly into user buffer */
|
||||
else { /* state->how == GZIP */
|
||||
strm->avail_out = len;
|
||||
strm->next_out = (unsigned char *)buf;
|
||||
else { /* state.state->how == GZIP */
|
||||
state.state->strm.avail_out = n;
|
||||
state.state->strm.next_out = (unsigned char *)buf;
|
||||
if (gz_decomp(state) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
n = state.state->x.have;
|
||||
state.state->x.have = 0;
|
||||
}
|
||||
@ -379,8 +371,75 @@ int ZEXPORT gzread(file, buf, len)
|
||||
state.state->x.pos += n;
|
||||
} while (len);
|
||||
|
||||
/* return number of bytes read into user buffer (will fit in int) */
|
||||
return (int)got;
|
||||
/* return number of bytes read into user buffer */
|
||||
return got;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzread(file, buf, len)
|
||||
gzFile file;
|
||||
voidp buf;
|
||||
unsigned len;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state.state->mode != GZ_READ ||
|
||||
(state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* since an int is returned, make sure len fits in one, otherwise return
|
||||
with an error (this avoids a flaw in the interface) */
|
||||
if ((int)len < 0) {
|
||||
gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read len or fewer bytes to buf */
|
||||
len = gz_read(state, buf, len);
|
||||
|
||||
/* check for an error */
|
||||
if (len == 0 && state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)
|
||||
return -1;
|
||||
|
||||
/* return the number of bytes read (this is assured to fit in an int) */
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_size_t ZEXPORT gzfread(buf, size, nitems, file)
|
||||
voidp buf;
|
||||
z_size_t size;
|
||||
z_size_t nitems;
|
||||
gzFile file;
|
||||
{
|
||||
z_size_t len;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state.state->mode != GZ_READ ||
|
||||
(state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
|
||||
return 0;
|
||||
|
||||
/* compute bytes to read -- error on overflow */
|
||||
len = nitems * size;
|
||||
if (size && len / size != nitems) {
|
||||
gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read len or fewer bytes to buf, return the number of full items read */
|
||||
return len ? gz_read(state, buf, len) / size : 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
@ -401,7 +460,6 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));
|
||||
#endif
|
||||
|
||||
|
||||
int ZEXPORT gzgetc(file)
|
||||
gzFile file;
|
||||
{
|
||||
@ -426,8 +484,8 @@ int ZEXPORT gzgetc(file)
|
||||
return *(state.state->x.next)++;
|
||||
}
|
||||
|
||||
/* nothing there -- try gzread() */
|
||||
ret = gzread(file, buf, 1);
|
||||
/* nothing there -- try gz_read() */
|
||||
ret = gz_read(state, buf, 1);
|
||||
return ret < 1 ? -1 : buf[0];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user