Merge pull request #514 from inikep/dev11

fixed gz functions based on zlib 1.2.11
dev
Yann Collet 2017-01-18 15:21:17 -08:00 committed by GitHub
commit 18b3ce6064
10 changed files with 424 additions and 217 deletions

View File

@ -1,11 +1,13 @@
# ################################################################ # ##########################################################################
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. # Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved. # All rights reserved.
# #
# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
#
# This source code is licensed under the BSD-style license found in the # This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant # LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory. # of patent rights can be found in the PATENTS file in the same directory.
# ################################################################ # ##########################################################################
# Version numbers # Version numbers
LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h` LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h`

View File

@ -370,7 +370,7 @@ typedef struct {
typedef struct { typedef struct {
unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */ unsigned contentSizeFlag; /**< 1: content size will be in frame header (if known). */
unsigned checksumFlag; /**< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */ unsigned checksumFlag; /**< 1: will generate a 32-bits checksum at end of frame, to be used for error detection by decompressor */
unsigned noDictIDFlag; /**< 1: no dict ID will be saved into frame header (if dictionary compression) */ unsigned noDictIDFlag; /**< 1: no dict ID will be saved into frame header (if dictionary compression) */
} ZSTD_frameParameters; } ZSTD_frameParameters;

View File

@ -2,6 +2,8 @@
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. # Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved. # All rights reserved.
# #
# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
#
# This source code is licensed under the BSD-style license found in the # This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant # LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory. # of patent rights can be found in the PATENTS file in the same directory.

View File

@ -2,6 +2,8 @@
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. # Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved. # All rights reserved.
# #
# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
#
# This source code is licensed under the BSD-style license found in the # This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant # LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory. # of patent rights can be found in the PATENTS file in the same directory.

View File

@ -43,3 +43,25 @@ ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode)); const char *mode));
#endif #endif
#endif #endif
#if ZLIB_VERNUM < 0x12B0
#ifdef Z_SOLO
typedef unsigned long z_size_t;
#else
# define z_longlong long long
# if defined(NO_SIZE_T)
typedef unsigned NO_SIZE_T z_size_t;
# elif defined(STDC)
# include <stddef.h>
typedef size_t z_size_t;
# else
typedef unsigned long z_size_t;
# endif
# undef z_longlong
#endif
ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
gzFile file));
ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
z_size_t nitems, gzFile file));
#endif

View File

