From 3bf9a72d9567cb0b78fc786f40a4351ea19f558c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 24 Nov 2016 18:26:30 +0100 Subject: [PATCH 01/17] experimental support for gz* functions --- zlibWrapper/gzclose.c | 25 ++ zlibWrapper/gzguts.h | 209 +++++++++++ zlibWrapper/gzlib.c | 634 +++++++++++++++++++++++++++++++++ zlibWrapper/gzread.c | 596 +++++++++++++++++++++++++++++++ zlibWrapper/gzwrite.c | 577 ++++++++++++++++++++++++++++++ zlibWrapper/zstd_zlibwrapper.c | 230 +----------- 6 files changed, 2053 insertions(+), 218 deletions(-) create mode 100644 zlibWrapper/gzclose.c create mode 100644 zlibWrapper/gzguts.h create mode 100644 zlibWrapper/gzlib.c create mode 100644 zlibWrapper/gzread.c create mode 100644 zlibWrapper/gzwrite.c diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/zlibWrapper/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h new file mode 100644 index 000000000..da66159a3 --- /dev/null +++ b/zlibWrapper/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zstd_zlibwrapper.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c new file mode 100644 index 000000000..fae202ef8 --- /dev/null +++ b/zlibWrapper/gzlib.c @@ -0,0 +1,634 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + 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 error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + 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 + 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 + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c new file mode 100644 index 000000000..2d28122d8 --- /dev/null +++ b/zlibWrapper/gzread.c @@ -0,0 +1,596 @@ +/* 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 copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +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)); + +/* 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. + 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) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + 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 + 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 + 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 will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + 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) + || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { // zstd + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* 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 success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes 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 + 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 + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && 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 == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + 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->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + 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 */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + 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->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + 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->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* 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->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c new file mode 100644 index 000000000..aa767fbf6 --- /dev/null +++ b/zlibWrapper/gzwrite.c @@ -0,0 +1,577 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +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)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* 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. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned 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; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + 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->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (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; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + 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 -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + 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; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + 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 Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + 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 Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 326fea260..477c53b41 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -24,8 +24,8 @@ #define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min #define ZWRAP_DEFAULT_CLEVEL 3 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ -#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ #define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; } #define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; } @@ -81,6 +81,7 @@ typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t; typedef struct { ZSTD_CStream* zbc; int compressionLevel; + int streamEnd; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ ZSTD_inBuffer inBuffer; @@ -187,6 +188,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, if (level == Z_DEFAULT_COMPRESSION) level = ZWRAP_DEFAULT_CLEVEL; + zwc->streamEnd = 0; zwc->compressionLevel = level; strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ strm->total_in = 0; @@ -214,6 +216,10 @@ int ZWRAP_deflateReset_keepDict(z_streamp strm) if (!g_ZWRAP_useZSTDcompression) return deflateReset(strm); + { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc) zwc->streamEnd = 0; + } + strm->total_in = 0; strm->total_out = 0; strm->adler = 0; @@ -230,7 +236,7 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) ZWRAP_deflateReset_keepDict(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - if (zwc) zwc->comprState = 0; + if (zwc) zwc->comprState = ZWRAP_useInit; } return Z_OK; } @@ -319,6 +325,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (flush == Z_FINISH) { size_t bytesLeft; + if (zwc->streamEnd) return Z_STREAM_END; zwc->outBuffer.dst = strm->next_out; zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; @@ -328,7 +335,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; - if (bytesLeft == 0) { LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } + if (bytesLeft == 0) { zwc->streamEnd = 1; LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } } else if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) { @@ -519,6 +526,7 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, { int ret = z_inflateInit_ (strm, version, stream_size); + LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits); if (ret == Z_OK) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state; if (zwd == NULL) return Z_STREAM_ERROR; @@ -1015,220 +1023,6 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, return Z_OK; } - - - /* gzip file access functions */ -ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzopen(path, mode); - FINISH_WITH_NULL_ERR("gzopen is not supported!"); -} - - -ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzdopen(fd, mode); - FINISH_WITH_NULL_ERR("gzdopen is not supported!"); -} - - -#if ZLIB_VERNUM >= 0x1240 -ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzbuffer(file, size); - FINISH_WITH_GZ_ERR("gzbuffer is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzoffset(file); - FINISH_WITH_GZ_ERR("gzoffset is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose_r(file); - FINISH_WITH_GZ_ERR("gzclose_r is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose_w(file); - FINISH_WITH_GZ_ERR("gzclose_w is not supported!"); -} -#endif - - -ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzsetparams(file, level, strategy); - FINISH_WITH_GZ_ERR("gzsetparams is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzread(file, buf, len); - FINISH_WITH_GZ_ERR("gzread is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file, - voidpc buf, unsigned len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzwrite(file, buf, len); - FINISH_WITH_GZ_ERR("gzwrite is not supported!"); -} - - -#if ZLIB_VERNUM >= 0x1260 -ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...)) -#else -ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) -#endif -{ - if (!g_ZWRAP_useZSTDcompression) { - int ret; - char buf[1024]; - va_list args; - va_start (args, format); - ret = vsprintf (buf, format, args); - va_end (args); - - ret = gzprintf(file, buf); - return ret; - } - FINISH_WITH_GZ_ERR("gzprintf is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzputs(file, s); - FINISH_WITH_GZ_ERR("gzputs is not supported!"); -} - - -ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzgets(file, buf, len); - FINISH_WITH_NULL_ERR("gzgets is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzputc(file, c); - FINISH_WITH_GZ_ERR("gzputc is not supported!"); -} - - -#if ZLIB_VERNUM == 0x1260 -ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file)) -#else -ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) -#endif -{ - if (!g_ZWRAP_useZSTDcompression) - return gzgetc(file); - FINISH_WITH_GZ_ERR("gzgetc is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzungetc(c, file); - FINISH_WITH_GZ_ERR("gzungetc is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzflush(file, flush); - FINISH_WITH_GZ_ERR("gzflush is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzseek(file, offset, whence); - FINISH_WITH_GZ_ERR("gzseek is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzrewind(file); - FINISH_WITH_GZ_ERR("gzrewind is not supported!"); -} - - -ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gztell(file); - FINISH_WITH_GZ_ERR("gztell is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzeof(file); - FINISH_WITH_GZ_ERR("gzeof is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzdirect(file); - FINISH_WITH_GZ_ERR("gzdirect is not supported!"); -} - - -ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzclose(file); - FINISH_WITH_GZ_ERR("gzclose is not supported!"); -} - - -ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) -{ - if (!g_ZWRAP_useZSTDcompression) - return gzerror(file, errnum); - FINISH_WITH_NULL_ERR("gzerror is not supported!"); -} - - -ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file)) -{ - if (!g_ZWRAP_useZSTDcompression) - gzclearerr(file); -} - - #endif /* !Z_SOLO */ From 6b3c2018dbde85eed1c53e6484eddf2ced4dd2a8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Thu, 24 Nov 2016 18:26:47 +0100 Subject: [PATCH 02/17] added minigzip --- zlibWrapper/Makefile | 6 +- zlibWrapper/minigzip.c | 651 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 656 insertions(+), 1 deletion(-) create mode 100644 zlibWrapper/minigzip.c diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 2503f0d7f..b58552761 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -18,7 +18,8 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wstrict-aliasing=1 -Wundef +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef +#-Wstrict-aliasing=1 all: clean fitblk example zwrapbench @@ -49,6 +50,9 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench #.c.o: # $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< +minigzip: gzclose.c gzlib.c gzread.c gzwrite.c minigzip.c $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) diff --git a/zlibWrapper/minigzip.c b/zlibWrapper/minigzip.c new file mode 100644 index 000000000..e56d5e1d7 --- /dev/null +++ b/zlibWrapper/minigzip.c @@ -0,0 +1,651 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zstd_zlibwrapper.h" +#include + +#ifdef STDC +# include +# include +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# ifdef UNDER_CE +# include +# endif +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +# include /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(q, p) + void *q, *p; +{ + q = Z_NULL; + free(p); +} + +typedef struct gzFile_s { + FILE *file; + int write; + int err; + char *msg; + z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ + return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ + return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gzFile gz; + int ret; + + gz = malloc(sizeof(struct gzFile_s)); + if (gz == NULL) + return NULL; + gz->write = strchr(mode, 'w') != NULL; + gz->strm.zalloc = myalloc; + gz->strm.zfree = myfree; + gz->strm.opaque = Z_NULL; + if (gz->write) + ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); + else { + gz->strm.next_in = 0; + gz->strm.avail_in = Z_NULL; + ret = inflateInit2(&(gz->strm), 15 + 16); + } + if (ret != Z_OK) { + free(gz); + return NULL; + } + gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : + fopen(path, gz->write ? "wb" : "rb"); + if (gz->file == NULL) { + gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); + free(gz); + return NULL; + } + gz->err = 0; + gz->msg = ""; + return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) + gzFile gz; + const void *buf; + unsigned len; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL || !gz->write) + return 0; + strm = &(gz->strm); + strm->next_in = (void *)buf; + strm->avail_in = len; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_NO_FLUSH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) + gzFile gz; + void *buf; + unsigned len; +{ + int ret; + unsigned got; + unsigned char in[1]; + z_stream *strm; + + if (gz == NULL || gz->write) + return 0; + if (gz->err) + return 0; + strm = &(gz->strm); + strm->next_out = (void *)buf; + strm->avail_out = len; + do { + got = fread(in, 1, 1, gz->file); + if (got == 0) + break; + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gz->err = Z_DATA_ERROR; + gz->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) + gzFile gz; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL) + return Z_STREAM_ERROR; + strm = &(gz->strm); + if (gz->write) { + strm->next_in = Z_NULL; + strm->avail_in = 0; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_FINISH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + deflateEnd(strm); + } + else + inflateEnd(strm); + fclose(gz->file); + free(gz); + return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) + gzFile gz; + int *err; +{ + *err = gz->err; + return gz->msg; +} + +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); +#else + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); +#endif + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf, sizeof(buf), "%s", file); +#else + strcpy(buf, file); +#endif + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); +#else + strcat(infile, GZ_SUFFIX); +#endif + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -r : compress with Z_RLE + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int copyout = 0; + int uncompr = 0; + gzFile file; + char *bname, outmode[20]; + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outmode, sizeof(outmode), "%s", "wb6 "); +#else + strcpy(outmode, "wb6 "); +#endif + + prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; + argc--, argv++; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + while (argc > 0) { + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if (strcmp(*argv, "-r") == 0) + outmode[3] = 'R'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (outmode[3] == ' ') + outmode[3] = 0; + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } + } else { + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } + } + } while (argv++, --argc); + } + return 0; +} From 37a00f2ac7ddc12aa152acc93e4b27bd814b1f07 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 14:09:29 +0100 Subject: [PATCH 03/17] turn on test_gzio --- zlibWrapper/examples/example.c | 5 ++--- zlibWrapper/{ => examples}/minigzip.c | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename zlibWrapper/{ => examples}/minigzip.c (100%) diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index 20ed81d57..9483129d2 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -600,9 +600,8 @@ int main(argc, argv) #else test_compress(compr, comprLen, uncompr, uncomprLen); - if (!ZWRAP_isUsingZSTDcompression()) - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); #endif test_deflate(compr, comprLen); diff --git a/zlibWrapper/minigzip.c b/zlibWrapper/examples/minigzip.c similarity index 100% rename from zlibWrapper/minigzip.c rename to zlibWrapper/examples/minigzip.c From 96fca2bd2d7f713525d579149638c7fcbe1d3653 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 14:36:27 +0100 Subject: [PATCH 04/17] improved zwrapbench.c --- zlibWrapper/examples/zwrapbench.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index ebf76e48f..e0aca0015 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -239,11 +239,18 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize, do { U32 blockNb; + size_t rSize; for (blockNb=0; blockNb Date: Fri, 25 Nov 2016 14:45:55 +0100 Subject: [PATCH 05/17] added minigzip test --- zlibWrapper/Makefile | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index b58552761..ada7ab651 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -12,6 +12,7 @@ ZLIB_LIBRARY ?= -lz ZSTDLIBDIR = ../lib ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a ZLIBWRAPPER_PATH = . +GZFILES = gzclose.o gzlib.o gzread.o gzwrite.o EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md @@ -22,15 +23,27 @@ CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdecla #-Wstrict-aliasing=1 -all: clean fitblk example zwrapbench +# Define *.exe as extension for Windows systems +ifneq (,$(filter Windows%,$(OS))) +EXT =.exe +else +EXT = +endif -test: example fitblk example_zstd fitblk_zstd zwrapbench + +all: clean fitblk example zwrapbench minigzip + +test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./example ./example_zstd ./fitblk 10240 <$(TEST_FILE) ./fitblk 40960 <$(TEST_FILE) ./fitblk_zstd 10240 <$(TEST_FILE) ./fitblk_zstd 40960 <$(TEST_FILE) + @echo ---- minigzip start ---- + ./minigzip_zstd zwrapbench$(EXT) + ./minigzip_zstd -d zwrapbench$(EXT).gz + @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) ./zwrapbench -rqb1e5 ../lib ../programs ../tests @@ -50,25 +63,27 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench #.c.o: # $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -minigzip: gzclose.c gzlib.c gzread.c gzwrite.c minigzip.c $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +minigzip: $(EXAMPLE_PATH)/minigzip.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@ -example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +minigzip_zstd: $(EXAMPLE_PATH)/minigzip.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@ -example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ + +example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ -fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) +fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) + $(CC) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@ -$(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h $(CC) $(CFLAGS) $(CPPFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c @@ -82,6 +97,7 @@ $(ZSTDLIBDIR)/libzstd.a: $(ZSTDLIBDIR)/libzstd.so: $(MAKE) -C $(ZSTDLIBDIR) libzstd + clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench minigzip minigzip_zstd @echo Cleaning completed From a6417761972c80aea1fb5162b9405c3d94379dc0 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Fri, 25 Nov 2016 17:13:25 +0100 Subject: [PATCH 06/17] zlibWrapper: improve "make clean" --- zlibWrapper/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index ada7ab651..0c8db9c7a 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -19,7 +19,7 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef #-Wstrict-aliasing=1 @@ -99,5 +99,5 @@ $(ZSTDLIBDIR)/libzstd.so: clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench minigzip minigzip_zstd + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o foo.gz example$(EXT) example_zstd$(EXT) fitblk$(EXT) fitblk_zstd$(EXT) zwrapbench$(EXT) minigzip$(EXT) minigzip_zstd$(EXT) @echo Cleaning completed From edd3e2a83435b5e72a51d302aec95cf79d49e590 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 12:46:16 +0100 Subject: [PATCH 07/17] Z_TREES only with ZLIB_VERNUM >= 0x1240 --- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 5fefac1d3..cbf1b1b30 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -137,12 +137,12 @@ Supported methods: - compress2 - compressBound - uncompress +- gzip file access functions Ignored methods (they do nothing): - deflateParams Unsupported methods: -- gzip file access functions - deflateCopy - deflateTune - deflatePending diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 477c53b41..3b23358f3 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -321,7 +321,12 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->avail_in -= zwc->inBuffer.pos; } - if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); + if (flush == Z_FULL_FLUSH +#if ZLIB_VERNUM >= 0x1240 + || flush == Z_TREES +#endif + || flush == Z_BLOCK) + return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; From 91437d844d8408977e160f5a1e90348deb91e2d8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 13:25:42 +0100 Subject: [PATCH 08/17] added gzcompatibility.h --- zlibWrapper/gzcompatibility.h | 47 +++++++++++++++++++++++++++++++++++ zlibWrapper/gzguts.h | 1 + 2 files changed, 48 insertions(+) create mode 100644 zlibWrapper/gzcompatibility.h diff --git a/zlibWrapper/gzcompatibility.h b/zlibWrapper/gzcompatibility.h new file mode 100644 index 000000000..d6e83a737 --- /dev/null +++ b/zlibWrapper/gzcompatibility.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc. + * All rights reserved. + * + * 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 + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#if ZLIB_VERNUM == 0x1260 && !defined(_LARGEFILE64_SOURCE) + // #define _LARGEFILE64_SOURCE 0 +#endif + +#if ZLIB_VERNUM <= 0x1240 +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif +#endif + + +#if ZLIB_VERNUM <= 0x1250 +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +#endif + + +#if ZLIB_VERNUM <= 0x1270 +#if defined(_WIN32) && !defined(Z_SOLO) +# include /* for wchar_t */ +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#endif diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index da66159a3..c7ccc84a2 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -20,6 +20,7 @@ #include #include "zstd_zlibwrapper.h" +#include "gzcompatibility.h" #ifdef STDC # include # include From c77befef811040c126adf37b8e421e99f9a1a822 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 14:09:26 +0100 Subject: [PATCH 09/17] make gz* functions compatible with zlib 1.2.3+ --- zlibWrapper/gzcompatibility.h | 4 +--- zlibWrapper/gzread.c | 13 +++++++++++++ zlibWrapper/zstd_zlibwrapper.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/gzcompatibility.h b/zlibWrapper/gzcompatibility.h index d6e83a737..a4f275e11 100644 --- a/zlibWrapper/gzcompatibility.h +++ b/zlibWrapper/gzcompatibility.h @@ -7,9 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#if ZLIB_VERNUM == 0x1260 && !defined(_LARGEFILE64_SOURCE) - // #define _LARGEFILE64_SOURCE 0 -#endif + #if ZLIB_VERNUM <= 0x1240 ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index 2d28122d8..c982b1429 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -381,11 +381,24 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ +#if ZLIB_VERNUM >= 0x1261 #ifdef Z_PREFIX_SET # undef z_gzgetc #else # undef gzgetc #endif +#endif + +#if ZLIB_VERNUM == 0x1260 +# undef gzgetc +#endif + +#if ZLIB_VERNUM <= 0x1250 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); +#endif + + int ZEXPORT gzgetc(file) gzFile file; { diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 45d15bac0..382716921 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -17,6 +17,7 @@ extern "C" { #define ZLIB_CONST #define Z_PREFIX +#define ZLIB_INTERNAL /* disables gz*64 functions but fixes zlib 1.2.4 with Z_PREFIX */ #include #if !defined(z_const) From 8b3e2f1a0b41e783c4985903fa2b38e9da7a79dd Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 15:41:36 +0100 Subject: [PATCH 10/17] updated zlibWrapper/Makefile --- zlibWrapper/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 0c8db9c7a..c6f061756 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -6,7 +6,7 @@ # Paths to static and dynamic zlib and zstd libraries -# Use "make ZLIB_LIBRARY=path/to/zlib" to select a path to library +# Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.a" to select a path to library ZLIB_LIBRARY ?= -lz ZSTDLIBDIR = ../lib @@ -17,7 +17,7 @@ EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs TEST_FILE = ../doc/zstd_compression_format.md -CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) +CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef #-Wstrict-aliasing=1 @@ -41,8 +41,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./fitblk_zstd 10240 <$(TEST_FILE) ./fitblk_zstd 40960 <$(TEST_FILE) @echo ---- minigzip start ---- - ./minigzip_zstd zwrapbench$(EXT) - ./minigzip_zstd -d zwrapbench$(EXT).gz + ./minigzip_zstd example$(EXT) + ./minigzip_zstd -d example$(EXT).gz @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) ./zwrapbench -rqb1e5 ../lib ../programs ../tests From 0fa3447dee0319322cf5ebaa64e4321dd8887f92 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Mon, 28 Nov 2016 16:55:14 +0100 Subject: [PATCH 11/17] plainly marked altered files from zlib --- zlibWrapper/Makefile | 1 + zlibWrapper/examples/example.c | 11 +++++++---- zlibWrapper/examples/fitblk.c | 5 ++++- zlibWrapper/examples/minigzip.c | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index c6f061756..41b334d32 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -8,6 +8,7 @@ # Paths to static and dynamic zlib and zstd libraries # Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.a" to select a path to library ZLIB_LIBRARY ?= -lz +ZLIB_PATH ?= . ZSTDLIBDIR = ../lib ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index 9483129d2..9000f7a32 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -1,8 +1,11 @@ -/* example.c -- usage example of the zlib compression library - * the file contains minimal changes required to be compiled with zstd wrapper for zlib - */ +/* example.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - test_flush() and test_sync() use functions not supported by zlibWrapper + therefore they are disabled while zstd compression is turned on */ - /* +/* example.c -- usage example of the zlib compression library + */ +/* Copyright (c) 1995-2006, 2011 Jean-loup Gailly This software is provided 'as-is', without any express or implied diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index e3fda3c80..760e338a2 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -1,3 +1,7 @@ +/* fitblk.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - writing block to stdout was disabled */ + /* fitblk.c: example of fitting compressed output to a specified size Not copyrighted -- provided to the public domain Version 1.1 25 November 2004 Mark Adler */ @@ -54,7 +58,6 @@ #include #include #include -//#include "zlib.h" #include "zstd_zlibwrapper.h" #define LOG_FITBLK(...) /*printf(__VA_ARGS__)*/ diff --git a/zlibWrapper/examples/minigzip.c b/zlibWrapper/examples/minigzip.c index e56d5e1d7..0ddc93f25 100644 --- a/zlibWrapper/examples/minigzip.c +++ b/zlibWrapper/examples/minigzip.c @@ -1,3 +1,6 @@ +/* minigzip.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" */ + /* minigzip.c -- simulate gzip using the zlib compression library * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h From a1f60632cb29b407af70b88670c78109cf412355 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 15:50:28 +0100 Subject: [PATCH 12/17] gz_statep is union --- zlibWrapper/gzclose.c | 2 +- zlibWrapper/gzguts.h | 7 +- zlibWrapper/gzlib.c | 228 +++++++++++++++++++++--------------------- 3 files changed, 121 insertions(+), 116 deletions(-) diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c index caeb99a31..b75124762 100644 --- a/zlibWrapper/gzclose.c +++ b/zlibWrapper/gzclose.c @@ -18,7 +18,7 @@ int ZEXPORT gzclose(file) return Z_STREAM_ERROR; state = (gz_statep)file; - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); + return state.state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); #else return gzclose_r(file); #endif diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index c7ccc84a2..c4c74f1a1 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -191,7 +191,12 @@ typedef struct { /* zlib inflate or deflate stream */ z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; -typedef gz_state FAR *gz_statep; + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ +typedef union { + gz_state* state; + gzFile file; +} gz_statep; /* shared functions */ void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c index fae202ef8..e811313b5 100644 --- a/zlibWrapper/gzlib.c +++ b/zlibWrapper/gzlib.c @@ -75,16 +75,16 @@ char ZLIB_INTERNAL *gz_strwinerror (error) local void gz_reset(state) gz_statep state; { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ + state.state->x.have = 0; /* no output data available */ + if (state.state->mode == GZ_READ) { /* for reading ... */ + state.state->eof = 0; /* not at end of file */ + state.state->past = 0; /* have not read past end yet */ + state.state->how = LOOK; /* look for gzip header */ } - state->seek = 0; /* no seek request pending */ + state.state->seek = 0; /* no seek request pending */ gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ + state.state->x.pos = 0; /* no uncompressed data yet */ + state.state->strm.avail_in = 0; /* no input data yet */ } /* Open a gzip file either by name or file descriptor. */ @@ -108,36 +108,36 @@ local gzFile gz_open(path, fd, mode) return NULL; /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) + state = (gz_statep)(gz_state*)malloc(sizeof(gz_state)); + if (state.state == NULL) return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ + state.state->size = 0; /* no buffers allocated yet */ + state.state->want = GZBUFSIZE; /* requested buffer size */ + state.state->msg = NULL; /* no error message yet */ /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; + state.state->mode = GZ_NONE; + state.state->level = Z_DEFAULT_COMPRESSION; + state.state->strategy = Z_DEFAULT_STRATEGY; + state.state->direct = 0; while (*mode) { if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; + state.state->level = *mode - '0'; else switch (*mode) { case 'r': - state->mode = GZ_READ; + state.state->mode = GZ_READ; break; #ifndef NO_GZCOMPRESS case 'w': - state->mode = GZ_WRITE; + state.state->mode = GZ_WRITE; break; case 'a': - state->mode = GZ_APPEND; + state.state->mode = GZ_APPEND; break; #endif case '+': /* can't read and write at the same time */ - free(state); + free(state.state); return NULL; case 'b': /* ignore -- will request binary anyway */ break; @@ -152,19 +152,19 @@ local gzFile gz_open(path, fd, mode) break; #endif case 'f': - state->strategy = Z_FILTERED; + state.state->strategy = Z_FILTERED; break; case 'h': - state->strategy = Z_HUFFMAN_ONLY; + state.state->strategy = Z_HUFFMAN_ONLY; break; case 'R': - state->strategy = Z_RLE; + state.state->strategy = Z_RLE; break; case 'F': - state->strategy = Z_FIXED; + state.state->strategy = Z_FIXED; break; case 'T': - state->direct = 1; + state.state->direct = 1; break; default: /* could consider as an error, but just ignore */ ; @@ -173,18 +173,18 @@ local gzFile gz_open(path, fd, mode) } /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); + if (state.state->mode == GZ_NONE) { + free(state.state); return NULL; } /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); + if (state.state->mode == GZ_READ) { + if (state.state->direct) { + free(state.state); return NULL; } - state->direct = 1; /* for empty file */ + state.state->direct = 1; /* for empty file */ } /* save the path name for error messages */ @@ -197,23 +197,23 @@ local gzFile gz_open(path, fd, mode) else #endif len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); + state.state->path = (char *)malloc(len + 1); + if (state.state->path == NULL) { + free(state.state); return NULL; } #ifdef _WIN32 if (fd == -2) if (len) - wcstombs(state->path, path, len + 1); + wcstombs(state.state->path, path, len + 1); else - *(state->path) = 0; + *(state.state->path) = 0; else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); + snprintf(state.state->path, len + 1, "%s", (const char *)path); #else - strcpy(state->path, path); + strcpy(state.state->path, path); #endif /* compute the flags for open() */ @@ -227,41 +227,41 @@ local gzFile gz_open(path, fd, mode) #ifdef O_CLOEXEC (cloexec ? O_CLOEXEC : 0) | #endif - (state->mode == GZ_READ ? + (state.state->mode == GZ_READ ? O_RDONLY : (O_WRONLY | O_CREAT | #ifdef O_EXCL (exclusive ? O_EXCL : 0) | #endif - (state->mode == GZ_WRITE ? + (state.state->mode == GZ_WRITE ? O_TRUNC : O_APPEND))); /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( + state.state->fd = fd > -1 ? fd : ( #ifdef _WIN32 fd == -2 ? _wopen(path, oflag, 0666) : #endif open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); + if (state.state->fd == -1) { + free(state.state->path); + free(state.state); return NULL; } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ + if (state.state->mode == GZ_APPEND) + state.state->mode = GZ_WRITE; /* simplify later checks */ /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; + if (state.state->mode == GZ_READ) { + state.state->start = LSEEK(state.state->fd, 0, SEEK_CUR); + if (state.state->start == -1) state.state->start = 0; } /* initialize stream */ gz_reset(state); /* return stream */ - return (gzFile)state; + return (gzFile)state.file; } /* -- see zlib.h -- */ @@ -321,17 +321,17 @@ int ZEXPORT gzbuffer(file, size) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* make sure we haven't already allocated memory */ - if (state->size != 0) + if (state.state->size != 0) return -1; /* check and set requested size */ if (size < 2) size = 2; /* need two bytes to check magic header */ - state->want = size; + state.state->want = size; return 0; } @@ -347,12 +347,12 @@ int ZEXPORT gzrewind(file) state = (gz_statep)file; /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + if (LSEEK(state.state->fd, state.state->start, SEEK_SET) == -1) return -1; gz_reset(state); return 0; @@ -372,11 +372,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) + if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR) return -1; /* can only seek from start or relative to current position */ @@ -385,32 +385,32 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) /* normalize offset to a SEEK_CUR specification */ if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; + offset -= state.state->x.pos; + else if (state.state->seek) + offset += state.state->skip; + state.state->seek = 0; /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (state.state->mode == GZ_READ && state.state->how == COPY && + state.state->x.pos + offset >= 0) { + ret = LSEEK(state.state->fd, offset - state.state->x.have, SEEK_CUR); if (ret == -1) return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; + state.state->x.have = 0; + state.state->eof = 0; + state.state->past = 0; + state.state->seek = 0; gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; + state.state->strm.avail_in = 0; + state.state->x.pos += offset; + return state.state->x.pos; } /* calculate skip amount, rewinding if needed for back seek when reading */ if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ + if (state.state->mode != GZ_READ) /* writing -- can't go backwards */ return -1; - offset += state->x.pos; + offset += state.state->x.pos; if (offset < 0) /* before start of file! */ return -1; if (gzrewind(file) == -1) /* rewind, then skip to offset */ @@ -418,21 +418,21 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) } /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + if (state.state->mode == GZ_READ) { + n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > offset ? + (unsigned)offset : state.state->x.have; + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; offset -= n; } /* request skip (if not zero) */ if (offset) { - state->seek = 1; - state->skip = offset; + state.state->seek = 1; + state.state->skip = offset; } - return state->x.pos + offset; + return state.state->x.pos + offset; } /* -- see zlib.h -- */ @@ -457,11 +457,11 @@ z_off64_t ZEXPORT gztell64(file) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); + return state.state->x.pos + (state.state->seek ? state.state->skip : 0); } /* -- see zlib.h -- */ @@ -485,15 +485,15 @@ z_off64_t ZEXPORT gzoffset64(file) if (file == NULL) return -1; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return -1; /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); + offset = LSEEK(state.state->fd, 0, SEEK_CUR); if (offset == -1) return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ + if (state.state->mode == GZ_READ) /* reading */ + offset -= state.state->strm.avail_in; /* don't count buffered input */ return offset; } @@ -517,11 +517,11 @@ int ZEXPORT gzeof(file) if (file == NULL) return 0; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return 0; /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; + return state.state->mode == GZ_READ ? state.state->past : 0; } /* -- see zlib.h -- */ @@ -535,14 +535,14 @@ const char * ZEXPORT gzerror(file, errnum) if (file == NULL) return NULL; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return NULL; /* return error information */ if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); + *errnum = state.state->err; + return state.state->err == Z_MEM_ERROR ? "out of memory" : + (state.state->msg == NULL ? "" : state.state->msg); } /* -- see zlib.h -- */ @@ -555,13 +555,13 @@ void ZEXPORT gzclearerr(file) if (file == NULL) return; state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) + if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) return; /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; + if (state.state->mode == GZ_READ) { + state.state->eof = 0; + state.state->past = 0; } gz_error(state, Z_OK, NULL); } @@ -578,18 +578,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg) const char *msg; { /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; + if (state.state->msg != NULL) { + if (state.state->err != Z_MEM_ERROR) + free(state.state->msg); + state.state->msg = NULL; } /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; + state.state->x.have = 0; /* set error code, and if no message, then done */ - state->err = err; + state.state->err = err; if (msg == NULL) return; @@ -598,18 +598,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg) return; /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + if ((state.state->msg = (char *)malloc(strlen(state.state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; + state.state->err = Z_MEM_ERROR; return; } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); + snprintf(state.state->msg, strlen(state.state->path) + strlen(msg) + 3, + "%s%s%s", state.state->path, ": ", msg); #else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); + strcpy(state.state->msg, state.state->path); + strcat(state.state->msg, ": "); + strcat(state.state->msg, msg); #endif return; } From 0feb24a2fab3d63b97f69f84ffaa2c30da90714c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 16:05:52 +0100 Subject: [PATCH 13/17] gzread.c, gzwrite.c: gz_statep is union --- zlibWrapper/gzread.c | 258 +++++++++++++++++++++--------------------- zlibWrapper/gzwrite.c | 236 +++++++++++++++++++------------------- 2 files changed, 247 insertions(+), 247 deletions(-) diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index c982b1429..5bc0f6ff9 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -27,7 +27,7 @@ local int gz_load(state, buf, len, have) *have = 0; do { - ret = read(state->fd, buf + *have, len - *have); + ret = read(state.state->fd, buf + *have, len - *have); if (ret <= 0) break; *have += ret; @@ -37,7 +37,7 @@ local int gz_load(state, buf, len, have) return -1; } if (ret == 0) - state->eof = 1; + state.state->eof = 1; return 0; } @@ -52,24 +52,24 @@ local int gz_avail(state) gz_statep state; { unsigned got; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); - if (state->err != Z_OK && state->err != Z_BUF_ERROR) + if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR) return -1; - if (state->eof == 0) { + if (state.state->eof == 0) { if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; + unsigned char *p = state.state->in; unsigned const char *q = strm->next_in; unsigned n = strm->avail_in; do { *p++ = *q++; } while (--n); } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) + if (gz_load(state, state.state->in + strm->avail_in, + state.state->size - strm->avail_in, &got) == -1) return -1; strm->avail_in += got; - strm->next_in = state->in; + strm->next_in = state.state->in; } return 0; } @@ -86,33 +86,33 @@ local int gz_avail(state) local int gz_look(state) gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate read buffers and inflate memory */ - if (state->size == 0) { + if (state.state->size == 0) { /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); + 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); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } - state->size = state->want; + state.state->size = state.state->want; /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; + state.state->strm.zalloc = Z_NULL; + state.state->strm.zfree = Z_NULL; + state.state->strm.opaque = Z_NULL; + state.state->strm.avail_in = 0; + state.state->strm.next_in = Z_NULL; + if (inflateInit2(&(state.state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state.state->out); + free(state.state->in); + state.state->size = 0; gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } @@ -138,31 +138,31 @@ local int gz_look(state) ((strm->next_in[0] == 31 && strm->next_in[1] == 139) || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { // zstd inflateReset(strm); - state->how = GZIP; - state->direct = 0; + state.state->how = GZIP; + state.state->direct = 0; return 0; } /* no gzip header -- if we were decoding gzip before, then this is trailing garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { + if (state.state->direct == 0) { strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; + state.state->eof = 1; + state.state->x.have = 0; return 0; } /* doing raw i/o, copy any leftover input to output -- this assumes that the output buffer is larger than the input buffer, which also assures space for gzungetc() */ - state->x.next = state->out; + state.state->x.next = state.state->out; if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; + memcpy(state.state->x.next, strm->next_in, strm->avail_in); + state.state->x.have = strm->avail_in; strm->avail_in = 0; } - state->how = COPY; - state->direct = 1; + state.state->how = COPY; + state.state->direct = 1; return 0; } @@ -176,7 +176,7 @@ local int gz_decomp(state) { int ret = Z_OK; unsigned had; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* fill output buffer up to end of deflate stream */ had = strm->avail_out; @@ -208,12 +208,12 @@ local int gz_decomp(state) } while (strm->avail_out && ret != Z_STREAM_END); /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; + state.state->x.have = had - strm->avail_out; + state.state->x.next = strm->next_out - state.state->x.have; /* if the gzip stream completed successfully, look for another */ if (ret == Z_STREAM_END) - state->how = LOOK; + state.state->how = LOOK; /* good decompression */ return 0; @@ -228,29 +228,29 @@ local int gz_decomp(state) local int gz_fetch(state) gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); do { - switch(state->how) { + switch(state.state->how) { case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ if (gz_look(state) == -1) return -1; - if (state->how == LOOK) + if (state.state->how == LOOK) return 0; break; case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + if (gz_load(state, state.state->out, state.state->size << 1, &(state.state->x.have)) == -1) return -1; - state->x.next = state->out; + state.state->x.next = state.state->out; return 0; case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; + strm->avail_out = state.state->size << 1; + strm->next_out = state.state->out; if (gz_decomp(state) == -1) return -1; } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + } while (state.state->x.have == 0 && (!state.state->eof || strm->avail_in)); return 0; } @@ -264,17 +264,17 @@ local int gz_skip(state, len) /* skip over len bytes or reach end-of-file, whichever comes first */ while (len) /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + if (state.state->x.have) { + n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > len ? + (unsigned)len : state.state->x.have; + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; len -= n; } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) + else if (state.state->eof && state.state->strm.avail_in == 0) break; /* need more data to skip -- load up output buffer */ @@ -300,11 +300,11 @@ int ZEXPORT gzread(file, buf, len) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_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 @@ -319,9 +319,9 @@ int ZEXPORT gzread(file, buf, len) return 0; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return -1; } @@ -329,22 +329,22 @@ int ZEXPORT gzread(file, buf, len) got = 0; do { /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; + if (state.state->x.have) { + n = state.state->x.have > len ? len : 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->eof && strm->avail_in == 0) { - state->past = 1; /* tried to read past end */ + else if (state.state->eof && 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->how == LOOK || len < (state->size << 1)) { + else if (state.state->how == LOOK || len < (state.state->size << 1)) { /* get more output, looking for header if required */ if (gz_fetch(state) == -1) return -1; @@ -354,7 +354,7 @@ int ZEXPORT gzread(file, buf, len) } /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ + else if (state.state->how == COPY) { /* read directly */ if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } @@ -365,15 +365,15 @@ int ZEXPORT gzread(file, buf, len) strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; - n = state->x.have; - state->x.have = 0; + n = state.state->x.have; + state.state->x.have = 0; } /* update progress */ len -= n; buf = (char *)buf + n; got += n; - state->x.pos += n; + state.state->x.pos += n; } while (len); /* return number of bytes read into user buffer (will fit in int) */ @@ -412,15 +412,15 @@ int ZEXPORT gzgetc(file) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; + if (state.state->x.have) { + state.state->x.have--; + state.state->x.pos++; + return *(state.state->x.next)++; } /* nothing there -- try gzread() */ @@ -447,14 +447,14 @@ int ZEXPORT gzungetc(c, file) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return -1; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return -1; } @@ -463,34 +463,34 @@ int ZEXPORT gzungetc(c, file) return -1; /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; + if (state.state->x.have == 0) { + state.state->x.have = 1; + state.state->x.next = state.state->out + (state.state->size << 1) - 1; + state.state->x.next[0] = c; + state.state->x.pos--; + state.state->past = 0; return c; } /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { + if (state.state->x.have == (state.state->size << 1)) { gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) + if (state.state->x.next == state.state->out) { + unsigned char *src = state.state->out + state.state->x.have; + unsigned char *dest = state.state->out + (state.state->size << 1); + while (src > state.state->out) *--dest = *--src; - state->x.next = dest; + state.state->x.next = dest; } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; + state.state->x.have++; + state.state->x.next--; + state.state->x.next[0] = c; + state.state->x.pos--; + state.state->past = 0; return c; } @@ -511,14 +511,14 @@ char * ZEXPORT gzgets(file, buf, len) state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) + if (state.state->mode != GZ_READ || + (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) return NULL; /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_skip(state, state.state->skip) == -1) return NULL; } @@ -529,24 +529,24 @@ char * ZEXPORT gzgets(file, buf, len) left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) + if (state.state->x.have == 0 && gz_fetch(state) == -1) return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ + if (state.state->x.have == 0) { /* end of file */ + state.state->past = 1; /* read past end */ break; /* return what we have */ } /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); + n = state.state->x.have > left ? left : state.state->x.have; + eol = (unsigned char *)memchr(state.state->x.next, '\n', n); if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; + n = (unsigned)(eol - state.state->x.next) + 1; /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; + memcpy(buf, state.state->x.next, n); + state.state->x.have -= n; + state.state->x.next += n; + state.state->x.pos += n; left -= n; buf += n; } while (left && eol == NULL); @@ -571,11 +571,11 @@ int ZEXPORT gzdirect(file) /* 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->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + if (state.state->mode == GZ_READ && state.state->how == LOOK && state.state->x.have == 0) (void)gz_look(state); /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; + return state.state->direct; } /* -- see zlib.h -- */ @@ -591,19 +591,19 @@ int ZEXPORT gzclose_r(file) state = (gz_statep)file; /* check that we're reading */ - if (state->mode != GZ_READ) + if (state.state->mode != GZ_READ) return Z_STREAM_ERROR; /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); + if (state.state->size) { + inflateEnd(&(state.state->strm)); + free(state.state->out); + free(state.state->in); } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + err = state.state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); + free(state.state->path); + ret = close(state.state->fd); + free(state.state); return ret ? Z_ERRNO : err; } diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c index aa767fbf6..7d4a614f2 100644 --- a/zlibWrapper/gzwrite.c +++ b/zlibWrapper/gzwrite.c @@ -16,21 +16,21 @@ local int gz_init(state) gz_statep state; { int ret; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate input buffer */ - state->in = (unsigned char *)malloc(state->want); - if (state->in == NULL) { + state.state->in = (unsigned char *)malloc(state.state->want); + if (state.state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } /* only need output buffer and deflate state if compressing */ - if (!state->direct) { + if (!state.state->direct) { /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); + state.state->out = (unsigned char *)malloc(state.state->want); + if (state.state->out == NULL) { + free(state.state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } @@ -39,24 +39,24 @@ local int gz_init(state) strm->zalloc = Z_NULL; strm->zfree = Z_NULL; strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + ret = deflateInit2(strm, state.state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state.state->strategy); if (ret != Z_OK) { - free(state->out); - free(state->in); + free(state.state->out); + free(state.state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } } /* mark state as initialized */ - state->size = state->want; + state.state->size = state.state->want; /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; + if (!state.state->direct) { + strm->avail_out = state.state->size; + strm->next_out = state.state->out; + state.state->x.next = strm->next_out; } return 0; } @@ -73,15 +73,15 @@ local int gz_comp(state, flush) { int ret, got; unsigned have; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return -1; /* write directly if requested */ - if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); + if (state.state->direct) { + got = write(state.state->fd, strm->next_in, strm->avail_in); if (got < 0 || (unsigned)got != strm->avail_in) { gz_error(state, Z_ERRNO, zstrerror()); return -1; @@ -97,17 +97,17 @@ local int gz_comp(state, flush) doing Z_FINISH then don't write until we get to Z_STREAM_END */ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + have = (unsigned)(strm->next_out - state.state->x.next); + if (have && ((got = write(state.state->fd, state.state->x.next, have)) < 0 || (unsigned)got != have)) { gz_error(state, Z_ERRNO, zstrerror()); return -1; } if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; + strm->avail_out = state.state->size; + strm->next_out = state.state->out; } - state->x.next = strm->next_out; + state.state->x.next = strm->next_out; } /* compress */ @@ -136,7 +136,7 @@ local int gz_zero(state, len) { int first; unsigned n; - z_streamp strm = &(state->strm); + z_streamp strm = &(state.state->strm); /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) @@ -145,15 +145,15 @@ local int gz_zero(state, len) /* compress len zeros (len guaranteed > 0) */ first = 1; while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; + n = GT_OFF(state.state->size) || (z_off64_t)state.state->size > len ? + (unsigned)len : state.state->size; if (first) { - memset(state->in, 0, n); + memset(state.state->in, 0, n); first = 0; } strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; + strm->next_in = state.state->in; + state.state->x.pos += n; if (gz_comp(state, Z_NO_FLUSH) == -1) return -1; len -= n; @@ -175,10 +175,10 @@ int ZEXPORT gzwrite(file, buf, len) if (file == NULL) return 0; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + 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 @@ -193,31 +193,31 @@ int ZEXPORT gzwrite(file, buf, len) return 0; /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { + if (len < state.state->size) { /* copy to input buffer, compress when full */ do { unsigned have, copy; if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - copy = state->size - have; + strm->next_in = state.state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in); + copy = state.state->size - have; if (copy > len) copy = len; - memcpy(state->in + have, buf, copy); + memcpy(state.state->in + have, buf, copy); strm->avail_in += copy; - state->x.pos += copy; + state.state->x.pos += copy; buf = (const char *)buf + copy; len -= copy; if (len && gz_comp(state, Z_NO_FLUSH) == -1) @@ -232,7 +232,7 @@ int ZEXPORT gzwrite(file, buf, len) /* directly compress user buffer to file */ strm->avail_in = len; strm->next_in = (z_const Bytef *)buf; - state->x.pos += len; + state.state->x.pos += len; if (gz_comp(state, Z_NO_FLUSH) == -1) return 0; } @@ -255,29 +255,29 @@ int ZEXPORT gzputc(file, c) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return -1; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ - if (state->size) { + if (state.state->size) { if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = c; + strm->next_in = state.state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state.state->in); + if (have < state.state->size) { + state.state->in[have] = c; strm->avail_in++; - state->x.pos++; + state.state->x.pos++; return c & 0xff; } } @@ -317,20 +317,20 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return 0; /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } @@ -339,33 +339,33 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) return 0; /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + size = (int)(state.state->size); + state.state->in[size - 1] = 0; #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void - (void)vsprintf((char *)(state->in), format, va); + (void)vsprintf((char *)(state.state->in), format, va); for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + if (state.state->in[len] == 0) break; # else - len = vsprintf((char *)(state->in), format, va); + len = vsprintf((char *)(state.state->in), format, va); # endif #else # ifdef HAS_vsnprintf_void - (void)vsnprintf((char *)(state->in), size, format, va); - len = strlen((char *)(state->in)); + (void)vsnprintf((char *)(state.state->in), size, format, va); + len = strlen((char *)(state.state->in)); # else - len = vsnprintf((char *)(state->in), size, format, va); + len = vsnprintf((char *)(state.state->in), size, format, va); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; + strm->next_in = state.state->in; + state.state->x.pos += len; return len; } @@ -398,24 +398,24 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, if (file == NULL) return -1; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that can really pass pointer in ints */ if (sizeof(int) != sizeof(void *)) return 0; /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return 0; /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) + if (state.state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return 0; } @@ -424,38 +424,38 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, return 0; /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + size = (int)(state.state->size); + state.state->in[size - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void - sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < size; len++) - if (state->in[len] == 0) break; + if (state.state->in[len] == 0) break; # else - len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + len = sprintf((char *)(state.state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void - snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen((char *)(state->in)); + len = strlen((char *)(state.state->in)); # else - len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + len = snprintf((char *)(state.state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #endif /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + if (len <= 0 || len >= (int)size || state.state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; + strm->next_in = state.state->in; + state.state->x.pos += len; return len; } @@ -474,7 +474,7 @@ int ZEXPORT gzflush(file, flush) state = (gz_statep)file; /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return Z_STREAM_ERROR; /* check flush parameter */ @@ -482,15 +482,15 @@ int ZEXPORT gzflush(file, flush) return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* compress remaining data with requested flush */ gz_comp(state, flush); - return state->err; + return state.state->err; } /* -- see zlib.h -- */ @@ -506,32 +506,32 @@ int ZEXPORT gzsetparams(file, level, strategy) if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; - strm = &(state->strm); + strm = &(state.state->strm); /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) + if (state.state->mode != GZ_WRITE || state.state->err != Z_OK) return Z_STREAM_ERROR; /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) + if (level == state.state->level && strategy == state.state->strategy) return Z_OK; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) return -1; } /* change compression parameters for subsequent input */ - if (state->size) { + if (state.state->size) { /* flush previous input with previous parameters before changing */ if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; + return state.state->err; deflateParams(strm, level, strategy); } - state->level = level; - state->strategy = strategy; + state.state->level = level; + state.state->strategy = strategy; return Z_OK; } @@ -548,30 +548,30 @@ int ZEXPORT gzclose_w(file) state = (gz_statep)file; /* check that we're writing */ - if (state->mode != GZ_WRITE) + if (state.state->mode != GZ_WRITE) return Z_STREAM_ERROR; /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; + if (state.state->seek) { + state.state->seek = 0; + if (gz_zero(state, state.state->skip) == -1) + ret = state.state->err; } /* flush, free memory, and close file */ if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); + ret = state.state->err; + if (state.state->size) { + if (!state.state->direct) { + (void)deflateEnd(&(state.state->strm)); + free(state.state->out); } - free(state->in); + free(state.state->in); } gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) + free(state.state->path); + if (close(state.state->fd) == -1) ret = Z_ERRNO; - free(state); + free(state.state); return ret; } From 087bd2c1988f6f33a23d70ee43202018aa41b32b Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 17:57:00 +0100 Subject: [PATCH 14/17] compile with -Wstrict-aliasing=1 --- zlibWrapper/Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 41b334d32..49d44e35a 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -20,8 +20,7 @@ TEST_FILE = ../doc/zstd_compression_format.md CPPFLAGS = -DXXH_NAMESPACE=XXH_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) CFLAGS ?= $(MOREFLAGS) -O3 -std=gnu99 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -#-Wstrict-aliasing=1 +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -Wstrict-aliasing=1 # Define *.exe as extension for Windows systems @@ -34,7 +33,7 @@ endif all: clean fitblk example zwrapbench minigzip -test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd +test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip minigzip_zstd ./example ./example_zstd ./fitblk 10240 <$(TEST_FILE) @@ -43,6 +42,10 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip_zstd ./fitblk_zstd 40960 <$(TEST_FILE) @echo ---- minigzip start ---- ./minigzip_zstd example$(EXT) + cp example$(EXT).gz example$(EXT)_zstd.gz + ./minigzip_zstd -d example$(EXT).gz + ./minigzip example$(EXT) + cp example$(EXT).gz example$(EXT)_gz.gz ./minigzip_zstd -d example$(EXT).gz @echo ---- minigzip end ---- ./zwrapbench -qb3B1K $(TEST_FILE) From f0d7da79dea23443fd86cf3d51b392b342b4c2e5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 18:02:34 +0100 Subject: [PATCH 15/17] updated headers in gz* files --- zlibWrapper/gzclose.c | 3 +++ zlibWrapper/gzguts.h | 4 ++++ zlibWrapper/gzlib.c | 3 +++ zlibWrapper/gzread.c | 3 +++ zlibWrapper/gzwrite.c | 3 +++ 5 files changed, 16 insertions(+) diff --git a/zlibWrapper/gzclose.c b/zlibWrapper/gzclose.c index b75124762..b5b7480c3 100644 --- a/zlibWrapper/gzclose.c +++ b/zlibWrapper/gzclose.c @@ -1,3 +1,6 @@ +/* gzclose.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzclose.c -- zlib gzclose() function * Copyright (C) 2004, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index c4c74f1a1..3d8d7e76a 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -1,3 +1,7 @@ +/* gzguts.h contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h" + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzguts.h -- zlib internal header definitions for gz* operations * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzlib.c b/zlibWrapper/gzlib.c index e811313b5..172041df5 100644 --- a/zlibWrapper/gzlib.c +++ b/zlibWrapper/gzlib.c @@ -1,3 +1,6 @@ +/* gzlib.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzlib.c -- zlib functions common to reading and writing gzip files * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/zlibWrapper/gzread.c b/zlibWrapper/gzread.c index 5bc0f6ff9..ad33ebc62 100644 --- a/zlibWrapper/gzread.c +++ b/zlibWrapper/gzread.c @@ -1,3 +1,6 @@ +/* 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 copyright notice in zlib.h diff --git a/zlibWrapper/gzwrite.c b/zlibWrapper/gzwrite.c index 7d4a614f2..d1478d3c1 100644 --- a/zlibWrapper/gzwrite.c +++ b/zlibWrapper/gzwrite.c @@ -1,3 +1,6 @@ +/* gzwrite.c contains minimal changes required to be compiled with zlibWrapper: + * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */ + /* gzwrite.c -- zlib functions for writing gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h From adf215e6e3386be49de16471a1dfd8624359311c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Tue, 29 Nov 2016 20:32:42 +0100 Subject: [PATCH 16/17] fixed Travis warnings --- zlibWrapper/gzguts.h | 1 - 1 file changed, 1 deletion(-) diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index 3d8d7e76a..5ec33a5b8 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -196,7 +196,6 @@ typedef struct { z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ typedef union { gz_state* state; gzFile file; From 45f7e00197697c1d23aa355a87f6011125b6ee7c Mon Sep 17 00:00:00 2001 From: Przemyslaw Skibinski Date: Wed, 30 Nov 2016 08:02:58 +0100 Subject: [PATCH 17/17] gz_state FAR *state --- zlibWrapper/gzguts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zlibWrapper/gzguts.h b/zlibWrapper/gzguts.h index 5ec33a5b8..e2538df15 100644 --- a/zlibWrapper/gzguts.h +++ b/zlibWrapper/gzguts.h @@ -197,7 +197,7 @@ typedef struct { } gz_state; typedef union { - gz_state* state; + gz_state FAR *state; gzFile file; } gz_statep;