ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
gzread.c
Go to the documentation of this file.
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
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
10
11#include "gzguts.h"
12
14
15/* Local functions */
16local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
18local int gz_next4 OF((gz_statep, unsigned long *));
23
24/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
25 state->fd, and update state->eof, state->err, and state->msg as appropriate.
26 This function needs to loop on read(), since read() is not guaranteed to
27 read the number of bytes requested, depending on the type of descriptor. */
28local int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have)
29{
30 int ret;
31
32 *have = 0;
33 do {
34 ret = read(state->fd, buf + *have, len - *have);
35 if (ret <= 0)
36 break;
37 *have += ret;
38 } while (*have < len);
39 if (ret < 0) {
40 gz_error(state, Z_ERRNO, zstrerror());
41 return -1;
42 }
43 if (ret == 0)
44 state->eof = 1;
45 return 0;
46}
47
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. */
54{
55 z_streamp strm = &(state->strm);
56
57 if (state->err != Z_OK)
58 return -1;
59 if (state->eof == 0) {
60 if (gz_load(state, state->in, state->size,
61 (unsigned *)&(strm->avail_in)) == -1)
62 return -1;
63 strm->next_in = state->in;
64 }
65 return 0;
66}
67
68/* Get next byte from input, or -1 if end or error. */
69#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
70 (strm->avail_in == 0 ? -1 : \
71 (strm->avail_in--, *(strm->next_in)++)))
72
73/* Get a four-byte little-endian integer and return 0 on success and the value
74 in *ret. Otherwise -1 is returned and *ret is not modified. */
75local int gz_next4(gz_statep state, unsigned long *ret)
76{
77 int ch;
78 unsigned long val;
79 z_streamp strm = &(state->strm);
80
81 val = NEXT();
82 val += (unsigned)NEXT() << 8;
83 val += (unsigned long)NEXT() << 16;
84 ch = NEXT();
85 if (ch == -1)
86 return -1;
87 val += (unsigned long)ch << 24;
88 *ret = val;
89 return 0;
90}
91
92/* Look for gzip header, set up for inflate or copy. state->have must be zero.
93 If this is the first time in, allocate required memory. state->how will be
94 left unchanged if there is no more input data available, will be set to COPY
95 if there is no gzip header and direct copying will be performed, or it will
96 be set to GZIP for decompression, and the gzip header will be skipped so
97 that the next available input data is the raw deflate stream. If direct
98 copying, then leftover input data from the input buffer will be copied to
99 the output buffer. In that case, all further file reads will be directly to
100 either the output buffer or a user buffer. If decompressing, the inflate
101 state and the check value will be initialized. gz_head() will return 0 on
102 success or -1 on failure. Failures may include read errors or gzip header
103 errors. */
105{
106 z_streamp strm = &(state->strm);
107 int flags;
108 unsigned len;
109
110 /* allocate read buffers and inflate memory */
111 if (state->size == 0) {
112 /* allocate buffers */
113 state->in = (unsigned char *)malloc(state->want);
114 state->out = (unsigned char *)malloc(state->want << 1);
115 if (state->in == NULL || state->out == NULL) {
116 if (state->out != NULL)
117 free(state->out);
118 if (state->in != NULL)
119 free(state->in);
120 gz_error(state, Z_MEM_ERROR, "out of memory");
121 return -1;
122 }
123 state->size = state->want;
124
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 */
132 free(state->out);
133 free(state->in);
134 state->size = 0;
135 gz_error(state, Z_MEM_ERROR, "out of memory");
136 return -1;
137 }
138 }
139
140 /* get some data in the input buffer */
141 if (strm->avail_in == 0) {
142 if (gz_avail(state) == -1)
143 return -1;
144 if (strm->avail_in == 0)
145 return 0;
146 }
147
148 /* look for the gzip magic header bytes 31 and 139 */
149 if (strm->next_in[0] == 31) {
150 strm->avail_in--;
151 strm->next_in++;
152 if (strm->avail_in == 0 && gz_avail(state) == -1)
153 return -1;
154 if (strm->avail_in && strm->next_in[0] == 139) {
155 /* we have a gzip header, woo hoo! */
156 strm->avail_in--;
157 strm->next_in++;
158
159 /* skip rest of header */
160 if (NEXT() != 8) { /* compression method */
161 gz_error(state, Z_DATA_ERROR, "unknown compression method");
162 return -1;
163 }
164 flags = NEXT();
165 if (flags & 0xe0) { /* reserved flag bits */
166 gz_error(state, Z_DATA_ERROR, "unknown header flags set");
167 return -1;
168 }
169 NEXT(); /* modification time */
170 NEXT();
171 NEXT();
172 NEXT();
173 NEXT(); /* extra flags */
174 NEXT(); /* operating system */
175 if (flags & 4) { /* extra field */
176 len = (unsigned)NEXT();
177 len += (unsigned)NEXT() << 8;
178 while (len--)
179 if (NEXT() < 0)
180 break;
181 }
182 if (flags & 8) /* file name */
183 while (NEXT() > 0)
184 ;
185 if (flags & 16) /* comment */
186 while (NEXT() > 0)
187 ;
188 if (flags & 2) { /* header crc */
189 NEXT();
190 NEXT();
191 }
192 /* an unexpected end of file is not checked for here -- it will be
193 noticed on the first request for uncompressed data */
194
195 /* set up for decompression */
196 inflateReset(strm);
197 strm->adler = crc32(0L, Z_NULL, 0);
198 state->how = GZIP;
199 state->direct = 0;
200 return 0;
201 }
202 else {
203 /* not a gzip file -- save first byte (31) and fall to raw i/o */
204 state->out[0] = 31;
205 state->have = 1;
206 }
207 }
208
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;
217 strm->avail_in = 0;
218 }
219 state->how = COPY;
220 state->direct = 1;
221 return 0;
222}
223
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. */
233{
234 int ret;
235 unsigned had;
236 unsigned long crc, len;
237 z_streamp strm = &(state->strm);
238
239 /* fill output buffer up to end of deflate stream */
240 had = strm->avail_out;
241 do {
242 /* get more input for inflate() */
243 if (strm->avail_in == 0 && gz_avail(state) == -1)
244 return -1;
245 if (strm->avail_in == 0) {
246 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
247 return -1;
248 }
249
250 /* decompress and handle errors */
251 ret = inflate(strm, Z_NO_FLUSH);
252 if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
254 "internal error: inflate stream corrupt");
255 return -1;
256 }
257 if (ret == Z_MEM_ERROR) {
258 gz_error(state, Z_MEM_ERROR, "out of memory");
259 return -1;
260 }
261 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
262 gz_error(state, Z_DATA_ERROR,
263 strm->msg == NULL ? "compressed data error" : strm->msg);
264 return -1;
265 }
266 } while (strm->avail_out && ret != Z_STREAM_END);
267
268 /* update available output and crc check value */
269 state->have = had - strm->avail_out;
270 state->next = strm->next_out - state->have;
271 strm->adler = crc32(strm->adler, state->next, state->have);
272
273 /* check gzip trailer if at end of deflate stream */
274 if (ret == Z_STREAM_END) {
275 if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
276 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
277 return -1;
278 }
279 if (crc != strm->adler) {
280 gz_error(state, Z_DATA_ERROR, "incorrect data check");
281 return -1;
282 }
283 if (len != (strm->total_out & 0xffffffffL)) {
284 gz_error(state, Z_DATA_ERROR, "incorrect length check");
285 return -1;
286 }
287 state->how = LOOK; /* ready for next stream, once have is 0 (leave
288 state->direct unchanged to remember how) */
289 }
290
291 /* good decompression */
292 return 0;
293}
294
295/* Make data and put in the output buffer. Assumes that state->have == 0.
296 Data is either copied from the input file or decompressed from the input
297 file depending on state->how. If state->how is LOOK, then a gzip header is
298 looked for (and skipped if found) to determine wither to copy or decompress.
299 Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
300 or GZIP unless the end of the input file has been reached and all data has
301 been processed. */
303{
304 z_streamp strm = &(state->strm);
305
306 if (state->how == LOOK) { /* look for gzip header */
307 if (gz_head(state) == -1)
308 return -1;
309 if (state->have) /* got some data from gz_head() */
310 return 0;
311 }
312 if (state->how == COPY) { /* straight copy */
313 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
314 return -1;
315 state->next = state->out;
316 }
317 else if (state->how == GZIP) { /* decompress */
318 strm->avail_out = state->size << 1;
319 strm->next_out = state->out;
320 if (gz_decomp(state) == -1)
321 return -1;
322 }
323 return 0;
324}
325
326/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
328{
329 unsigned n;
330
331 /* skip over len bytes or reach end-of-file, whichever comes first */
332 while (len)
333 /* skip over whatever is in output buffer */
334 if (state->have) {
335 n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
336 (unsigned)len : state->have;
337 state->have -= n;
338 state->next += n;
339 state->pos += n;
340 len -= n;
341 }
342
343 /* output buffer empty -- return if we're at the end of the input */
344 else if (state->eof && state->strm.avail_in == 0)
345 break;
346
347 /* need more data to skip -- load up output buffer */
348 else {
349 /* get more output, looking for header if required */
350 if (gz_make(state) == -1)
351 return -1;
352 }
353 return 0;
354}
355
356/* -- see zlib.h -- */
357int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
358{
359 unsigned got, n;
360 gz_statep state;
361 z_streamp strm;
362
363 /* get internal structure */
364 if (file == NULL)
365 return -1;
366 state = (gz_statep)file;
367 strm = &(state->strm);
368
369 /* check that we're reading and that there's no error */
370 if (state->mode != GZ_READ || state->err != Z_OK)
371 return -1;
372
373 /* since an int is returned, make sure len fits in one, otherwise return
374 with an error (this avoids the flaw in the interface) */
375 if ((int)len < 0) {
376 gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
377 return -1;
378 }
379
380 /* if len is zero, avoid unnecessary operations */
381 if (len == 0)
382 return 0;
383
384 /* process a skip request */
385 if (state->seek) {
386 state->seek = 0;
387 if (gz_skip(state, state->skip) == -1)
388 return -1;
389 }
390
391 /* get len bytes to buf, or less than len if at the end */
392 got = 0;
393 do {
394 /* first just try copying data from the output buffer */
395 if (state->have) {
396 n = state->have > len ? len : state->have;
397 memcpy(buf, state->next, n);
398 state->next += n;
399 state->have -= n;
400 }
401
402 /* output buffer empty -- return if we're at the end of the input */
403 else if (state->eof && strm->avail_in == 0)
404 break;
405
406 /* need output data -- for small len or new stream load up our output
407 buffer */
408 else if (state->how == LOOK || len < (state->size << 1)) {
409 /* get more output, looking for header if required */
410 if (gz_make(state) == -1)
411 return -1;
412 continue; /* no progress yet -- go back to memcpy() above */
413 /* the copy above assures that we will leave with space in the
414 output buffer, allowing at least one gzungetc() to succeed */
415 }
416
417 /* large len -- read directly into user buffer */
418 else if (state->how == COPY) { /* read directly */
419 if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
420 return -1;
421 }
422
423 /* large len -- decompress directly into user buffer */
424 else { /* state->how == GZIP */
425 strm->avail_out = len;
426 strm->next_out = (unsigned char *)buf;
427 if (gz_decomp(state) == -1)
428 return -1;
429 n = state->have;
430 state->have = 0;
431 }
432
433 /* update progress */
434 len -= n;
435 buf = (char *)buf + n;
436 got += n;
437 state->pos += n;
438 } while (len);
439
440 /* return number of bytes read into user buffer (will fit in int) */
441 return (int)got;
442}
443
444/* -- see zlib.h -- */
446{
447 int ret;
448 unsigned char buf[1];
449 gz_statep state;
450
451 /* get internal structure */
452 if (file == NULL)
453 return -1;
454 state = (gz_statep)file;
455
456 /* check that we're reading and that there's no error */
457 if (state->mode != GZ_READ || state->err != Z_OK)
458 return -1;
459
460 /* try output buffer (no need to check for skip request) */
461 if (state->have) {
462 state->have--;
463 state->pos++;
464 return *(state->next)++;
465 }
466
467 /* nothing there -- try gzread() */
468 ret = gzread(file, buf, 1);
469 return ret < 1 ? -1 : buf[0];
470}
471
472/* -- see zlib.h -- */
474{
475 gz_statep state;
476
477 /* get internal structure */
478 if (file == NULL)
479 return -1;
480 state = (gz_statep)file;
481
482 /* check that we're reading and that there's no error */
483 if (state->mode != GZ_READ || state->err != Z_OK)
484 return -1;
485
486 /* process a skip request */
487 if (state->seek) {
488 state->seek = 0;
489 if (gz_skip(state, state->skip) == -1)
490 return -1;
491 }
492
493 /* can't push EOF */
494 if (c < 0)
495 return -1;
496
497 /* if output buffer empty, put byte at end (allows more pushing) */
498 if (state->have == 0) {
499 state->have = 1;
500 state->next = state->out + (state->size << 1) - 1;
501 state->next[0] = c;
502 state->pos--;
503 return c;
504 }
505
506 /* if no room, give up (must have already done a gzungetc()) */
507 if (state->have == (state->size << 1)) {
508 gz_error(state, Z_BUF_ERROR, "out of room to push characters");
509 return -1;
510 }
511
512 /* slide output data if needed and insert byte before existing data */
513 if (state->next == state->out) {
514 unsigned char *src = state->out + state->have;
515 unsigned char *dest = state->out + (state->size << 1);
516 while (src > state->out)
517 *--dest = *--src;
518 state->next = dest;
519 }
520 state->have++;
521 state->next--;
522 state->next[0] = c;
523 state->pos--;
524 return c;
525}
526
527/* -- see zlib.h -- */
528char * ZEXPORT gzgets(gzFile file, char *buf, int len)
529{
530 unsigned left, n;
531 char *str;
532 unsigned char *eol;
533 gz_statep state;
534
535 /* check parameters and get internal structure */
536 if (file == NULL || buf == NULL || len < 1)
537 return NULL;
538 state = (gz_statep)file;
539
540 /* check that we're reading and that there's no error */
541 if (state->mode != GZ_READ || state->err != Z_OK)
542 return NULL;
543
544 /* process a skip request */
545 if (state->seek) {
546 state->seek = 0;
547 if (gz_skip(state, state->skip) == -1)
548 return NULL;
549 }
550
551 /* copy output bytes up to new line or len - 1, whichever comes first --
552 append a terminating zero to the string (we don't check for a zero in
553 the contents, let the user worry about that) */
554 str = buf;
555 left = (unsigned)len - 1;
556 if (left) do {
557 /* assure that something is in the output buffer */
558 if (state->have == 0) {
559 if (gz_make(state) == -1)
560 return NULL; /* error */
561 if (state->have == 0) { /* end of file */
562 if (buf == str) /* got bupkus */
563 return NULL;
564 break; /* got something -- return it */
565 }
566 }
567
568 /* look for end-of-line in current output buffer */
569 n = state->have > left ? left : state->have;
570 eol = (unsigned char *)memchr(state->next, '\n', n);
571 if (eol != NULL)
572 n = (unsigned)(eol - state->next) + 1;
573
574 /* copy through end-of-line, or remainder if not found */
575 memcpy(buf, state->next, n);
576 state->have -= n;
577 state->next += n;
578 state->pos += n;
579 left -= n;
580 buf += n;
581 } while (left && eol == NULL);
582
583 /* found end-of-line or out of space -- terminate string and return it */
584 buf[0] = 0;
585 return str;
586}
587
588/* -- see zlib.h -- */
590{
591 gz_statep state;
592
593 /* get internal structure */
594 if (file == NULL)
595 return 0;
596 state = (gz_statep)file;
597
598 /* check that we're reading */
599 if (state->mode != GZ_READ)
600 return 0;
601
602 /* if the state is not known, but we can find out, then do so (this is
603 mainly for right after a gzopen() or gzdopen()) */
604 if (state->how == LOOK && state->have == 0)
605 (void)gz_head(state);
606
607 /* return 1 if reading direct, 0 if decompressing a gzip stream */
608 return state->direct;
609}
610
611/* -- see zlib.h -- */
613{
614 int ret;
615 gz_statep state;
616
617 /* get internal structure */
618 if (file == NULL)
619 return Z_STREAM_ERROR;
620 state = (gz_statep)file;
621
622 /* check that we're reading */
623 if (state->mode != GZ_READ)
624 return Z_STREAM_ERROR;
625
626 /* free memory and close file */
627 if (state->size) {
628 inflateEnd(&(state->strm));
629 free(state->out);
630 free(state->in);
631 }
632 gz_error(state, Z_OK, NULL);
633 free(state->path);
634 ret = close(state->fd);
635 free(state);
636 return ret ? Z_ERRNO : Z_OK;
637}
638
639
641
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define local
Definition adler32.c:17
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition crc32.c:230
#define GZIP
Definition deflate.h:25
gz_state FAR * gz_statep
Definition gzguts.h:129
#define LOOK
Definition gzguts.h:94
#define GT_OFF(x)
Definition gzguts.h:144
#define GZ_READ
Definition gzguts.h:89
#define COPY
Definition gzguts.h:95
#define zstrerror()
Definition gzguts.h:59
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition gzlib.c:464
int ZEXPORT gzungetc(int c, gzFile file)
Definition gzread.c:473
int ZEXPORT gzgetc(gzFile file)
Definition gzread.c:445
int ZEXPORT gzdirect(gzFile file)
Definition gzread.c:589
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition gzread.c:357
local int gz_decomp(gz_statep state)
Definition gzread.c:232
int ZEXPORT gzclose_r(gzFile file)
Definition gzread.c:612
local int gz_avail(gz_statep state)
Definition gzread.c:53
char *ZEXPORT gzgets(gzFile file, char *buf, int len)
Definition gzread.c:528
local int gz_head(gz_statep state)
Definition gzread.c:104
local int gz_skip(gz_statep state, z_off64_t len)
Definition gzread.c:327
local int gz_next4(gz_statep state, unsigned long *ret)
Definition gzread.c:75
local int gz_make(gz_statep state)
Definition gzread.c:302
local int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have)
Definition gzread.c:28
#define NEXT()
Definition gzread.c:69
int ZEXPORT inflate(z_streamp strm, int flush)
Definition inflate.c:580
int ZEXPORT inflateReset(z_streamp strm)
Definition inflate.c:110
int ZEXPORT inflateEnd(z_streamp strm)
Definition inflate.c:1227
Definition file.h:23
Definition flags.h:11
char * memcpy()
char * memchr()
VOID_HACK free()
char * malloc()
#define ZEXPORT
Definition zconf.h:322
Byte * voidp
Definition zconf.h:356
#define OF(args)
Definition zconf.h:242
#define z_off64_t
Definition zconf.h:402
#define Z_NEED_DICT
Definition zlib.h:183
#define Z_ERRNO
Definition zlib.h:184
#define Z_BUF_ERROR
Definition zlib.h:188
#define inflateInit2(strm, windowBits)
Definition zlib.h:1561
z_stream FAR * z_streamp
Definition zlib.h:114
#define Z_STREAM_END
Definition zlib.h:182
#define Z_OK
Definition zlib.h:181
#define Z_DATA_ERROR
Definition zlib.h:186
#define Z_STREAM_ERROR
Definition zlib.h:185
#define Z_NO_FLUSH
Definition zlib.h:172
voidp gzFile
Definition zlib.h:1173
#define Z_NULL
Definition zlib.h:216
#define Z_MEM_ERROR
Definition zlib.h:187