ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
gzread.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "misc/util/abc_global.h"
#include "gzguts.h"
Include dependency graph for gzread.c:

Go to the source code of this file.

Macros

#define NEXT()
 

Functions

ABC_NAMESPACE_IMPL_START local int gz_load OF ((gz_statep, unsigned char *, unsigned, unsigned *))
 
local int gz_avail OF ((gz_statep))
 
local int gz_next4 OF ((gz_statep, unsigned long *))
 
local int gz_skip OF ((gz_statep, z_off64_t))
 
local int gz_load (gz_statep state, unsigned char *buf, unsigned len, unsigned *have)
 
local int gz_avail (gz_statep state)
 
local int gz_next4 (gz_statep state, unsigned long *ret)
 
local int gz_head (gz_statep state)
 
local int gz_decomp (gz_statep state)
 
local int gz_make (gz_statep state)
 
local int gz_skip (gz_statep state, z_off64_t len)
 
int ZEXPORT gzread (gzFile file, voidp buf, unsigned len)
 
int ZEXPORT gzgetc (gzFile file)
 
int ZEXPORT gzungetc (int c, gzFile file)
 
char *ZEXPORT gzgets (gzFile file, char *buf, int len)
 
int ZEXPORT gzdirect (gzFile file)
 
int ZEXPORT gzclose_r (gzFile file)
 

Macro Definition Documentation

◆ NEXT

#define NEXT ( )
Value:
((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
(strm->avail_in == 0 ? -1 : \
(strm->avail_in--, *(strm->next_in)++)))
local int gz_avail(gz_statep state)
Definition gzread.c:53

Definition at line 69 of file gzread.c.

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)++)))

Function Documentation

◆ gz_avail()

local int gz_avail ( gz_statep state)

Definition at line 53 of file gzread.c.

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}
local int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have)
Definition gzread.c:28
z_stream FAR * z_streamp
Definition zlib.h:114
#define Z_OK
Definition zlib.h:181
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gz_decomp()

local int gz_decomp ( gz_statep state)

Definition at line 232 of file gzread.c.

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}
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition crc32.c:230
#define LOOK
Definition gzguts.h:94
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition gzlib.c:464
local int gz_next4(gz_statep state, unsigned long *ret)
Definition gzread.c:75
int ZEXPORT inflate(z_streamp strm, int flush)
Definition inflate.c:580
#define Z_NEED_DICT
Definition zlib.h:183
#define Z_STREAM_END
Definition zlib.h:182
#define Z_DATA_ERROR
Definition zlib.h:186
#define Z_STREAM_ERROR
Definition zlib.h:185
#define Z_NO_FLUSH
Definition zlib.h:172
#define Z_MEM_ERROR
Definition zlib.h:187
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gz_head()

local int gz_head ( gz_statep state)

Definition at line 104 of file gzread.c.

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}
#define GZIP
Definition deflate.h:25
#define COPY
Definition gzguts.h:95
#define NEXT()
Definition gzread.c:69
int ZEXPORT inflateReset(z_streamp strm)
Definition inflate.c:110
Definition flags.h:11
char * memcpy()
VOID_HACK free()
char * malloc()
#define inflateInit2(strm, windowBits)
Definition zlib.h:1561
#define Z_NULL
Definition zlib.h:216
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gz_load()

local int gz_load ( gz_statep state,
unsigned char * buf,
unsigned len,
unsigned * have )

Definition at line 28 of file gzread.c.

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}
#define zstrerror()
Definition gzguts.h:59
#define Z_ERRNO
Definition zlib.h:184
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gz_make()

local int gz_make ( gz_statep state)

Definition at line 302 of file gzread.c.

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}
local int gz_decomp(gz_statep state)
Definition gzread.c:232
local int gz_head(gz_statep state)
Definition gzread.c:104
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gz_next4()

local int gz_next4 ( gz_statep state,
unsigned long * ret )

Definition at line 75 of file gzread.c.

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}
Here is the caller graph for this function:

◆ gz_skip()

local int gz_skip ( gz_statep state,
z_off64_t len )

Definition at line 327 of file gzread.c.

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}
#define GT_OFF(x)
Definition gzguts.h:144
local int gz_make(gz_statep state)
Definition gzread.c:302
#define z_off64_t
Definition zconf.h:402
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzclose_r()

int ZEXPORT gzclose_r ( gzFile file)

Definition at line 612 of file gzread.c.

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}
gz_state FAR * gz_statep
Definition gzguts.h:129
#define GZ_READ
Definition gzguts.h:89
int ZEXPORT inflateEnd(z_streamp strm)
Definition inflate.c:1227
Definition file.h:23
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzdirect()

int ZEXPORT gzdirect ( gzFile file)

Definition at line 589 of file gzread.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzgetc()

int ZEXPORT gzgetc ( gzFile file)

Definition at line 445 of file gzread.c.

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}
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition gzread.c:357
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzgets()

char *ZEXPORT gzgets ( gzFile file,
char * buf,
int len )

Definition at line 528 of file gzread.c.

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}
local int gz_skip(gz_statep state, z_off64_t len)
Definition gzread.c:327
char * memchr()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzread()

int ZEXPORT gzread ( gzFile file,
voidp buf,
unsigned len )

Definition at line 357 of file gzread.c.

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}
#define Z_BUF_ERROR
Definition zlib.h:188
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gzungetc()

int ZEXPORT gzungetc ( int c,
gzFile file )

Definition at line 473 of file gzread.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ OF() [1/4]

local int gz_avail OF ( (gz_statep) )
Here is the call graph for this function:

◆ OF() [2/4]

ABC_NAMESPACE_IMPL_START local int gz_load OF ( (gz_statep, unsigned char *, unsigned, unsigned *) )
Here is the call graph for this function:

◆ OF() [3/4]

local int gz_next4 OF ( (gz_statep, unsigned long *) )
Here is the call graph for this function:

◆ OF() [4/4]

Here is the call graph for this function: