< prev index next >

src/java.base/share/native/libzip/zlib/gzread.c

Print this page

 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  */
 24 
 25 /* gzread.c -- zlib functions for reading gzip files
 26  * Copyright (C) 2004-2017 Mark Adler
 27  * For conditions of distribution and use, see copyright notice in zlib.h
 28  */
 29 
 30 #include "gzguts.h"
 31 
 32 /* Local functions */
 33 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
 34 local int gz_avail OF((gz_statep));
 35 local int gz_look OF((gz_statep));
 36 local int gz_decomp OF((gz_statep));
 37 local int gz_fetch OF((gz_statep));
 38 local int gz_skip OF((gz_statep, z_off64_t));
 39 local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
 40 
 41 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
 42    state->fd, and update state->eof, state->err, and state->msg as appropriate.
 43    This function needs to loop on read(), since read() is not guaranteed to
 44    read the number of bytes requested, depending on the type of descriptor. */
 45 local int gz_load(state, buf, len, have)
 46     gz_statep state;
 47     unsigned char *buf;
 48     unsigned len;
 49     unsigned *have;
 50 {
 51     int ret;
 52     unsigned get, max = ((unsigned)-1 >> 2) + 1;
 53 
 54     *have = 0;
 55     do {
 56         get = len - *have;
 57         if (get > max)
 58             get = max;
 59         ret = read(state->fd, buf + *have, get);
 60         if (ret <= 0)
 61             break;
 62         *have += (unsigned)ret;
 63     } while (*have < len);
 64     if (ret < 0) {
 65         gz_error(state, Z_ERRNO, zstrerror());
 66         return -1;
 67     }
 68     if (ret == 0)
 69         state->eof = 1;
 70     return 0;
 71 }
 72 
 73 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
 74    error, 0 otherwise.  Note that the eof flag is set when the end of the input
 75    file is reached, even though there may be unused data in the buffer.  Once
 76    that data has been used, no more attempts will be made to read the file.
 77    If strm->avail_in != 0, then the current data is moved to the beginning of
 78    the input buffer, and then the remainder of the buffer is loaded with the
 79    available data from the input file. */
 80 local int gz_avail(state)
 81     gz_statep state;
 82 {
 83     unsigned got;
 84     z_streamp strm = &(state->strm);
 85 
 86     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
 87         return -1;
 88     if (state->eof == 0) {
 89         if (strm->avail_in) {       /* copy what's there to the start */
 90             unsigned char *p = state->in;
 91             unsigned const char *q = strm->next_in;
 92             unsigned n = strm->avail_in;
 93             do {
 94                 *p++ = *q++;
 95             } while (--n);
 96         }
 97         if (gz_load(state, state->in + strm->avail_in,
 98                     state->size - strm->avail_in, &got) == -1)
 99             return -1;
100         strm->avail_in += got;
101         strm->next_in = state->in;
102     }
103     return 0;
104 }
105 
106 /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
107    If this is the first time in, allocate required memory.  state->how will be
108    left unchanged if there is no more input data available, will be set to COPY
109    if there is no gzip header and direct copying will be performed, or it will
110    be set to GZIP for decompression.  If direct copying, then leftover input
111    data from the input buffer will be copied to the output buffer.  In that
112    case, all further file reads will be directly to either the output buffer or
113    a user buffer.  If decompressing, the inflate state will be initialized.
114    gz_look() will return 0 on success or -1 on failure. */
115 local int gz_look(state)
116     gz_statep state;
117 {
118     z_streamp strm = &(state->strm);
119 
120     /* allocate read buffers and inflate memory */
121     if (state->size == 0) {
122         /* allocate buffers */
123         state->in = (unsigned char *)malloc(state->want);
124         state->out = (unsigned char *)malloc(state->want << 1);
125         if (state->in == NULL || state->out == NULL) {
126             free(state->out);
127             free(state->in);
128             gz_error(state, Z_MEM_ERROR, "out of memory");
129             return -1;
130         }
131         state->size = state->want;
132 
133         /* allocate inflate memory */
134         state->strm.zalloc = Z_NULL;
135         state->strm.zfree = Z_NULL;
136         state->strm.opaque = Z_NULL;
137         state->strm.avail_in = 0;

177         return 0;
178     }
179 
180     /* doing raw i/o, copy any leftover input to output -- this assumes that
181        the output buffer is larger than the input buffer, which also assures
182        space for gzungetc() */
183     state->x.next = state->out;
184     memcpy(state->x.next, strm->next_in, strm->avail_in);
185     state->x.have = strm->avail_in;
186     strm->avail_in = 0;
187     state->how = COPY;
188     state->direct = 1;
189     return 0;
190 }
191 
192 /* Decompress from input to the provided next_out and avail_out in the state.
193    On return, state->x.have and state->x.next point to the just decompressed
194    data.  If the gzip stream completes, state->how is reset to LOOK to look for
195    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
196    on success, -1 on failure. */
197 local int gz_decomp(state)
198     gz_statep state;
199 {
200     int ret = Z_OK;
201     unsigned had;
202     z_streamp strm = &(state->strm);
203 
204     /* fill output buffer up to end of deflate stream */
205     had = strm->avail_out;
206     do {
207         /* get more input for inflate() */
208         if (strm->avail_in == 0 && gz_avail(state) == -1)
209             return -1;
210         if (strm->avail_in == 0) {
211             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
212             break;
213         }
214 
215         /* decompress and handle errors */
216         ret = inflate(strm, Z_NO_FLUSH);
217         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
218             gz_error(state, Z_STREAM_ERROR,
219                      "internal error: inflate stream corrupt");

231     } while (strm->avail_out && ret != Z_STREAM_END);
232 
233     /* update available output */
234     state->x.have = had - strm->avail_out;
235     state->x.next = strm->next_out - state->x.have;
236 
237     /* if the gzip stream completed successfully, look for another */
238     if (ret == Z_STREAM_END)
239         state->how = LOOK;
240 
241     /* good decompression */
242     return 0;
243 }
244 
245 /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
246    Data is either copied from the input file or decompressed from the input
247    file depending on state->how.  If state->how is LOOK, then a gzip header is
248    looked for to determine whether to copy or decompress.  Returns -1 on error,
249    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
250    end of the input file has been reached and all data has been processed.  */
251 local int gz_fetch(state)
252     gz_statep state;
253 {
254     z_streamp strm = &(state->strm);
255 
256     do {
257         switch(state->how) {
258         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
259             if (gz_look(state) == -1)
260                 return -1;
261             if (state->how == LOOK)
262                 return 0;
263             break;
264         case COPY:      /* -> COPY */
265             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
266                     == -1)
267                 return -1;
268             state->x.next = state->out;
269             return 0;
270         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
271             strm->avail_out = state->size << 1;
272             strm->next_out = state->out;
273             if (gz_decomp(state) == -1)
274                 return -1;
275         }
276     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
277     return 0;
278 }
279 
280 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
281 local int gz_skip(state, len)
282     gz_statep state;
283     z_off64_t len;
284 {
285     unsigned n;
286 
287     /* skip over len bytes or reach end-of-file, whichever comes first */
288     while (len)
289         /* skip over whatever is in output buffer */
290         if (state->x.have) {
291             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
292                 (unsigned)len : state->x.have;
293             state->x.have -= n;
294             state->x.next += n;
295             state->x.pos += n;
296             len -= n;
297         }
298 
299         /* output buffer empty -- return if we're at the end of the input */
300         else if (state->eof && state->strm.avail_in == 0)
301             break;
302 
303         /* need more data to skip -- load up output buffer */
304         else {
305             /* get more output, looking for header if required */
306             if (gz_fetch(state) == -1)
307                 return -1;
308         }
309     return 0;
310 }
311 
312 /* Read len bytes into buf from file, or less than len up to the end of the
313    input.  Return the number of bytes read.  If zero is returned, either the
314    end of file was reached, or there was an error.  state->err must be
315    consulted in that case to determine which. */
316 local z_size_t gz_read(state, buf, len)
317     gz_statep state;
318     voidp buf;
319     z_size_t len;
320 {
321     z_size_t got;
322     unsigned n;
323 
324     /* if len is zero, avoid unnecessary operations */
325     if (len == 0)
326         return 0;
327 
328     /* process a skip request */
329     if (state->seek) {
330         state->seek = 0;
331         if (gz_skip(state, state->skip) == -1)
332             return 0;
333     }
334 
335     /* get len bytes to buf, or less than len if at the end */
336     got = 0;
337     do {
338         /* set n to the maximum amount of len that fits in an unsigned int */
339         n = (unsigned)-1;
340         if (n > len)

377             state->strm.avail_out = n;
378             state->strm.next_out = (unsigned char *)buf;
379             if (gz_decomp(state) == -1)
380                 return 0;
381             n = state->x.have;
382             state->x.have = 0;
383         }
384 
385         /* update progress */
386         len -= n;
387         buf = (char *)buf + n;
388         got += n;
389         state->x.pos += n;
390     } while (len);
391 
392     /* return number of bytes read into user buffer */
393     return got;
394 }
395 
396 /* -- see zlib.h -- */
397 int ZEXPORT gzread(file, buf, len)
398     gzFile file;
399     voidp buf;
400     unsigned len;
401 {
402     gz_statep state;
403 
404     /* get internal structure */
405     if (file == NULL)
406         return -1;
407     state = (gz_statep)file;
408 
409     /* check that we're reading and that there's no (serious) error */
410     if (state->mode != GZ_READ ||
411             (state->err != Z_OK && state->err != Z_BUF_ERROR))
412         return -1;
413 
414     /* since an int is returned, make sure len fits in one, otherwise return
415        with an error (this avoids a flaw in the interface) */
416     if ((int)len < 0) {
417         gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
418         return -1;
419     }
420 
421     /* read len or fewer bytes to buf */
422     len = (unsigned)gz_read(state, buf, len);
423 
424     /* check for an error */
425     if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
426         return -1;
427 
428     /* return the number of bytes read (this is assured to fit in an int) */
429     return (int)len;
430 }
431 
432 /* -- see zlib.h -- */
433 z_size_t ZEXPORT gzfread(buf, size, nitems, file)
434     voidp buf;
435     z_size_t size;
436     z_size_t nitems;
437     gzFile file;
438 {
439     z_size_t len;
440     gz_statep state;
441 
442     /* get internal structure */
443     if (file == NULL)
444         return 0;
445     state = (gz_statep)file;
446 
447     /* check that we're reading and that there's no (serious) error */
448     if (state->mode != GZ_READ ||
449             (state->err != Z_OK && state->err != Z_BUF_ERROR))
450         return 0;
451 
452     /* compute bytes to read -- error on overflow */
453     len = nitems * size;
454     if (size && len / size != nitems) {
455         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
456         return 0;
457     }
458 
459     /* read len or fewer bytes to buf, return the number of full items read */
460     return len ? gz_read(state, buf, len) / size : 0;
461 }
462 
463 /* -- see zlib.h -- */
464 #ifdef Z_PREFIX_SET
465 #  undef z_gzgetc
466 #else
467 #  undef gzgetc
468 #endif
469 int ZEXPORT gzgetc(file)
470     gzFile file;
471 {
472     unsigned char buf[1];
473     gz_statep state;
474 
475     /* get internal structure */
476     if (file == NULL)
477         return -1;
478     state = (gz_statep)file;
479 
480     /* check that we're reading and that there's no (serious) error */
481     if (state->mode != GZ_READ ||
482         (state->err != Z_OK && state->err != Z_BUF_ERROR))
483         return -1;
484 
485     /* try output buffer (no need to check for skip request) */
486     if (state->x.have) {
487         state->x.have--;
488         state->x.pos++;
489         return *(state->x.next)++;
490     }
491 
492     /* nothing there -- try gz_read() */
493     return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
494 }
495 
496 int ZEXPORT gzgetc_(file)
497 gzFile file;
498 {
499     return gzgetc(file);
500 }
501 
502 /* -- see zlib.h -- */
503 int ZEXPORT gzungetc(c, file)
504     int c;
505     gzFile file;
506 {
507     gz_statep state;
508 
509     /* get internal structure */
510     if (file == NULL)
511         return -1;
512     state = (gz_statep)file;
513 




514     /* check that we're reading and that there's no (serious) error */
515     if (state->mode != GZ_READ ||
516         (state->err != Z_OK && state->err != Z_BUF_ERROR))
517         return -1;
518 
519     /* process a skip request */
520     if (state->seek) {
521         state->seek = 0;
522         if (gz_skip(state, state->skip) == -1)
523             return -1;
524     }
525 
526     /* can't push EOF */
527     if (c < 0)
528         return -1;
529 
530     /* if output buffer empty, put byte at end (allows more pushing) */
531     if (state->x.have == 0) {
532         state->x.have = 1;
533         state->x.next = state->out + (state->size << 1) - 1;

543         return -1;
544     }
545 
546     /* slide output data if needed and insert byte before existing data */
547     if (state->x.next == state->out) {
548         unsigned char *src = state->out + state->x.have;
549         unsigned char *dest = state->out + (state->size << 1);
550         while (src > state->out)
551             *--dest = *--src;
552         state->x.next = dest;
553     }
554     state->x.have++;
555     state->x.next--;
556     state->x.next[0] = (unsigned char)c;
557     state->x.pos--;
558     state->past = 0;
559     return c;
560 }
561 
562 /* -- see zlib.h -- */
563 char * ZEXPORT gzgets(file, buf, len)
564     gzFile file;
565     char *buf;
566     int len;
567 {
568     unsigned left, n;
569     char *str;
570     unsigned char *eol;
571     gz_statep state;
572 
573     /* check parameters and get internal structure */
574     if (file == NULL || buf == NULL || len < 1)
575         return NULL;
576     state = (gz_statep)file;
577 
578     /* check that we're reading and that there's no (serious) error */
579     if (state->mode != GZ_READ ||
580         (state->err != Z_OK && state->err != Z_BUF_ERROR))
581         return NULL;
582 
583     /* process a skip request */
584     if (state->seek) {
585         state->seek = 0;
586         if (gz_skip(state, state->skip) == -1)
587             return NULL;

607         if (eol != NULL)
608             n = (unsigned)(eol - state->x.next) + 1;
609 
610         /* copy through end-of-line, or remainder if not found */
611         memcpy(buf, state->x.next, n);
612         state->x.have -= n;
613         state->x.next += n;
614         state->x.pos += n;
615         left -= n;
616         buf += n;
617     } while (left && eol == NULL);
618 
619     /* return terminated string, or if nothing, end of file */
620     if (buf == str)
621         return NULL;
622     buf[0] = 0;
623     return str;
624 }
625 
626 /* -- see zlib.h -- */
627 int ZEXPORT gzdirect(file)
628     gzFile file;
629 {
630     gz_statep state;
631 
632     /* get internal structure */
633     if (file == NULL)
634         return 0;
635     state = (gz_statep)file;
636 
637     /* if the state is not known, but we can find out, then do so (this is
638        mainly for right after a gzopen() or gzdopen()) */
639     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
640         (void)gz_look(state);
641 
642     /* return 1 if transparent, 0 if processing a gzip stream */
643     return state->direct;
644 }
645 
646 /* -- see zlib.h -- */
647 int ZEXPORT gzclose_r(file)
648     gzFile file;
649 {
650     int ret, err;
651     gz_statep state;
652 
653     /* get internal structure */
654     if (file == NULL)
655         return Z_STREAM_ERROR;
656     state = (gz_statep)file;
657 
658     /* check that we're reading */
659     if (state->mode != GZ_READ)
660         return Z_STREAM_ERROR;
661 
662     /* free memory and close file */
663     if (state->size) {
664         inflateEnd(&(state->strm));
665         free(state->out);
666         free(state->in);
667     }
668     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
669     gz_error(state, Z_OK, NULL);

 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  */
 24 
 25 /* gzread.c -- zlib functions for reading gzip files
 26  * Copyright (C) 2004-2017 Mark Adler
 27  * For conditions of distribution and use, see copyright notice in zlib.h
 28  */
 29 
 30 #include "gzguts.h"
 31 









 32 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
 33    state->fd, and update state->eof, state->err, and state->msg as appropriate.
 34    This function needs to loop on read(), since read() is not guaranteed to
 35    read the number of bytes requested, depending on the type of descriptor. */
 36 local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
 37                   unsigned *have) {




 38     int ret;
 39     unsigned get, max = ((unsigned)-1 >> 2) + 1;
 40 
 41     *have = 0;
 42     do {
 43         get = len - *have;
 44         if (get > max)
 45             get = max;
 46         ret = read(state->fd, buf + *have, get);
 47         if (ret <= 0)
 48             break;
 49         *have += (unsigned)ret;
 50     } while (*have < len);
 51     if (ret < 0) {
 52         gz_error(state, Z_ERRNO, zstrerror());
 53         return -1;
 54     }
 55     if (ret == 0)
 56         state->eof = 1;
 57     return 0;
 58 }
 59 
 60 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
 61    error, 0 otherwise.  Note that the eof flag is set when the end of the input
 62    file is reached, even though there may be unused data in the buffer.  Once
 63    that data has been used, no more attempts will be made to read the file.
 64    If strm->avail_in != 0, then the current data is moved to the beginning of
 65    the input buffer, and then the remainder of the buffer is loaded with the
 66    available data from the input file. */
 67 local int gz_avail(gz_statep state) {


 68     unsigned got;
 69     z_streamp strm = &(state->strm);
 70 
 71     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
 72         return -1;
 73     if (state->eof == 0) {
 74         if (strm->avail_in) {       /* copy what's there to the start */
 75             unsigned char *p = state->in;
 76             unsigned const char *q = strm->next_in;
 77             unsigned n = strm->avail_in;
 78             do {
 79                 *p++ = *q++;
 80             } while (--n);
 81         }
 82         if (gz_load(state, state->in + strm->avail_in,
 83                     state->size - strm->avail_in, &got) == -1)
 84             return -1;
 85         strm->avail_in += got;
 86         strm->next_in = state->in;
 87     }
 88     return 0;
 89 }
 90 
 91 /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
 92    If this is the first time in, allocate required memory.  state->how will be
 93    left unchanged if there is no more input data available, will be set to COPY
 94    if there is no gzip header and direct copying will be performed, or it will
 95    be set to GZIP for decompression.  If direct copying, then leftover input
 96    data from the input buffer will be copied to the output buffer.  In that
 97    case, all further file reads will be directly to either the output buffer or
 98    a user buffer.  If decompressing, the inflate state will be initialized.
 99    gz_look() will return 0 on success or -1 on failure. */
