ReactOS  0.4.14-dev-293-g2b39b42
gzread.c
Go to the documentation of this file.
1 /* gzread.c -- zlib functions for reading gzip files
2  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 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_look OF((gz_statep));
13 local int gz_fetch 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. */
23  unsigned char *buf;
24  unsigned len;
25  unsigned *have;
26 {
27  int ret;
28  unsigned get, max = ((unsigned)-1 >> 2) + 1;
29 
30  *have = 0;
31  do {
32  get = len - *have;
33  if (get > max)
34  get = max;
35  ret = read(state->fd, buf + *have, get);
36  if (ret <= 0)
37  break;
38  *have += (unsigned)ret;
39  } while (*have < len);
40  if (ret < 0) {
42  return -1;
43  }
44  if (ret == 0)
45  state->eof = 1;
46  return 0;
47 }
48 
49 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
50  error, 0 otherwise. Note that the eof flag is set when the end of the input
51  file is reached, even though there may be unused data in the buffer. Once
52  that data has been used, no more attempts will be made to read the file.
53  If strm->avail_in != 0, then the current data is moved to the beginning of
54  the input buffer, and then the remainder of the buffer is loaded with the
55  available data from the input file. */
58 {
59  unsigned got;
60  z_streamp strm = &(state->strm);
61 
62  if (state->err != Z_OK && state->err != Z_BUF_ERROR)
63  return -1;
64  if (state->eof == 0) {
65  if (strm->avail_in) { /* copy what's there to the start */
66  unsigned char *p = state->in;
67  unsigned const char *q = strm->next_in;
68  unsigned n = strm->avail_in;
69  do {
70  *p++ = *q++;
71  } while (--n);
72  }
73  if (gz_load(state, state->in + strm->avail_in,
74  state->size - strm->avail_in, &got) == -1)
75  return -1;
76  strm->avail_in += got;
77  strm->next_in = state->in;
78  }
79  return 0;
80 }
81 
82 /* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
83  If this is the first time in, allocate required memory. state->how will be
84  left unchanged if there is no more input data available, will be set to COPY
85  if there is no gzip header and direct copying will be performed, or it will
86  be set to GZIP for decompression. If direct copying, then leftover input
87  data from the input buffer will be copied to the output buffer. In that
88  case, all further file reads will be directly to either the output buffer or
89  a user buffer. If decompressing, the inflate state will be initialized.
90  gz_look() will return 0 on success or -1 on failure. */
93 {
94  z_streamp strm = &(state->strm);
95 
96  /* allocate read buffers and inflate memory */
97  if (state->size == 0) {
98  /* allocate buffers */
99  state->in = (unsigned char *)malloc(state->want);
100  state->out = (unsigned char *)malloc(state->want << 1);
101  if (state->in == NULL || state->out == NULL) {
102  free(state->out);
103  free(state->in);
104  gz_error(state, Z_MEM_ERROR, "out of memory");
105  return -1;
106  }
107  state->size = state->want;
108 
109  /* allocate inflate memory */
110  state->strm.zalloc = Z_NULL;
111  state->strm.zfree = Z_NULL;
112  state->strm.opaque = Z_NULL;
113  state->strm.avail_in = 0;
114  state->strm.next_in = Z_NULL;
115  if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
116  free(state->out);
117  free(state->in);
118  state->size = 0;
119  gz_error(state, Z_MEM_ERROR, "out of memory");
120  return -1;
121  }
122  }
123 
124  /* get at least the magic bytes in the input buffer */
125  if (strm->avail_in < 2) {
126  if (gz_avail(state) == -1)
127  return -1;
128  if (strm->avail_in == 0)
129  return 0;
130  }
131 
132  /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
133  a logical dilemma here when considering the case of a partially written
134  gzip file, to wit, if a single 31 byte is written, then we cannot tell
135  whether this is a single-byte file, or just a partially written gzip
136  file -- for here we assume that if a gzip file is being written, then
137  the header will be written in a single operation, so that reading a
138  single byte is sufficient indication that it is not a gzip file) */
139  if (strm->avail_in > 1 &&
140  strm->next_in[0] == 31 && strm->next_in[1] == 139) {
141  inflateReset(strm);
142  state->how = GZIP;
143  state->direct = 0;
144  return 0;
145  }
146 
147  /* no gzip header -- if we were decoding gzip before, then this is trailing
148  garbage. Ignore the trailing garbage and finish. */
149  if (state->direct == 0) {
150  strm->avail_in = 0;
151  state->eof = 1;
152  state->x.have = 0;
153  return 0;
154  }
155 
156  /* doing raw i/o, copy any leftover input to output -- this assumes that
157  the output buffer is larger than the input buffer, which also assures
158  space for gzungetc() */
159  state->x.next = state->out;
160  if (strm->avail_in) {
161  memcpy(state->x.next, strm->next_in, strm->avail_in);
162  state->x.have = strm->avail_in;
163  strm->avail_in = 0;
164  }
165  state->how = COPY;
166  state->direct = 1;
167  return 0;
168 }
169 
170 /* Decompress from input to the provided next_out and avail_out in the state.
171  On return, state->x.have and state->x.next point to the just decompressed
172  data. If the gzip stream completes, state->how is reset to LOOK to look for
173  the next gzip stream or raw data, once state->x.have is depleted. Returns 0
174  on success, -1 on failure. */
177 {
178  int ret = Z_OK;
179  unsigned had;
180  z_streamp strm = &(state->strm);
181 
182  /* fill output buffer up to end of deflate stream */
183  had = strm->avail_out;
184  do {
185  /* get more input for inflate() */
186  if (strm->avail_in == 0 && gz_avail(state) == -1)
187  return -1;
188  if (strm->avail_in == 0) {
189  gz_error(state, Z_BUF_ERROR, "unexpected end of file");
190  break;
191  }
192 
193  /* decompress and handle errors */
194  ret = inflate(strm, Z_NO_FLUSH);
195  if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
197  "internal error: inflate stream corrupt");
198  return -1;
199  }
200  if (ret == Z_MEM_ERROR) {
201  gz_error(state, Z_MEM_ERROR, "out of memory");
202  return -1;
203  }
204  if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
206  strm->msg == NULL ? "compressed data error" : strm->msg);
207  return -1;
208  }
209  } while (strm->avail_out && ret != Z_STREAM_END);
210 
211  /* update available output */
212  state->x.have = had - strm->avail_out;
213  state->x.next = strm->next_out - state->x.have;
214 
215  /* if the gzip stream completed successfully, look for another */
216  if (ret == Z_STREAM_END)
217  state->how = LOOK;
218 
219  /* good decompression */
220  return 0;
221 }
222 
223 /* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
224  Data is either copied from the input file or decompressed from the input
225  file depending on state->how. If state->how is LOOK, then a gzip header is
226  looked for to determine whether to copy or decompress. Returns -1 on error,
227  otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
228  end of the input file has been reached and all data has been processed. */
231 {
232  z_streamp strm = &(state->strm);
233 
234  do {
235  switch(state->how) {
236  case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
237  if (gz_look(state) == -1)
238  return -1;
239  if (state->how == LOOK)
240  return 0;
241  break;
242  case COPY: /* -> COPY */
243  if (gz_load(state, state->out, state->size << 1, &(state->x.have))
244  == -1)
245  return -1;
246  state->x.next = state->out;
247  return 0;
248  case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
249  strm->avail_out = state->size << 1;
250  strm->next_out = state->out;
251  if (gz_decomp(state) == -1)
252  return -1;
253  }
254  } while (state->x.have == 0 && (!state->eof || strm->avail_in));
255  return 0;
256 }
257 
258 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
261  z_off64_t len;
262 {
263  unsigned n;
264 
265  /* skip over len bytes or reach end-of-file, whichever comes first */
266  while (len)
267  /* skip over whatever is in output buffer */
268  if (state->x.have) {
269  n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
270  (unsigned)len : state->x.have;
271  state->x.have -= n;
272  state->x.next += n;
273  state->x.pos += n;
274  len -= n;
275  }
276 
277  /* output buffer empty -- return if we're at the end of the input */
278  else if (state->eof && state->strm.avail_in == 0)
279  break;
280 
281  /* need more data to skip -- load up output buffer */
282  else {
283  /* get more output, looking for header if required */
284  if (gz_fetch(state) == -1)
285  return -1;
286  }
287  return 0;
288 }
289 
290 /* Read len bytes into buf from file, or less than len up to the end of the
291  input. Return the number of bytes read. If zero is returned, either the
292  end of file was reached, or there was an error. state->err must be
293  consulted in that case to determine which. */
296  voidp buf;
297  z_size_t len;
298 {
299  z_size_t got;
300  unsigned n;
301 
302  /* if len is zero, avoid unnecessary operations */
303  if (len == 0)
304  return 0;
305 
306  /* process a skip request */
307  if (state->seek) {
308  state->seek = 0;
309  if (gz_skip(state, state->skip) == -1)
310  return 0;
311  }
312 
313  /* get len bytes to buf, or less than len if at the end */
314  got = 0;
315  do {
316  /* set n to the maximum amount of len that fits in an unsigned int */
317  n = -1;
318  if (n > len)
319  n = len;
320 
321  /* first just try copying data from the output buffer */
322  if (state->x.have) {
323  if (state->x.have < n)
324  n = state->x.have;
325  memcpy(buf, state->x.next, n);
326  state->x.next += n;
327  state->x.have -= n;
328  }
329 
330  /* output buffer empty -- return if we're at the end of the input */
331  else if (state->eof && state->strm.avail_in == 0) {
332  state->past = 1; /* tried to read past end */
333  break;
334  }
335 
336  /* need output data -- for small len or new stream load up our output
337  buffer */
338  else if (state->how == LOOK || n < (state->size << 1)) {
339  /* get more output, looking for header if required */
340  if (gz_fetch(state) == -1)
341  return 0;
342  continue; /* no progress yet -- go back to copy above */
343  /* the copy above assures that we will leave with space in the
344  output buffer, allowing at least one gzungetc() to succeed */
345  }
346 
347  /* large len -- read directly into user buffer */
348  else if (state->how == COPY) { /* read directly */
349  if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
350  return 0;
351  }
352 
353  /* large len -- decompress directly into user buffer */
354  else { /* state->how == GZIP */
355  state->strm.avail_out = n;
356  state->strm.next_out = (unsigned char *)buf;
357  if (gz_decomp(state) == -1)
358  return 0;
359  n = state->x.have;
360  state->x.have = 0;
361  }
362 
363  /* update progress */
364  len -= n;
365  buf = (char *)buf + n;
366  got += n;
367  state->x.pos += n;
368  } while (len);
369 
370  /* return number of bytes read into user buffer */
371  return got;
372 }
373 
374 /* -- see zlib.h -- */
376  gzFile file;
377  voidp buf;
378  unsigned len;
379 {
381 
382  /* get internal structure */
383  if (file == NULL)
384  return -1;
385  state = (gz_statep)file;
386 
387  /* check that we're reading and that there's no (serious) error */
388  if (state->mode != GZ_READ ||
389  (state->err != Z_OK && state->err != Z_BUF_ERROR))
390  return -1;
391 
392  /* since an int is returned, make sure len fits in one, otherwise return
393  with an error (this avoids a flaw in the interface) */
394  if ((int)len < 0) {
395  gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
396  return -1;
397  }
398 
399  /* read len or fewer bytes to buf */
400  len = gz_read(state, buf, len);
401 
402  /* check for an error */
403  if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
404  return -1;
405 
406  /* return the number of bytes read (this is assured to fit in an int) */
407  return (int)len;
408 }
409 
410 /* -- see zlib.h -- */
412  voidp buf;
413  z_size_t size;
414  z_size_t nitems;
415  gzFile file;
416 {
417  z_size_t len;
419 
420  /* get internal structure */
421  if (file == NULL)
422  return 0;
423  state = (gz_statep)file;
424 
425  /* check that we're reading and that there's no (serious) error */
426  if (state->mode != GZ_READ ||
427  (state->err != Z_OK && state->err != Z_BUF_ERROR))
428  return 0;
429 
430  /* compute bytes to read -- error on overflow */
431  len = nitems * size;
432  if (size && len / size != nitems) {
433  gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
434  return 0;
435  }
436 
437  /* read len or fewer bytes to buf, return the number of full items read */
438  return len ? gz_read(state, buf, len) / size : 0;
439 }
440 
441 /* -- see zlib.h -- */
442 #ifdef Z_PREFIX_SET
443 # undef z_gzgetc
444 #else
445 # undef gzgetc
446 #endif
448  gzFile file;
449 {
450  int ret;
451  unsigned char buf[1];
453 
454  /* get internal structure */
455  if (file == NULL)
456  return -1;
457  state = (gz_statep)file;
458 
459  /* check that we're reading and that there's no (serious) error */
460  if (state->mode != GZ_READ ||
461  (state->err != Z_OK && state->err != Z_BUF_ERROR))
462  return -1;
463 
464  /* try output buffer (no need to check for skip request) */
465  if (state->x.have) {
466  state->x.have--;
467  state->x.pos++;
468  return *(state->x.next)++;
469  }
470 
471  /* nothing there -- try gz_read() */
472  ret = gz_read(state, buf, 1);
473  return ret < 1 ? -1 : buf[0];
474 }
475 
477 gzFile file;
478 {
479  return gzgetc(file);
480 }
481 
482 /* -- see zlib.h -- */
484  int c;
485  gzFile file;
486 {
488 
489  /* get internal structure */
490  if (file == NULL)
491  return -1;
492  state = (gz_statep)file;
493 
494  /* check that we're reading and that there's no (serious) error */
495  if (state->mode != GZ_READ ||
496  (state->err != Z_OK && state->err != Z_BUF_ERROR))
497  return -1;
498 
499  /* process a skip request */
500  if (state->seek) {
501  state->seek = 0;
502  if (gz_skip(state, state->skip) == -1)
503  return -1;
504  }
505 
506  /* can't push EOF */
507  if (c < 0)
508  return -1;
509 
510  /* if output buffer empty, put byte at end (allows more pushing) */
511  if (state->x.have == 0) {
512  state->x.have = 1;
513  state->x.next = state->out + (state->size << 1) - 1;
514  state->x.next[0] = (unsigned char)c;
515  state->x.pos--;
516  state->past = 0;
517  return c;
518  }
519 
520  /* if no room, give up (must have already done a gzungetc()) */
521  if (state->x.have == (state->size << 1)) {
522  gz_error(state, Z_DATA_ERROR, "out of room to push characters");
523  return -1;
524  }
525 
526  /* slide output data if needed and insert byte before existing data */
527  if (state->x.next == state->out) {
528  unsigned char *src = state->out + state->x.have;
529  unsigned char *dest = state->out + (state->size << 1);
530  while (src > state->out)
531  *--dest = *--src;
532  state->x.next = dest;
533  }
534  state->x.have++;
535  state->x.next--;
536  state->x.next[0] = (unsigned char)c;
537  state->x.pos--;
538  state->past = 0;
539  return c;
540 }
541 
542 /* -- see zlib.h -- */
544  gzFile file;
545  char *buf;
546  int len;
547 {
548  unsigned left, n;
549  char *str;
550  unsigned char *eol;
552 
553  /* check parameters and get internal structure */
554  if (file == NULL || buf == NULL || len < 1)
555  return NULL;
556  state = (gz_statep)file;
557 
558  /* check that we're reading and that there's no (serious) error */
559  if (state->mode != GZ_READ ||
560  (state->err != Z_OK && state->err != Z_BUF_ERROR))
561  return NULL;
562 
563  /* process a skip request */
564  if (state->seek) {
565  state->seek = 0;
566  if (gz_skip(state, state->skip) == -1)
567  return NULL;
568  }
569 
570  /* copy output bytes up to new line or len - 1, whichever comes first --
571  append a terminating zero to the string (we don't check for a zero in
572  the contents, let the user worry about that) */
573  str = buf;
574  left = (unsigned)len - 1;
575  if (left) do {
576  /* assure that something is in the output buffer */
577  if (state->x.have == 0 && gz_fetch(state) == -1)
578  return NULL; /* error */
579  if (state->x.have == 0) { /* end of file */
580  state->past = 1; /* read past end */
581  break; /* return what we have */
582  }
583 
584  /* look for end-of-line in current output buffer */
585  n = state->x.have > left ? left : state->x.have;
586  eol = (unsigned char *)memchr(state->x.next, '\n', n);
587  if (eol != NULL)
588  n = (unsigned)(eol - state->x.next) + 1;
589 
590  /* copy through end-of-line, or remainder if not found */
591  memcpy(buf, state->x.next, n);
592  state->x.have -= n;
593  state->x.next += n;
594  state->x.pos += n;
595  left -= n;
596  buf += n;
597  } while (left && eol == NULL);
598 
599  /* return terminated string, or if nothing, end of file */
600  if (buf == str)
601  return NULL;
602  buf[0] = 0;
603  return str;
604 }
605 
606 /* -- see zlib.h -- */
608  gzFile file;
609 {
611 
612  /* get internal structure */
613  if (file == NULL)
614  return 0;
615  state = (gz_statep)file;
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->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
620  (void)gz_look(state);
621 
622  /* return 1 if transparent, 0 if processing a gzip stream */
623  return state->direct;
624 }
625 
626 /* -- see zlib.h -- */
628  gzFile file;
629 {
630  int ret, err;
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  err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
649  gz_error(state, Z_OK, NULL);
650  free(state->path);
651  ret = close(state->fd);
652  free(state);
653  return ret ? Z_ERRNO : err;
654 }
unsigned long z_size_t
Definition: zconf.h:250
int ZEXPORT gzdirect(gzFile file)
Definition: gzread.c:607
#define max(a, b)
Definition: svc.c:63
#define Z_ERRNO
Definition: zlib.h:180
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define COPY(len)
Definition: rtl.c:274
#define memchr(s, c, n)
Definition: mkisofs.h:875
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int gz_avail(gz_statep state)
Definition: gzread.c:56
#define free
Definition: debug_ros.c:5
int ZEXPORT inflateEnd(z_streamp strm)
Definition: inflate.c:1277
#define GT_OFF(x)
Definition: gzguts.h:217
unsigned have
Definition: zlib.h:1818
GLdouble n
Definition: glext.h:7729
#define GZ_READ
Definition: gzguts.h:160
#define z_off64_t
Definition: zconf.h:513
z_size_t gz_read(gz_statep state, voidp buf, z_size_t len)
Definition: gzread.c:294
#define Z_NEED_DICT
Definition: zlib.h:179
#define Z_STREAM_ERROR
Definition: zlib.h:181
#define Z_STREAM_END
Definition: zlib.h:178
#define Z_BUF_ERROR
Definition: zlib.h:184
z_stream FAR * z_streamp
Definition: zlib.h:108
int ZEXPORT gzgetc_(gzFile file)
Definition: gzread.c:476
#define Z_OK
Definition: zlib.h:177
int gz_fetch(gz_statep state)
Definition: gzread.c:229
int ZEXPORT gzungetc(int c, gzFile file)
Definition: gzread.c:483
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
int gz_decomp(gz_statep state)
Definition: gzread.c:175
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.c:579
void get(int argc, const char *argv[])
Definition: cmds.c:480
GLsizeiptr size
Definition: glext.h:5919
int ZEXPORT gzclose_r(gzFile file)
Definition: gzread.c:627
const char file[]
Definition: icontest.c:11
const GLubyte * c
Definition: glext.h:8905
#define inflateInit2(strm, windowBits)
Definition: zlib.h:1800
GLint left
Definition: glext.h:7726
#define Z_DATA_ERROR
Definition: zlib.h:182
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
#define Z_NO_FLUSH
Definition: zlib.h:168
int gz_look(gz_statep state)
Definition: gzread.c:91
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: inflate.c:622
int ret
int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have)
Definition: gzread.c:21
Byte * voidp
Definition: zconf.h:414
static int state
Definition: maze.c:121
int ZEXPORT inflateReset(z_streamp strm)
Definition: inflate.c:144
z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)
Definition: gzread.c:411
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
char *ZEXPORT gzgets(gzFile file, char *buf, int len)
Definition: gzread.c:543
GLenum src
Definition: glext.h:6340
#define close
Definition: acwin.h:98
#define err(...)
int ZEXPORT gzgetc(gzFile file)
Definition: gzread.c:447
#define local
Definition: zutil.h:30
#define LOOK
Definition: gzguts.h:165
int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *))
int gz_skip(gz_statep state, z_off64_t len)
Definition: gzread.c:259
gz_state FAR * gz_statep
Definition: gzguts.h:202
#define c
Definition: ke_i.h:80
#define malloc
Definition: debug_ros.c:4
static char * dest
Definition: rtl.c:135
GLfloat GLfloat p
Definition: glext.h:8902
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzread.c:375
#define Z_NULL
Definition: zlib.h:212
#define ZEXPORT
Definition: zconf.h:380
#define Z_MEM_ERROR
Definition: zlib.h:183
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define GZIP
Definition: deflate.h:23
#define zstrerror(errnum)
Definition: zutil.h:152
Definition: fci.c:126