annotate src/zlib-1.2.7/gzlib.c @ 169:223a55898ab9 tip default

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