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
9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
10 local int gz_avail OF((gz_statep));
11 local int gz_next4 OF((gz_statep, unsigned long *));
12 local int gz_head OF((gz_statep));
13 local int gz_decomp OF((gz_statep));
14 local int gz_make OF((gz_statep));
15 local int gz_skip OF((gz_statep, z_off64_t));
17 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
18 state->fd, and update state->eof, state->err, and state->msg as appropriate.
19 This function needs to loop on read(), since read() is not guaranteed to
20 read the number of bytes requested, depending on the type of descriptor. */
21 local int gz_load(state, buf, len, have)
31 ret = read(state->fd, buf + *have, len - *have);
35 } while (*have < len);
37 gz_error(state, Z_ERRNO, zstrerror());
45 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
46 error, 0 otherwise. Note that the eof flag is set when the end of the input
47 file is reached, even though there may be unused data in the buffer. Once
48 that data has been used, no more attempts will be made to read the file.
49 gz_avail() assumes that strm->avail_in == 0. */
50 local int gz_avail(state)
53 z_streamp strm = &(state->strm);
55 if (state->err != Z_OK)
57 if (state->eof == 0) {
58 if (gz_load(state, state->in, state->size, &(strm->avail_in)) == -1)
60 strm->next_in = state->in;
65 /* Get next byte from input, or -1 if end or error. */
66 #define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
67 (strm->avail_in == 0 ? -1 : \
68 (strm->avail_in--, *(strm->next_in)++)))
70 /* Get a four-byte little-endian integer and return 0 on success and the value
71 in *ret. Otherwise -1 is returned and *ret is not modified. */
72 local int gz_next4(state, ret)
78 z_streamp strm = &(state->strm);
81 val += (unsigned)NEXT() << 8;
82 val += (unsigned long)NEXT() << 16;
86 val += (unsigned long)ch << 24;
91 /* Look for gzip header, set up for inflate or copy. state->have must be zero.
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, and the gzip header will be skipped so
96 that the next available input data is the raw deflate stream. If direct
97 copying, then leftover input data from the input buffer will be copied to
98 the output buffer. In that case, all further file reads will be directly to
99 either the output buffer or a user buffer. If decompressing, the inflate
100 state and the check value will be initialized. gz_head() will return 0 on
101 success or -1 on failure. Failures may include read errors or gzip header
103 local int gz_head(state)
106 z_streamp strm = &(state->strm);
110 /* allocate read buffers and inflate memory */
111 if (state->size == 0) {
112 /* allocate buffers */
113 state->in = malloc(state->want);
114 state->out = malloc(state->want << 1);
115 if (state->in == NULL || state->out == NULL) {
116 if (state->out != NULL)
118 if (state->in != NULL)
120 gz_error(state, Z_MEM_ERROR, "out of memory");
123 state->size = state->want;
125 /* allocate inflate memory */
126 state->strm.zalloc = Z_NULL;
127 state->strm.zfree = Z_NULL;
128 state->strm.opaque = Z_NULL;
129 state->strm.avail_in = 0;
130 state->strm.next_in = Z_NULL;
131 if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
135 gz_error(state, Z_MEM_ERROR, "out of memory");
140 /* get some data in the input buffer */
141 if (strm->avail_in == 0) {
142 if (gz_avail(state) == -1)
144 if (strm->avail_in == 0)
148 /* look for the gzip magic header bytes 31 and 139 */
149 if (strm->next_in[0] == 31) {
152 if (strm->avail_in == 0 && gz_avail(state) == -1)
154 if (strm->avail_in && strm->next_in[0] == 139) {
155 /* we have a gzip header, woo hoo! */
159 /* skip rest of header */
160 if (NEXT() != 8) { /* compression method */
161 gz_error(state, Z_DATA_ERROR, "unknown compression method");
165 if (flags & 0xe0) { /* reserved flag bits */
166 gz_error(state, Z_DATA_ERROR, "unknown header flags set");
169 NEXT(); /* modification time */
173 NEXT(); /* extra flags */
174 NEXT(); /* operating system */
175 if (flags & 4) { /* extra field */
176 len = (unsigned)NEXT();
177 len += (unsigned)NEXT() << 8;
182 if (flags & 8) /* file name */
185 if (flags & 16) /* comment */
188 if (flags & 2) { /* header crc */
192 /* an unexpected end of file is not checked for here -- it will be
193 noticed on the first request for uncompressed data */
195 /* set up for decompression */
197 strm->adler = crc32(0L, Z_NULL, 0);
203 /* not a gzip file -- save first byte (31) and fall to raw i/o */
209 /* doing raw i/o, save start of raw data for seeking, copy any leftover
210 input to output -- this assumes that the output buffer is larger than
211 the input buffer, which also assures space for gzungetc() */
212 state->raw = state->pos;
213 state->next = state->out;
214 if (strm->avail_in) {
215 memcpy(state->next + state->have, strm->next_in, strm->avail_in);
216 state->have += strm->avail_in;
224 /* Decompress from input to the provided next_out and avail_out in the state.
225 If the end of the compressed data is reached, then verify the gzip trailer
226 check value and length (modulo 2^32). state->have and state->next are set
227 to point to the just decompressed data, and the crc is updated. If the
228 trailer is verified, state->how is reset to LOOK to look for the next gzip
229 stream or raw data, once state->have is depleted. Returns 0 on success, -1
230 on failure. Failures may include invalid compressed data or a failed gzip
231 trailer verification. */
232 local int gz_decomp(state)
237 unsigned long crc, len;
238 z_streamp strm = &(state->strm);
240 /* fill output buffer up to end of deflate stream */
241 had = strm->avail_out;
243 /* get more input for inflate() */
244 if (strm->avail_in == 0 && gz_avail(state) == -1)
246 if (strm->avail_in == 0) {
247 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
251 /* decompress and handle errors */
252 ret = inflate(strm, Z_NO_FLUSH);
253 if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
254 gz_error(state, Z_STREAM_ERROR,
255 "internal error: inflate stream corrupt");
258 if (ret == Z_MEM_ERROR) {
259 gz_error(state, Z_MEM_ERROR, "out of memory");
262 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
263 gz_error(state, Z_DATA_ERROR,
264 strm->msg == NULL ? "compressed data error" : strm->msg);
267 } while (strm->avail_out && ret != Z_STREAM_END);
269 /* update available output and crc check value */
270 state->have = had - strm->avail_out;
271 state->next = strm->next_out - state->have;
272 strm->adler = crc32(strm->adler, state->next, state->have);
274 /* check gzip trailer if at end of deflate stream */
275 if (ret == Z_STREAM_END) {
276 if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
277 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
280 if (crc != strm->adler) {
281 gz_error(state, Z_DATA_ERROR, "incorrect data check");
284 if (len != (strm->total_out & 0xffffffffL)) {
285 gz_error(state, Z_DATA_ERROR, "incorrect length check");
288 state->how = LOOK; /* ready for next stream, once have is 0 (leave
289 state->direct unchanged to remember how) */
292 /* good decompression */
296 /* Make data and put in the output buffer. Assumes that state->have == 0.
297 Data is either copied from the input file or decompressed from the input
298 file depending on state->how. If state->how is LOOK, then a gzip header is
299 looked for (and skipped if found) to determine wither to copy or decompress.
300 Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
301 or GZIP unless the end of the input file has been reached and all data has
303 local int gz_make(state)
306 z_streamp strm = &(state->strm);
308 if (state->how == LOOK) { /* look for gzip header */
309 if (gz_head(state) == -1)
311 if (state->have) /* got some data from gz_head() */
314 if (state->how == COPY) { /* straight copy */
315 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
317 state->next = state->out;
319 else if (state->how == GZIP) { /* decompress */
320 strm->avail_out = state->size << 1;
321 strm->next_out = state->out;
322 if (gz_decomp(state) == -1)
328 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
329 local int gz_skip(state, len)
335 /* skip over len bytes or reach end-of-file, whichever comes first */
337 /* skip over whatever is in output buffer */
339 n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
340 (unsigned)len : state->have;
347 /* output buffer empty -- return if we're at the end of the input */
348 else if (state->eof && state->strm.avail_in == 0)
351 /* need more data to skip -- load up output buffer */
353 /* get more output, looking for header if required */
354 if (gz_make(state) == -1)
360 /* -- see zlib.h -- */
361 int ZEXPORT gzread(file, buf, len)
370 /* get internal structure */
373 state = (gz_statep)file;
374 strm = &(state->strm);
376 /* check that we're reading and that there's no error */
377 if (state->mode != GZ_READ || state->err != Z_OK)
380 /* since an int is returned, make sure len fits in one, otherwise return
381 with an error (this avoids the flaw in the interface) */
383 gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
387 /* if len is zero, avoid unnecessary operations */
391 /* process a skip request */
394 if (gz_skip(state, state->skip) == -1)
398 /* get len bytes to buf, or less than len if at the end */
401 /* first just try copying data from the output buffer */
403 n = state->have > len ? len : state->have;
404 memcpy(buf, state->next, n);
409 /* output buffer empty -- return if we're at the end of the input */
410 else if (state->eof && strm->avail_in == 0)
413 /* need output data -- for small len or new stream load up our output
415 else if (state->how == LOOK || len < (state->size << 1)) {
416 /* get more output, looking for header if required */
417 if (gz_make(state) == -1)
419 continue; /* no progress yet -- go back to memcpy() above */
420 /* the copy above assures that we will leave with space in the
421 output buffer, allowing at least one gzungetc() to succeed */
424 /* large len -- read directly into user buffer */
425 else if (state->how == COPY) { /* read directly */
426 if (gz_load(state, buf, len, &n) == -1)
430 /* large len -- decompress directly into user buffer */
431 else { /* state->how == GZIP */
432 strm->avail_out = len;
433 strm->next_out = buf;
434 if (gz_decomp(state) == -1)
440 /* update progress */
442 buf = (char *)buf + n;
447 /* return number of bytes read into user buffer (will fit in int) */
451 /* -- see zlib.h -- */
452 int ZEXPORT gzgetc(file)
456 unsigned char buf[1];
459 /* get internal structure */
462 state = (gz_statep)file;
464 /* check that we're reading and that there's no error */
465 if (state->mode != GZ_READ || state->err != Z_OK)
468 /* try output buffer (no need to check for skip request) */
472 return *(state->next)++;
475 /* nothing there -- try gzread() */
476 ret = gzread(file, buf, 1);
477 return ret < 1 ? -1 : buf[0];
480 /* -- see zlib.h -- */
481 int ZEXPORT gzungetc(c, file)
487 /* get internal structure */
490 state = (gz_statep)file;
492 /* check that we're reading and that there's no error */
493 if (state->mode != GZ_READ || state->err != Z_OK)
496 /* process a skip request */
499 if (gz_skip(state, state->skip) == -1)
507 /* if output buffer empty, put byte at end (allows more pushing) */
508 if (state->have == 0) {
510 state->next = state->out + (state->size << 1) - 1;
516 /* if no room, give up (must have already done a gzungetc()) */
517 if (state->have == (state->size << 1)) {
518 gz_error(state, Z_BUF_ERROR, "out of room to push characters");
522 /* slide output data if needed and insert byte before existing data */
523 if (state->next == state->out) {
524 unsigned char *src = state->out + state->have;
525 unsigned char *dest = state->out + (state->size << 1);
526 while (src > state->out)
537 /* -- see zlib.h -- */
538 char * ZEXPORT gzgets(file, buf, len)
548 /* check parameters and get internal structure */
549 if (file == NULL || buf == NULL || len < 1)
551 state = (gz_statep)file;
553 /* check that we're reading and that there's no error */
554 if (state->mode != GZ_READ || state->err != Z_OK)
557 /* process a skip request */
560 if (gz_skip(state, state->skip) == -1)
564 /* copy output bytes up to new line or len - 1, whichever comes first --
565 append a terminating zero to the string (we don't check for a zero in
566 the contents, let the user worry about that) */
568 left = (unsigned)len - 1;
570 /* assure that something is in the output buffer */
571 if (state->have == 0) {
572 if (gz_make(state) == -1)
573 return NULL; /* error */
574 if (state->have == 0) { /* end of file */
575 if (buf == str) /* got bupkus */
577 break; /* got something -- return it */
581 /* look for end-of-line in current output buffer */
582 n = state->have > left ? left : state->have;
583 eol = memchr(state->next, '\n', n);
585 n = (unsigned)(eol - state->next) + 1;
587 /* copy through end-of-line, or remainder if not found */
588 memcpy(buf, state->next, n);
594 } while (left && eol == NULL);
596 /* found end-of-line or out of space -- terminate string and return it */
601 /* -- see zlib.h -- */
602 int ZEXPORT gzdirect(file)
607 /* get internal structure */
610 state = (gz_statep)file;
612 /* check that we're reading */
613 if (state->mode != GZ_READ)
616 /* if the state is not known, but we can find out, then do so (this is
617 mainly for right after a gzopen() or gzdopen()) */
618 if (state->how == LOOK && state->have == 0)
619 (void)gz_head(state);
621 /* return 1 if reading direct, 0 if decompressing a gzip stream */
622 return state->direct;
625 /* -- see zlib.h -- */
626 int ZEXPORT gzclose_r(file)
632 /* get internal structure */
634 return Z_STREAM_ERROR;
635 state = (gz_statep)file;
637 /* check that we're reading */
638 if (state->mode != GZ_READ)
639 return Z_STREAM_ERROR;
641 /* free memory and close file */
643 inflateEnd(&(state->strm));
647 gz_error(state, Z_OK, NULL);
648 ret = close(state->fd);
650 return ret ? Z_ERRNO : Z_OK;