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