|
|
|
@ -9,6 +9,7 @@ |
|
|
|
|
local int gz_init OF((gz_statep)); |
|
|
|
|
local int gz_comp OF((gz_statep, int)); |
|
|
|
|
local int gz_zero OF((gz_statep, z_off64_t)); |
|
|
|
|
local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); |
|
|
|
|
|
|
|
|
|
/* Initialize state for writing a gzip file. Mark initialization by setting
|
|
|
|
|
state->size to non-zero. Return -1 on a memory allocation failure, or 0 on |
|
|
|
@ -170,32 +171,14 @@ local int gz_zero(state, len) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -- see zlib.h -- */ |
|
|
|
|
int ZEXPORT gzwrite(file, buf, len) |
|
|
|
|
gzFile file; |
|
|
|
|
/* Write len bytes from buf to file. Return the number of bytes written. If
|
|
|
|
|
the returned value is less than len, then there was an error. */ |
|
|
|
|
local z_size_t gz_write(state, buf, len) |
|
|
|
|
gz_statep state; |
|
|
|
|
voidpc buf; |
|
|
|
|
unsigned len; |
|
|
|
|
z_size_t len; |
|
|
|
|
{ |
|
|
|
|
unsigned put = len; |
|
|
|
|
gz_statep state; |
|
|
|
|
z_streamp strm; |
|
|
|
|
|
|
|
|
|
/* get internal structure */ |
|
|
|
|
if (file == NULL) |
|
|
|
|
return 0; |
|
|
|
|
state = (gz_statep)file; |
|
|
|
|
strm = &(state->strm); |
|
|
|
|
|
|
|
|
|
/* check that we're writing and that there's no error */ |
|
|
|
|
if (state->mode != GZ_WRITE || state->err != Z_OK) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
/* 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 0; |
|
|
|
|
} |
|
|
|
|
z_size_t put = len; |
|
|
|
|
|
|
|
|
|
/* if len is zero, avoid unnecessary operations */ |
|
|
|
|
if (len == 0) |
|
|
|
@ -218,14 +201,15 @@ int ZEXPORT gzwrite(file, buf, len) |
|
|
|
|
do { |
|
|
|
|
unsigned have, copy; |
|
|
|
|
|
|
|
|
|
if (strm->avail_in == 0) |
|
|
|
|
strm->next_in = state->in; |
|
|
|
|
have = (unsigned)((strm->next_in + strm->avail_in) - state->in); |
|
|
|
|
if (state->strm.avail_in == 0) |
|
|
|
|
state->strm.next_in = state->in; |
|
|
|
|
have = (unsigned)((state->strm.next_in + state->strm.avail_in) - |
|
|
|
|
state->in); |
|
|
|
|
copy = state->size - have; |
|
|
|
|
if (copy > len) |
|
|
|
|
copy = len; |
|
|
|
|
memcpy(state->in + have, buf, copy); |
|
|
|
|
strm->avail_in += copy; |
|
|
|
|
state->strm.avail_in += copy; |
|
|
|
|
state->x.pos += copy; |
|
|
|
|
buf = (const char *)buf + copy; |
|
|
|
|
len -= copy; |
|
|
|
@ -235,19 +219,83 @@ int ZEXPORT gzwrite(file, buf, len) |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
/* consume whatever's left in the input buffer */ |
|
|
|
|
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) |
|
|
|
|
if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
/* directly compress user buffer to file */ |
|
|
|
|
strm->avail_in = len; |
|
|
|
|
strm->next_in = (z_const Bytef *)buf; |
|
|
|
|
state->x.pos += len; |
|
|
|
|
if (gz_comp(state, Z_NO_FLUSH) == -1) |
|
|
|
|
return 0; |
|
|
|
|
state->strm.next_in = (z_const Bytef *)buf; |
|
|
|
|
do { |
|
|
|
|
unsigned n = -1; |
|
|
|
|
if (n > len) |
|
|
|
|
n = len; |
|
|
|
|
state->strm.avail_in = n; |
|
|
|
|
state->x.pos += n; |
|
|
|
|
if (gz_comp(state, Z_NO_FLUSH) == -1) |
|
|
|
|
return 0; |
|
|
|
|
len -= n; |
|
|
|
|
} while (len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* input was all buffered or compressed */ |
|
|
|
|
return put; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -- see zlib.h -- */ |
|
|
|
|
int ZEXPORT gzwrite(file, buf, len) |
|
|
|
|
gzFile file; |
|
|
|
|
voidpc buf; |
|
|
|
|
unsigned len; |
|
|
|
|
{ |
|
|
|
|
gz_statep state; |
|
|
|
|
|
|
|
|
|
/* get internal structure */ |
|
|
|
|
if (file == NULL) |
|
|
|
|
return 0; |
|
|
|
|
state = (gz_statep)file; |
|
|
|
|
|
|
|
|
|
/* check that we're writing and that there's no error */ |
|
|
|
|
if (state->mode != GZ_WRITE || state->err != Z_OK) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
/* 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_DATA_ERROR, "requested length does not fit in int"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* write len bytes from buf (the return value will fit in an int) */ |
|
|
|
|
return (int)gz_write(state, buf, len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -- see zlib.h -- */ |
|
|
|
|
z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) |
|
|
|
|
voidpc 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 writing and that there's no error */ |
|
|
|
|
if (state->mode != GZ_WRITE || state->err != Z_OK) |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* input was all buffered or compressed (put will fit in int) */ |
|
|
|
|
return (int)put; |
|
|
|
|
/* write len bytes to buf, return the number of full items written */ |
|
|
|
|
return len ? gz_write(state, buf, len) / size : 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* -- see zlib.h -- */ |
|
|
|
@ -293,7 +341,7 @@ int ZEXPORT gzputc(file, c) |
|
|
|
|
|
|
|
|
|
/* no room in buffer or not initialized, use gz_write() */ |
|
|
|
|
buf[0] = (unsigned char)c; |
|
|
|
|
if (gzwrite(file, buf, 1) != 1) |
|
|
|
|
if (gz_write(state, buf, 1) != 1) |
|
|
|
|
return -1; |
|
|
|
|
return c & 0xff; |
|
|
|
|
} |
|
|
|
@ -304,11 +352,21 @@ int ZEXPORT gzputs(file, str) |
|
|
|
|
const char *str; |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
unsigned len; |
|
|
|
|
z_size_t len; |
|
|
|
|
gz_statep state; |
|
|
|
|
|
|
|
|
|
/* get internal structure */ |
|
|
|
|
if (file == NULL) |
|
|
|
|
return -1; |
|
|
|
|
state = (gz_statep)file; |
|
|
|
|
|
|
|
|
|
/* check that we're writing and that there's no error */ |
|
|
|
|
if (state->mode != GZ_WRITE || state->err != Z_OK) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
/* write string */ |
|
|
|
|
len = (unsigned)strlen(str); |
|
|
|
|
ret = gzwrite(file, str, len); |
|
|
|
|
len = strlen(str); |
|
|
|
|
ret = gz_write(state, str, len); |
|
|
|
|
return ret == 0 && len != 0 ? -1 : ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|