1 /* gzread.c -- zlib functions for reading gzip files
2 * Copyright (C) 2004, 2005, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
12 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
13 local int gz_avail OF((gz_statep));
14 local int gz_next4 OF((gz_statep, unsigned long *));
15 local int gz_head OF((gz_statep));
16 local int gz_decomp OF((gz_statep));
17 local int gz_make OF((gz_statep));
18 local int gz_skip OF((gz_statep, z_off64_t));
20 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
21 state->fd, and update state->eof, state->err, and state->msg as appropriate.
22 This function needs to loop on read(), since read() is not guaranteed to
23 read the number of bytes requested, depending on the type of descriptor. */
24 local int gz_load(state, buf, len, have)
34 ret = read(state->fd, buf + *have, len - *have);
38 } while (*have < len);
40 gz_error(state, Z_ERRNO, zstrerror());
48 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
49 error, 0 otherwise. Note that the eof flag is set when the end of the input
50 file is reached, even though there may be unused data in the buffer. Once
51 that data has been used, no more attempts will be made to read the file.
52 gz_avail() assumes that strm->avail_in == 0. */
53 local int gz_avail(state)
56 z_streamp strm = &(state->strm);
58 if (state->err != Z_OK)
60 if (state->eof == 0) {
61 if (gz_load(state, state->in, state->size,
62 (unsigned *)&(strm->avail_in)) == -1)
64 strm->next_in = state->in;
69 /* Get next byte from input, or -1 if end or error. */
70 #define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
71 (strm->avail_in == 0 ? -1 : \
72 (strm->avail_in--, *(strm->next_in)++)))
74 /* Get a four-byte little-endian integer and return 0 on success and the value
75 in *ret. Otherwise -1 is returned and *ret is not modified. */
76 local int gz_next4(state, ret)
82 z_streamp strm = &(state->strm);
85 val += (unsigned)NEXT() << 8;
86 val += (unsigned long)NEXT() << 16;
90 val += (unsigned long)ch << 24;
95 /* Look for gzip header, set up for inflate or copy. state->have must be zero.
96 If this is the first time in, allocate required memory. state->how will be
97 left unchanged if there is no more input data available, will be set to COPY
98 if there is no gzip header and direct copying will be performed, or it will
99 be set to GZIP for decompression, and the gzip header will be skipped so
100 that the next available input data is the raw deflate stream. If direct
101 copying, then leftover input data from the input buffer will be copied to
102 the output buffer. In that case, all further file reads will be directly to
103 either the output buffer or a user buffer. If decompressing, the inflate
104 state and the check value will be initialized. gz_head() will return 0 on
105 success or -1 on failure. Failures may include read errors or gzip header
107 local int gz_head(state)
110 z_streamp strm = &(state->strm);
114 /* allocate read buffers and inflate memory */
115 if (state->size == 0) {
116 /* allocate buffers */
117 state->in = malloc(state->want);
118 state->out = malloc(state->want << 1);
119 if (state->in == NULL || state->out == NULL) {
120 if (state->out != NULL)
122 if (state->in != NULL)
124 gz_error(state, Z_MEM_ERROR, "out of memory");
127 state->size = state->want;
129 /* allocate inflate memory */
130 state->strm.zalloc = Z_NULL;
131 state->strm.zfree = Z_NULL;
132 state->strm.opaque = Z_NULL;
133 state->strm.avail_in = 0;
134 state->strm.next_in = Z_NULL;
135 if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
139 gz_error(state, Z_MEM_ERROR, "out of memory");
144 /* get some data in the input buffer */
145 if (strm->avail_in == 0) {
146 if (gz_avail(state) == -1)
148 if (strm->avail_in == 0)
152 /* look for the gzip magic header bytes 31 and 139 */
153 if (strm->next_in[0] == 31) {
156 if (strm->avail_in == 0 && gz_avail(state) == -1)
158 if (strm->avail_in && strm->next_in[0] == 139) {
159 /* we have a gzip header, woo hoo! */
163 /* skip rest of header */
164 if (NEXT() != 8) { /* compression method */
165 gz_error(state, Z_DATA_ERROR, "unknown compression method");
169 if (flags & 0xe0) { /* reserved flag bits */
170 gz_error(state, Z_DATA_ERROR, "unknown header flags set");
173 NEXT(); /* modification time */
177 NEXT(); /* extra flags */
178 NEXT(); /* operating system */
179 if (flags & 4) { /* extra field */
180 len = (unsigned)NEXT();
181 len += (unsigned)NEXT() << 8;
186 if (flags & 8) /* file name */
189 if (flags & 16) /* comment */
192 if (flags & 2) { /* header crc */
196 /* an unexpected end of file is not checked for here -- it will be
197 noticed on the first request for uncompressed data */
199 /* set up for decompression */
201 strm->adler = crc32(0L, Z_NULL, 0);
207 /* not a gzip file -- save first byte (31) and fall to raw i/o */
213 /* doing raw i/o, save start of raw data for seeking, copy any leftover
214 input to output -- this assumes that the output buffer is larger than
215 the input buffer, which also assures space for gzungetc() */
216 state->raw = state->pos;
217 state->next = state->out;
218 if (strm->avail_in) {
219 memcpy(state->next + state->have, strm->next_in, strm->avail_in);
220 state->have += strm->avail_in;
228 /* Decompress from input to the provided next_out and avail_out in the state.
229 If the end of the compressed data is reached, then verify the gzip trailer
230 check value and length (modulo 2^32). state->have and state->next are set
231 to point to the just decompressed data, and the crc is updated. If the
232 trailer is verified, state->how is reset to LOOK to look for the next gzip
233 stream or raw data, once state->have is depleted. Returns 0 on success, -1
234 on failure. Failures may include invalid compressed data or a failed gzip
235 trailer verification. */
236 local int gz_decomp(state)
241 unsigned long crc, len;
242 z_streamp strm = &(state->strm);
244 /* fill output buffer up to end of deflate stream */
245 had = strm->avail_out;
247 /* get more input for inflate() */
248 if (strm->avail_in == 0 && gz_avail(state) == -1)
250 if (strm->avail_in == 0) {
251 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
255 /* decompress and handle errors */
256 ret = inflate(strm, Z_NO_FLUSH);
257 if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
258 gz_error(state, Z_STREAM_ERROR,
259 "internal error: inflate stream corrupt");
262 if (ret == Z_MEM_ERROR) {
263 gz_error(state, Z_MEM_ERROR, "out of memory");
266 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
267 gz_error(state, Z_DATA_ERROR,
268 strm->msg == NULL ? "compressed data error" : strm->msg);
271 } while (strm->avail_out && ret != Z_STREAM_END);
273 /* update available output and crc check value */
274 state->have = had - strm->avail_out;
275 state->next = strm->next_out - state->have;
276 strm->adler = crc32(strm->adler, state->next, state->have);
278 /* check gzip trailer if at end of deflate stream */
279 if (ret == Z_STREAM_END) {
280 if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
281 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
284 if (crc != strm->adler) {
285 gz_error(state, Z_DATA_ERROR, "incorrect data check");
288 if (len != (strm->total_out & 0xffffffffL)) {
289 gz_error(state, Z_DATA_ERROR, "incorrect length check");
292 state->how = LOOK; /* ready for next stream, once have is 0 (leave
293 state->direct unchanged to remember how) */
296 /* good decompression */
300 /* Make data and put in the output buffer. Assumes that state->have == 0.
301 Data is either copied from the input file or decompressed from the input
302 file depending on state->how. If state->how is LOOK, then a gzip header is
303 looked for (and skipped if found) to determine wither to copy or decompress.
304 Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
305 or GZIP unless the end of the input file has been reached and all data has
307 local int gz_make(state)
310 z_streamp strm = &(state->strm);
312 if (state->how == LOOK) { /* look for gzip header */
313 if (gz_head(state) == -1)
315 if (state->have) /* got some data from gz_head() */
318 if (state->how == COPY) { /* straight copy */
319 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
321 state->next = state->out;
323 else if (state->how == GZIP) { /* decompress */
324 strm->avail_out = state->size << 1;
325 strm->next_out = state->out;
326 if (gz_decomp(state) == -1)
332 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
333 local int gz_skip(state, len)
339 /* skip over len bytes or reach end-of-file, whichever comes first */
341 /* skip over whatever is in output buffer */
343 n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
344 (unsigned)len : state->have;
351 /* output buffer empty -- return if we're at the end of the input */
352 else if (state->eof && state->strm.avail_in == 0)
355 /* need more data to skip -- load up output buffer */
357 /* get more output, looking for header if required */
358 if (gz_make(state) == -1)
364 /* -- see zlib.h -- */
365 int ZEXPORT gzread(file, buf, len)
374 /* get internal structure */
377 state = (gz_statep)file;
378 strm = &(state->strm);
380 /* check that we're reading and that there's no error */
381 if (state->mode != GZ_READ || state->err != Z_OK)
384 /* since an int is returned, make sure len fits in one, otherwise return
385 with an error (this avoids the flaw in the interface) */
387 gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
391 /* if len is zero, avoid unnecessary operations */
395 /* process a skip request */
398 if (gz_skip(state, state->skip) == -1)
402 /* get len bytes to buf, or less than len if at the end */
405 /* first just try copying data from the output buffer */
407 n = state->have > len ? len : state->have;
408 memcpy(buf, state->next, n);
413 /* output buffer empty -- return if we're at the end of the input */
414 else if (state->eof && strm->avail_in == 0)
417 /* need output data -- for small len or new stream load up our output
419 else if (state->how == LOOK || len < (state->size << 1)) {
420 /* get more output, looking for header if required */
421 if (gz_make(state) == -1)
423 continue; /* no progress yet -- go back to memcpy() above */
424 /* the copy above assures that we will leave with space in the
425 output buffer, allowing at least one gzungetc() to succeed */
428 /* large len -- read directly into user buffer */
429 else if (state->how == COPY) { /* read directly */
430 if (gz_load(state, buf, len, &n) == -1)
434 /* large len -- decompress directly into user buffer */
435 else { /* state->how == GZIP */
436 strm->avail_out = len;
437 strm->next_out = buf;
438 if (gz_decomp(state) == -1)
444 /* update progress */
446 buf = (char *)buf + n;
451 /* return number of bytes read into user buffer (will fit in int) */
455 /* -- see zlib.h -- */
456 int ZEXPORT gzgetc(file)
460 unsigned char buf[1];
463 /* get internal structure */
466 state = (gz_statep)file;
468 /* check that we're reading and that there's no error */
469 if (state->mode != GZ_READ || state->err != Z_OK)
472 /* try output buffer (no need to check for skip request) */
476 return *(state->next)++;
479 /* nothing there -- try gzread() */
480 ret = gzread(file, buf, 1);
481 return ret < 1 ? -1 : buf[0];
484 /* -- see zlib.h -- */
485 int ZEXPORT gzungetc(c, file)
491 /* get internal structure */
494 state = (gz_statep)file;
496 /* check that we're reading and that there's no error */
497 if (state->mode != GZ_READ || state->err != Z_OK)
500 /* process a skip request */
503 if (gz_skip(state, state->skip) == -1)
511 /* if output buffer empty, put byte at end (allows more pushing) */
512 if (state->have == 0) {
514 state->next = state->out + (state->size << 1) - 1;
520 /* if no room, give up (must have already done a gzungetc()) */
521 if (state->have == (state->size << 1)) {
522 gz_error(state, Z_BUF_ERROR, "out of room to push characters");
526 /* slide output data if needed and insert byte before existing data */
527 if (state->next == state->out) {
528 unsigned char *src = state->out + state->have;
529 unsigned char *dest = state->out + (state->size << 1);
530 while (src > state->out)
541 /* -- see zlib.h -- */
542 char * ZEXPORT gzgets(file, buf, len)
552 /* check parameters and get internal structure */
553 if (file == NULL || buf == NULL || len < 1)
555 state = (gz_statep)file;
557 /* check that we're reading and that there's no error */
558 if (state->mode != GZ_READ || state->err != Z_OK)
561 /* process a skip request */
564 if (gz_skip(state, state->skip) == -1)
568 /* copy output bytes up to new line or len - 1, whichever comes first --
569 append a terminating zero to the string (we don't check for a zero in
570 the contents, let the user worry about that) */
572 left = (unsigned)len - 1;
574 /* assure that something is in the output buffer */
575 if (state->have == 0) {
576 if (gz_make(state) == -1)
577 return NULL; /* error */
578 if (state->have == 0) { /* end of file */
579 if (buf == str) /* got bupkus */
581 break; /* got something -- return it */
585 /* look for end-of-line in current output buffer */
586 n = state->have > left ? left : state->have;
587 eol = memchr(state->next, '\n', n);
589 n = (unsigned)(eol - state->next) + 1;
591 /* copy through end-of-line, or remainder if not found */
592 memcpy(buf, state->next, n);
598 } while (left && eol == NULL);
600 /* found end-of-line or out of space -- terminate string and return it */
605 /* -- see zlib.h -- */
606 int ZEXPORT gzdirect(file)
611 /* get internal structure */
614 state = (gz_statep)file;
616 /* check that we're reading */
617 if (state->mode != GZ_READ)
620 /* if the state is not known, but we can find out, then do so (this is
621 mainly for right after a gzopen() or gzdopen()) */
622 if (state->how == LOOK && state->have == 0)
623 (void)gz_head(state);
625 /* return 1 if reading direct, 0 if decompressing a gzip stream */
626 return state->direct;
629 /* -- see zlib.h -- */
630 int ZEXPORT gzclose_r(file)
636 /* get internal structure */
638 return Z_STREAM_ERROR;
639 state = (gz_statep)file;
641 /* check that we're reading */
642 if (state->mode != GZ_READ)
643 return Z_STREAM_ERROR;
645 /* free memory and close file */
647 inflateEnd(&(state->strm));
651 gz_error(state, Z_OK, NULL);
653 ret = close(state->fd);
655 return ret ? Z_ERRNO : Z_OK;