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