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