gzio.c
Go to the documentation of this file.
1 /* gzio.c -- IO on .gz files
2  * Copyright (C) 1995-2005 Jean-loup Gailly.
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  *
5  * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
6  */
7 
8 /* @(#) $Id$ */
9 
10 #include <stdio.h>
11 
12 #include "zutil.h"
13 
14 #ifdef NO_DEFLATE /* for compatibility with old definition */
15 # define NO_GZCOMPRESS
16 #endif
17 
18 #ifndef NO_DUMMY_DECL
19 struct internal_state {int dummy;}; /* for buggy compilers */
20 #endif
21 
22 #ifndef Z_BUFSIZE
23 # ifdef MAXSEG_64K
24 # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
25 # else
26 # define Z_BUFSIZE 16384
27 # endif
28 #endif
29 #ifndef Z_PRINTF_BUFSIZE
30 # define Z_PRINTF_BUFSIZE 4096
31 #endif
32 
33 #ifdef __MVS__
34 # pragma map (fdopen , "\174\174FDOPEN")
35  FILE *fdopen(int, const char *);
36 #endif
37 
38 #ifndef STDC
39 extern voidp malloc OF((uInt size));
40 extern void free OF((voidpf ptr));
41 #endif
42 
43 #define ALLOC(size) malloc(size)
44 #define TRYFREE(p) {if (p) free(p);}
45 
46 static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
47 
48 /* gzip flag byte */
49 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
50 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
51 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
52 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
53 #define COMMENT 0x10 /* bit 4 set: file comment present */
54 #define RESERVED 0xE0 /* bits 5..7: reserved */
55 
56 typedef struct gz_stream {
58  int z_err; /* error code for last stream operation */
59  int z_eof; /* set if end of input file */
60  FILE *file; /* .gz file */
61  Byte *inbuf; /* input buffer */
62  Byte *outbuf; /* output buffer */
63  uLong crc; /* crc32 of uncompressed data */
64  char *msg; /* error message */
65  char *path; /* path name for debugging only */
66  int transparent; /* 1 if input file is not a .gz file */
67  char mode; /* 'w' or 'r' */
68  z_off_t start; /* start of compressed data in file (header skipped) */
69  z_off_t in; /* bytes into deflate or inflate */
70  z_off_t out; /* bytes out of deflate or inflate */
71  int back; /* one character push-back */
72  int last; /* true if push-back is last character */
73 } gz_stream;
74 
75 
76 local gzFile gz_open OF((const char *path, const char *mode, int fd));
77 local int do_flush OF((gzFile file, int flush));
78 local int get_byte OF((gz_stream *s));
79 local void check_header OF((gz_stream *s));
80 local int destroy OF((gz_stream *s));
81 local void putLong OF((FILE *file, uLong x));
83 
84 /* ===========================================================================
85  Opens a gzip (.gz) file for reading or writing. The mode parameter
86  is as in fopen ("rb" or "wb"). The file is given either by file descriptor
87  or path name (if fd == -1).
88  gz_open returns NULL if the file could not be opened or if there was
89  insufficient memory to allocate the (de)compression state; errno
90  can be checked to distinguish the two cases (if errno is zero, the
91  zlib error is Z_MEM_ERROR).
92 */
93 local gzFile gz_open (path, mode, fd)
94  const char *path;
95  const char *mode;
96  int fd;
97 {
98  int err;
99  int level = Z_DEFAULT_COMPRESSION; /* compression level */
100  int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
101  char *p = (char*)mode;
102  gz_stream *s;
103  char fmode[80]; /* copy of mode, without the compression level */
104  char *m = fmode;
105 
106  if (!path || !mode) return Z_NULL;
107 
108  s = (gz_stream *)ALLOC(sizeof(gz_stream));
109  if (!s) return Z_NULL;
110 
111  s->stream.zalloc = (alloc_func)0;
112  s->stream.zfree = (free_func)0;
113  s->stream.opaque = (voidpf)0;
114  s->stream.next_in = s->inbuf = Z_NULL;
115  s->stream.next_out = s->outbuf = Z_NULL;
116  s->stream.avail_in = s->stream.avail_out = 0;
117  s->file = NULL;
118  s->z_err = Z_OK;
119  s->z_eof = 0;
120  s->in = 0;
121  s->out = 0;
122  s->back = EOF;
123  s->crc = crc32(0L, Z_NULL, 0);
124  s->msg = NULL;
125  s->transparent = 0;
126 
127  s->path = (char*)ALLOC(strlen(path)+1);
128  if (s->path == NULL) {
129  return destroy(s), (gzFile)Z_NULL;
130  }
131  strcpy(s->path, path); /* do this early for debugging */
132 
133  s->mode = '\0';
134  do {
135  if (*p == 'r') s->mode = 'r';
136  if (*p == 'w' || *p == 'a') s->mode = 'w';
137  if (*p >= '0' && *p <= '9') {
138  level = *p - '0';
139  } else if (*p == 'f') {
140  strategy = Z_FILTERED;
141  } else if (*p == 'h') {
142  strategy = Z_HUFFMAN_ONLY;
143  } else if (*p == 'R') {
144  strategy = Z_RLE;
145  } else {
146  *m++ = *p; /* copy the mode */
147  }
148  } while (*p++ && m != fmode + sizeof(fmode));
149  if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
150 
151  if (s->mode == 'w') {
152 #ifdef NO_GZCOMPRESS
153  err = Z_STREAM_ERROR;
154 #else
155  err = deflateInit2(&(s->stream), level,
156  Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
157  /* windowBits is passed < 0 to suppress zlib header */
158 
159  s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
160 #endif
161  if (err != Z_OK || s->outbuf == Z_NULL) {
162  return destroy(s), (gzFile)Z_NULL;
163  }
164  } else {
165  s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
166 
167  err = inflateInit2(&(s->stream), -MAX_WBITS);
168  /* windowBits is passed < 0 to tell that there is no zlib header.
169  * Note that in this case inflate *requires* an extra "dummy" byte
170  * after the compressed stream in order to complete decompression and
171  * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
172  * present after the compressed stream.
173  */
174  if (err != Z_OK || s->inbuf == Z_NULL) {
175  return destroy(s), (gzFile)Z_NULL;
176  }
177  }
179 
180  errno = 0;
181  s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
182 
183  if (s->file == NULL) {
184  return destroy(s), (gzFile)Z_NULL;
185  }
186  if (s->mode == 'w') {
187  /* Write a very simple .gz header:
188  */
189  fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
190  Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
191  s->start = 10L;
192  /* We use 10L instead of ftell(s->file) to because ftell causes an
193  * fflush on some systems. This version of the library doesn't use
194  * start anyway in write mode, so this initialization is not
195  * necessary.
196  */
197  } else {
198  check_header(s); /* skip the .gz header */
199  s->start = ftell(s->file) - s->stream.avail_in;
200  }
201 
202  return (gzFile)s;
203 }
204 
205 /* ===========================================================================
206  Opens a gzip (.gz) file for reading or writing.
207 */
208 gzFile ZEXPORT gzopen (path, mode)
209  const char *path;
210  const char *mode;
211 {
212  return gz_open (path, mode, -1);
213 }
214 
215 /* ===========================================================================
216  Associate a gzFile with the file descriptor fd. fd is not dup'ed here
217  to mimic the behavio(u)r of fdopen.
218 */
220  int fd;
221  const char *mode;
222 {
223  char name[46]; /* allow for up to 128-bit integers */
224 
225  if (fd < 0) return (gzFile)Z_NULL;
226  sprintf(name, "<fd:%d>", fd); /* for debugging */
227 
228  return gz_open (name, mode, fd);
229 }
230 
231 /* ===========================================================================
232  * Update the compression level and strategy
233  */
235  gzFile file;
236  int level;
237  int strategy;
238 {
239  gz_stream *s = (gz_stream*)file;
240 
241  if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
242 
243  /* Make room to allow flushing */
244  if (s->stream.avail_out == 0) {
245 
246  s->stream.next_out = s->outbuf;
247  if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
248  s->z_err = Z_ERRNO;
249  }
251  }
252 
253  return deflateParams (&(s->stream), level, strategy);
254 }
255 
256 /* ===========================================================================
257  Read a byte from a gz_stream; update next_in and avail_in. Return EOF
258  for end of file.
259  IN assertion: the stream s has been sucessfully opened for reading.
260 */
262  gz_stream *s;
263 {
264  if (s->z_eof) return EOF;
265  if (s->stream.avail_in == 0) {
266  errno = 0;
267  s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
268  if (s->stream.avail_in == 0) {
269  s->z_eof = 1;
270  if (ferror(s->file)) s->z_err = Z_ERRNO;
271  return EOF;
272  }
273  s->stream.next_in = s->inbuf;
274  }
275  s->stream.avail_in--;
276  return *(s->stream.next_in)++;
277 }
278 
279 /* ===========================================================================
280  Check the gzip header of a gz_stream opened for reading. Set the stream
281  mode to transparent if the gzip magic header is not present; set s->err
282  to Z_DATA_ERROR if the magic header is present but the rest of the header
283  is incorrect.
284  IN assertion: the stream s has already been created sucessfully;
285  s->stream.avail_in is zero for the first time, but may be non-zero
286  for concatenated .gz files.
287 */
289  gz_stream *s;
290 {
291  int method; /* method byte */
292  int flags; /* flags byte */
293  uInt len;
294  int c;
295 
296  /* Assure two bytes in the buffer so we can peek ahead -- handle case
297  where first byte of header is at the end of the buffer after the last
298  gzip segment */
299  len = s->stream.avail_in;
300  if (len < 2) {
301  if (len) s->inbuf[0] = s->stream.next_in[0];
302  errno = 0;
303  len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
304  if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
305  s->stream.avail_in += len;
306  s->stream.next_in = s->inbuf;
307  if (s->stream.avail_in < 2) {
308  s->transparent = s->stream.avail_in;
309  return;
310  }
311  }
312 
313  /* Peek ahead to check the gzip magic header */
314  if (s->stream.next_in[0] != gz_magic[0] ||
315  s->stream.next_in[1] != gz_magic[1]) {
316  s->transparent = 1;
317  return;
318  }
319  s->stream.avail_in -= 2;
320  s->stream.next_in += 2;
321 
322  /* Check the rest of the gzip header */
323  method = get_byte(s);
324  flags = get_byte(s);
325  if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
326  s->z_err = Z_DATA_ERROR;
327  return;
328  }
329 
330  /* Discard time, xflags and OS code: */
331  for (len = 0; len < 6; len++) (void)get_byte(s);
332 
333  if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
334  len = (uInt)get_byte(s);
335  len += ((uInt)get_byte(s))<<8;
336  /* len is garbage if EOF but the loop below will quit anyway */
337  while (len-- != 0 && get_byte(s) != EOF) ;
338  }
339  if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
340  while ((c = get_byte(s)) != 0 && c != EOF) ;
341  }
342  if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
343  while ((c = get_byte(s)) != 0 && c != EOF) ;
344  }
345  if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
346  for (len = 0; len < 2; len++) (void)get_byte(s);
347  }
348  s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
349 }
350 
351  /* ===========================================================================
352  * Cleanup then free the given gz_stream. Return a zlib error code.
353  Try freeing in the reverse order of allocations.
354  */
355 local int destroy (s)
356  gz_stream *s;
357 {
358  int err = Z_OK;
359 
360  if (!s) return Z_STREAM_ERROR;
361 
362  TRYFREE(s->msg);
363 
364  if (s->stream.state != NULL) {
365  if (s->mode == 'w') {
366 #ifdef NO_GZCOMPRESS
367  err = Z_STREAM_ERROR;
368 #else
369  err = deflateEnd(&(s->stream));
370 #endif
371  } else if (s->mode == 'r') {
372  err = inflateEnd(&(s->stream));
373  }
374  }
375  if (s->file != NULL && fclose(s->file)) {
376 #ifdef ESPIPE
377  if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
378 #endif
379  err = Z_ERRNO;
380  }
381  if (s->z_err < 0) err = s->z_err;
382 
383  TRYFREE(s->inbuf);
384  TRYFREE(s->outbuf);
385  TRYFREE(s->path);
386  TRYFREE(s);
387  return err;
388 }
389 
390 /* ===========================================================================
391  Reads the given number of uncompressed bytes from the compressed file.
392  gzread returns the number of bytes actually read (0 for end of file).
393 */
394 int ZEXPORT gzread (file, buf, len)
395  gzFile file;
396  voidp buf;
397  unsigned len;
398 {
399  gz_stream *s = (gz_stream*)file;
400  Bytef *start = (Bytef*)buf; /* starting point for crc computation */
401  Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
402 
403  if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
404 
405  if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
406  if (s->z_err == Z_STREAM_END) return 0; /* EOF */
407 
408  next_out = (Byte*)buf;
409  s->stream.next_out = (Bytef*)buf;
410  s->stream.avail_out = len;
411 
412  if (s->stream.avail_out && s->back != EOF) {
413  *next_out++ = s->back;
414  s->stream.next_out++;
415  s->stream.avail_out--;
416  s->back = EOF;
417  s->out++;
418  start++;
419  if (s->last) {
420  s->z_err = Z_STREAM_END;
421  return 1;
422  }
423  }
424 
425  while (s->stream.avail_out != 0) {
426 
427  if (s->transparent) {
428  /* Copy first the lookahead bytes: */
429  uInt n = s->stream.avail_in;
430  if (n > s->stream.avail_out) n = s->stream.avail_out;
431  if (n > 0) {
432  zmemcpy(s->stream.next_out, s->stream.next_in, n);
433  next_out += n;
434  s->stream.next_out = next_out;
435  s->stream.next_in += n;
436  s->stream.avail_out -= n;
437  s->stream.avail_in -= n;
438  }
439  if (s->stream.avail_out > 0) {
440  s->stream.avail_out -=
441  (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
442  }
443  len -= s->stream.avail_out;
444  s->in += len;
445  s->out += len;
446  if (len == 0) s->z_eof = 1;
447  return (int)len;
448  }
449  if (s->stream.avail_in == 0 && !s->z_eof) {
450 
451  errno = 0;
452  s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
453  if (s->stream.avail_in == 0) {
454  s->z_eof = 1;
455  if (ferror(s->file)) {
456  s->z_err = Z_ERRNO;
457  break;
458  }
459  }
460  s->stream.next_in = s->inbuf;
461  }
462  s->in += s->stream.avail_in;
463  s->out += s->stream.avail_out;
464  s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
465  s->in -= s->stream.avail_in;
466  s->out -= s->stream.avail_out;
467 
468  if (s->z_err == Z_STREAM_END) {
469  /* Check CRC and original size */
470  s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
471  start = s->stream.next_out;
472 
473  if (getLong(s) != s->crc) {
474  s->z_err = Z_DATA_ERROR;
475  } else {
476  (void)getLong(s);
477  /* The uncompressed length returned by above getlong() may be
478  * different from s->out in case of concatenated .gz files.
479  * Check for such files:
480  */
481  check_header(s);
482  if (s->z_err == Z_OK) {
483  inflateReset(&(s->stream));
484  s->crc = crc32(0L, Z_NULL, 0);
485  }
486  }
487  }
488  if (s->z_err != Z_OK || s->z_eof) break;
489  }
490  s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
491 
492  if (len == s->stream.avail_out &&
493  (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
494  return -1;
495  return (int)(len - s->stream.avail_out);
496 }
497 
498 
499 /* ===========================================================================
500  Reads one byte from the compressed file. gzgetc returns this byte
501  or -1 in case of end of file or error.
502 */
503 int ZEXPORT gzgetc(file)
504  gzFile file;
505 {
506  unsigned char c;
507 
508  return gzread(file, &c, 1) == 1 ? c : -1;
509 }
510 
511 
512 /* ===========================================================================
513  Push one byte back onto the stream.
514 */
515 int ZEXPORT gzungetc(c, file)
516  int c;
517  gzFile file;
518 {
519  gz_stream *s = (gz_stream*)file;
520 
521  if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
522  s->back = c;
523  s->out--;
524  s->last = (s->z_err == Z_STREAM_END);
525  if (s->last) s->z_err = Z_OK;
526  s->z_eof = 0;
527  return c;
528 }
529 
530 
531 /* ===========================================================================
532  Reads bytes from the compressed file until len-1 characters are
533  read, or a newline character is read and transferred to buf, or an
534  end-of-file condition is encountered. The string is then terminated
535  with a null character.
536  gzgets returns buf, or Z_NULL in case of error.
537 
538  The current implementation is not optimized at all.
539 */
540 char * ZEXPORT gzgets(file, buf, len)
541  gzFile file;
542  char *buf;
543  int len;
544 {
545  char *b = buf;
546  if (buf == Z_NULL || len <= 0) return Z_NULL;
547 
548  while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
549  *buf = '\0';
550  return b == buf && len > 0 ? Z_NULL : b;
551 }
552 
553 
554 #ifndef NO_GZCOMPRESS
555 /* ===========================================================================
556  Writes the given number of uncompressed bytes into the compressed file.
557  gzwrite returns the number of bytes actually written (0 in case of error).
558 */
559 int ZEXPORT gzwrite (file, buf, len)
560  gzFile file;
561  voidpc buf;
562  unsigned len;
563 {
564  gz_stream *s = (gz_stream*)file;
565 
566  if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
567 
568  s->stream.next_in = (Bytef*)buf;
569  s->stream.avail_in = len;
570 
571  while (s->stream.avail_in != 0) {
572 
573  if (s->stream.avail_out == 0) {
574 
575  s->stream.next_out = s->outbuf;
576  if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
577  s->z_err = Z_ERRNO;
578  break;
579  }
581  }
582  s->in += s->stream.avail_in;
583  s->out += s->stream.avail_out;
584  s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
585  s->in -= s->stream.avail_in;
586  s->out -= s->stream.avail_out;
587  if (s->z_err != Z_OK) break;
588  }
589  s->crc = crc32(s->crc, (const Bytef *)buf, len);
590 
591  return (int)(len - s->stream.avail_in);
592 }
593 
594 
595 /* ===========================================================================
596  Converts, formats, and writes the args to the compressed file under
597  control of the format string, as in fprintf. gzprintf returns the number of
598  uncompressed bytes actually written (0 in case of error).
599 */
600 #ifdef STDC
601 #include <stdarg.h>
602 
603 int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
604 {
605  char buf[Z_PRINTF_BUFSIZE];
606  va_list va;
607  int len;
608 
609  buf[sizeof(buf) - 1] = 0;
610  va_start(va, format);
611 #ifdef NO_vsnprintf
612 # ifdef HAS_vsprintf_void
613  (void)vsprintf(buf, format, va);
614  va_end(va);
615  for (len = 0; len < sizeof(buf); len++)
616  if (buf[len] == 0) break;
617 # else
618  len = vsprintf(buf, format, va);
619  va_end(va);
620 # endif
621 #else
622 # ifdef HAS_vsnprintf_void
623  (void)vsnprintf(buf, sizeof(buf), format, va);
624  va_end(va);
625  len = strlen(buf);
626 # else
627  len = vsnprintf(buf, sizeof(buf), format, va);
628  va_end(va);
629 # endif
630 #endif
631  if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
632  return 0;
633  return gzwrite(file, buf, (unsigned)len);
634 }
635 #else /* not ANSI C */
636 
637 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
638  a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
639  gzFile file;
640  const char *format;
641  int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
642  a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
643 {
644  char buf[Z_PRINTF_BUFSIZE];
645  int len;
646 
647  buf[sizeof(buf) - 1] = 0;
648 #ifdef NO_snprintf
649 # ifdef HAS_sprintf_void
650  sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
651  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
652  for (len = 0; len < sizeof(buf); len++)
653  if (buf[len] == 0) break;
654 # else
655  len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
656  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
657 # endif
658 #else
659 # ifdef HAS_snprintf_void
660  snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
661  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
662  len = strlen(buf);
663 # else
664  len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
665  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
666 # endif
667 #endif
668  if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
669  return 0;
670  return gzwrite(file, buf, len);
671 }
672 #endif
673 
674 /* ===========================================================================
675  Writes c, converted to an unsigned char, into the compressed file.
676  gzputc returns the value that was written, or -1 in case of error.
677 */
678 int ZEXPORT gzputc(file, c)
679  gzFile file;
680  int c;
681 {
682  unsigned char cc = (unsigned char) c; /* required for big endian systems */
683 
684  return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
685 }
686 
687 
688 /* ===========================================================================
689  Writes the given null-terminated string to the compressed file, excluding
690  the terminating null character.
691  gzputs returns the number of characters written, or -1 in case of error.
692 */
693 int ZEXPORT gzputs(file, s)
694  gzFile file;
695  const char *s;
696 {
697  return gzwrite(file, (char*)s, (unsigned)strlen(s));
698 }
699 
700 
701 /* ===========================================================================
702  Flushes all pending output into the compressed file. The parameter
703  flush is as in the deflate() function.
704 */
705 local int do_flush (file, flush)
706  gzFile file;
707  int flush;
708 {
709  uInt len;
710  int done = 0;
711  gz_stream *s = (gz_stream*)file;
712 
713  if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
714 
715  s->stream.avail_in = 0; /* should be zero already anyway */
716 
717  for (;;) {
718  len = Z_BUFSIZE - s->stream.avail_out;
719 
720  if (len != 0) {
721  if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
722  s->z_err = Z_ERRNO;
723  return Z_ERRNO;
724  }
725  s->stream.next_out = s->outbuf;
727  }
728  if (done) break;
729  s->out += s->stream.avail_out;
730  s->z_err = deflate(&(s->stream), flush);
731  s->out -= s->stream.avail_out;
732 
733  /* Ignore the second of two consecutive flushes: */
734  if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
735 
736  /* deflate has finished flushing only when it hasn't used up
737  * all the available space in the output buffer:
738  */
739  done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
740 
741  if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
742  }
743  return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
744 }
745 
746 int ZEXPORT gzflush (file, flush)
747  gzFile file;
748  int flush;
749 {
750  gz_stream *s = (gz_stream*)file;
751  int err = do_flush (file, flush);
752 
753  if (err) return err;
754  fflush(s->file);
755  return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
756 }
757 #endif /* NO_GZCOMPRESS */
758 
759 /* ===========================================================================
760  Sets the starting position for the next gzread or gzwrite on the given
761  compressed file. The offset represents a number of bytes in the
762  gzseek returns the resulting offset location as measured in bytes from
763  the beginning of the uncompressed stream, or -1 in case of error.
764  SEEK_END is not implemented, returns error.
765  In this version of the library, gzseek can be extremely slow.
766 */
767 z_off_t ZEXPORT gzseek (file, offset, whence)
768  gzFile file;
769  z_off_t offset;
770  int whence;
771 {
772  gz_stream *s = (gz_stream*)file;
773 
774  if (s == NULL || whence == SEEK_END ||
775  s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
776  return -1L;
777  }
778 
779  if (s->mode == 'w') {
780 #ifdef NO_GZCOMPRESS
781  return -1L;
782 #else
783  if (whence == SEEK_SET) {
784  offset -= s->in;
785  }
786  if (offset < 0) return -1L;
787 
788  /* At this point, offset is the number of zero bytes to write. */
789  if (s->inbuf == Z_NULL) {
790  s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
791  if (s->inbuf == Z_NULL) return -1L;
792  zmemzero(s->inbuf, Z_BUFSIZE);
793  }
794  while (offset > 0) {
795  uInt size = Z_BUFSIZE;
796  if (offset < Z_BUFSIZE) size = (uInt)offset;
797 
798  size = gzwrite(file, s->inbuf, size);
799  if (size == 0) return -1L;
800 
801  offset -= size;
802  }
803  return s->in;
804 #endif
805  }
806  /* Rest of function is for reading only */
807 
808  /* compute absolute position */
809  if (whence == SEEK_CUR) {
810  offset += s->out;
811  }
812  if (offset < 0) return -1L;
813 
814  if (s->transparent) {
815  /* map to fseek */
816  s->back = EOF;
817  s->stream.avail_in = 0;
818  s->stream.next_in = s->inbuf;
819  if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
820 
821  s->in = s->out = offset;
822  return offset;
823  }
824 
825  /* For a negative seek, rewind and use positive seek */
826  if (offset >= s->out) {
827  offset -= s->out;
828  } else if (gzrewind(file) < 0) {
829  return -1L;
830  }
831  /* offset is now the number of bytes to skip. */
832 
833  if (offset != 0 && s->outbuf == Z_NULL) {
834  s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
835  if (s->outbuf == Z_NULL) return -1L;
836  }
837  if (offset && s->back != EOF) {
838  s->back = EOF;
839  s->out++;
840  offset--;
841  if (s->last) s->z_err = Z_STREAM_END;
842  }
843  while (offset > 0) {
844  int size = Z_BUFSIZE;
845  if (offset < Z_BUFSIZE) size = (int)offset;
846 
847  size = gzread(file, s->outbuf, (uInt)size);
848  if (size <= 0) return -1L;
849  offset -= size;
850  }
851  return s->out;
852 }
853 
854 /* ===========================================================================
855  Rewinds input file.
856 */
857 int ZEXPORT gzrewind (file)
858  gzFile file;
859 {
860  gz_stream *s = (gz_stream*)file;
861 
862  if (s == NULL || s->mode != 'r') return -1;
863 
864  s->z_err = Z_OK;
865  s->z_eof = 0;
866  s->back = EOF;
867  s->stream.avail_in = 0;
868  s->stream.next_in = s->inbuf;
869  s->crc = crc32(0L, Z_NULL, 0);
870  if (!s->transparent) (void)inflateReset(&s->stream);
871  s->in = 0;
872  s->out = 0;
873  return fseek(s->file, s->start, SEEK_SET);
874 }
875 
876 /* ===========================================================================
877  Returns the starting position for the next gzread or gzwrite on the
878  given compressed file. This position represents a number of bytes in the
879  uncompressed data stream.
880 */
882  gzFile file;
883 {
884  return gzseek(file, 0L, SEEK_CUR);
885 }
886 
887 /* ===========================================================================
888  Returns 1 when EOF has previously been detected reading the given
889  input stream, otherwise zero.
890 */
891 int ZEXPORT gzeof (file)
892  gzFile file;
893 {
894  gz_stream *s = (gz_stream*)file;
895 
896  /* With concatenated compressed files that can have embedded
897  * crc trailers, z_eof is no longer the only/best indicator of EOF
898  * on a gz_stream. Handle end-of-stream error explicitly here.
899  */
900  if (s == NULL || s->mode != 'r') return 0;
901  if (s->z_eof) return 1;
902  return s->z_err == Z_STREAM_END;
903 }
904 
905 /* ===========================================================================
906  Returns 1 if reading and doing so transparently, otherwise zero.
907 */
908 int ZEXPORT gzdirect (file)
909  gzFile file;
910 {
911  gz_stream *s = (gz_stream*)file;
912 
913  if (s == NULL || s->mode != 'r') return 0;
914  return s->transparent;
915 }
916 
917 /* ===========================================================================
918  Outputs a long in LSB order to the given file
919 */
920 local void putLong (file, x)
921  FILE *file;
922  uLong x;
923 {
924  int n;
925  for (n = 0; n < 4; n++) {
926  fputc((int)(x & 0xff), file);
927  x >>= 8;
928  }
929 }
930 
931 /* ===========================================================================
932  Reads a long in LSB order from the given gz_stream. Sets z_err in case
933  of error.
934 */
936  gz_stream *s;
937 {
938  uLong x = (uLong)get_byte(s);
939  int c;
940 
941  x += ((uLong)get_byte(s))<<8;
942  x += ((uLong)get_byte(s))<<16;
943  c = get_byte(s);
944  if (c == EOF) s->z_err = Z_DATA_ERROR;
945  x += ((uLong)c)<<24;
946  return x;
947 }
948 
949 /* ===========================================================================
950  Flushes all pending output if necessary, closes the compressed file
951  and deallocates all the (de)compression state.
952 */
953 int ZEXPORT gzclose (file)
954  gzFile file;
955 {
956  gz_stream *s = (gz_stream*)file;
957 
958  if (s == NULL) return Z_STREAM_ERROR;
959 
960  if (s->mode == 'w') {
961 #ifdef NO_GZCOMPRESS
962  return Z_STREAM_ERROR;
963 #else
964  if (do_flush (file, Z_FINISH) != Z_OK)
965  return destroy((gz_stream*)file);
966 
967  putLong (s->file, s->crc);
968  putLong (s->file, (uLong)(s->in & 0xffffffff));
969 #endif
970  }
971  return destroy((gz_stream*)file);
972 }
973 
974 #ifdef STDC
975 # define zstrerror(errnum) strerror(errnum)
976 #else
977 # define zstrerror(errnum) ""
978 #endif
979 
980 /* ===========================================================================
981  Returns the error message for the last error which occurred on the
982  given compressed file. errnum is set to zlib error number. If an
983  error occurred in the file system and not in the compression library,
984  errnum is set to Z_ERRNO and the application may consult errno
985  to get the exact error code.
986 */
987 const char * ZEXPORT gzerror (file, errnum)
988  gzFile file;
989  int *errnum;
990 {
991  char *m;
992  gz_stream *s = (gz_stream*)file;
993 
994  if (s == NULL) {
995  *errnum = Z_STREAM_ERROR;
996  return (const char*)ERR_MSG(Z_STREAM_ERROR);
997  }
998  *errnum = s->z_err;
999  if (*errnum == Z_OK) return (const char*)"";
1000 
1001  m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
1002 
1003  if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
1004 
1005  TRYFREE(s->msg);
1006  s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
1007  if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
1008  strcpy(s->msg, s->path);
1009  strcat(s->msg, ": ");
1010  strcat(s->msg, m);
1011  return (const char*)s->msg;
1012 }
1013 
1014 /* ===========================================================================
1015  Clear the error and end-of-file flags, and do the same for the real file.
1016 */
1017 void ZEXPORT gzclearerr (file)
1018  gzFile file;
1019 {
1020  gz_stream *s = (gz_stream*)file;
1021 
1022  if (s == NULL) return;
1023  if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
1024  s->z_eof = 0;
1025  clearerr(s->file);
1026 }
int ZEXPORT gzgetc(gzFile file)
Definition: gzio.c:503
Byte * inbuf
Definition: gzio.c:61
int c
Definition: autoplay.py:16
#define HEAD_CRC
Definition: gzio.c:50
int ZEXPORT deflateParams(z_streamp strm, int level, int strategy)
Definition: deflate.c:416
Byte FAR * voidpf
Definition: zconf.h:283
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:1335
#define ORIG_NAME
Definition: gzio.c:52
char *ZEXPORT gzgets(gzFile file, char *buf, int len)
Definition: gzio.c:540
int ZEXPORT inflateReset(z_streamp strm)
Definition: inflate.c:103
Bytef * next_in
Definition: zlib.h:83
z_off_t start
Definition: gzio.c:68
#define SEEK_CUR
Definition: zconf.h:297
unsigned char Byte
Definition: zconf.h:261
void zmemcpy(Bytef *dest, const Bytef *source, uInt len)
Definition: zutil.c:149
* x
Definition: IceUtils.h:98
#define Z_NO_FLUSH
Definition: zlib.h:162
#define Z_PRINTF_BUFSIZE
Definition: gzio.c:30
png_voidp ptr
Definition: png.h:2063
#define z_off_t
Definition: zconf.h:301
uInt avail_in
Definition: zlib.h:84
#define Z_ERRNO
Definition: zlib.h:173
char * msg
Definition: gzio.c:64
png_uint_32 size
Definition: png.h:1521
#define SEEK_END
Definition: zconf.h:298
char * malloc()
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzio.c:219
#define TRYFREE(p)
Definition: gzio.c:44
voidp malloc OF((uInt size))
png_infop png_charpp name
Definition: png.h:2382
local uLong getLong(gz_stream *s)
Definition: gzio.c:935
struct gz_stream gz_stream
char * msg
Definition: zlib.h:91
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzio.c:394
unsigned long uLong
Definition: zconf.h:264
int ZEXPORT gzsetparams(gzFile file, int level, int strategy)
Definition: gzio.c:234
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzio.c:559
int z_err
Definition: gzio.c:58
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:859
#define Z_FILTERED
Definition: zlib.h:189
int ZEXPORT gzungetc(int c, gzFile file)
Definition: gzio.c:515
#define Z_STREAM_ERROR
Definition: zlib.h:174
static int const gz_magic[2]
Definition: gzio.c:46
local gzFile gz_open(char *path, const char *mode, int fd) const
Definition: gzio.c:93
Byte FAR Bytef
Definition: zconf.h:270
long b
Definition: jpegint.h:371
voidpf opaque
Definition: zlib.h:96
int ZEXPORT gzclose(gzFile file)
Definition: gzio.c:953
voidp gzFile
Definition: zlib.h:1066
free_func zfree
Definition: zlib.h:95
png_uint_32 int flags
Definition: png.h:1656
#define ERR_MSG(err)
Definition: zutil.h:56
int transparent
Definition: gzio.c:66
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzio.c:208
#define inflateInit2(strm, windowBits)
Definition: zlib.h:1338
#define DEF_MEM_LEVEL
Definition: zutil.h:70
#define Z_FINISH
Definition: zlib.h:166
#define zstrerror(errnum)
Definition: gzio.c:977
#define ALLOC(size)
Definition: gzio.c:43
int z_eof
Definition: gzio.c:59
#define COMMENT
Definition: gzio.c:53
int ZEXPORT gzflush(gzFile file, int flush)
Definition: gzio.c:746
#define RESERVED
Definition: gzio.c:54
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, unsigned len)
Definition: crc32.c:219
#define Z_BUFSIZE
Definition: gzio.c:26
char mode
Definition: gzio.c:67
#define SEEK_SET
Definition: jmemansi.c:26
#define Z_DEFLATED
Definition: zlib.h:202
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzio.c:987
#define Z_DATA_ERROR
Definition: zlib.h:175
local void check_header(gz_stream *s)
Definition: gzio.c:288
z_off_t out
Definition: gzio.c:70
typedef void(PNGAPI *png_error_ptr) PNGARG((png_structp
local int get_byte(gz_stream *s)
Definition: gzio.c:261
#define Z_STREAM_END
Definition: zlib.h:171
int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20)
Definition: gzio.c:637
z_stream stream
Definition: gzio.c:57
alloc_func zalloc
Definition: zlib.h:94
int free()
Bytef * next_out
Definition: zlib.h:87
int ZEXPORT gzputs(gzFile file, const char *s)
Definition: gzio.c:693
#define Z_MEM_ERROR
Definition: zlib.h:176
FILE * file
Definition: gzio.c:60
local int destroy(gz_stream *s)
Definition: gzio.c:355
png_bytep buf
Definition: png.h:2729
int ZEXPORT gzrewind(gzFile file)
Definition: gzio.c:857
Byte * voidp
Definition: zconf.h:284
path
png_size_t start
Definition: png.h:1496
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.c:552
Definition: gzio.c:56
int dummy
Definition: gzio.c:19
int ZEXPORT gzeof(gzFile file)
Definition: gzio.c:891
#define Z_HUFFMAN_ONLY
Definition: zlib.h:190
int ZEXPORT gzdirect(gzFile file)
Definition: gzio.c:908
typedef int
Definition: png.h:1113
z_off_t ZEXPORT gztell(gzFile file)
Definition: gzio.c:881
uLong crc
Definition: gzio.c:63
std::string sprintf(char const *__restrict fmt,...)
void ZEXPORT gzclearerr(gzFile file)
Definition: gzio.c:1017
#define Z_BUF_ERROR
Definition: zlib.h:177
int back
Definition: gzio.c:71
#define F_OPEN(name, mode)
Definition: zutil.h:173
local void putLong(FILE *file, uLong x)
Definition: gzio.c:920
uInt avail_out
Definition: zlib.h:88
#define Z_OK
Definition: zlib.h:170
#define local
Definition: crc32.c:31
int last
Definition: gzio.c:72
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: inflate.c:554
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:193
#define Z_NULL
Definition: zlib.h:205
#define EXTRA_FIELD
Definition: gzio.c:51
z_off_t in
Definition: gzio.c:69
Byte const * voidpc
Definition: zconf.h:282
Byte * outbuf
Definition: gzio.c:62
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence)
Definition: gzio.c:767
char * path
Definition: gzio.c:65
local int do_flush(gzFile file, int flush)
Definition: gzio.c:705
#define MAX_WBITS
Definition: zconf.h:148
#define ZEXPORT
Definition: zconf.h:250
void zmemzero(Bytef *dest, uInt len)
Definition: zutil.c:173
#define ZEXPORTVA
Definition: zconf.h:253
int ZEXPORT inflateEnd(z_streamp strm)
Definition: inflate.c:1155
int ZEXPORT gzputc(gzFile file, int c)
Definition: gzio.c:678
#define OS_CODE
Definition: zutil.h:169
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:186
unsigned int uInt
Definition: zconf.h:263
#define Z_RLE
Definition: zlib.h:191


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Sep 8 2022 02:24:03