annotate src/zlib-1.2.7/gzlib.c @ 42:2cd0e3b3e1fd

Current fftw source
author Chris Cannam
date Tue, 18 Oct 2016 13:40:26 +0100
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