annotate src/zlib-1.2.8/gzlib.c @ 83:ae30d91d2ffe

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