@ -3,7 +3,7 @@
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
/* gzguts.h -- zlib internal header definitions for gz* operations /* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
* For conditions of distribution and use, see http://www.zlib.net/zlib_license.html * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
*/ */
@ -30,6 +30,10 @@
# include <stdlib.h> # include <stdlib.h>
# include <limits.h> # include <limits.h>
#endif #endif
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE
#endif
#include <fcntl.h> #include <fcntl.h>
#ifdef _WIN32 #ifdef _WIN32
@ -40,6 +44,10 @@
# include <io.h> # include <io.h>
#endif #endif
#if defined(_WIN32) || defined(__CYGWIN__)
# define WIDECHAR
#endif
#ifdef WINAPI_FAMILY #ifdef WINAPI_FAMILY
# define open _open # define open _open
# define read _read # define read _read
@ -100,18 +108,19 @@
# endif # endif
#endif #endif
/* unlike snprintf (which is required in C99, yet still not supported by /* unlike snprintf (which is required in C99), _snprintf does not guarantee
Microsoft more than a decade later!), _snprintf does not guarantee null null termination of the result -- however this is only used in gzlib.c where
termination of the result -- however this is only used in gzlib.c where
the result is assured to fit in the space provided */ the result is assured to fit in the space provided */
#ifdef _MSC_VER #if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf _snprintf # define snprintf _snprintf
#endif #endif
#ifndef local #ifndef local
# define local static # define local static
#endif #endif
/* compile with -Dlocal if your debugger can't find static symbols */ /* since "static" is used to mean two completely different things in C, we
define "local" for the non-static meaning of "static", for readability
(compile with -Dlocal if your debugger can't find static symbols) */
/* gz* functions always use library allocation functions */ /* gz* functions always use library allocation functions */
#ifndef STDC #ifndef STDC
@ -175,7 +184,7 @@ typedef struct {
char *path; /* path or fd for error messages */ char *path; /* path or fd for error messages */
unsigned size; /* buffer size, zero if not allocated yet */ unsigned size; /* buffer size, zero if not allocated yet */
unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned want; /* requested buffer size, default is GZBUFSIZE */
unsigned char *in; /* input buffer */ unsigned char *in; /* input buffer (double-sized when writing) */
unsigned char *out; /* output buffer (double-sized when reading) */ unsigned char *out; /* output buffer (double-sized when reading) */
int direct; /* 0 if processing gzip, 1 if transparent */ int direct; /* 0 if processing gzip, 1 if transparent */
/* just for reading */ /* just for reading */

View File

@ -1,14 +1,14 @@
/* gzlib.c contains minimal changes required to be compiled with zlibWrapper: /* gzlib.c contains minimal changes required to be compiled with zlibWrapper:
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
/* gzlib.c -- zlib functions common to reading and writing gzip files /* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see http://www.zlib.net/zlib_license.html * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
*/ */
#include "gzguts.h" #include "gzguts.h"
#if defined(_WIN32) && !defined(__BORLANDC__) #if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
# define LSEEK _lseeki64 # define LSEEK _lseeki64
#else #else
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
@ -97,7 +97,7 @@ local gzFile gz_open(path, fd, mode)
const char *mode; const char *mode;
{ {
gz_statep state; gz_statep state;
size_t len; z_size_t len;
int oflag; int oflag;
#ifdef O_CLOEXEC #ifdef O_CLOEXEC
int cloexec = 0; int cloexec = 0;
@ -191,10 +191,10 @@ local gzFile gz_open(path, fd, mode)
} }
/* save the path name for error messages */ /* save the path name for error messages */
#ifdef _WIN32 #ifdef WIDECHAR
if (fd == -2) { if (fd == -2) {
len = wcstombs(NULL, path, 0); len = wcstombs(NULL, path, 0);
if (len == (size_t)-1) if (len == (z_size_t)-1)
len = 0; len = 0;
} }
else else
@ -205,7 +205,7 @@ local gzFile gz_open(path, fd, mode)
free(state.state); free(state.state);
return NULL; return NULL;
} }
#ifdef _WIN32 #ifdef WIDECHAR
if (fd == -2) if (fd == -2)
if (len) if (len)
wcstombs(state.state->path, path, len + 1); wcstombs(state.state->path, path, len + 1);
@ -214,7 +214,7 @@ local gzFile gz_open(path, fd, mode)
else else
#endif #endif
#if !defined(NO_snprintf) && !defined(NO_vsnprintf) #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(state.state->path, len + 1, "%s", (const char *)path); (void)snprintf(state.state->path, len + 1, "%s", (const char *)path);
#else #else
strcpy(state.state->path, path); strcpy(state.state->path, path);
#endif #endif
@ -242,7 +242,7 @@ local gzFile gz_open(path, fd, mode)
/* open the file with the appropriate flags (or just use fd) */ /* open the file with the appropriate flags (or just use fd) */
state.state->fd = fd > -1 ? fd : ( state.state->fd = fd > -1 ? fd : (
#ifdef _WIN32 #ifdef WIDECHAR
fd == -2 ? _wopen(path, oflag, 0666) : fd == -2 ? _wopen(path, oflag, 0666) :
#endif #endif
open((const char *)path, oflag, 0666)); open((const char *)path, oflag, 0666));
@ -251,8 +251,10 @@ local gzFile gz_open(path, fd, mode)
free(state.state); free(state.state);
return NULL; return NULL;
} }
if (state.state->mode == GZ_APPEND) if (state.state->mode == GZ_APPEND) {
LSEEK(state.state->fd, 0, SEEK_END); /* so gzoffset() is correct */
state.state->mode = GZ_WRITE; /* simplify later checks */ state.state->mode = GZ_WRITE; /* simplify later checks */
}
/* save the current position for rewinding (only if reading) */ /* save the current position for rewinding (only if reading) */
if (state.state->mode == GZ_READ) { if (state.state->mode == GZ_READ) {
@ -294,7 +296,7 @@ gzFile ZEXPORT gzdopen(fd, mode)
if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
return NULL; return NULL;
#if !defined(NO_snprintf) && !defined(NO_vsnprintf) #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
#else #else
sprintf(path, "<fd:%d>", fd); /* for debugging */ sprintf(path, "<fd:%d>", fd); /* for debugging */
#endif #endif
@ -304,7 +306,7 @@ gzFile ZEXPORT gzdopen(fd, mode)
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
#ifdef _WIN32 #ifdef WIDECHAR
gzFile ZEXPORT gzopen_w(path, mode) gzFile ZEXPORT gzopen_w(path, mode)
const wchar_t *path; const wchar_t *path;
const char *mode; const char *mode;
@ -332,6 +334,8 @@ int ZEXPORT gzbuffer(file, size)
return -1; return -1;
/* check and set requested size */ /* check and set requested size */
if ((size << 1) < size)
return -1; /* need to be able to double it */
if (size < 2) if (size < 2)
size = 2; /* need two bytes to check magic header */ size = 2; /* need two bytes to check magic header */
state.state->want = size; state.state->want = size;
@ -569,8 +573,8 @@ void ZEXPORT gzclearerr(file)
gz_error(state, Z_OK, NULL); gz_error(state, Z_OK, NULL);
} }
/* Create an error message in allocated memory and set state->err and /* Create an error message in allocated memory and set state.state->err and
state->msg accordingly. Free any previous error message already there. Do state.state->msg accordingly. Free any previous error message already there. Do
not try to free or allocate space if the error is Z_MEM_ERROR (out of not try to free or allocate space if the error is Z_MEM_ERROR (out of
memory). Simply save the error message as a static string. If there is an memory). Simply save the error message as a static string. If there is an
allocation failure constructing the error message, then convert the error to allocation failure constructing the error message, then convert the error to
@ -587,7 +591,7 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
state.state->msg = NULL; state.state->msg = NULL;
} }
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ /* if fatal, set state.state->x.have to 0 so that the gzgetc() macro fails */
if (err != Z_OK && err != Z_BUF_ERROR) if (err != Z_OK && err != Z_BUF_ERROR)
state.state->x.have = 0; state.state->x.have = 0;
@ -607,14 +611,13 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
return; return;
} }
#if !defined(NO_snprintf) && !defined(NO_vsnprintf) #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(state.state->msg, strlen(state.state->path) + strlen(msg) + 3, (void)snprintf(state.state->msg, strlen(state.state->path) + strlen(msg) + 3,
"%s%s%s", state.state->path, ": ", msg); "%s%s%s", state.state->path, ": ", msg);
#else #else
strcpy(state.state->msg, state.state->path); strcpy(state.state->msg, state.state->path);
strcat(state.state->msg, ": "); strcat(state.state->msg, ": ");
strcat(state.state->msg, msg); strcat(state.state->msg, msg);
#endif #endif
return;
} }
#ifndef INT_MAX #ifndef INT_MAX

