gz_statep is union

This commit is contained in:
Przemyslaw Skibinski 2016-11-29 15:50:28 +01:00
parent 0fa3447dee
commit a1f60632cb
3 changed files with 121 additions and 116 deletions

View File

@ -18,7 +18,7 @@ int ZEXPORT gzclose(file)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
state = (gz_statep)file; 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 #else
return gzclose_r(file); return gzclose_r(file);
#endif #endif

View File

@ -191,7 +191,12 @@ typedef struct {
/* zlib inflate or deflate stream */ /* zlib inflate or deflate stream */
z_stream strm; /* stream structure in-place (not a pointer) */ z_stream strm; /* stream structure in-place (not a pointer) */
} gz_state; } 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 */ /* shared functions */
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));

View File

@ -75,16 +75,16 @@ char ZLIB_INTERNAL *gz_strwinerror (error)
local void gz_reset(state) local void gz_reset(state)
gz_statep state; gz_statep state;
{ {
state->x.have = 0; /* no output data available */ state.state->x.have = 0; /* no output data available */
if (state->mode == GZ_READ) { /* for reading ... */ if (state.state->mode == GZ_READ) { /* for reading ... */
state->eof = 0; /* not at end of file */ state.state->eof = 0; /* not at end of file */
state->past = 0; /* have not read past end yet */ state.state->past = 0; /* have not read past end yet */
state->how = LOOK; /* look for gzip header */ 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 */ gz_error(state, Z_OK, NULL); /* clear error */
state->x.pos = 0; /* no uncompressed data yet */ state.state->x.pos = 0; /* no uncompressed data yet */
state->strm.avail_in = 0; /* no input data yet */ state.state->strm.avail_in = 0; /* no input data yet */
} }
/* Open a gzip file either by name or file descriptor. */ /* Open a gzip file either by name or file descriptor. */
@ -108,36 +108,36 @@ local gzFile gz_open(path, fd, mode)
return NULL; return NULL;
/* allocate gzFile structure to return */ /* allocate gzFile structure to return */
state = (gz_statep)malloc(sizeof(gz_state)); state = (gz_statep)(gz_state*)malloc(sizeof(gz_state));
if (state == NULL) if (state.state == NULL)
return NULL; return NULL;
state->size = 0; /* no buffers allocated yet */ state.state->size = 0; /* no buffers allocated yet */
state->want = GZBUFSIZE; /* requested buffer size */ state.state->want = GZBUFSIZE; /* requested buffer size */
state->msg = NULL; /* no error message yet */ state.state->msg = NULL; /* no error message yet */
/* interpret mode */ /* interpret mode */
state->mode = GZ_NONE; state.state->mode = GZ_NONE;
state->level = Z_DEFAULT_COMPRESSION; state.state->level = Z_DEFAULT_COMPRESSION;
state->strategy = Z_DEFAULT_STRATEGY; state.state->strategy = Z_DEFAULT_STRATEGY;
state->direct = 0; state.state->direct = 0;
while (*mode) { while (*mode) {
if (*mode >= '0' && *mode <= '9') if (*mode >= '0' && *mode <= '9')
state->level = *mode - '0'; state.state->level = *mode - '0';
else else
switch (*mode) { switch (*mode) {
case 'r': case 'r':
state->mode = GZ_READ; state.state->mode = GZ_READ;
break; break;
#ifndef NO_GZCOMPRESS #ifndef NO_GZCOMPRESS
case 'w': case 'w':
state->mode = GZ_WRITE; state.state->mode = GZ_WRITE;
break; break;
case 'a': case 'a':
state->mode = GZ_APPEND; state.state->mode = GZ_APPEND;
break; break;
#endif #endif
case '+': /* can't read and write at the same time */ case '+': /* can't read and write at the same time */
free(state); free(state.state);
return NULL; return NULL;
case 'b': /* ignore -- will request binary anyway */ case 'b': /* ignore -- will request binary anyway */
break; break;
@ -152,19 +152,19 @@ local gzFile gz_open(path, fd, mode)
break; break;
#endif #endif
case 'f': case 'f':
state->strategy = Z_FILTERED; state.state->strategy = Z_FILTERED;
break; break;
case 'h': case 'h':
state->strategy = Z_HUFFMAN_ONLY; state.state->strategy = Z_HUFFMAN_ONLY;
break; break;
case 'R': case 'R':
state->strategy = Z_RLE; state.state->strategy = Z_RLE;
break; break;
case 'F': case 'F':
state->strategy = Z_FIXED; state.state->strategy = Z_FIXED;
break; break;
case 'T': case 'T':
state->direct = 1; state.state->direct = 1;
break; break;
default: /* could consider as an error, but just ignore */ 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" */ /* must provide an "r", "w", or "a" */
if (state->mode == GZ_NONE) { if (state.state->mode == GZ_NONE) {
free(state); free(state.state);
return NULL; return NULL;
} }
/* can't force transparent read */ /* can't force transparent read */
if (state->mode == GZ_READ) { if (state.state->mode == GZ_READ) {
if (state->direct) { if (state.state->direct) {
free(state); free(state.state);
return NULL; return NULL;
} }
state->direct = 1; /* for empty file */ state.state->direct = 1; /* for empty file */
} }
/* save the path name for error messages */ /* save the path name for error messages */
@ -197,23 +197,23 @@ local gzFile gz_open(path, fd, mode)
else else
#endif #endif
len = strlen((const char *)path); len = strlen((const char *)path);
state->path = (char *)malloc(len + 1); state.state->path = (char *)malloc(len + 1);
if (state->path == NULL) { if (state.state->path == NULL) {
free(state); free(state.state);
return NULL; return NULL;
} }
#ifdef _WIN32 #ifdef _WIN32
if (fd == -2) if (fd == -2)
if (len) if (len)
wcstombs(state->path, path, len + 1); wcstombs(state.state->path, path, len + 1);
else else
*(state->path) = 0; *(state.state->path) = 0;
else else
#endif #endif
#if !defined(NO_snprintf) && !defined(NO_vsnprintf) #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 #else
strcpy(state->path, path); strcpy(state.state->path, path);
#endif #endif
/* compute the flags for open() */ /* compute the flags for open() */
@ -227,41 +227,41 @@ local gzFile gz_open(path, fd, mode)
#ifdef O_CLOEXEC #ifdef O_CLOEXEC
(cloexec ? O_CLOEXEC : 0) | (cloexec ? O_CLOEXEC : 0) |
#endif #endif
(state->mode == GZ_READ ? (state.state->mode == GZ_READ ?
O_RDONLY : O_RDONLY :
(O_WRONLY | O_CREAT | (O_WRONLY | O_CREAT |
#ifdef O_EXCL #ifdef O_EXCL
(exclusive ? O_EXCL : 0) | (exclusive ? O_EXCL : 0) |
#endif #endif
(state->mode == GZ_WRITE ? (state.state->mode == GZ_WRITE ?
O_TRUNC : O_TRUNC :
O_APPEND))); O_APPEND)));
/* open the file with the appropriate flags (or just use fd) */ /* open the file with the appropriate flags (or just use fd) */
state->fd = fd > -1 ? fd : ( state.state->fd = fd > -1 ? fd : (
#ifdef _WIN32 #ifdef _WIN32
fd == -2 ? _wopen(path, oflag, 0666) : fd == -2 ? _wopen(path, oflag, 0666) :
#endif #endif
open((const char *)path, oflag, 0666)); open((const char *)path, oflag, 0666));
if (state->fd == -1) { if (state.state->fd == -1) {
free(state->path); free(state.state->path);
free(state); free(state.state);
return NULL; return NULL;
} }
if (state->mode == GZ_APPEND) if (state.state->mode == GZ_APPEND)
state->mode = GZ_WRITE; /* simplify later checks */ state.state->mode = GZ_WRITE; /* simplify later checks */
/* save the current position for rewinding (only if reading) */ /* save the current position for rewinding (only if reading) */
if (state->mode == GZ_READ) { if (state.state->mode == GZ_READ) {
state->start = LSEEK(state->fd, 0, SEEK_CUR); state.state->start = LSEEK(state.state->fd, 0, SEEK_CUR);
if (state->start == -1) state->start = 0; if (state.state->start == -1) state.state->start = 0;
} }
/* initialize stream */ /* initialize stream */
gz_reset(state); gz_reset(state);
/* return stream */ /* return stream */
return (gzFile)state; return (gzFile)state.file;
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
@ -321,17 +321,17 @@ int ZEXPORT gzbuffer(file, size)
if (file == NULL) if (file == NULL)
return -1; return -1;
state = (gz_statep)file; 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 -1;
/* make sure we haven't already allocated memory */ /* make sure we haven't already allocated memory */
if (state->size != 0) if (state.state->size != 0)
return -1; return -1;
/* check and set requested size */ /* check and set requested size */
if (size < 2) if (size < 2)
size = 2; /* need two bytes to check magic header */ size = 2; /* need two bytes to check magic header */
state->want = size; state.state->want = size;
return 0; return 0;
} }
@ -347,12 +347,12 @@ int ZEXPORT gzrewind(file)
state = (gz_statep)file; state = (gz_statep)file;
/* check that we're reading and that there's no error */ /* check that we're reading and that there's no error */
if (state->mode != GZ_READ || if (state.state->mode != GZ_READ ||
(state->err != Z_OK && state->err != Z_BUF_ERROR)) (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
return -1; return -1;
/* back up and start over */ /* 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; return -1;
gz_reset(state); gz_reset(state);
return 0; return 0;
@ -372,11 +372,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
if (file == NULL) if (file == NULL)
return -1; return -1;
state = (gz_statep)file; 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 -1;
/* check that there's no error */ /* 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; return -1;
/* can only seek from start or relative to current position */ /* 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 */ /* normalize offset to a SEEK_CUR specification */
if (whence == SEEK_SET) if (whence == SEEK_SET)
offset -= state->x.pos; offset -= state.state->x.pos;
else if (state->seek) else if (state.state->seek)
offset += state->skip; offset += state.state->skip;
state->seek = 0; state.state->seek = 0;
/* if within raw area while reading, just go there */ /* if within raw area while reading, just go there */
if (state->mode == GZ_READ && state->how == COPY && if (state.state->mode == GZ_READ && state.state->how == COPY &&
state->x.pos + offset >= 0) { state.state->x.pos + offset >= 0) {
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); ret = LSEEK(state.state->fd, offset - state.state->x.have, SEEK_CUR);
if (ret == -1) if (ret == -1)
return -1; return -1;
state->x.have = 0; state.state->x.have = 0;
state->eof = 0; state.state->eof = 0;
state->past = 0; state.state->past = 0;
state->seek = 0; state.state->seek = 0;
gz_error(state, Z_OK, NULL); gz_error(state, Z_OK, NULL);
state->strm.avail_in = 0; state.state->strm.avail_in = 0;
state->x.pos += offset; state.state->x.pos += offset;
return state->x.pos; return state.state->x.pos;
} }
/* calculate skip amount, rewinding if needed for back seek when reading */ /* calculate skip amount, rewinding if needed for back seek when reading */
if (offset < 0) { 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; return -1;
offset += state->x.pos; offset += state.state->x.pos;
if (offset < 0) /* before start of file! */ if (offset < 0) /* before start of file! */
return -1; return -1;
if (gzrewind(file) == -1) /* rewind, then skip to offset */ 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 reading, skip what's in output buffer (one less gzgetc() check) */
if (state->mode == GZ_READ) { if (state.state->mode == GZ_READ) {
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > offset ?
(unsigned)offset : state->x.have; (unsigned)offset : state.state->x.have;
state->x.have -= n; state.state->x.have -= n;
state->x.next += n; state.state->x.next += n;
state->x.pos += n; state.state->x.pos += n;
offset -= n; offset -= n;
} }
/* request skip (if not zero) */ /* request skip (if not zero) */
if (offset) { if (offset) {
state->seek = 1; state.state->seek = 1;
state->skip = offset; state.state->skip = offset;
} }
return state->x.pos + offset; return state.state->x.pos + offset;
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
@ -457,11 +457,11 @@ z_off64_t ZEXPORT gztell64(file)
if (file == NULL) if (file == NULL)
return -1; return -1;
state = (gz_statep)file; 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 -1;
/* return position */ /* 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 -- */ /* -- see zlib.h -- */
@ -485,15 +485,15 @@ z_off64_t ZEXPORT gzoffset64(file)
if (file == NULL) if (file == NULL)
return -1; return -1;
state = (gz_statep)file; 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 -1;
/* compute and return effective offset in file */ /* 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) if (offset == -1)
return -1; return -1;
if (state->mode == GZ_READ) /* reading */ if (state.state->mode == GZ_READ) /* reading */
offset -= state->strm.avail_in; /* don't count buffered input */ offset -= state.state->strm.avail_in; /* don't count buffered input */
return offset; return offset;
} }
@ -517,11 +517,11 @@ int ZEXPORT gzeof(file)
if (file == NULL) if (file == NULL)
return 0; return 0;
state = (gz_statep)file; 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 0;
/* return end-of-file state */ /* 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 -- */ /* -- see zlib.h -- */
@ -535,14 +535,14 @@ const char * ZEXPORT gzerror(file, errnum)
if (file == NULL) if (file == NULL)
return NULL; return NULL;
state = (gz_statep)file; 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 NULL;
/* return error information */ /* return error information */
if (errnum != NULL) if (errnum != NULL)
*errnum = state->err; *errnum = state.state->err;
return state->err == Z_MEM_ERROR ? "out of memory" : return state.state->err == Z_MEM_ERROR ? "out of memory" :
(state->msg == NULL ? "" : state->msg); (state.state->msg == NULL ? "" : state.state->msg);
} }
/* -- see zlib.h -- */ /* -- see zlib.h -- */
@ -555,13 +555,13 @@ void ZEXPORT gzclearerr(file)
if (file == NULL) if (file == NULL)
return; return;
state = (gz_statep)file; 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; return;
/* clear error and end-of-file */ /* clear error and end-of-file */
if (state->mode == GZ_READ) { if (state.state->mode == GZ_READ) {
state->eof = 0; state.state->eof = 0;
state->past = 0; state.state->past = 0;
} }
gz_error(state, Z_OK, NULL); gz_error(state, Z_OK, NULL);
} }
@ -578,18 +578,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
const char *msg; const char *msg;
{ {
/* free previously allocated message and clear */ /* free previously allocated message and clear */
if (state->msg != NULL) { if (state.state->msg != NULL) {
if (state->err != Z_MEM_ERROR) if (state.state->err != Z_MEM_ERROR)
free(state->msg); free(state.state->msg);
state->msg = NULL; state.state->msg = NULL;
} }
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
if (err != Z_OK && err != Z_BUF_ERROR) if (err != Z_OK && err != Z_BUF_ERROR)
state->x.have = 0; state.state->x.have = 0;
/* set error code, and if no message, then done */ /* set error code, and if no message, then done */
state->err = err; state.state->err = err;
if (msg == NULL) if (msg == NULL)
return; return;
@ -598,18 +598,18 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
return; return;
/* construct error message with path */ /* 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) { NULL) {
state->err = Z_MEM_ERROR; state.state->err = Z_MEM_ERROR;
return; return;
} }
#if !defined(NO_snprintf) && !defined(NO_vsnprintf) #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, snprintf(state.state->msg, strlen(state.state->path) + strlen(msg) + 3,
"%s%s%s", state->path, ": ", msg); "%s%s%s", state.state->path, ": ", msg);
#else #else
strcpy(state->msg, state->path); strcpy(state.state->msg, state.state->path);
strcat(state->msg, ": "); strcat(state.state->msg, ": ");
strcat(state->msg, msg); strcat(state.state->msg, msg);
#endif #endif
return; return;
} }