/* gzlib.c -- zlib functions common to reading and writing gzip files * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h
*/
/* 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(DWORD error) { staticchar 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;
}
/* Reset gzip file state */
local void gz_reset(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 */
} else/* for writing ... */
state->reset = 0; /* no deflateReset pending */
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(constvoid *path, int fd, constchar *mode) {
gz_statep state;
z_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 */
/* open the file with the appropriate flags (or just use fd) */
state->fd = fd > -1 ? fd : ( #ifdef WIDECHAR
fd == -2 ? _wopen(path, oflag, 0666) : #endif
open((constchar *)path, oflag, 0666)); if (state->fd == -1) {
free(state->path);
free(state); return NULL;
} if (state->mode == GZ_APPEND) {
LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
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;
}
/* -- see zlib.h -- */ int ZEXPORT gzbuffer(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 << 1) < size) return -1; /* need to be able to double it */ if (size < 8)
size = 8; /* needed to behave well with flushing */
state->want = size; return 0;
}
/* -- see zlib.h -- */ int ZEXPORT gzrewind(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;
}
/* 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; elseif (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 - (z_off64_t)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;
}
/* get internal structure and check integrity */ if (file == NULL) return;
state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return;
/* 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(gz_statep state, int err, constchar *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;
/* 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(void) { #ifdef INT_MAX return INT_MAX; #else unsigned p = 1, q; do {
q = p;
p <<= 1;
p++;
} while (p > q); return q >> 1; #endif
}
¤ Dauer der Verarbeitung: 0.29 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.