View File

@ -1,8 +1,8 @@
/* gzread.c contains minimal changes required to be compiled with zlibWrapper: /* gzread.c contains minimal changes required to be compiled with zlibWrapper:
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
/* gzread.c -- zlib functions for reading gzip files /* gzread.c -- zlib functions for reading gzip files
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
* For conditions of distribution and use, see http://www.zlib.net/zlib_license.html * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
*/ */
@ -15,9 +15,10 @@ local int gz_look OF((gz_statep));
local int gz_decomp OF((gz_statep)); local int gz_decomp OF((gz_statep));
local int gz_fetch OF((gz_statep)); local int gz_fetch OF((gz_statep));
local int gz_skip OF((gz_statep, z_off64_t)); 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 /* 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 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. */ read the number of bytes requested, depending on the type of descriptor. */
local int gz_load(state, buf, len, have) local int gz_load(state, buf, len, have)
@ -26,14 +27,18 @@ local int gz_load(state, buf, len, have)
unsigned len; unsigned len;
unsigned *have; unsigned *have;
{ {
int ret; ssize_t ret;
unsigned get, max = ((unsigned)-1 >> 2) + 1;
*have = 0; *have = 0;
do { 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) if (ret <= 0)
break; break;
*have += ret; *have += (unsigned)ret;
} while (*have < len); } while (*have < len);
if (ret < 0) { if (ret < 0) {
gz_error(state, Z_ERRNO, zstrerror()); gz_error(state, Z_ERRNO, zstrerror());
@ -77,8 +82,8 @@ local int gz_avail(state)
return 0; return 0;
} }
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. /* 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->how will be 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 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 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 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->in = (unsigned char *)malloc(state.state->want);
state.state->out = (unsigned char *)malloc(state.state->want << 1); state.state->out = (unsigned char *)malloc(state.state->want << 1);
if (state.state->in == NULL || state.state->out == NULL) { if (state.state->in == NULL || state.state->out == NULL) {
if (state.state->out != NULL) free(state.state->out);
free(state.state->out); free(state.state->in);
if (state.state->in != NULL)
free(state.state->in);
gz_error(state, Z_MEM_ERROR, "out of memory"); gz_error(state, Z_MEM_ERROR, "out of memory");
return -1; 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 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 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) */ 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 && if (strm->avail_in > 1 &&
((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */ ((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */
|| (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { /* zstd 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. /* 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 On return, state.state->x.have and state.state->x.next point to the just decompressed
data. If the gzip stream completes, state->how is reset to LOOK to look for 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->x.have is depleted. Returns 0 the next gzip stream or raw data, once state.state->x.have is depleted. Returns 0
on success, -1 on failure. */ on success, -1 on failure. */
local int gz_decomp(state) local int gz_decomp(state)
gz_statep state; gz_statep state;
@ -222,11 +224,11 @@ local int gz_decomp(state)
return 0; 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 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, 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. */ end of the input file has been reached and all data has been processed. */
local int gz_fetch(state) local int gz_fetch(state)
gz_statep state; gz_statep state;
@ -289,33 +291,17 @@ local int gz_skip(state, len)
return 0; return 0;
} }
/* -- see zlib.h -- */ /* Read len bytes into buf from file, or less than len up to the end of the
int ZEXPORT gzread(file, buf, len) input. Return the number of bytes read. If zero is returned, either the
gzFile file; end of file was reached, or there was an error. state.state->err must be
voidp buf; consulted in that case to determine which. */
unsigned len; local z_size_t gz_read(state, buf, len)
{
unsigned got, n;
gz_statep state; gz_statep state;
z_streamp strm; voidp buf;
z_size_t len;
/* get internal structure */ {
if (file == NULL) z_size_t got;
return -1; unsigned n;
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;
}
/* if len is zero, avoid unnecessary operations */ /* if len is zero, avoid unnecessary operations */
if (len == 0) if (len == 0)
@ -325,32 +311,38 @@ int ZEXPORT gzread(file, buf, len)
if (state.state->seek) { if (state.state->seek) {
state.state->seek = 0; state.state->seek = 0;
if (gz_skip(state, state.state->skip) == -1) 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 */ /* get len bytes to buf, or less than len if at the end */
got = 0; got = 0;
do { do {
/* set n to the maximum amount of len that fits in an unsigned int */
n = -1;
if (n > len)
n = (unsigned)len;
/* first just try copying data from the output buffer */ /* first just try copying data from the output buffer */
if (state.state->x.have) { 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); memcpy(buf, state.state->x.next, n);
state.state->x.next += n; state.state->x.next += n;
state.state->x.have -= n; state.state->x.have -= n;
} }
/* output buffer empty -- return if we're at the end of the input */ /* 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 */ state.state->past = 1; /* tried to read past end */
break; break;
} }
/* need output data -- for small len or new stream load up our output /* need output data -- for small len or new stream load up our output
buffer */ 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 */ /* get more output, looking for header if required */
if (gz_fetch(state) == -1) if (gz_fetch(state) == -1)
return -1; return 0;
continue; /* no progress yet -- go back to copy above */ continue; /* no progress yet -- go back to copy above */
/* the copy above assures that we will leave with space in the /* the copy above assures that we will leave with space in the
output buffer, allowing at least one gzungetc() to succeed */ 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 */ /* large len -- read directly into user buffer */
else if (state.state->how == COPY) { /* read directly */ else if (state.state->how == COPY) { /* read directly */
if (gz_load(state, (unsigned char *)buf, len, &n) == -1) if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
return -1; return 0;
} }
/* large len -- decompress directly into user buffer */ /* large len -- decompress directly into user buffer */
else { /* state->how == GZIP */ else { /* state.state->how == GZIP */
strm->avail_out = len; state.state->strm.avail_out = n;
strm->next_out = (unsigned char *)buf; state.state->strm.next_out = (unsigned char *)buf;
if (gz_decomp(state) == -1) if (gz_decomp(state) == -1)
return -1; return 0;
n = state.state->x.have; n = state.state->x.have;
state.state->x.have = 0; state.state->x.have = 0;
} }
@ -379,8 +371,75 @@ int ZEXPORT gzread(file, buf, len)
state.state->x.pos += n; state.state->x.pos += n;
} while (len); } while (len);
/* return number of bytes read into user buffer (will fit in int) */ /* return number of bytes read into user buffer */
return (int)got; 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 = (unsigned)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 -- */ /* -- see zlib.h -- */
@ -401,7 +460,6 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));
#endif #endif
int ZEXPORT gzgetc(file) int ZEXPORT gzgetc(file)
gzFile file; gzFile file;
{ {
@ -426,8 +484,8 @@ int ZEXPORT gzgetc(file)
return *(state.state->x.next)++; return *(state.state->x.next)++;
} }
/* nothing there -- try gzread() */ /* nothing there -- try gz_read() */
ret = gzread(file, buf, 1); ret = (unsigned)gz_read(state, buf, 1);
return ret < 1 ? -1 : buf[0]; return ret < 1 ? -1 : buf[0];
} }

