Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/zlib/src/gzread.c

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/zlib/src/gzread.c (Version 11.3.0) and /externals/zlib/src/gzread.c (Version 10.5.p1)


  1 /* gzread.c -- zlib functions for reading gzip      1 /* gzread.c -- zlib functions for reading gzip files
  2  * Copyright (C) 2004-2017 Mark Adler          <<   2  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
  3  * For conditions of distribution and use, see      3  * For conditions of distribution and use, see copyright notice in zlib.h
  4  */                                                 4  */
  5                                                     5 
  6 #include "gzguts.h"                                 6 #include "gzguts.h"
  7                                                     7 
  8 /* Local functions */                               8 /* Local functions */
  9 local int gz_load OF((gz_statep, unsigned char      9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
 10 local int gz_avail OF((gz_statep));                10 local int gz_avail OF((gz_statep));
 11 local int gz_look OF((gz_statep));                 11 local int gz_look OF((gz_statep));
 12 local int gz_decomp OF((gz_statep));               12 local int gz_decomp OF((gz_statep));
 13 local int gz_fetch OF((gz_statep));                13 local int gz_fetch OF((gz_statep));
 14 local int gz_skip OF((gz_statep, z_off64_t));      14 local int gz_skip OF((gz_statep, z_off64_t));
 15 local z_size_t gz_read OF((gz_statep, voidp, z     15 local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
 16                                                    16 
 17 /* Use read() to load a buffer -- return -1 on     17 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
 18    state->fd, and update state->eof, state->er     18    state->fd, and update state->eof, state->err, and state->msg as appropriate.
 19    This function needs to loop on read(), sinc     19    This function needs to loop on read(), since read() is not guaranteed to
 20    read the number of bytes requested, dependi     20    read the number of bytes requested, depending on the type of descriptor. */
 21 local int gz_load(state, buf, len, have)           21 local int gz_load(state, buf, len, have)
 22     gz_statep state;                               22     gz_statep state;
 23     unsigned char *buf;                            23     unsigned char *buf;
 24     unsigned len;                                  24     unsigned len;
 25     unsigned *have;                                25     unsigned *have;
 26 {                                                  26 {
 27     int ret;                                       27     int ret;
 28     unsigned get, max = ((unsigned)-1 >> 2) +      28     unsigned get, max = ((unsigned)-1 >> 2) + 1;
 29                                                    29 
 30     *have = 0;                                     30     *have = 0;
 31     do {                                           31     do {
 32         get = len - *have;                         32         get = len - *have;
 33         if (get > max)                             33         if (get > max)
 34             get = max;                             34             get = max;
 35         ret = read(state->fd, buf + *have, get     35         ret = read(state->fd, buf + *have, get);
 36         if (ret <= 0)                              36         if (ret <= 0)
 37             break;                                 37             break;
 38         *have += (unsigned)ret;                    38         *have += (unsigned)ret;
 39     } while (*have < len);                         39     } while (*have < len);
 40     if (ret < 0) {                                 40     if (ret < 0) {
 41         gz_error(state, Z_ERRNO, zstrerror());     41         gz_error(state, Z_ERRNO, zstrerror());
 42         return -1;                                 42         return -1;
 43     }                                              43     }
 44     if (ret == 0)                                  44     if (ret == 0)
 45         state->eof = 1;                            45         state->eof = 1;
 46     return 0;                                      46     return 0;
 47 }                                                  47 }
 48                                                    48 
 49 /* Load up input buffer and set eof flag if la     49 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
 50    error, 0 otherwise.  Note that the eof flag     50    error, 0 otherwise.  Note that the eof flag is set when the end of the input
 51    file is reached, even though there may be u     51    file is reached, even though there may be unused data in the buffer.  Once
 52    that data has been used, no more attempts w     52    that data has been used, no more attempts will be made to read the file.
 53    If strm->avail_in != 0, then the current da     53    If strm->avail_in != 0, then the current data is moved to the beginning of
 54    the input buffer, and then the remainder of     54    the input buffer, and then the remainder of the buffer is loaded with the
 55    available data from the input file. */          55    available data from the input file. */
 56 local int gz_avail(state)                          56 local int gz_avail(state)
 57     gz_statep state;                               57     gz_statep state;
 58 {                                                  58 {
 59     unsigned got;                                  59     unsigned got;
 60     z_streamp strm = &(state->strm);               60     z_streamp strm = &(state->strm);
 61                                                    61 
 62     if (state->err != Z_OK && state->err != Z_     62     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
 63         return -1;                                 63         return -1;
 64     if (state->eof == 0) {                         64     if (state->eof == 0) {
 65         if (strm->avail_in) {       /* copy wh     65         if (strm->avail_in) {       /* copy what's there to the start */
 66             unsigned char *p = state->in;          66             unsigned char *p = state->in;
 67             unsigned const char *q = strm->nex     67             unsigned const char *q = strm->next_in;
 68             unsigned n = strm->avail_in;           68             unsigned n = strm->avail_in;
 69             do {                                   69             do {
 70                 *p++ = *q++;                       70                 *p++ = *q++;
 71             } while (--n);                         71             } while (--n);
 72         }                                          72         }
 73         if (gz_load(state, state->in + strm->a     73         if (gz_load(state, state->in + strm->avail_in,
 74                     state->size - strm->avail_     74                     state->size - strm->avail_in, &got) == -1)
 75             return -1;                             75             return -1;
 76         strm->avail_in += got;                     76         strm->avail_in += got;
 77         strm->next_in = state->in;                 77         strm->next_in = state->in;
 78     }                                              78     }
 79     return 0;                                      79     return 0;
 80 }                                                  80 }
 81                                                    81 
 82 /* Look for gzip header, set up for inflate or     82 /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
 83    If this is the first time in, allocate requ     83    If this is the first time in, allocate required memory.  state->how will be
 84    left unchanged if there is no more input da     84    left unchanged if there is no more input data available, will be set to COPY
 85    if there is no gzip header and direct copyi     85    if there is no gzip header and direct copying will be performed, or it will
 86    be set to GZIP for decompression.  If direc     86    be set to GZIP for decompression.  If direct copying, then leftover input
 87    data from the input buffer will be copied t     87    data from the input buffer will be copied to the output buffer.  In that
 88    case, all further file reads will be direct     88    case, all further file reads will be directly to either the output buffer or
 89    a user buffer.  If decompressing, the infla     89    a user buffer.  If decompressing, the inflate state will be initialized.
 90    gz_look() will return 0 on success or -1 on     90    gz_look() will return 0 on success or -1 on failure. */
 91 local int gz_look(state)                           91 local int gz_look(state)
 92     gz_statep state;                               92     gz_statep state;
 93 {                                                  93 {
 94     z_streamp strm = &(state->strm);               94     z_streamp strm = &(state->strm);
 95                                                    95 
 96     /* allocate read buffers and inflate memor     96     /* allocate read buffers and inflate memory */
 97     if (state->size == 0) {                        97     if (state->size == 0) {
 98         /* allocate buffers */                     98         /* allocate buffers */
 99         state->in = (unsigned char *)malloc(st     99         state->in = (unsigned char *)malloc(state->want);
100         state->out = (unsigned char *)malloc(s    100         state->out = (unsigned char *)malloc(state->want << 1);
101         if (state->in == NULL || state->out ==    101         if (state->in == NULL || state->out == NULL) {
102             free(state->out);                     102             free(state->out);
103             free(state->in);                      103             free(state->in);
104             gz_error(state, Z_MEM_ERROR, "out     104             gz_error(state, Z_MEM_ERROR, "out of memory");
105             return -1;                            105             return -1;
106         }                                         106         }
107         state->size = state->want;                107         state->size = state->want;
108                                                   108 
109         /* allocate inflate memory */             109         /* allocate inflate memory */
110         state->strm.zalloc = Z_NULL;              110         state->strm.zalloc = Z_NULL;
111         state->strm.zfree = Z_NULL;               111         state->strm.zfree = Z_NULL;
112         state->strm.opaque = Z_NULL;              112         state->strm.opaque = Z_NULL;
113         state->strm.avail_in = 0;                 113         state->strm.avail_in = 0;
114         state->strm.next_in = Z_NULL;             114         state->strm.next_in = Z_NULL;
115         if (inflateInit2(&(state->strm), 15 +     115         if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
116             free(state->out);                     116             free(state->out);
117             free(state->in);                      117             free(state->in);
118             state->size = 0;                      118             state->size = 0;
119             gz_error(state, Z_MEM_ERROR, "out     119             gz_error(state, Z_MEM_ERROR, "out of memory");
120             return -1;                            120             return -1;
121         }                                         121         }
122     }                                             122     }
123                                                   123 
124     /* get at least the magic bytes in the inp    124     /* get at least the magic bytes in the input buffer */
125     if (strm->avail_in < 2) {                     125     if (strm->avail_in < 2) {
126         if (gz_avail(state) == -1)                126         if (gz_avail(state) == -1)
127             return -1;                            127             return -1;
128         if (strm->avail_in == 0)                  128         if (strm->avail_in == 0)
129             return 0;                             129             return 0;
130     }                                             130     }
131                                                   131 
132     /* look for gzip magic bytes -- if there,     132     /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
133        a logical dilemma here when considering    133        a logical dilemma here when considering the case of a partially written
134        gzip file, to wit, if a single 31 byte     134        gzip file, to wit, if a single 31 byte is written, then we cannot tell
135        whether this is a single-byte file, or     135        whether this is a single-byte file, or just a partially written gzip
136        file -- for here we assume that if a gz    136        file -- for here we assume that if a gzip file is being written, then
137        the header will be written in a single     137        the header will be written in a single operation, so that reading a
138        single byte is sufficient indication th    138        single byte is sufficient indication that it is not a gzip file) */
139     if (strm->avail_in > 1 &&                     139     if (strm->avail_in > 1 &&
140             strm->next_in[0] == 31 && strm->ne    140             strm->next_in[0] == 31 && strm->next_in[1] == 139) {
141         inflateReset(strm);                       141         inflateReset(strm);
142         state->how = GZIP;                        142         state->how = GZIP;
143         state->direct = 0;                        143         state->direct = 0;
144         return 0;                                 144         return 0;
145     }                                             145     }
146                                                   146 
147     /* no gzip header -- if we were decoding g    147     /* no gzip header -- if we were decoding gzip before, then this is trailing
148        garbage.  Ignore the trailing garbage a    148        garbage.  Ignore the trailing garbage and finish. */
149     if (state->direct == 0) {                     149     if (state->direct == 0) {
150         strm->avail_in = 0;                       150         strm->avail_in = 0;
151         state->eof = 1;                           151         state->eof = 1;
152         state->x.have = 0;                        152         state->x.have = 0;
153         return 0;                                 153         return 0;
154     }                                             154     }
155                                                   155 
156     /* doing raw i/o, copy any leftover input     156     /* doing raw i/o, copy any leftover input to output -- this assumes that
157        the output buffer is larger than the in    157        the output buffer is larger than the input buffer, which also assures
158        space for gzungetc() */                    158        space for gzungetc() */
159     state->x.next = state->out;                   159     state->x.next = state->out;
160     memcpy(state->x.next, strm->next_in, strm- << 160     if (strm->avail_in) {
161     state->x.have = strm->avail_in;            << 161         memcpy(state->x.next, strm->next_in, strm->avail_in);
162     strm->avail_in = 0;                        << 162         state->x.have = strm->avail_in;
                                                   >> 163         strm->avail_in = 0;
                                                   >> 164     }
163     state->how = COPY;                            165     state->how = COPY;
164     state->direct = 1;                            166     state->direct = 1;
165     return 0;                                     167     return 0;
166 }                                                 168 }
167                                                   169 
168 /* Decompress from input to the provided next_    170 /* Decompress from input to the provided next_out and avail_out in the state.
169    On return, state->x.have and state->x.next     171    On return, state->x.have and state->x.next point to the just decompressed
170    data.  If the gzip stream completes, state-    172    data.  If the gzip stream completes, state->how is reset to LOOK to look for
171    the next gzip stream or raw data, once stat    173    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
172    on success, -1 on failure. */                  174    on success, -1 on failure. */
173 local int gz_decomp(state)                        175 local int gz_decomp(state)
174     gz_statep state;                              176     gz_statep state;
175 {                                                 177 {
176     int ret = Z_OK;                               178     int ret = Z_OK;
177     unsigned had;                                 179     unsigned had;
178     z_streamp strm = &(state->strm);              180     z_streamp strm = &(state->strm);
179                                                   181 
180     /* fill output buffer up to end of deflate    182     /* fill output buffer up to end of deflate stream */
181     had = strm->avail_out;                        183     had = strm->avail_out;
182     do {                                          184     do {
183         /* get more input for inflate() */        185         /* get more input for inflate() */
184         if (strm->avail_in == 0 && gz_avail(st    186         if (strm->avail_in == 0 && gz_avail(state) == -1)
185             return -1;                            187             return -1;
186         if (strm->avail_in == 0) {                188         if (strm->avail_in == 0) {
187             gz_error(state, Z_BUF_ERROR, "unex    189             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
188             break;                                190             break;
189         }                                         191         }
190                                                   192 
191         /* decompress and handle errors */        193         /* decompress and handle errors */
192         ret = inflate(strm, Z_NO_FLUSH);          194         ret = inflate(strm, Z_NO_FLUSH);
193         if (ret == Z_STREAM_ERROR || ret == Z_    195         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
194             gz_error(state, Z_STREAM_ERROR,       196             gz_error(state, Z_STREAM_ERROR,
195                      "internal error: inflate     197                      "internal error: inflate stream corrupt");
196             return -1;                            198             return -1;
197         }                                         199         }
198         if (ret == Z_MEM_ERROR) {                 200         if (ret == Z_MEM_ERROR) {
199             gz_error(state, Z_MEM_ERROR, "out     201             gz_error(state, Z_MEM_ERROR, "out of memory");
200             return -1;                            202             return -1;
201         }                                         203         }
202         if (ret == Z_DATA_ERROR) {                204         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
203             gz_error(state, Z_DATA_ERROR,         205             gz_error(state, Z_DATA_ERROR,
204                      strm->msg == NULL ? "comp    206                      strm->msg == NULL ? "compressed data error" : strm->msg);
205             return -1;                            207             return -1;
206         }                                         208         }
207     } while (strm->avail_out && ret != Z_STREA    209     } while (strm->avail_out && ret != Z_STREAM_END);
208                                                   210 
209     /* update available output */                 211     /* update available output */
210     state->x.have = had - strm->avail_out;        212     state->x.have = had - strm->avail_out;
211     state->x.next = strm->next_out - state->x.    213     state->x.next = strm->next_out - state->x.have;
212                                                   214 
213     /* if the gzip stream completed successful    215     /* if the gzip stream completed successfully, look for another */
214     if (ret == Z_STREAM_END)                      216     if (ret == Z_STREAM_END)
215         state->how = LOOK;                        217         state->how = LOOK;
216                                                   218 
217     /* good decompression */                      219     /* good decompression */
218     return 0;                                     220     return 0;
219 }                                                 221 }
220                                                   222 
221 /* Fetch data and put it in the output buffer.    223 /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
222    Data is either copied from the input file o    224    Data is either copied from the input file or decompressed from the input
223    file depending on state->how.  If state->ho    225    file depending on state->how.  If state->how is LOOK, then a gzip header is
224    looked for to determine whether to copy or     226    looked for to determine whether to copy or decompress.  Returns -1 on error,
225    otherwise 0.  gz_fetch() will leave state->    227    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
226    end of the input file has been reached and     228    end of the input file has been reached and all data has been processed.  */
227 local int gz_fetch(state)                         229 local int gz_fetch(state)
228     gz_statep state;                              230     gz_statep state;
229 {                                                 231 {
230     z_streamp strm = &(state->strm);              232     z_streamp strm = &(state->strm);
231                                                   233 
232     do {                                          234     do {
233         switch(state->how) {                      235         switch(state->how) {
234         case LOOK:      /* -> LOOK, COPY (only    236         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
235             if (gz_look(state) == -1)             237             if (gz_look(state) == -1)
236                 return -1;                        238                 return -1;
237             if (state->how == LOOK)               239             if (state->how == LOOK)
238                 return 0;                         240                 return 0;
239             break;                                241             break;
240         case COPY:      /* -> COPY */             242         case COPY:      /* -> COPY */
241             if (gz_load(state, state->out, sta    243             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
242                     == -1)                        244                     == -1)
243                 return -1;                        245                 return -1;
244             state->x.next = state->out;           246             state->x.next = state->out;
245             return 0;                             247             return 0;
246         case GZIP:      /* -> GZIP or LOOK (if    248         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
247             strm->avail_out = state->size << 1    249             strm->avail_out = state->size << 1;
248             strm->next_out = state->out;          250             strm->next_out = state->out;
249             if (gz_decomp(state) == -1)           251             if (gz_decomp(state) == -1)
250                 return -1;                        252                 return -1;
251         }                                         253         }
252     } while (state->x.have == 0 && (!state->eo    254     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
253     return 0;                                     255     return 0;
254 }                                                 256 }
255                                                   257 
256 /* Skip len uncompressed bytes of output.  Ret    258 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
257 local int gz_skip(state, len)                     259 local int gz_skip(state, len)
258     gz_statep state;                              260     gz_statep state;
259     z_off64_t len;                                261     z_off64_t len;
260 {                                                 262 {
261     unsigned n;                                   263     unsigned n;
262                                                   264 
263     /* skip over len bytes or reach end-of-fil    265     /* skip over len bytes or reach end-of-file, whichever comes first */
264     while (len)                                   266     while (len)
265         /* skip over whatever is in output buf    267         /* skip over whatever is in output buffer */
266         if (state->x.have) {                      268         if (state->x.have) {
267             n = GT_OFF(state->x.have) || (z_of    269             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
268                 (unsigned)len : state->x.have;    270                 (unsigned)len : state->x.have;
269             state->x.have -= n;                   271             state->x.have -= n;
270             state->x.next += n;                   272             state->x.next += n;
271             state->x.pos += n;                    273             state->x.pos += n;
272             len -= n;                             274             len -= n;
273         }                                         275         }
274                                                   276 
275         /* output buffer empty -- return if we    277         /* output buffer empty -- return if we're at the end of the input */
276         else if (state->eof && state->strm.ava    278         else if (state->eof && state->strm.avail_in == 0)
277             break;                                279             break;
278                                                   280 
279         /* need more data to skip -- load up o    281         /* need more data to skip -- load up output buffer */
280         else {                                    282         else {
281             /* get more output, looking for he    283             /* get more output, looking for header if required */
282             if (gz_fetch(state) == -1)            284             if (gz_fetch(state) == -1)
283                 return -1;                        285                 return -1;
284         }                                         286         }
285     return 0;                                     287     return 0;
286 }                                                 288 }
287                                                   289 
288 /* Read len bytes into buf from file, or less     290 /* Read len bytes into buf from file, or less than len up to the end of the
289    input.  Return the number of bytes read.  I    291    input.  Return the number of bytes read.  If zero is returned, either the
290    end of file was reached, or there was an er    292    end of file was reached, or there was an error.  state->err must be
291    consulted in that case to determine which.     293    consulted in that case to determine which. */
292 local z_size_t gz_read(state, buf, len)           294 local z_size_t gz_read(state, buf, len)
293     gz_statep state;                              295     gz_statep state;
294     voidp buf;                                    296     voidp buf;
295     z_size_t len;                                 297     z_size_t len;
296 {                                                 298 {
297     z_size_t got;                                 299     z_size_t got;
298     unsigned n;                                   300     unsigned n;
299                                                   301 
300     /* if len is zero, avoid unnecessary opera    302     /* if len is zero, avoid unnecessary operations */
301     if (len == 0)                                 303     if (len == 0)
302         return 0;                                 304         return 0;
303                                                   305 
304     /* process a skip request */                  306     /* process a skip request */
305     if (state->seek) {                            307     if (state->seek) {
306         state->seek = 0;                          308         state->seek = 0;
307         if (gz_skip(state, state->skip) == -1)    309         if (gz_skip(state, state->skip) == -1)
308             return 0;                             310             return 0;
309     }                                             311     }
310                                                   312 
311     /* get len bytes to buf, or less than len     313     /* get len bytes to buf, or less than len if at the end */
312     got = 0;                                      314     got = 0;
313     do {                                          315     do {
314         /* set n to the maximum amount of len     316         /* set n to the maximum amount of len that fits in an unsigned int */
315         n = (unsigned)-1;                      << 317         n = -1;
316         if (n > len)                              318         if (n > len)
317             n = (unsigned)len;                    319             n = (unsigned)len;
318                                                   320 
319         /* first just try copying data from th    321         /* first just try copying data from the output buffer */
320         if (state->x.have) {                      322         if (state->x.have) {
321             if (state->x.have < n)                323             if (state->x.have < n)
322                 n = state->x.have;                324                 n = state->x.have;
323             memcpy(buf, state->x.next, n);        325             memcpy(buf, state->x.next, n);
324             state->x.next += n;                   326             state->x.next += n;
325             state->x.have -= n;                   327             state->x.have -= n;
326         }                                         328         }
327                                                   329 
328         /* output buffer empty -- return if we    330         /* output buffer empty -- return if we're at the end of the input */
329         else if (state->eof && state->strm.ava    331         else if (state->eof && state->strm.avail_in == 0) {
330             state->past = 1;        /* tried t    332             state->past = 1;        /* tried to read past end */
331             break;                                333             break;
332         }                                         334         }
333                                                   335 
334         /* need output data -- for small len o    336         /* need output data -- for small len or new stream load up our output
335            buffer */                              337            buffer */
336         else if (state->how == LOOK || n < (st    338         else if (state->how == LOOK || n < (state->size << 1)) {
337             /* get more output, looking for he    339             /* get more output, looking for header if required */
338             if (gz_fetch(state) == -1)            340             if (gz_fetch(state) == -1)
339                 return 0;                         341                 return 0;
340             continue;       /* no progress yet    342             continue;       /* no progress yet -- go back to copy above */
341             /* the copy above assures that we     343             /* the copy above assures that we will leave with space in the
342                output buffer, allowing at leas    344                output buffer, allowing at least one gzungetc() to succeed */
343         }                                         345         }
344                                                   346 
345         /* large len -- read directly into use    347         /* large len -- read directly into user buffer */
346         else if (state->how == COPY) {      /*    348         else if (state->how == COPY) {      /* read directly */
347             if (gz_load(state, (unsigned char     349             if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
348                 return 0;                         350                 return 0;
349         }                                         351         }
350                                                   352 
351         /* large len -- decompress directly in    353         /* large len -- decompress directly into user buffer */
352         else {  /* state->how == GZIP */          354         else {  /* state->how == GZIP */
353             state->strm.avail_out = n;            355             state->strm.avail_out = n;
354             state->strm.next_out = (unsigned c    356             state->strm.next_out = (unsigned char *)buf;
355             if (gz_decomp(state) == -1)           357             if (gz_decomp(state) == -1)
356                 return 0;                         358                 return 0;
357             n = state->x.have;                    359             n = state->x.have;
358             state->x.have = 0;                    360             state->x.have = 0;
359         }                                         361         }
360                                                   362 
361         /* update progress */                     363         /* update progress */
362         len -= n;                                 364         len -= n;
363         buf = (char *)buf + n;                    365         buf = (char *)buf + n;
364         got += n;                                 366         got += n;
365         state->x.pos += n;                        367         state->x.pos += n;
366     } while (len);                                368     } while (len);
367                                                   369 
368     /* return number of bytes read into user b    370     /* return number of bytes read into user buffer */
369     return got;                                   371     return got;
370 }                                                 372 }
371                                                   373 
372 /* -- see zlib.h -- */                            374 /* -- see zlib.h -- */
373 int ZEXPORT gzread(file, buf, len)                375 int ZEXPORT gzread(file, buf, len)
374     gzFile file;                                  376     gzFile file;
375     voidp buf;                                    377     voidp buf;
376     unsigned len;                                 378     unsigned len;
377 {                                                 379 {
378     gz_statep state;                              380     gz_statep state;
379                                                   381 
380     /* get internal structure */                  382     /* get internal structure */
381     if (file == NULL)                             383     if (file == NULL)
382         return -1;                                384         return -1;
383     state = (gz_statep)file;                      385     state = (gz_statep)file;
384                                                   386 
385     /* check that we're reading and that there    387     /* check that we're reading and that there's no (serious) error */
386     if (state->mode != GZ_READ ||                 388     if (state->mode != GZ_READ ||
387             (state->err != Z_OK && state->err     389             (state->err != Z_OK && state->err != Z_BUF_ERROR))
388         return -1;                                390         return -1;
389                                                   391 
390     /* since an int is returned, make sure len    392     /* since an int is returned, make sure len fits in one, otherwise return
391        with an error (this avoids a flaw in th    393        with an error (this avoids a flaw in the interface) */
392     if ((int)len < 0) {                           394     if ((int)len < 0) {
393         gz_error(state, Z_STREAM_ERROR, "reque    395         gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
394         return -1;                                396         return -1;
395     }                                             397     }
396                                                   398 
397     /* read len or fewer bytes to buf */          399     /* read len or fewer bytes to buf */
398     len = (unsigned)gz_read(state, buf, len);     400     len = (unsigned)gz_read(state, buf, len);
399                                                   401 
400     /* check for an error */                      402     /* check for an error */
401     if (len == 0 && state->err != Z_OK && stat    403     if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
402         return -1;                                404         return -1;
403                                                   405 
404     /* return the number of bytes read (this i    406     /* return the number of bytes read (this is assured to fit in an int) */
405     return (int)len;                              407     return (int)len;
406 }                                                 408 }
407                                                   409 
408 /* -- see zlib.h -- */                            410 /* -- see zlib.h -- */
409 z_size_t ZEXPORT gzfread(buf, size, nitems, fi    411 z_size_t ZEXPORT gzfread(buf, size, nitems, file)
410     voidp buf;                                    412     voidp buf;
411     z_size_t size;                                413     z_size_t size;
412     z_size_t nitems;                              414     z_size_t nitems;
413     gzFile file;                                  415     gzFile file;
414 {                                                 416 {
415     z_size_t len;                                 417     z_size_t len;
416     gz_statep state;                              418     gz_statep state;
417                                                   419 
418     /* get internal structure */                  420     /* get internal structure */
419     if (file == NULL)                             421     if (file == NULL)
420         return 0;                                 422         return 0;
421     state = (gz_statep)file;                      423     state = (gz_statep)file;
422                                                   424 
423     /* check that we're reading and that there    425     /* check that we're reading and that there's no (serious) error */
424     if (state->mode != GZ_READ ||                 426     if (state->mode != GZ_READ ||
425             (state->err != Z_OK && state->err     427             (state->err != Z_OK && state->err != Z_BUF_ERROR))
426         return 0;                                 428         return 0;
427                                                   429 
428     /* compute bytes to read -- error on overf    430     /* compute bytes to read -- error on overflow */
429     len = nitems * size;                          431     len = nitems * size;
430     if (size && len / size != nitems) {           432     if (size && len / size != nitems) {
431         gz_error(state, Z_STREAM_ERROR, "reque    433         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
432         return 0;                                 434         return 0;
433     }                                             435     }
434                                                   436 
435     /* read len or fewer bytes to buf, return     437     /* read len or fewer bytes to buf, return the number of full items read */
436     return len ? gz_read(state, buf, len) / si    438     return len ? gz_read(state, buf, len) / size : 0;
437 }                                                 439 }
438                                                   440 
439 /* -- see zlib.h -- */                            441 /* -- see zlib.h -- */
440 #ifdef Z_PREFIX_SET                               442 #ifdef Z_PREFIX_SET
441 #  undef z_gzgetc                                 443 #  undef z_gzgetc
442 #else                                             444 #else
443 #  undef gzgetc                                   445 #  undef gzgetc
444 #endif                                            446 #endif
445 int ZEXPORT gzgetc(file)                          447 int ZEXPORT gzgetc(file)
446     gzFile file;                                  448     gzFile file;
447 {                                                 449 {
                                                   >> 450     int ret;
448     unsigned char buf[1];                         451     unsigned char buf[1];
449     gz_statep state;                              452     gz_statep state;
450                                                   453 
451     /* get internal structure */                  454     /* get internal structure */
452     if (file == NULL)                             455     if (file == NULL)
453         return -1;                                456         return -1;
454     state = (gz_statep)file;                      457     state = (gz_statep)file;
455                                                   458 
456     /* check that we're reading and that there    459     /* check that we're reading and that there's no (serious) error */
457     if (state->mode != GZ_READ ||                 460     if (state->mode != GZ_READ ||
458         (state->err != Z_OK && state->err != Z    461         (state->err != Z_OK && state->err != Z_BUF_ERROR))
459         return -1;                                462         return -1;
460                                                   463 
461     /* try output buffer (no need to check for    464     /* try output buffer (no need to check for skip request) */
462     if (state->x.have) {                          465     if (state->x.have) {
463         state->x.have--;                          466         state->x.have--;
464         state->x.pos++;                           467         state->x.pos++;
465         return *(state->x.next)++;                468         return *(state->x.next)++;
466     }                                             469     }
467                                                   470 
468     /* nothing there -- try gz_read() */          471     /* nothing there -- try gz_read() */
469     return gz_read(state, buf, 1) < 1 ? -1 : b << 472     ret = (int)gz_read(state, buf, 1);
                                                   >> 473     return ret < 1 ? -1 : buf[0];
470 }                                                 474 }
471                                                   475 
472 int ZEXPORT gzgetc_(file)                         476 int ZEXPORT gzgetc_(file)
473 gzFile file;                                      477 gzFile file;
474 {                                                 478 {
475     return gzgetc(file);                          479     return gzgetc(file);
476 }                                                 480 }
477                                                   481 
478 /* -- see zlib.h -- */                            482 /* -- see zlib.h -- */
479 int ZEXPORT gzungetc(c, file)                     483 int ZEXPORT gzungetc(c, file)
480     int c;                                        484     int c;
481     gzFile file;                                  485     gzFile file;
482 {                                                 486 {
483     gz_statep state;                              487     gz_statep state;
484                                                   488 
485     /* get internal structure */                  489     /* get internal structure */
486     if (file == NULL)                             490     if (file == NULL)
487         return -1;                                491         return -1;
488     state = (gz_statep)file;                      492     state = (gz_statep)file;
489                                                   493 
490     /* check that we're reading and that there    494     /* check that we're reading and that there's no (serious) error */
491     if (state->mode != GZ_READ ||                 495     if (state->mode != GZ_READ ||
492         (state->err != Z_OK && state->err != Z    496         (state->err != Z_OK && state->err != Z_BUF_ERROR))
493         return -1;                                497         return -1;
494                                                   498 
495     /* process a skip request */                  499     /* process a skip request */
496     if (state->seek) {                            500     if (state->seek) {
497         state->seek = 0;                          501         state->seek = 0;
498         if (gz_skip(state, state->skip) == -1)    502         if (gz_skip(state, state->skip) == -1)
499             return -1;                            503             return -1;
500     }                                             504     }
501                                                   505 
502     /* can't push EOF */                          506     /* can't push EOF */
503     if (c < 0)                                    507     if (c < 0)
504         return -1;                                508         return -1;
505                                                   509 
506     /* if output buffer empty, put byte at end    510     /* if output buffer empty, put byte at end (allows more pushing) */
507     if (state->x.have == 0) {                     511     if (state->x.have == 0) {
508         state->x.have = 1;                        512         state->x.have = 1;
509         state->x.next = state->out + (state->s    513         state->x.next = state->out + (state->size << 1) - 1;
510         state->x.next[0] = (unsigned char)c;      514         state->x.next[0] = (unsigned char)c;
511         state->x.pos--;                           515         state->x.pos--;
512         state->past = 0;                          516         state->past = 0;
513         return c;                                 517         return c;
514     }                                             518     }
515                                                   519 
516     /* if no room, give up (must have already     520     /* if no room, give up (must have already done a gzungetc()) */
517     if (state->x.have == (state->size << 1)) {    521     if (state->x.have == (state->size << 1)) {
518         gz_error(state, Z_DATA_ERROR, "out of     522         gz_error(state, Z_DATA_ERROR, "out of room to push characters");
519         return -1;                                523         return -1;
520     }                                             524     }
521                                                   525 
522     /* slide output data if needed and insert     526     /* slide output data if needed and insert byte before existing data */
523     if (state->x.next == state->out) {            527     if (state->x.next == state->out) {
524         unsigned char *src = state->out + stat    528         unsigned char *src = state->out + state->x.have;
525         unsigned char *dest = state->out + (st    529         unsigned char *dest = state->out + (state->size << 1);
526         while (src > state->out)                  530         while (src > state->out)
527             *--dest = *--src;                     531             *--dest = *--src;
528         state->x.next = dest;                     532         state->x.next = dest;
529     }                                             533     }
530     state->x.have++;                              534     state->x.have++;
531     state->x.next--;                              535     state->x.next--;
532     state->x.next[0] = (unsigned char)c;          536     state->x.next[0] = (unsigned char)c;
533     state->x.pos--;                               537     state->x.pos--;
534     state->past = 0;                              538     state->past = 0;
535     return c;                                     539     return c;
536 }                                                 540 }
537                                                   541 
538 /* -- see zlib.h -- */                            542 /* -- see zlib.h -- */
539 char * ZEXPORT gzgets(file, buf, len)             543 char * ZEXPORT gzgets(file, buf, len)
540     gzFile file;                                  544     gzFile file;
541     char *buf;                                    545     char *buf;
542     int len;                                      546     int len;
543 {                                                 547 {
544     unsigned left, n;                             548     unsigned left, n;
545     char *str;                                    549     char *str;
546     unsigned char *eol;                           550     unsigned char *eol;
547     gz_statep state;                              551     gz_statep state;
548                                                   552 
549     /* check parameters and get internal struc    553     /* check parameters and get internal structure */
550     if (file == NULL || buf == NULL || len < 1    554     if (file == NULL || buf == NULL || len < 1)
551         return NULL;                              555         return NULL;
552     state = (gz_statep)file;                      556     state = (gz_statep)file;
553                                                   557 
554     /* check that we're reading and that there    558     /* check that we're reading and that there's no (serious) error */
555     if (state->mode != GZ_READ ||                 559     if (state->mode != GZ_READ ||
556         (state->err != Z_OK && state->err != Z    560         (state->err != Z_OK && state->err != Z_BUF_ERROR))
557         return NULL;                              561         return NULL;
558                                                   562 
559     /* process a skip request */                  563     /* process a skip request */
560     if (state->seek) {                            564     if (state->seek) {
561         state->seek = 0;                          565         state->seek = 0;
562         if (gz_skip(state, state->skip) == -1)    566         if (gz_skip(state, state->skip) == -1)
563             return NULL;                          567             return NULL;
564     }                                             568     }
565                                                   569 
566     /* copy output bytes up to new line or len    570     /* copy output bytes up to new line or len - 1, whichever comes first --
567        append a terminating zero to the string    571        append a terminating zero to the string (we don't check for a zero in
568        the contents, let the user worry about     572        the contents, let the user worry about that) */
569     str = buf;                                    573     str = buf;
570     left = (unsigned)len - 1;                     574     left = (unsigned)len - 1;
571     if (left) do {                                575     if (left) do {
572         /* assure that something is in the out    576         /* assure that something is in the output buffer */
573         if (state->x.have == 0 && gz_fetch(sta    577         if (state->x.have == 0 && gz_fetch(state) == -1)
574             return NULL;                /* err    578             return NULL;                /* error */
575         if (state->x.have == 0) {       /* end    579         if (state->x.have == 0) {       /* end of file */
576             state->past = 1;            /* rea    580             state->past = 1;            /* read past end */
577             break;                      /* ret    581             break;                      /* return what we have */
578         }                                         582         }
579                                                   583 
580         /* look for end-of-line in current out    584         /* look for end-of-line in current output buffer */
581         n = state->x.have > left ? left : stat    585         n = state->x.have > left ? left : state->x.have;
582         eol = (unsigned char *)memchr(state->x    586         eol = (unsigned char *)memchr(state->x.next, '\n', n);
583         if (eol != NULL)                          587         if (eol != NULL)
584             n = (unsigned)(eol - state->x.next    588             n = (unsigned)(eol - state->x.next) + 1;
585                                                   589 
586         /* copy through end-of-line, or remain    590         /* copy through end-of-line, or remainder if not found */
587         memcpy(buf, state->x.next, n);            591         memcpy(buf, state->x.next, n);
588         state->x.have -= n;                       592         state->x.have -= n;
589         state->x.next += n;                       593         state->x.next += n;
590         state->x.pos += n;                        594         state->x.pos += n;
591         left -= n;                                595         left -= n;
592         buf += n;                                 596         buf += n;
593     } while (left && eol == NULL);                597     } while (left && eol == NULL);
594                                                   598 
595     /* return terminated string, or if nothing    599     /* return terminated string, or if nothing, end of file */
596     if (buf == str)                               600     if (buf == str)
597         return NULL;                              601         return NULL;
598     buf[0] = 0;                                   602     buf[0] = 0;
599     return str;                                   603     return str;
600 }                                                 604 }
601                                                   605 
602 /* -- see zlib.h -- */                            606 /* -- see zlib.h -- */
603 int ZEXPORT gzdirect(file)                        607 int ZEXPORT gzdirect(file)
604     gzFile file;                                  608     gzFile file;
605 {                                                 609 {
606     gz_statep state;                              610     gz_statep state;
607                                                   611 
608     /* get internal structure */                  612     /* get internal structure */
609     if (file == NULL)                             613     if (file == NULL)
610         return 0;                                 614         return 0;
611     state = (gz_statep)file;                      615     state = (gz_statep)file;
612                                                   616 
613     /* if the state is not known, but we can f    617     /* if the state is not known, but we can find out, then do so (this is
614        mainly for right after a gzopen() or gz    618        mainly for right after a gzopen() or gzdopen()) */
615     if (state->mode == GZ_READ && state->how =    619     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
616         (void)gz_look(state);                     620         (void)gz_look(state);
617                                                   621 
618     /* return 1 if transparent, 0 if processin    622     /* return 1 if transparent, 0 if processing a gzip stream */
619     return state->direct;                         623     return state->direct;
620 }                                                 624 }
621                                                   625 
622 /* -- see zlib.h -- */                            626 /* -- see zlib.h -- */
623 int ZEXPORT gzclose_r(file)                       627 int ZEXPORT gzclose_r(file)
624     gzFile file;                                  628     gzFile file;
625 {                                                 629 {
626     int ret, err;                                 630     int ret, err;
627     gz_statep state;                              631     gz_statep state;
628                                                   632 
629     /* get internal structure */                  633     /* get internal structure */
630     if (file == NULL)                             634     if (file == NULL)
631         return Z_STREAM_ERROR;                    635         return Z_STREAM_ERROR;
632     state = (gz_statep)file;                      636     state = (gz_statep)file;
633                                                   637 
634     /* check that we're reading */                638     /* check that we're reading */
635     if (state->mode != GZ_READ)                   639     if (state->mode != GZ_READ)
636         return Z_STREAM_ERROR;                    640         return Z_STREAM_ERROR;
637                                                   641 
638     /* free memory and close file */              642     /* free memory and close file */
639     if (state->size) {                            643     if (state->size) {
640         inflateEnd(&(state->strm));               644         inflateEnd(&(state->strm));
641         free(state->out);                         645         free(state->out);
642         free(state->in);                          646         free(state->in);
643     }                                             647     }
644     err = state->err == Z_BUF_ERROR ? Z_BUF_ER    648     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
645     gz_error(state, Z_OK, NULL);                  649     gz_error(state, Z_OK, NULL);
646     free(state->path);                            650     free(state->path);
647     ret = close(state->fd);                       651     ret = close(state->fd);
648     free(state);                                  652     free(state);
649     return ret ? Z_ERRNO : err;                   653     return ret ? Z_ERRNO : err;
650 }                                                 654 }
651                                                   655