100 local int gz_look(gz_statep state) {


101     z_streamp strm = &(state->strm);
102 
103     /* allocate read buffers and inflate memory */
104     if (state->size == 0) {
105         /* allocate buffers */
106         state->in = (unsigned char *)malloc(state->want);
107         state->out = (unsigned char *)malloc(state->want << 1);
108         if (state->in == NULL || state->out == NULL) {
109             free(state->out);
110             free(state->in);
111             gz_error(state, Z_MEM_ERROR, "out of memory");
112             return -1;
113         }
114         state->size = state->want;
115 
116         /* allocate inflate memory */
117         state->strm.zalloc = Z_NULL;
118         state->strm.zfree = Z_NULL;
119         state->strm.opaque = Z_NULL;
120         state->strm.avail_in = 0;

160         return 0;
161     }
162 
163     /* doing raw i/o, copy any leftover input to output -- this assumes that
164        the output buffer is larger than the input buffer, which also assures
165        space for gzungetc() */
166     state->x.next = state->out;
167     memcpy(state->x.next, strm->next_in, strm->avail_in);
168     state->x.have = strm->avail_in;
169     strm->avail_in = 0;
170     state->how = COPY;
171     state->direct = 1;
172     return 0;
173 }
174 
175 /* Decompress from input to the provided next_out and avail_out in the state.
176    On return, state->x.have and state->x.next point to the just decompressed
177    data.  If the gzip stream completes, state->how is reset to LOOK to look for
178    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
179    on success, -1 on failure. */
180 local int gz_decomp(gz_statep state) {


181     int ret = Z_OK;
182     unsigned had;
183     z_streamp strm = &(state->strm);
184 
185     /* fill output buffer up to end of deflate stream */
186     had = strm->avail_out;
187     do {
188         /* get more input for inflate() */
189         if (strm->avail_in == 0 && gz_avail(state) == -1)
190             return -1;
191         if (strm->avail_in == 0) {
192             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
193             break;
194         }
195 
196         /* decompress and handle errors */
197         ret = inflate(strm, Z_NO_FLUSH);
198         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
199             gz_error(state, Z_STREAM_ERROR,
200                      "internal error: inflate stream corrupt");

212     } while (strm->avail_out && ret != Z_STREAM_END);
213 
214     /* update available output */
215     state->x.have = had - strm->avail_out;
216     state->x.next = strm->next_out - state->x.have;
217 
218     /* if the gzip stream completed successfully, look for another */
219     if (ret == Z_STREAM_END)
220         state->how = LOOK;
221 
222     /* good decompression */
223     return 0;
224 }
225 
226 /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
227    Data is either copied from the input file or decompressed from the input
228    file depending on state->how.  If state->how is LOOK, then a gzip header is
229    looked for to determine whether to copy or decompress.  Returns -1 on error,
230    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
231    end of the input file has been reached and all data has been processed.  */
232 local int gz_fetch(gz_statep state) {


233     z_streamp strm = &(state->strm);
234 
235     do {
236         switch(state->how) {
237         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
238             if (gz_look(state) == -1)
239                 return -1;
240             if (state->how == LOOK)
241                 return 0;
242             break;
243         case COPY:      /* -> COPY */
244             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
245                     == -1)
246                 return -1;
247             state->x.next = state->out;
248             return 0;
249         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
250             strm->avail_out = state->size << 1;
251             strm->next_out = state->out;
252             if (gz_decomp(state) == -1)
253                 return -1;
254         }
255     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
256     return 0;
257 }
258 
259 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
260 local int gz_skip(gz_statep state, z_off64_t len) {



261     unsigned n;
262 
263     /* skip over len bytes or reach end-of-file, whichever comes first */
264     while (len)
265         /* skip over whatever is in output buffer */
266         if (state->x.have) {
267             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
268                 (unsigned)len : state->x.have;
269             state->x.have -= n;
270             state->x.next += n;
271             state->x.pos += n;
272             len -= n;
273         }
274 
275         /* output buffer empty -- return if we're at the end of the input */
276         else if (state->eof && state->strm.avail_in == 0)
277             break;
278 
279         /* need more data to skip -- load up output buffer */
280         else {
281             /* get more output, looking for header if required */
282             if (gz_fetch(state) == -1)
283                 return -1;
284         }
285     return 0;
286 }
287 
288 /* 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.  If zero is returned, either the
290    end of file was reached, or there was an error.  state->err must be
291    consulted in that case to determine which. */
292 local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {




293     z_size_t got;
294     unsigned n;
295 
296     /* if len is zero, avoid unnecessary operations */
297     if (len == 0)
298         return 0;
299 
300     /* process a skip request */
301     if (state->seek) {
302         state->seek = 0;
303         if (gz_skip(state, state->skip) == -1)
304             return 0;
305     }
306 
307     /* get len bytes to buf, or less than len if at the end */
308     got = 0;
309     do {
310         /* set n to the maximum amount of len that fits in an unsigned int */
311         n = (unsigned)-1;
312         if (n > len)

349             state->strm.avail_out = n;
350             state->strm.next_out = (unsigned char *)buf;
351             if (gz_decomp(state) == -1)
352                 return 0;
353             n = state->x.have;
354             state->x.have = 0;
355         }
356 
357         /* update progress */
358         len -= n;
359         buf = (char *)buf + n;
360         got += n;
361         state->x.pos += n;
362     } while (len);
363 
364     /* return number of bytes read into user buffer */
365     return got;
366 }
367 
368 /* -- see zlib.h -- */
369 int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {




370     gz_statep state;
371 
372     /* get internal structure */
373     if (file == NULL)
374         return -1;
375     state = (gz_statep)file;
376 
377     /* check that we're reading and that there's no (serious) error */
378     if (state->mode != GZ_READ ||
379             (state->err != Z_OK && state->err != Z_BUF_ERROR))
380         return -1;
381 
382     /* since an int is returned, make sure len fits in one, otherwise return
383        with an error (this avoids a flaw in the interface) */
384     if ((int)len < 0) {
385         gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
386         return -1;
387     }
388 
389     /* read len or fewer bytes to buf */
390     len = (unsigned)gz_read(state, buf, len);
391 
392     /* check for an error */
393     if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
394         return -1;
395 
396     /* return the number of bytes read (this is assured to fit in an int) */
397     return (int)len;
398 }
399 
400 /* -- see zlib.h -- */
401 z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) {





402     z_size_t len;
403     gz_statep state;
404 
405     /* get internal structure */
406     if (file == NULL)
407         return 0;
408     state = (gz_statep)file;
409 
410     /* check that we're reading and that there's no (serious) error */
411     if (state->mode != GZ_READ ||
412             (state->err != Z_OK && state->err != Z_BUF_ERROR))
413         return 0;
414 
415     /* compute bytes to read -- error on overflow */
416     len = nitems * size;
417     if (size && len / size != nitems) {
418         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
419         return 0;
420     }
421 
422     /* read len or fewer bytes to buf, return the number of full items read */
423     return len ? gz_read(state, buf, len) / size : 0;
424 }
425 
426 /* -- see zlib.h -- */
427 #ifdef Z_PREFIX_SET
428 #  undef z_gzgetc
429 #else
430 #  undef gzgetc
431 #endif
432 int ZEXPORT gzgetc(gzFile file) {


433     unsigned char buf[1];
434     gz_statep state;
435 
436     /* get internal structure */
437     if (file == NULL)
438         return -1;
439     state = (gz_statep)file;
440 
441     /* check that we're reading and that there's no (serious) error */
442     if (state->mode != GZ_READ ||
443         (state->err != Z_OK && state->err != Z_BUF_ERROR))
444         return -1;
445 
446     /* try output buffer (no need to check for skip request) */
447     if (state->x.have) {
448         state->x.have--;
449         state->x.pos++;
450         return *(state->x.next)++;
451     }
452 
453     /* nothing there -- try gz_read() */
454     return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
455 }
456 
457 int ZEXPORT gzgetc_(gzFile file) {


458     return gzgetc(file);
459 }
460 
461 /* -- see zlib.h -- */
462 int ZEXPORT gzungetc(int c, gzFile file) {



463     gz_statep state;
464 
465     /* get internal structure */
466     if (file == NULL)
467         return -1;
468     state = (gz_statep)file;
469 
470     /* in case this was just opened, set up the input buffer */
471     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
472         (void)gz_look(state);
473 
474     /* check that we're reading and that there's no (serious) error */
475     if (state->mode != GZ_READ ||
476         (state->err != Z_OK && state->err != Z_BUF_ERROR))
477         return -1;
478 
479     /* process a skip request */
480     if (state->seek) {
481         state->seek = 0;
482         if (gz_skip(state, state->skip) == -1)
483             return -1;
484     }
485 
486     /* can't push EOF */
487     if (c < 0)
488         return -1;
489 
490     /* if output buffer empty, put byte at end (allows more pushing) */
491     if (state->x.have == 0) {
492         state->x.have = 1;
493         state->x.next = state->out + (state->size << 1) - 1;

503         return -1;
504     }
505 
506     /* slide output data if needed and insert byte before existing data */
507     if (state->x.next == state->out) {
508         unsigned char *src = state->out + state->x.have;
509         unsigned char *dest = state->out + (state->size << 1);
510         while (src > state->out)
511             *--dest = *--src;
512         state->x.next = dest;
513     }
514     state->x.have++;
515     state->x.next--;
516     state->x.next[0] = (unsigned char)c;
517     state->x.pos--;
518     state->past = 0;
519     return c;
520 }
521 
522 /* -- see zlib.h -- */
523 char * ZEXPORT gzgets(gzFile file, char *buf, int len) {




524     unsigned left, n;
525     char *str;
526     unsigned char *eol;
527     gz_statep state;
528 
529     /* check parameters and get internal structure */
530     if (file == NULL || buf == NULL || len < 1)
531         return NULL;
532     state = (gz_statep)file;
533 
534     /* check that we're reading and that there's no (serious) error */
535     if (state->mode != GZ_READ ||
536         (state->err != Z_OK && state->err != Z_BUF_ERROR))
537         return NULL;
538 
539     /* process a skip request */
540     if (state->seek) {
541         state->seek = 0;
542         if (gz_skip(state, state->skip) == -1)
543             return NULL;

563         if (eol != NULL)
564             n = (unsigned)(eol - state->x.next) + 1;
565 
566         /* copy through end-of-line, or remainder if not found */
567         memcpy(buf, state->x.next, n);
568         state->x.have -= n;
569         state->x.next += n;
570         state->x.pos += n;
571         left -= n;
572         buf += n;
573     } while (left && eol == NULL);
574 
575     /* return terminated string, or if nothing, end of file */
576     if (buf == str)
577         return NULL;
578     buf[0] = 0;
579     return str;
580 }
581 
582 /* -- see zlib.h -- */
583 int ZEXPORT gzdirect(gzFile file) {


584     gz_statep state;
585 
586     /* get internal structure */
587     if (file == NULL)
588         return 0;
589     state = (gz_statep)file;
590 
591     /* if the state is not known, but we can find out, then do so (this is
592        mainly for right after a gzopen() or gzdopen()) */
593     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
594         (void)gz_look(state);
595 
596     /* return 1 if transparent, 0 if processing a gzip stream */
597     return state->direct;
598 }
599 
600 /* -- see zlib.h -- */
601 int ZEXPORT gzclose_r(gzFile file) {


602     int ret, err;
603     gz_statep state;
604 
605     /* get internal structure */
606     if (file == NULL)
607         return Z_STREAM_ERROR;
608     state = (gz_statep)file;
609 
610     /* check that we're reading */
611     if (state->mode != GZ_READ)
612         return Z_STREAM_ERROR;
613 
614     /* free memory and close file */
615     if (state->size) {
616         inflateEnd(&(state->strm));
617         free(state->out);
618         free(state->in);
619     }
620     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
621     gz_error(state, Z_OK, NULL);
< prev index next >