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