View File

@ -1,8 +1,8 @@
/* gzwrite.c contains minimal changes required to be compiled with zlibWrapper: /* gzwrite.c contains minimal changes required to be compiled with zlibWrapper:
* - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
/* gzwrite.c -- zlib functions for writing gzip files /* gzwrite.c -- zlib functions for writing gzip files
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see http://www.zlib.net/zlib_license.html * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html
*/ */
@ -12,17 +12,19 @@
local int gz_init OF((gz_statep)); local int gz_init OF((gz_statep));
local int gz_comp OF((gz_statep, int)); local int gz_comp OF((gz_statep, int));
local int gz_zero OF((gz_statep, z_off64_t)); 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 /* Initialize state for writing a gzip file. Mark initialization by setting
state->size to non-zero. Return -1 on failure or 0 on success. */ state.state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
success. */
local int gz_init(state) local int gz_init(state)
gz_statep state; gz_statep state;
{ {
int ret; int ret;
z_streamp strm = &(state.state->strm); z_streamp strm = &(state.state->strm);
/* allocate input buffer */ /* allocate input buffer (double size for gzprintf) */
state.state->in = (unsigned char *)malloc(state.state->want); state.state->in = (unsigned char *)malloc(state.state->want << 1);
if (state.state->in == NULL) { if (state.state->in == NULL) {
gz_error(state, Z_MEM_ERROR, "out of memory"); gz_error(state, Z_MEM_ERROR, "out of memory");
return -1; return -1;
@ -50,6 +52,7 @@ local int gz_init(state)
gz_error(state, Z_MEM_ERROR, "out of memory"); gz_error(state, Z_MEM_ERROR, "out of memory");
return -1; return -1;
} }
strm->next_in = NULL;
} }
/* mark state as initialized */ /* mark state as initialized */
@ -65,17 +68,17 @@ local int gz_init(state)
} }
/* Compress whatever is at avail_in and next_in and write to the output file. /* Compress whatever is at avail_in and next_in and write to the output file.
Return -1 if there is an error writing to the output file, otherwise 0. Return -1 if there is an error writing to the output file or if gz_init()
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, fails to allocate memory, otherwise 0. flush is assumed to be a valid
then the deflate() state is reset to start a new gzip stream. If gz->direct deflate() flush value. If flush is Z_FINISH, then the deflate() state is
is true, then simply write to the output file without compressing, and reset to start a new gzip stream. If gz->direct is true, then simply write
ignore flush. */ to the output file without compressing, and ignore flush. */
local int gz_comp(state, flush) local int gz_comp(state, flush)
gz_statep state; gz_statep state;
int flush; int flush;
{ {
int ret, got; int ret, writ;
unsigned have; unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
z_streamp strm = &(state.state->strm); z_streamp strm = &(state.state->strm);
/* allocate memory if this is the first time through */ /* allocate memory if this is the first time through */
@ -84,12 +87,16 @@ local int gz_comp(state, flush)
/* write directly if requested */ /* write directly if requested */
if (state.state->direct) { if (state.state->direct) {
got = (int)write(state.state->fd, strm->next_in, strm->avail_in); while (strm->avail_in) {
if (got < 0 || (unsigned)got != strm->avail_in) { put = strm->avail_in > max ? max : strm->avail_in;
gz_error(state, Z_ERRNO, zstrerror()); writ = (int)write(state.state->fd, strm->next_in, put);
return -1; if (writ < 0) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
strm->avail_in -= (unsigned)writ;
strm->next_in += writ;
} }
strm->avail_in = 0;
return 0; return 0;
} }
@ -100,17 +107,21 @@ local int gz_comp(state, flush)
doing Z_FINISH then don't write until we get to Z_STREAM_END */ doing Z_FINISH then don't write until we get to Z_STREAM_END */
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
(flush != Z_FINISH || ret == Z_STREAM_END))) { (flush != Z_FINISH || ret == Z_STREAM_END))) {
have = (unsigned)(strm->next_out - state.state->x.next); while (strm->next_out > state.state->x.next) {
if (have && ((got = (int)write(state.state->fd, state.state->x.next, have)) < 0 || put = strm->next_out - state.state->x.next > (int)max ? max :
(unsigned)got != have)) { (unsigned)(strm->next_out - state.state->x.next);
gz_error(state, Z_ERRNO, zstrerror()); writ = (int)write(state.state->fd, state.state->x.next, put);
return -1; if (writ < 0) {
gz_error(state, Z_ERRNO, zstrerror());
return -1;
}
state.state->x.next += writ;
} }
if (strm->avail_out == 0) { if (strm->avail_out == 0) {
strm->avail_out = state.state->size; strm->avail_out = state.state->size;
strm->next_out = state.state->out; strm->next_out = state.state->out;
state.state->x.next = state.state->out;
} }
state.state->x.next = strm->next_out;
} }
/* compress */ /* compress */
@ -132,7 +143,8 @@ local int gz_comp(state, flush)
return 0; return 0;
} }
/* Compress len zeros to output. Return -1 on error, 0 on success. */ /* Compress len zeros to output. Return -1 on a write error or memory
allocation failure by gz_comp(), or 0 on success. */
local int gz_zero(state, len) local int gz_zero(state, len)
gz_statep state; gz_statep state;
z_off64_t len; z_off64_t len;
@ -164,32 +176,14 @@ local int gz_zero(state, len)
return 0; return 0;
} }
/* -- see zlib.h -- */ /* Write len bytes from buf to file. Return the number of bytes written. If
int ZEXPORT gzwrite(file, buf, len) the returned value is less than len, then there was an error. */
gzFile file; local z_size_t gz_write(state, buf, len)
voidpc buf;
unsigned len;
{
unsigned put = len;
gz_statep state; gz_statep state;
z_streamp strm; voidpc buf;
z_size_t len;
/* get internal structure */ {
if (file == NULL) z_size_t put = len;
return 0;
state = (gz_statep)file;
strm = &(state.state->strm);
/* check that we're writing and that there's no error */
if (state.state->mode != GZ_WRITE || state.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;
}
/* if len is zero, avoid unnecessary operations */ /* if len is zero, avoid unnecessary operations */
if (len == 0) if (len == 0)
@ -210,16 +204,17 @@ int ZEXPORT gzwrite(file, buf, len)
if (len < state.state->size) { if (len < state.state->size) {
/* copy to input buffer, compress when full */ /* copy to input buffer, compress when full */
do { do {
unsigned have, copy; z_size_t have, copy;
if (strm->avail_in == 0) if (state.state->strm.avail_in == 0)
strm->next_in = state.state->in; state.state->strm.next_in = state.state->in;
have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in); have = (unsigned)((state.state->strm.next_in + state.state->strm.avail_in) -
state.state->in);
copy = state.state->size - have; copy = state.state->size - have;
if (copy > len) if (copy > len)
copy = len; copy = len;
memcpy(state.state->in + have, buf, copy); memcpy(state.state->in + have, buf, copy);
strm->avail_in += copy; state.state->strm.avail_in += copy;
state.state->x.pos += copy; state.state->x.pos += copy;
buf = (const char *)buf + copy; buf = (const char *)buf + copy;
len -= copy; len -= copy;
@ -229,19 +224,83 @@ int ZEXPORT gzwrite(file, buf, len)
} }
else { else {
/* consume whatever's left in the input buffer */ /* consume whatever's left in the input buffer */
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) if (state.state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
return 0; return 0;
/* directly compress user buffer to file */ /* directly compress user buffer to file */
strm->avail_in = len; state.state->strm.next_in = (z_const Bytef *)buf;
strm->next_in = (z_const Bytef *)buf; do {
state.state->x.pos += len; z_size_t n = (unsigned)-1;
if (gz_comp(state, Z_NO_FLUSH) == -1) if (n > len)
return 0; n = len;
state.state->strm.avail_in = (z_uInt)n;
state.state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return 0;
len -= n;
} while (len);
} }
/* input was all buffered or compressed (put will fit in int) */ /* input was all buffered or compressed */
return (int)put; 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.state->mode != GZ_WRITE || state.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.state->mode != GZ_WRITE || state.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;
}
/* write len bytes to buf, return the number of full items written */
return len ? gz_write(state, buf, len) / size : 0;
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
@ -271,7 +330,7 @@ int ZEXPORT gzputc(file, c)
return -1; return -1;
} }
/* try writing to input buffer for speed (state->size == 0 if buffer not /* try writing to input buffer for speed (state.state->size == 0 if buffer not
initialized) */ initialized) */
if (state.state->size) { if (state.state->size) {
if (strm->avail_in == 0) if (strm->avail_in == 0)
@ -287,7 +346,7 @@ int ZEXPORT gzputc(file, c)
/* no room in buffer or not initialized, use gz_write() */ /* no room in buffer or not initialized, use gz_write() */
buf[0] = (unsigned char)c; buf[0] = (unsigned char)c;
if (gzwrite(file, buf, 1) != 1) if (gz_write(state, buf, 1) != 1)
return -1; return -1;
return c & 0xff; return c & 0xff;
} }
@ -298,11 +357,21 @@ int ZEXPORT gzputs(file, str)
const char *str; const char *str;
{ {
int ret; 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.state->mode != GZ_WRITE || state.state->err != Z_OK)
return -1;
/* write string */ /* write string */
len = (unsigned)strlen(str); len = strlen(str);
ret = gzwrite(file, str, len); ret = (int)gz_write(state, str, len);
return ret == 0 && len != 0 ? -1 : ret; return ret == 0 && len != 0 ? -1 : ret;
} }
@ -312,63 +381,73 @@ int ZEXPORT gzputs(file, str)
/* -- see zlib.h -- */ /* -- see zlib.h -- */
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
{ {
int size, len; int len;
unsigned left;
char *next;
gz_statep state; gz_statep state;
z_streamp strm; z_streamp strm;
/* get internal structure */ /* get internal structure */
if (file == NULL) if (file == NULL)
return -1; return Z_STREAM_ERROR;
state = (gz_statep)file; state = (gz_statep)file;
strm = &(state.state->strm); strm = &(state.state->strm);
/* check that we're writing and that there's no error */ /* check that we're writing and that there's no error */
if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
return 0; return Z_STREAM_ERROR;
/* make sure we have some buffer space */ /* make sure we have some buffer space */
if (state.state->size == 0 && gz_init(state) == -1) if (state.state->size == 0 && gz_init(state) == -1)
return 0; return state.state->err;
/* check for seek request */ /* check for seek request */
if (state.state->seek) { if (state.state->seek) {
state.state->seek = 0; state.state->seek = 0;
if (gz_zero(state, state.state->skip) == -1) if (gz_zero(state, state.state->skip) == -1)
return 0; return state.state->err;
} }
/* consume whatever's left in the input buffer */ /* do the printf() into the input buffer, put length in len -- the input
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) buffer is double-sized just for this function, so there is guaranteed to
return 0; be state.state->size bytes available after the current contents */
if (strm->avail_in == 0)
/* do the printf() into the input buffer, put length in len */ strm->next_in = state.state->in;
size = (int)(state.state->size); next = (char *)(state.state->in + (strm->next_in - state.state->in) + strm->avail_in);
state.state->in[size - 1] = 0; next[state.state->size - 1] = 0;
#ifdef NO_vsnprintf #ifdef NO_vsnprintf
# ifdef HAS_vsprintf_void # ifdef HAS_vsprintf_void
(void)vsprintf((char *)(state.state->in), format, va); (void)vsprintf(next, format, va);
for (len = 0; len < size; len++) for (len = 0; len < state.state->size; len++)
if (state.state->in[len] == 0) break; if (next[len] == 0) break;
# else # else
len = vsprintf((char *)(state.state->in), format, va); len = vsprintf(next, format, va);
# endif # endif
#else #else
# ifdef HAS_vsnprintf_void # ifdef HAS_vsnprintf_void
(void)vsnprintf((char *)(state.state->in), size, format, va); (void)vsnprintf(next, state.state->size, format, va);
len = strlen((char *)(state.state->in)); len = strlen(next);
# else # else
len = vsnprintf((char *)(state.state->in), size, format, va); len = vsnprintf(next, state.state->size, format, va);
# endif # endif
#endif #endif
/* check that printf() results fit in buffer */ /* check that printf() results fit in buffer */
if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) if (len == 0 || (unsigned)len >= state.state->size || next[state.state->size - 1] != 0)
return 0; return 0;
/* update buffer and position, defer compression until needed */ /* update buffer and position, compress first half if past that */
strm->avail_in = (unsigned)len; strm->avail_in += (unsigned)len;
strm->next_in = state.state->in;
state.state->x.pos += len; state.state->x.pos += len;
if (strm->avail_in >= state.state->size) {
left = strm->avail_in - state.state->size;
strm->avail_in = state.state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state.state->err;
memcpy(state.state->in, state.state->in + state.state->size, left);
strm->next_in = state.state->in;
strm->avail_in = left;
}
return len; return len;
} }
@ -393,73 +472,82 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{ {
int size, len; unsigned len, left;
char *next;
gz_statep state; gz_statep state;
z_streamp strm; z_streamp strm;
/* get internal structure */ /* get internal structure */
if (file == NULL) if (file == NULL)
return -1; return Z_STREAM_ERROR;
state = (gz_statep)file; state = (gz_statep)file;
strm = &(state.state->strm); strm = &(state.state->strm);
/* check that can really pass pointer in ints */ /* check that can really pass pointer in ints */
if (sizeof(int) != sizeof(void *)) if (sizeof(int) != sizeof(void *))
return 0; return Z_STREAM_ERROR;
/* check that we're writing and that there's no error */ /* check that we're writing and that there's no error */
if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) if (state.state->mode != GZ_WRITE || state.state->err != Z_OK)
return 0; return Z_STREAM_ERROR;
/* make sure we have some buffer space */ /* make sure we have some buffer space */
if (state.state->size == 0 && gz_init(state) == -1) if (state.state->size == 0 && gz_init(state) == -1)
return 0; return state.state->error;
/* check for seek request */ /* check for seek request */
if (state.state->seek) { if (state.state->seek) {
state.state->seek = 0; state.state->seek = 0;
if (gz_zero(state, state.state->skip) == -1) if (gz_zero(state, state.state->skip) == -1)
return 0; return state.state->error;
} }
/* consume whatever's left in the input buffer */ /* do the printf() into the input buffer, put length in len -- the input
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) buffer is double-sized just for this function, so there is guaranteed to
return 0; be state.state->size bytes available after the current contents */
if (strm->avail_in == 0)
/* do the printf() into the input buffer, put length in len */ strm->next_in = state.state->in;
size = (int)(state.state->size); next = (char *)(strm->next_in + strm->avail_in);
state.state->in[size - 1] = 0; next[state.state->size - 1] = 0;
#ifdef NO_snprintf #ifdef NO_snprintf
# ifdef HAS_sprintf_void # ifdef HAS_sprintf_void
sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < size; len++) for (len = 0; len < size; len++)
if (state.state->in[len] == 0) break; if (next[len] == 0)
break;
# else # else
len = sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif # endif
#else #else
# ifdef HAS_snprintf_void # ifdef HAS_snprintf_void
snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, snprintf(next, state.state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
len = strlen((char *)(state.state->in)); len = strlen(next);
# else # else
len = snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, len = snprintf(next, state.state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
a19, a20);
# endif # endif
#endif #endif
/* check that printf() results fit in buffer */ /* check that printf() results fit in buffer */
if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) if (len == 0 || len >= state.state->size || next[state.state->size - 1] != 0)
return 0; return 0;
/* update buffer and position, defer compression until needed */ /* update buffer and position, compress first half if past that */
strm->avail_in = (unsigned)len; strm->avail_in += len;
strm->next_in = state.state->in;
state.state->x.pos += len; state.state->x.pos += len;
return len; if (strm->avail_in >= state.state->size) {
left = strm->avail_in - state.state->size;
strm->avail_in = state.state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state.state->err;
memcpy(state.state->in, state.state->in + state.state->size, left);
strm->next_in = state.state->in;
strm->avail_in = left;
}
return (int)len;
} }
#endif #endif
@ -473,7 +561,7 @@ int ZEXPORT gzflush(file, flush)
/* get internal structure */ /* get internal structure */
if (file == NULL) if (file == NULL)
return -1; return Z_STREAM_ERROR;
state = (gz_statep)file; state = (gz_statep)file;
/* check that we're writing and that there's no error */ /* check that we're writing and that there's no error */
@ -488,11 +576,11 @@ int ZEXPORT gzflush(file, flush)
if (state.state->seek) { if (state.state->seek) {
state.state->seek = 0; state.state->seek = 0;
if (gz_zero(state, state.state->skip) == -1) if (gz_zero(state, state.state->skip) == -1)
return -1; return state.state->err;
} }
/* compress remaining data with requested flush */ /* compress remaining data with requested flush */
gz_comp(state, flush); (void)gz_comp(state, flush);
return state.state->err; return state.state->err;
} }
@ -523,13 +611,13 @@ int ZEXPORT gzsetparams(file, level, strategy)
if (state.state->seek) { if (state.state->seek) {
state.state->seek = 0; state.state->seek = 0;
if (gz_zero(state, state.state->skip) == -1) if (gz_zero(state, state.state->skip) == -1)
return -1; return state.state->err;
} }
/* change compression parameters for subsequent input */ /* change compression parameters for subsequent input */
if (state.state->size) { if (state.state->size) {
/* flush previous input with previous parameters before changing */ /* flush previous input with previous parameters before changing */
if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
return state.state->err; return state.state->err;
deflateParams(strm, level, strategy); deflateParams(strm, level, strategy);
} }

View File

@ -1042,3 +1042,24 @@ ZEXTERN uLong ZEXPORT z_crc32 OF((uLong crc, const Bytef *buf, uInt len))
{ {
return crc32(crc, buf, len); return crc32(crc, buf, len);
} }
#if ZLIB_VERNUM >= 0x12B0
ZEXTERN uLong ZEXPORT z_adler32_z OF((uLong adler, const Bytef *buf, z_size_t len))
{
return adler32_z(adler, buf, len);
}
ZEXTERN uLong ZEXPORT z_crc32_z OF((uLong crc, const Bytef *buf, z_size_t len))
{
return crc32_z(crc, buf, len);
}
#endif
#if ZLIB_VERNUM >= 0x1270
ZEXTERN const z_crc_t FAR * ZEXPORT z_get_crc_table OF((void))
{
return get_crc_table();
}
#endif