117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* gzlib.c -- zlib functions common to reading and writing gzip files 217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler 317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner * For conditions of distribution and use, see copyright notice in zlib.h 417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner */ 517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#include "gzguts.h" 717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if defined(_WIN32) && !defined(__BORLANDC__) 917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner# define LSEEK _lseeki64 1017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 1117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 1217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner# define LSEEK lseek64 1317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 1417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner# define LSEEK lseek 1517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 1617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 1717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 1817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* Local functions */ 1917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal void gz_reset OF((gz_statep)); 2017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal gzFile gz_open OF((const void *, int, const char *)); 2117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 2217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if defined UNDER_CE 2317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 2417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* Map the Windows error number in ERROR to a locale-dependent error message 2517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner string and return a pointer to it. Typically, the values for ERROR come 2617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner from GetLastError. 2717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 2817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner The string pointed to shall not be modified by the application, but may be 2917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner overwritten by a subsequent call to gz_strwinerror 3017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 3117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner The gz_strwinerror function does not change the current setting of 3217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner GetLastError. */ 3317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerchar ZLIB_INTERNAL *gz_strwinerror (error) 3417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DWORD error; 3517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 3617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner static char buf[1024]; 3717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 3817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner wchar_t *msgbuf; 3917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DWORD lasterr = GetLastError(); 4017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 4117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner | FORMAT_MESSAGE_ALLOCATE_BUFFER, 4217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NULL, 4317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner error, 4417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 0, /* Default language */ 4517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (LPVOID)&msgbuf, 4617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 0, 4717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NULL); 4817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (chars != 0) { 4917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* If there is an \r\n appended, zap it. */ 5017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (chars >= 2 5117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 5217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner chars -= 2; 5317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner msgbuf[chars] = 0; 5417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 5517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 5617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (chars > sizeof (buf) - 1) { 5717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner chars = sizeof (buf) - 1; 5817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner msgbuf[chars] = 0; 5917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 6017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 6117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner wcstombs(buf, msgbuf, chars + 1); 6217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner LocalFree(msgbuf); 6317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 6417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else { 6517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner sprintf(buf, "unknown win32 error (%ld)", error); 6617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 6717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 6817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner SetLastError(lasterr); 6917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return buf; 7017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 7117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 7217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif /* UNDER_CE */ 7317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 7417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* Reset gzip file state */ 7517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal void gz_reset(state) 7617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 7717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 7817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.have = 0; /* no output data available */ 7917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) { /* for reading ... */ 8017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->eof = 0; /* not at end of file */ 8117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->past = 0; /* have not read past end yet */ 8217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->how = LOOK; /* look for gzip header */ 8317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 8417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->seek = 0; /* no seek request pending */ 8517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_error(state, Z_OK, NULL); /* clear error */ 8617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.pos = 0; /* no uncompressed data yet */ 8717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strm.avail_in = 0; /* no input data yet */ 8817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 8917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 9017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* Open a gzip file either by name or file descriptor. */ 9117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerlocal gzFile gz_open(path, fd, mode) 9217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const void *path; 9317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int fd; 9417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *mode; 9517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 9617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 9717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner size_t len; 9817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int oflag; 9917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_CLOEXEC 10017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int cloexec = 0; 10117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 10217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_EXCL 10317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int exclusive = 0; 10417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 10517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 10617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* check input */ 10717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (path == NULL) 10817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 10917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 11017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* allocate gzFile structure to return */ 11117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)malloc(sizeof(gz_state)); 11217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state == NULL) 11317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 11417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->size = 0; /* no buffers allocated yet */ 11517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->want = GZBUFSIZE; /* requested buffer size */ 11617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->msg = NULL; /* no error message yet */ 11717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 11817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* interpret mode */ 11917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = GZ_NONE; 12017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->level = Z_DEFAULT_COMPRESSION; 12117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strategy = Z_DEFAULT_STRATEGY; 12217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->direct = 0; 12317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner while (*mode) { 12417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (*mode >= '0' && *mode <= '9') 12517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->level = *mode - '0'; 12617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else 12717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner switch (*mode) { 12817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'r': 12917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = GZ_READ; 13017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 13117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifndef NO_GZCOMPRESS 13217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'w': 13317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = GZ_WRITE; 13417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 13517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'a': 13617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = GZ_APPEND; 13717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 13817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 13917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case '+': /* can't read and write at the same time */ 14017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state); 14117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 14217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'b': /* ignore -- will request binary anyway */ 14317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 14417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_CLOEXEC 14517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'e': 14617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner cloexec = 1; 14717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 14817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 14917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_EXCL 15017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'x': 15117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner exclusive = 1; 15217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 15317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 15417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'f': 15517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strategy = Z_FILTERED; 15617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 15717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'h': 15817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strategy = Z_HUFFMAN_ONLY; 15917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 16017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'R': 16117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strategy = Z_RLE; 16217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 16317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'F': 16417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strategy = Z_FIXED; 16517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 16617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner case 'T': 16717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->direct = 1; 16817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 16917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner default: /* could consider as an error, but just ignore */ 17017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner ; 17117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 17217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner mode++; 17317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 17417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 17517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* must provide an "r", "w", or "a" */ 17617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_NONE) { 17717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state); 17817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 17917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 18017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 18117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* can't force transparent read */ 18217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) { 18317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->direct) { 18417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state); 18517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 18617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 18717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->direct = 1; /* for empty file */ 18817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 18917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 19017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* save the path name for error messages */ 19117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef _WIN32 19217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (fd == -2) { 19317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner len = wcstombs(NULL, path, 0); 19417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (len == (size_t)-1) 19517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner len = 0; 19617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 19717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else 19817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 19917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner len = strlen((const char *)path); 20017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->path = (char *)malloc(len + 1); 20117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->path == NULL) { 20217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state); 20317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 20417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 20517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef _WIN32 20617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (fd == -2) 20717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (len) 20817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner wcstombs(state->path, path, len + 1); 20917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else 21017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner *(state->path) = 0; 21117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else 21217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 21317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 21417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner snprintf(state->path, len + 1, "%s", (const char *)path); 21517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 21617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strcpy(state->path, path); 21717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 21817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 21917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* compute the flags for open() */ 22017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner oflag = 22117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_LARGEFILE 22217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner O_LARGEFILE | 22317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 22417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_BINARY 22517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner O_BINARY | 22617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 22717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_CLOEXEC 22817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (cloexec ? O_CLOEXEC : 0) | 22917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 23017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (state->mode == GZ_READ ? 23117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner O_RDONLY : 23217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (O_WRONLY | O_CREAT | 23317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef O_EXCL 23417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (exclusive ? O_EXCL : 0) | 23517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 23617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (state->mode == GZ_WRITE ? 23717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner O_TRUNC : 23817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner O_APPEND))); 23917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 24017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* open the file with the appropriate flags (or just use fd) */ 24117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->fd = fd > -1 ? fd : ( 24217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef _WIN32 24317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner fd == -2 ? _wopen(path, oflag, 0666) : 24417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 24517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner open((const char *)path, oflag, 0666)); 24617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->fd == -1) { 24717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state->path); 24817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state); 24917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 25017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 25117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_APPEND) 25217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = GZ_WRITE; /* simplify later checks */ 25317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 25417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* save the current position for rewinding (only if reading) */ 25517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) { 25617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->start = LSEEK(state->fd, 0, SEEK_CUR); 25717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->start == -1) state->start = 0; 25817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 25917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 26017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* initialize stream */ 26117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_reset(state); 26217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 26317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* return stream */ 26417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return (gzFile)state; 26517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 26617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 26717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 26817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurnergzFile ZEXPORT gzopen(path, mode) 26917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *path; 27017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *mode; 27117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 27217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return gz_open(path, -1, mode); 27317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 27417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 27517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 27617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurnergzFile ZEXPORT gzopen64(path, mode) 27717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *path; 27817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *mode; 27917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 28017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return gz_open(path, -1, mode); 28117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 28217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 28317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 28417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurnergzFile ZEXPORT gzdopen(fd, mode) 28517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int fd; 28617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *mode; 28717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 28817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner char *path; /* identifier for error messages */ 28917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile gz; 29017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 29117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 29217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 29317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 29417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ 29517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 29617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner sprintf(path, "<fd:%d>", fd); /* for debugging */ 29717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 29817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz = gz_open(path, fd, mode); 29917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(path); 30017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return gz; 30117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 30217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 30317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 30417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef _WIN32 30517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' TurnergzFile ZEXPORT gzopen_w(path, mode) 30617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const wchar_t *path; 30717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *mode; 30817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 30917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return gz_open(path, -2, mode); 31017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 31117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 31217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 31317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 31417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerint ZEXPORT gzbuffer(file, size) 31517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 31617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner unsigned size; 31717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 31817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 31917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 32017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 32117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 32217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 32317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 32417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 32517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 32617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 32717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* make sure we haven't already allocated memory */ 32817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->size != 0) 32917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 33017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 33117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* check and set requested size */ 33217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (size < 2) 33317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner size = 2; /* need two bytes to check magic header */ 33417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->want = size; 33517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return 0; 33617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 33717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 33817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 33917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerint ZEXPORT gzrewind(file) 34017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 34117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 34217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 34317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 34417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure */ 34517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 34617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 34717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 34817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 34917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* check that we're reading and that there's no error */ 35017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ || 35117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (state->err != Z_OK && state->err != Z_BUF_ERROR)) 35217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 35317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 35417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* back up and start over */ 35517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 35617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 35717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_reset(state); 35817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return 0; 35917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 36017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 36117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 36217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off64_t ZEXPORT gzseek64(file, offset, whence) 36317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 36417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t offset; 36517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int whence; 36617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 36717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner unsigned n; 36817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t ret; 36917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 37017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 37117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 37217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 37317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 37417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 37517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 37617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 37717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 37817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* check that there's no error */ 37917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->err != Z_OK && state->err != Z_BUF_ERROR) 38017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 38117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 38217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* can only seek from start or relative to current position */ 38317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (whence != SEEK_SET && whence != SEEK_CUR) 38417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 38517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 38617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* normalize offset to a SEEK_CUR specification */ 38717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (whence == SEEK_SET) 38817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset -= state->x.pos; 38917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else if (state->seek) 39017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset += state->skip; 39117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->seek = 0; 39217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 39317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* if within raw area while reading, just go there */ 39417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ && state->how == COPY && 39517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.pos + offset >= 0) { 39617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 39717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (ret == -1) 39817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 39917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.have = 0; 40017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->eof = 0; 40117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->past = 0; 40217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->seek = 0; 40317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_error(state, Z_OK, NULL); 40417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->strm.avail_in = 0; 40517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.pos += offset; 40617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return state->x.pos; 40717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 40817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 40917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* calculate skip amount, rewinding if needed for back seek when reading */ 41017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (offset < 0) { 41117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ) /* writing -- can't go backwards */ 41217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 41317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset += state->x.pos; 41417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (offset < 0) /* before start of file! */ 41517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 41617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (gzrewind(file) == -1) /* rewind, then skip to offset */ 41717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 41817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 41917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 42017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* if reading, skip what's in output buffer (one less gzgetc() check) */ 42117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) { 42217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 42317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (unsigned)offset : state->x.have; 42417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.have -= n; 42517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.next += n; 42617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.pos += n; 42717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset -= n; 42817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 42917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 43017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* request skip (if not zero) */ 43117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (offset) { 43217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->seek = 1; 43317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->skip = offset; 43417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 43517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return state->x.pos + offset; 43617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 43717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 43817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 43917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off_t ZEXPORT gzseek(file, offset, whence) 44017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 44117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off_t offset; 44217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int whence; 44317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 44417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t ret; 44517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 44617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner ret = gzseek64(file, (z_off64_t)offset, whence); 44717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return ret == (z_off_t)ret ? (z_off_t)ret : -1; 44817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 44917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 45017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 45117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off64_t ZEXPORT gztell64(file) 45217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 45317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 45417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 45517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 45617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 45717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 45817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 45917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 46017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 46117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 46217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 46317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* return position */ 46417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return state->x.pos + (state->seek ? state->skip : 0); 46517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 46617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 46717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 46817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off_t ZEXPORT gztell(file) 46917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 47017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 47117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t ret; 47217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 47317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner ret = gztell64(file); 47417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return ret == (z_off_t)ret ? (z_off_t)ret : -1; 47517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 47617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 47717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 47817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off64_t ZEXPORT gzoffset64(file) 47917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 48017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 48117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t offset; 48217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 48317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 48417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 48517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 48617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 48717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 48817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 48917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 49017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 49117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* compute and return effective offset in file */ 49217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset = LSEEK(state->fd, 0, SEEK_CUR); 49317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (offset == -1) 49417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return -1; 49517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) /* reading */ 49617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner offset -= state->strm.avail_in; /* don't count buffered input */ 49717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return offset; 49817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 49917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 50017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 50117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerz_off_t ZEXPORT gzoffset(file) 50217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 50317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 50417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_off64_t ret; 50517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 50617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner ret = gzoffset64(file); 50717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return ret == (z_off_t)ret ? (z_off_t)ret : -1; 50817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 50917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 51017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 51117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerint ZEXPORT gzeof(file) 51217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 51317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 51417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 51517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 51617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 51717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 51817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return 0; 51917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 52017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 52117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return 0; 52217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 52317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* return end-of-file state */ 52417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return state->mode == GZ_READ ? state->past : 0; 52517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 52617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 52717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 52817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerconst char * ZEXPORT gzerror(file, errnum) 52917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 53017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int *errnum; 53117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 53217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 53317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 53417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 53517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 53617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 53717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 53817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 53917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return NULL; 54017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 54117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* return error information */ 54217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (errnum != NULL) 54317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner *errnum = state->err; 54417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return state->err == Z_MEM_ERROR ? "out of memory" : 54517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner (state->msg == NULL ? "" : state->msg); 54617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 54717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 54817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* -- see zlib.h -- */ 54917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnervoid ZEXPORT gzclearerr(file) 55017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gzFile file; 55117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 55217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 55317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 55417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* get internal structure and check integrity */ 55517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (file == NULL) 55617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 55717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state = (gz_statep)file; 55817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode != GZ_READ && state->mode != GZ_WRITE) 55917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 56017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 56117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* clear error and end-of-file */ 56217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->mode == GZ_READ) { 56317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->eof = 0; 56417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->past = 0; 56517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 56617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_error(state, Z_OK, NULL); 56717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 56817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 56917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* Create an error message in allocated memory and set state->err and 57017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->msg accordingly. Free any previous error message already there. Do 57117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner not try to free or allocate space if the error is Z_MEM_ERROR (out of 57217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner memory). Simply save the error message as a static string. If there is an 57317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner allocation failure constructing the error message, then convert the error to 57417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner out of memory. */ 57517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnervoid ZLIB_INTERNAL gz_error(state, err, msg) 57617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner gz_statep state; 57717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner int err; 57817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner const char *msg; 57917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 58017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* free previously allocated message and clear */ 58117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->msg != NULL) { 58217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->err != Z_MEM_ERROR) 58317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner free(state->msg); 58417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->msg = NULL; 58517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 58617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 58717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 58817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (err != Z_OK && err != Z_BUF_ERROR) 58917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->x.have = 0; 59017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 59117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* set error code, and if no message, then done */ 59217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->err = err; 59317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (msg == NULL) 59417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 59517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 59617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* for an out of memory error, return literal string when requested */ 59717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (err == Z_MEM_ERROR) 59817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 59917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 60017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* construct error message with path */ 60117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 60217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NULL) { 60317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->err = Z_MEM_ERROR; 60417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 60517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 60617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#if !defined(NO_snprintf) && !defined(NO_vsnprintf) 60717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 60817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner "%s%s%s", state->path, ": ", msg); 60917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 61017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strcpy(state->msg, state->path); 61117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strcat(state->msg, ": "); 61217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strcat(state->msg, msg); 61317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 61417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return; 61517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 61617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 61717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifndef INT_MAX 61817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner/* portably return maximum value for an int (when limits.h presumed not 61917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner available) -- we need to do this to cover cases where 2's complement not 62017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner used, since C standard permits 1's complement and sign-bit representations, 62117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner otherwise we could just use ((unsigned)-1) >> 1 */ 62217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turnerunsigned ZLIB_INTERNAL gz_intmax() 62317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner{ 62417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner unsigned p, q; 62517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 62617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner p = 1; 62717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner do { 62817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner q = p; 62917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner p <<= 1; 63017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner p++; 63117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } while (p > q); 63217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return q >> 1; 63317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner} 63417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 635