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