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