Fossil SCM

fossil-scm / compat / zlib / gzlib.c
Source Blame History 609 lines
7ef7284… drh 1 /* gzlib.c -- zlib functions common to reading and writing gzip files
6ea30fb… florian 2 * Copyright (C) 2004-2026 Mark Adler
7ef7284… drh 3 * For conditions of distribution and use, see copyright notice in zlib.h
7ef7284… drh 4 */
7ef7284… drh 5
7ef7284… drh 6 #include "gzguts.h"
7ef7284… drh 7
6ea30fb… florian 8 #if defined(__DJGPP__)
6ea30fb… florian 9 # define LSEEK llseek
6ea30fb… florian 10 #elif defined(_WIN32) && !defined(__BORLANDC__) && !defined(UNDER_CE)
7ef7284… drh 11 # define LSEEK _lseeki64
6ea30fb… florian 12 #elif defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
7ef7284… drh 13 # define LSEEK lseek64
7ef7284… drh 14 #else
7ef7284… drh 15 # define LSEEK lseek
7ef7284… drh 16 #endif
7ef7284… drh 17
7ef7284… drh 18 #if defined UNDER_CE
7ef7284… drh 19
7ef7284… drh 20 /* Map the Windows error number in ERROR to a locale-dependent error message
7ef7284… drh 21 string and return a pointer to it. Typically, the values for ERROR come
7ef7284… drh 22 from GetLastError.
7ef7284… drh 23
7ef7284… drh 24 The string pointed to shall not be modified by the application, but may be
7ef7284… drh 25 overwritten by a subsequent call to gz_strwinerror
7ef7284… drh 26
7ef7284… drh 27 The gz_strwinerror function does not change the current setting of
7ef7284… drh 28 GetLastError. */
f1f1d6c… drh 29 char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
7ef7284… drh 30 static char buf[1024];
7ef7284… drh 31
7ef7284… drh 32 wchar_t *msgbuf;
7ef7284… drh 33 DWORD lasterr = GetLastError();
7ef7284… drh 34 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
7ef7284… drh 35 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
7ef7284… drh 36 NULL,
7ef7284… drh 37 error,
7ef7284… drh 38 0, /* Default language */
7ef7284… drh 39 (LPVOID)&msgbuf,
7ef7284… drh 40 0,
7ef7284… drh 41 NULL);
7ef7284… drh 42 if (chars != 0) {
7ef7284… drh 43 /* If there is an \r\n appended, zap it. */
7ef7284… drh 44 if (chars >= 2
7ef7284… drh 45 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
7ef7284… drh 46 chars -= 2;
7ef7284… drh 47 msgbuf[chars] = 0;
7ef7284… drh 48 }
7ef7284… drh 49
7ef7284… drh 50 if (chars > sizeof (buf) - 1) {
7ef7284… drh 51 chars = sizeof (buf) - 1;
7ef7284… drh 52 msgbuf[chars] = 0;
7ef7284… drh 53 }
7ef7284… drh 54
6ea30fb… florian 55 wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */
7ef7284… drh 56 LocalFree(msgbuf);
7ef7284… drh 57 }
7ef7284… drh 58 else {
7ef7284… drh 59 sprintf(buf, "unknown win32 error (%ld)", error);
7ef7284… drh 60 }
7ef7284… drh 61
7ef7284… drh 62 SetLastError(lasterr);
7ef7284… drh 63 return buf;
7ef7284… drh 64 }
7ef7284… drh 65
7ef7284… drh 66 #endif /* UNDER_CE */
7ef7284… drh 67
7ef7284… drh 68 /* Reset gzip file state */
f1f1d6c… drh 69 local void gz_reset(gz_statep state) {
7ef7284… drh 70 state->x.have = 0; /* no output data available */
7ef7284… drh 71 if (state->mode == GZ_READ) { /* for reading ... */
7ef7284… drh 72 state->eof = 0; /* not at end of file */
7ef7284… drh 73 state->past = 0; /* have not read past end yet */
7ef7284… drh 74 state->how = LOOK; /* look for gzip header */
6ea30fb… florian 75 state->junk = -1; /* mark first member */
7ef7284… drh 76 }
adb9e8e… drh 77 else /* for writing ... */
adb9e8e… drh 78 state->reset = 0; /* no deflateReset pending */
6ea30fb… florian 79 state->again = 0; /* no stalled i/o yet */
6ea30fb… florian 80 state->skip = 0; /* no seek request pending */
7ef7284… drh 81 gz_error(state, Z_OK, NULL); /* clear error */
7ef7284… drh 82 state->x.pos = 0; /* no uncompressed data yet */
7ef7284… drh 83 state->strm.avail_in = 0; /* no input data yet */
7ef7284… drh 84 }
7ef7284… drh 85
7ef7284… drh 86 /* Open a gzip file either by name or file descriptor. */
f1f1d6c… drh 87 local gzFile gz_open(const void *path, int fd, const char *mode) {
7ef7284… drh 88 gz_statep state;
e38d5e1… jan.nijtmans 89 z_size_t len;
6ea30fb… florian 90 int oflag = 0;
7ef7284… drh 91 #ifdef O_EXCL
7ef7284… drh 92 int exclusive = 0;
7ef7284… drh 93 #endif
7ef7284… drh 94
7ef7284… drh 95 /* check input */
6ea30fb… florian 96 if (path == NULL || mode == NULL)
7ef7284… drh 97 return NULL;
7ef7284… drh 98
7ef7284… drh 99 /* allocate gzFile structure to return */
bb4776e… jan.nijtmans 100 state = (gz_statep)malloc(sizeof(gz_state));
7ef7284… drh 101 if (state == NULL)
7ef7284… drh 102 return NULL;
7ef7284… drh 103 state->size = 0; /* no buffers allocated yet */
7ef7284… drh 104 state->want = GZBUFSIZE; /* requested buffer size */
6ea30fb… florian 105 state->err = Z_OK; /* no error yet */
7ef7284… drh 106 state->msg = NULL; /* no error message yet */
7ef7284… drh 107
7ef7284… drh 108 /* interpret mode */
7ef7284… drh 109 state->mode = GZ_NONE;
7ef7284… drh 110 state->level = Z_DEFAULT_COMPRESSION;
7ef7284… drh 111 state->strategy = Z_DEFAULT_STRATEGY;
7ef7284… drh 112 state->direct = 0;
7ef7284… drh 113 while (*mode) {
7ef7284… drh 114 if (*mode >= '0' && *mode <= '9')
7ef7284… drh 115 state->level = *mode - '0';
7ef7284… drh 116 else
7ef7284… drh 117 switch (*mode) {
7ef7284… drh 118 case 'r':
7ef7284… drh 119 state->mode = GZ_READ;
7ef7284… drh 120 break;
7ef7284… drh 121 #ifndef NO_GZCOMPRESS
7ef7284… drh 122 case 'w':
7ef7284… drh 123 state->mode = GZ_WRITE;
7ef7284… drh 124 break;
7ef7284… drh 125 case 'a':
7ef7284… drh 126 state->mode = GZ_APPEND;
7ef7284… drh 127 break;
7ef7284… drh 128 #endif
7ef7284… drh 129 case '+': /* can't read and write at the same time */
7ef7284… drh 130 free(state);
7ef7284… drh 131 return NULL;
7ef7284… drh 132 case 'b': /* ignore -- will request binary anyway */
7ef7284… drh 133 break;
7ef7284… drh 134 #ifdef O_CLOEXEC
7ef7284… drh 135 case 'e':
6ea30fb… florian 136 oflag |= O_CLOEXEC;
7ef7284… drh 137 break;
7ef7284… drh 138 #endif
7ef7284… drh 139 #ifdef O_EXCL
7ef7284… drh 140 case 'x':
7ef7284… drh 141 exclusive = 1;
7ef7284… drh 142 break;
7ef7284… drh 143 #endif
7ef7284… drh 144 case 'f':
7ef7284… drh 145 state->strategy = Z_FILTERED;
7ef7284… drh 146 break;
7ef7284… drh 147 case 'h':
7ef7284… drh 148 state->strategy = Z_HUFFMAN_ONLY;
7ef7284… drh 149 break;
7ef7284… drh 150 case 'R':
7ef7284… drh 151 state->strategy = Z_RLE;
7ef7284… drh 152 break;
7ef7284… drh 153 case 'F':
7ef7284… drh 154 state->strategy = Z_FIXED;
bb4776e… jan.nijtmans 155 break;
6ea30fb… florian 156 case 'G':
6ea30fb… florian 157 state->direct = -1;
6ea30fb… florian 158 break;
6ea30fb… florian 159 #ifdef O_NONBLOCK
6ea30fb… florian 160 case 'N':
6ea30fb… florian 161 oflag |= O_NONBLOCK;
6ea30fb… florian 162 break;
6ea30fb… florian 163 #endif
7ef7284… drh 164 case 'T':
7ef7284… drh 165 state->direct = 1;
bb4776e… jan.nijtmans 166 break;
7ef7284… drh 167 default: /* could consider as an error, but just ignore */
7ef7284… drh 168 ;
7ef7284… drh 169 }
7ef7284… drh 170 mode++;
7ef7284… drh 171 }
7ef7284… drh 172
7ef7284… drh 173 /* must provide an "r", "w", or "a" */
7ef7284… drh 174 if (state->mode == GZ_NONE) {
7ef7284… drh 175 free(state);
7ef7284… drh 176 return NULL;
7ef7284… drh 177 }
7ef7284… drh 178
6ea30fb… florian 179 /* direct is 0, 1 if "T", or -1 if "G" (last "G" or "T" wins) */
7ef7284… drh 180 if (state->mode == GZ_READ) {
6ea30fb… florian 181 if (state->direct == 1) {
6ea30fb… florian 182 /* can't force a transparent read */
7ef7284… drh 183 free(state);
7ef7284… drh 184 return NULL;
7ef7284… drh 185 }
6ea30fb… florian 186 if (state->direct == 0)
6ea30fb… florian 187 /* default when reading is auto-detect of gzip vs. transparent --
6ea30fb… florian 188 start with a transparent assumption in case of an empty file */
6ea30fb… florian 189 state->direct = 1;
6ea30fb… florian 190 }
6ea30fb… florian 191 else if (state->direct == -1) {
6ea30fb… florian 192 /* "G" has no meaning when writing -- disallow it */
6ea30fb… florian 193 free(state);
6ea30fb… florian 194 return NULL;
7ef7284… drh 195 }
6ea30fb… florian 196 /* if reading, direct == 1 for auto-detect, -1 for gzip only; if writing or
6ea30fb… florian 197 appending, direct == 0 for gzip, 1 for transparent (copy in to out) */
7ef7284… drh 198
7ef7284… drh 199 /* save the path name for error messages */
e38d5e1… jan.nijtmans 200 #ifdef WIDECHAR
6ea30fb… florian 201 if (fd == -2)
7ef7284… drh 202 len = wcstombs(NULL, path, 0);
7ef7284… drh 203 else
7ef7284… drh 204 #endif
bb4776e… jan.nijtmans 205 len = strlen((const char *)path);
bb4776e… jan.nijtmans 206 state->path = (char *)malloc(len + 1);
7ef7284… drh 207 if (state->path == NULL) {
7ef7284… drh 208 free(state);
7ef7284… drh 209 return NULL;
7ef7284… drh 210 }
e38d5e1… jan.nijtmans 211 #ifdef WIDECHAR
6ea30fb… florian 212 if (fd == -2) {
7ef7284… drh 213 if (len)
7ef7284… drh 214 wcstombs(state->path, path, len + 1);
7ef7284… drh 215 else
7ef7284… drh 216 *(state->path) = 0;
6ea30fb… florian 217 }
7ef7284… drh 218 else
7ef7284… drh 219 #endif
6ea30fb… florian 220 {
bb4776e… jan.nijtmans 221 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
ad8ad49… jan.nijtmans 222 (void)snprintf(state->path, len + 1, "%s", (const char *)path);
bb4776e… jan.nijtmans 223 #else
7ef7284… drh 224 strcpy(state->path, path);
bb4776e… jan.nijtmans 225 #endif
6ea30fb… florian 226 }
7ef7284… drh 227
7ef7284… drh 228 /* compute the flags for open() */
6ea30fb… florian 229 oflag |=
7ef7284… drh 230 #ifdef O_LARGEFILE
7ef7284… drh 231 O_LARGEFILE |
7ef7284… drh 232 #endif
7ef7284… drh 233 #ifdef O_BINARY
7ef7284… drh 234 O_BINARY |
7ef7284… drh 235 #endif
7ef7284… drh 236 (state->mode == GZ_READ ?
7ef7284… drh 237 O_RDONLY :
7ef7284… drh 238 (O_WRONLY | O_CREAT |
7ef7284… drh 239 #ifdef O_EXCL
7ef7284… drh 240 (exclusive ? O_EXCL : 0) |
7ef7284… drh 241 #endif
7ef7284… drh 242 (state->mode == GZ_WRITE ?
7ef7284… drh 243 O_TRUNC :
7ef7284… drh 244 O_APPEND)));
7ef7284… drh 245
7ef7284… drh 246 /* open the file with the appropriate flags (or just use fd) */
6ea30fb… florian 247 if (fd == -1)
6ea30fb… florian 248 state->fd = open((const char *)path, oflag, 0666);
e38d5e1… jan.nijtmans 249 #ifdef WIDECHAR
6ea30fb… florian 250 else if (fd == -2)
6ea30fb… florian 251 state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE);
6ea30fb… florian 252 #endif
6ea30fb… florian 253 else {
6ea30fb… florian 254 #ifdef O_NONBLOCK
6ea30fb… florian 255 if (oflag & O_NONBLOCK)
6ea30fb… florian 256 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
6ea30fb… florian 257 #endif
6ea30fb… florian 258 #ifdef O_CLOEXEC
6ea30fb… florian 259 if (oflag & O_CLOEXEC)
6ea30fb… florian 260 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC);
7ef7284… drh 261 #endif
6ea30fb… florian 262 state->fd = fd;
6ea30fb… florian 263 }
7ef7284… drh 264 if (state->fd == -1) {
7ef7284… drh 265 free(state->path);
7ef7284… drh 266 free(state);
7ef7284… drh 267 return NULL;
7ef7284… drh 268 }
e38d5e1… jan.nijtmans 269 if (state->mode == GZ_APPEND) {
e38d5e1… jan.nijtmans 270 LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
7ef7284… drh 271 state->mode = GZ_WRITE; /* simplify later checks */
e38d5e1… jan.nijtmans 272 }
7ef7284… drh 273
7ef7284… drh 274 /* save the current position for rewinding (only if reading) */
7ef7284… drh 275 if (state->mode == GZ_READ) {
7ef7284… drh 276 state->start = LSEEK(state->fd, 0, SEEK_CUR);
7ef7284… drh 277 if (state->start == -1) state->start = 0;
7ef7284… drh 278 }
7ef7284… drh 279
7ef7284… drh 280 /* initialize stream */
7ef7284… drh 281 gz_reset(state);
7ef7284… drh 282
7ef7284… drh 283 /* return stream */
7ef7284… drh 284 return (gzFile)state;
7ef7284… drh 285 }
7ef7284… drh 286
7ef7284… drh 287 /* -- see zlib.h -- */
f1f1d6c… drh 288 gzFile ZEXPORT gzopen(const char *path, const char *mode) {
f1f1d6c… drh 289 return gz_open(path, -1, mode);
f1f1d6c… drh 290 }
f1f1d6c… drh 291
f1f1d6c… drh 292 /* -- see zlib.h -- */
f1f1d6c… drh 293 gzFile ZEXPORT gzopen64(const char *path, const char *mode) {
7ef7284… drh 294 return gz_open(path, -1, mode);
7ef7284… drh 295 }
7ef7284… drh 296
7ef7284… drh 297 /* -- see zlib.h -- */
f1f1d6c… drh 298 gzFile ZEXPORT gzdopen(int fd, const char *mode) {
7ef7284… drh 299 char *path; /* identifier for error messages */
7ef7284… drh 300 gzFile gz;
7ef7284… drh 301
bb4776e… jan.nijtmans 302 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
7ef7284… drh 303 return NULL;
bb4776e… jan.nijtmans 304 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
ad8ad49… jan.nijtmans 305 (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
bb4776e… jan.nijtmans 306 #else
7ef7284… drh 307 sprintf(path, "<fd:%d>", fd); /* for debugging */
bb4776e… jan.nijtmans 308 #endif
7ef7284… drh 309 gz = gz_open(path, fd, mode);
7ef7284… drh 310 free(path);
7ef7284… drh 311 return gz;
7ef7284… drh 312 }
7ef7284… drh 313
7ef7284… drh 314 /* -- see zlib.h -- */
e38d5e1… jan.nijtmans 315 #ifdef WIDECHAR
f1f1d6c… drh 316 gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {
7ef7284… drh 317 return gz_open(path, -2, mode);
7ef7284… drh 318 }
7ef7284… drh 319 #endif
7ef7284… drh 320
7ef7284… drh 321 /* -- see zlib.h -- */
f1f1d6c… drh 322 int ZEXPORT gzbuffer(gzFile file, unsigned size) {
7ef7284… drh 323 gz_statep state;
7ef7284… drh 324
7ef7284… drh 325 /* get internal structure and check integrity */
7ef7284… drh 326 if (file == NULL)
7ef7284… drh 327 return -1;
7ef7284… drh 328 state = (gz_statep)file;
7ef7284… drh 329 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 330 return -1;
7ef7284… drh 331
7ef7284… drh 332 /* make sure we haven't already allocated memory */
7ef7284… drh 333 if (state->size != 0)
7ef7284… drh 334 return -1;
7ef7284… drh 335
7ef7284… drh 336 /* check and set requested size */
e38d5e1… jan.nijtmans 337 if ((size << 1) < size)
e38d5e1… jan.nijtmans 338 return -1; /* need to be able to double it */
f1f1d6c… drh 339 if (size < 8)
f1f1d6c… drh 340 size = 8; /* needed to behave well with flushing */
7ef7284… drh 341 state->want = size;
7ef7284… drh 342 return 0;
7ef7284… drh 343 }
7ef7284… drh 344
7ef7284… drh 345 /* -- see zlib.h -- */
f1f1d6c… drh 346 int ZEXPORT gzrewind(gzFile file) {
7ef7284… drh 347 gz_statep state;
7ef7284… drh 348
7ef7284… drh 349 /* get internal structure */
7ef7284… drh 350 if (file == NULL)
7ef7284… drh 351 return -1;
7ef7284… drh 352 state = (gz_statep)file;
7ef7284… drh 353
7ef7284… drh 354 /* check that we're reading and that there's no error */
7ef7284… drh 355 if (state->mode != GZ_READ ||
7ef7284… drh 356 (state->err != Z_OK && state->err != Z_BUF_ERROR))
7ef7284… drh 357 return -1;
7ef7284… drh 358
7ef7284… drh 359 /* back up and start over */
7ef7284… drh 360 if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
7ef7284… drh 361 return -1;
7ef7284… drh 362 gz_reset(state);
7ef7284… drh 363 return 0;
7ef7284… drh 364 }
7ef7284… drh 365
7ef7284… drh 366 /* -- see zlib.h -- */
f1f1d6c… drh 367 z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
7ef7284… drh 368 unsigned n;
7ef7284… drh 369 z_off64_t ret;
7ef7284… drh 370 gz_statep state;
7ef7284… drh 371
7ef7284… drh 372 /* get internal structure and check integrity */
7ef7284… drh 373 if (file == NULL)
7ef7284… drh 374 return -1;
7ef7284… drh 375 state = (gz_statep)file;
7ef7284… drh 376 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 377 return -1;
7ef7284… drh 378
7ef7284… drh 379 /* check that there's no error */
7ef7284… drh 380 if (state->err != Z_OK && state->err != Z_BUF_ERROR)
7ef7284… drh 381 return -1;
7ef7284… drh 382
7ef7284… drh 383 /* can only seek from start or relative to current position */
7ef7284… drh 384 if (whence != SEEK_SET && whence != SEEK_CUR)
7ef7284… drh 385 return -1;
7ef7284… drh 386
7ef7284… drh 387 /* normalize offset to a SEEK_CUR specification */
7ef7284… drh 388 if (whence == SEEK_SET)
7ef7284… drh 389 offset -= state->x.pos;
6ea30fb… florian 390 else {
6ea30fb… florian 391 offset += state->past ? 0 : state->skip;
6ea30fb… florian 392 state->skip = 0;
6ea30fb… florian 393 }
7ef7284… drh 394
7ef7284… drh 395 /* if within raw area while reading, just go there */
7ef7284… drh 396 if (state->mode == GZ_READ && state->how == COPY &&
7ef7284… drh 397 state->x.pos + offset >= 0) {
adb9e8e… drh 398 ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
7ef7284… drh 399 if (ret == -1)
7ef7284… drh 400 return -1;
7ef7284… drh 401 state->x.have = 0;
7ef7284… drh 402 state->eof = 0;
7ef7284… drh 403 state->past = 0;
6ea30fb… florian 404 state->skip = 0;
7ef7284… drh 405 gz_error(state, Z_OK, NULL);
7ef7284… drh 406 state->strm.avail_in = 0;
7ef7284… drh 407 state->x.pos += offset;
7ef7284… drh 408 return state->x.pos;
7ef7284… drh 409 }
7ef7284… drh 410
7ef7284… drh 411 /* calculate skip amount, rewinding if needed for back seek when reading */
7ef7284… drh 412 if (offset < 0) {
7ef7284… drh 413 if (state->mode != GZ_READ) /* writing -- can't go backwards */
7ef7284… drh 414 return -1;
7ef7284… drh 415 offset += state->x.pos;
7ef7284… drh 416 if (offset < 0) /* before start of file! */
7ef7284… drh 417 return -1;
7ef7284… drh 418 if (gzrewind(file) == -1) /* rewind, then skip to offset */
7ef7284… drh 419 return -1;
7ef7284… drh 420 }
7ef7284… drh 421
7ef7284… drh 422 /* if reading, skip what's in output buffer (one less gzgetc() check) */
7ef7284… drh 423 if (state->mode == GZ_READ) {
7ef7284… drh 424 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
7ef7284… drh 425 (unsigned)offset : state->x.have;
7ef7284… drh 426 state->x.have -= n;
7ef7284… drh 427 state->x.next += n;
7ef7284… drh 428 state->x.pos += n;
7ef7284… drh 429 offset -= n;
7ef7284… drh 430 }
7ef7284… drh 431
7ef7284… drh 432 /* request skip (if not zero) */
6ea30fb… florian 433 state->skip = offset;
7ef7284… drh 434 return state->x.pos + offset;
7ef7284… drh 435 }
7ef7284… drh 436
7ef7284… drh 437 /* -- see zlib.h -- */
f1f1d6c… drh 438 z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {
7ef7284… drh 439 z_off64_t ret;
7ef7284… drh 440
7ef7284… drh 441 ret = gzseek64(file, (z_off64_t)offset, whence);
7ef7284… drh 442 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
7ef7284… drh 443 }
7ef7284… drh 444
7ef7284… drh 445 /* -- see zlib.h -- */
f1f1d6c… drh 446 z_off64_t ZEXPORT gztell64(gzFile file) {
7ef7284… drh 447 gz_statep state;
7ef7284… drh 448
7ef7284… drh 449 /* get internal structure and check integrity */
7ef7284… drh 450 if (file == NULL)
7ef7284… drh 451 return -1;
7ef7284… drh 452 state = (gz_statep)file;
7ef7284… drh 453 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 454 return -1;
7ef7284… drh 455
7ef7284… drh 456 /* return position */
6ea30fb… florian 457 return state->x.pos + (state->past ? 0 : state->skip);
7ef7284… drh 458 }
7ef7284… drh 459
7ef7284… drh 460 /* -- see zlib.h -- */
f1f1d6c… drh 461 z_off_t ZEXPORT gztell(gzFile file) {
7ef7284… drh 462 z_off64_t ret;
7ef7284… drh 463
7ef7284… drh 464 ret = gztell64(file);
7ef7284… drh 465 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
7ef7284… drh 466 }
7ef7284… drh 467
7ef7284… drh 468 /* -- see zlib.h -- */
f1f1d6c… drh 469 z_off64_t ZEXPORT gzoffset64(gzFile file) {
7ef7284… drh 470 z_off64_t offset;
7ef7284… drh 471 gz_statep state;
7ef7284… drh 472
7ef7284… drh 473 /* get internal structure and check integrity */
7ef7284… drh 474 if (file == NULL)
7ef7284… drh 475 return -1;
7ef7284… drh 476 state = (gz_statep)file;
7ef7284… drh 477 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 478 return -1;
7ef7284… drh 479
7ef7284… drh 480 /* compute and return effective offset in file */
7ef7284… drh 481 offset = LSEEK(state->fd, 0, SEEK_CUR);
7ef7284… drh 482 if (offset == -1)
7ef7284… drh 483 return -1;
7ef7284… drh 484 if (state->mode == GZ_READ) /* reading */
7ef7284… drh 485 offset -= state->strm.avail_in; /* don't count buffered input */
7ef7284… drh 486 return offset;
7ef7284… drh 487 }
7ef7284… drh 488
7ef7284… drh 489 /* -- see zlib.h -- */
f1f1d6c… drh 490 z_off_t ZEXPORT gzoffset(gzFile file) {
7ef7284… drh 491 z_off64_t ret;
7ef7284… drh 492
7ef7284… drh 493 ret = gzoffset64(file);
7ef7284… drh 494 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
7ef7284… drh 495 }
7ef7284… drh 496
7ef7284… drh 497 /* -- see zlib.h -- */
f1f1d6c… drh 498 int ZEXPORT gzeof(gzFile file) {
7ef7284… drh 499 gz_statep state;
7ef7284… drh 500
7ef7284… drh 501 /* get internal structure and check integrity */
7ef7284… drh 502 if (file == NULL)
7ef7284… drh 503 return 0;
7ef7284… drh 504 state = (gz_statep)file;
7ef7284… drh 505 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 506 return 0;
7ef7284… drh 507
7ef7284… drh 508 /* return end-of-file state */
7ef7284… drh 509 return state->mode == GZ_READ ? state->past : 0;
7ef7284… drh 510 }
7ef7284… drh 511
7ef7284… drh 512 /* -- see zlib.h -- */
f1f1d6c… drh 513 const char * ZEXPORT gzerror(gzFile file, int *errnum) {
7ef7284… drh 514 gz_statep state;
7ef7284… drh 515
7ef7284… drh 516 /* get internal structure and check integrity */
7ef7284… drh 517 if (file == NULL)
7ef7284… drh 518 return NULL;
7ef7284… drh 519 state = (gz_statep)file;
7ef7284… drh 520 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 521 return NULL;
7ef7284… drh 522
7ef7284… drh 523 /* return error information */
7ef7284… drh 524 if (errnum != NULL)
7ef7284… drh 525 *errnum = state->err;
bb4776e… jan.nijtmans 526 return state->err == Z_MEM_ERROR ? "out of memory" :
bb4776e… jan.nijtmans 527 (state->msg == NULL ? "" : state->msg);
7ef7284… drh 528 }
7ef7284… drh 529
7ef7284… drh 530 /* -- see zlib.h -- */
f1f1d6c… drh 531 void ZEXPORT gzclearerr(gzFile file) {
7ef7284… drh 532 gz_statep state;
7ef7284… drh 533
7ef7284… drh 534 /* get internal structure and check integrity */
7ef7284… drh 535 if (file == NULL)
7ef7284… drh 536 return;
7ef7284… drh 537 state = (gz_statep)file;
7ef7284… drh 538 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
7ef7284… drh 539 return;
7ef7284… drh 540
7ef7284… drh 541 /* clear error and end-of-file */
7ef7284… drh 542 if (state->mode == GZ_READ) {
7ef7284… drh 543 state->eof = 0;
7ef7284… drh 544 state->past = 0;
7ef7284… drh 545 }
7ef7284… drh 546 gz_error(state, Z_OK, NULL);
7ef7284… drh 547 }
7ef7284… drh 548
7ef7284… drh 549 /* Create an error message in allocated memory and set state->err and
7ef7284… drh 550 state->msg accordingly. Free any previous error message already there. Do
7ef7284… drh 551 not try to free or allocate space if the error is Z_MEM_ERROR (out of
7ef7284… drh 552 memory). Simply save the error message as a static string. If there is an
7ef7284… drh 553 allocation failure constructing the error message, then convert the error to
7ef7284… drh 554 out of memory. */
f1f1d6c… drh 555 void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
7ef7284… drh 556 /* free previously allocated message and clear */
7ef7284… drh 557 if (state->msg != NULL) {
7ef7284… drh 558 if (state->err != Z_MEM_ERROR)
7ef7284… drh 559 free(state->msg);
7ef7284… drh 560 state->msg = NULL;
7ef7284… drh 561 }
7ef7284… drh 562
7ef7284… drh 563 /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
6ea30fb… florian 564 if (err != Z_OK && err != Z_BUF_ERROR && !state->again)
7ef7284… drh 565 state->x.have = 0;
7ef7284… drh 566
7ef7284… drh 567 /* set error code, and if no message, then done */
7ef7284… drh 568 state->err = err;
7ef7284… drh 569 if (msg == NULL)
7ef7284… drh 570 return;
7ef7284… drh 571
bb4776e… jan.nijtmans 572 /* for an out of memory error, return literal string when requested */
bb4776e… jan.nijtmans 573 if (err == Z_MEM_ERROR)
7ef7284… drh 574 return;
7ef7284… drh 575
7ef7284… drh 576 /* construct error message with path */
bb4776e… jan.nijtmans 577 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
bb4776e… jan.nijtmans 578 NULL) {
7ef7284… drh 579 state->err = Z_MEM_ERROR;
7ef7284… drh 580 return;
7ef7284… drh 581 }
bb4776e… jan.nijtmans 582 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
ad8ad49… jan.nijtmans 583 (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
ad8ad49… jan.nijtmans 584 "%s%s%s", state->path, ": ", msg);
bb4776e… jan.nijtmans 585 #else
7ef7284… drh 586 strcpy(state->msg, state->path);
7ef7284… drh 587 strcat(state->msg, ": ");
7ef7284… drh 588 strcat(state->msg, msg);
bb4776e… jan.nijtmans 589 #endif
7ef7284… drh 590 }
7ef7284… drh 591
7ef7284… drh 592 /* portably return maximum value for an int (when limits.h presumed not
7ef7284… drh 593 available) -- we need to do this to cover cases where 2's complement not
7ef7284… drh 594 used, since C standard permits 1's complement and sign-bit representations,
7ef7284… drh 595 otherwise we could just use ((unsigned)-1) >> 1 */
f1f1d6c… drh 596 unsigned ZLIB_INTERNAL gz_intmax(void) {
64ce68d… drh 597 #ifdef INT_MAX
64ce68d… drh 598 return INT_MAX;
64ce68d… drh 599 #else
64ce68d… drh 600 unsigned p = 1, q;
6ea30fb… florian 601
7ef7284… drh 602 do {
7ef7284… drh 603 q = p;
7ef7284… drh 604 p <<= 1;
7ef7284… drh 605 p++;
7ef7284… drh 606 } while (p > q);
7ef7284… drh 607 return q >> 1;
7ef7284… drh 608 #endif
64ce68d… drh 609 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button