20 # define NO_GZCOMPRESS
29 # define Z_BUFSIZE 4096
31 # define Z_BUFSIZE 16384
34 #ifndef Z_PRINTF_BUFSIZE
35 # define Z_PRINTF_BUFSIZE 4096
39 # pragma map (fdopen , "\174\174FDOPEN")
40 FILE *fdopen(
int,
const char *);
44 extern voidp malloc OF((uInt
size));
45 extern void free OF((voidpf ptr));
48 #define ALLOC(size) malloc(size)
49 #define TRYFREE(p) {if (p) free(p);}
51 static int const gz_magic[2] = {0x1f, 0x8b};
54 #define ASCII_FLAG 0x01
56 #define EXTRA_FIELD 0x04
57 #define ORIG_NAME 0x08
81 local gzFile gz_open OF((
const char *path,
const char *
mode,
int fd));
82 local
int do_flush OF((gzFile
file,
int flush));
84 local
void check_header OF((
gz_stream *s));
86 local
void putLong OF((FILE *
file, uLong x));
98 local gzFile gz_open (path,
mode, fd)
104 int level = Z_DEFAULT_COMPRESSION;
105 int strategy = Z_DEFAULT_STRATEGY;
106 char *p = (
char*)mode;
111 if (!path || !mode)
return Z_NULL;
114 if (!s)
return Z_NULL;
116 s->stream.zalloc = (alloc_func)0;
117 s->stream.zfree = (free_func)0;
118 s->stream.opaque = (voidpf)0;
119 s->stream.next_in = s->inbuf = Z_NULL;
120 s->stream.next_out = s->outbuf = Z_NULL;
121 s->stream.avail_in = s->stream.avail_out = 0;
128 s->crc = crc32(0L, Z_NULL, 0);
132 s->path = (
char*)ALLOC(strlen(path)+1);
133 if (s->path == NULL) {
134 return destroy(s), (gzFile)Z_NULL;
136 strcpy(s->path, path);
140 if (*p ==
'r') s->mode =
'r';
141 if (*p ==
'w' || *p ==
'a') s->mode =
'w';
142 if (*p >=
'0' && *p <=
'9') {
144 }
else if (*p ==
'f') {
145 strategy = Z_FILTERED;
146 }
else if (*p ==
'h') {
147 strategy = Z_HUFFMAN_ONLY;
148 }
else if (*p ==
'R') {
153 }
while (*p++ && m != fmode +
sizeof(fmode));
154 if (s->mode ==
'\0')
return destroy(s), (gzFile)Z_NULL;
156 if (s->mode ==
'w') {
158 err = Z_STREAM_ERROR;
160 err = deflateInit2(&(s->stream), level,
161 Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
164 s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
166 if (err != Z_OK || s->outbuf == Z_NULL) {
167 return destroy(s), (gzFile)Z_NULL;
170 s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
172 err = inflateInit2(&(s->stream), -MAX_WBITS);
179 if (err != Z_OK || s->inbuf == Z_NULL) {
180 return destroy(s), (gzFile)Z_NULL;
183 s->stream.avail_out = Z_BUFSIZE;
186 s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
188 if (s->file == NULL) {
189 return destroy(s), (gzFile)Z_NULL;
191 if (s->mode ==
'w') {
194 fprintf(s->file,
"%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
195 Z_DEFLATED, 0 , 0,0,0,0 , 0 , OS_CODE);
204 s->start = ftell(s->file) - s->stream.avail_in;
213 gzFile ZEXPORT gzopen (path, mode)
217 return gz_open (path, mode, -1);
224 gzFile ZEXPORT gzdopen (fd, mode)
230 if (fd < 0)
return (gzFile)Z_NULL;
231 sprintf(name,
"<fd:%d>", fd);
233 return gz_open (name, mode, fd);
239 int ZEXPORT gzsetparams (
file, level, strategy)
246 if (s == NULL || s->mode !=
'w')
return Z_STREAM_ERROR;
249 if (s->stream.avail_out == 0) {
251 s->stream.next_out = s->outbuf;
252 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
255 s->stream.avail_out = Z_BUFSIZE;
258 return deflateParams (&(s->stream), level, strategy);
266 local
int get_byte(s)
269 if (s->z_eof)
return EOF;
270 if (s->stream.avail_in == 0) {
272 s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
273 if (s->stream.avail_in == 0) {
275 if (ferror(s->file)) s->z_err = Z_ERRNO;
278 s->stream.next_in = s->inbuf;
280 s->stream.avail_in--;
281 return *(s->stream.next_in)++;
293 local
void check_header(s)
304 len = s->stream.avail_in;
306 if (len) s->inbuf[0] = s->stream.next_in[0];
308 len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
309 if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
310 s->stream.avail_in += len;
311 s->stream.next_in = s->inbuf;
312 if (s->stream.avail_in < 2) {
313 s->transparent = s->stream.avail_in;
319 if (s->stream.next_in[0] != gz_magic[0] ||
320 s->stream.next_in[1] != gz_magic[1]) {
324 s->stream.avail_in -= 2;
325 s->stream.next_in += 2;
328 method = get_byte(s);
330 if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
331 s->z_err = Z_DATA_ERROR;
336 for (len = 0; len < 6; len++) (
void)get_byte(s);
338 if ((flags & EXTRA_FIELD) != 0) {
339 len = (uInt)get_byte(s);
340 len += ((uInt)get_byte(s))<<8;
342 while (len-- != 0 && get_byte(s) != EOF) ;
344 if ((flags & ORIG_NAME) != 0) {
345 while ((c = get_byte(s)) != 0 && c != EOF) ;
347 if ((flags & COMMENT) != 0) {
348 while ((c = get_byte(s)) != 0 && c != EOF) ;
350 if ((flags & HEAD_CRC) != 0) {
351 for (len = 0; len < 2; len++) (
void)get_byte(s);
353 s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
360 local
int destroy (s)
365 if (!s)
return Z_STREAM_ERROR;
369 if (s->stream.state != NULL) {
370 if (s->mode ==
'w') {
372 err = Z_STREAM_ERROR;
374 err = deflateEnd(&(s->stream));
376 }
else if (s->mode ==
'r') {
377 err = inflateEnd(&(s->stream));
380 if (s->file != NULL && fclose(s->file)) {
386 if (s->z_err < 0) err = s->z_err;
399 int ZEXPORT gzread (file,
buf, len)
405 Bytef *start = (Bytef*)buf;
408 if (s == NULL || s->mode !=
'r')
return Z_STREAM_ERROR;
410 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
return -1;
411 if (s->z_err == Z_STREAM_END)
return 0;
413 next_out = (Byte*)buf;
414 s->stream.next_out = (Bytef*)buf;
415 s->stream.avail_out = len;
417 if (s->stream.avail_out && s->back != EOF) {
418 *next_out++ = s->back;
419 s->stream.next_out++;
420 s->stream.avail_out--;
425 s->z_err = Z_STREAM_END;
430 while (s->stream.avail_out != 0) {
432 if (s->transparent) {
434 uInt
n = s->stream.avail_in;
435 if (n > s->stream.avail_out) n = s->stream.avail_out;
437 zmemcpy(s->stream.next_out, s->stream.next_in, n);
439 s->stream.next_out = next_out;
440 s->stream.next_in +=
n;
441 s->stream.avail_out -=
n;
442 s->stream.avail_in -=
n;
444 if (s->stream.avail_out > 0) {
445 s->stream.avail_out -=
446 (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
448 len -= s->stream.avail_out;
451 if (len == 0) s->z_eof = 1;
454 if (s->stream.avail_in == 0 && !s->z_eof) {
457 s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
458 if (s->stream.avail_in == 0) {
460 if (ferror(s->file)) {
465 s->stream.next_in = s->inbuf;
467 s->in += s->stream.avail_in;
468 s->out += s->stream.avail_out;
469 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
470 s->in -= s->stream.avail_in;
471 s->out -= s->stream.avail_out;
473 if (s->z_err == Z_STREAM_END) {
475 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
476 start = s->stream.next_out;
478 if (getLong(s) != s->crc) {
479 s->z_err = Z_DATA_ERROR;
487 if (s->z_err == Z_OK) {
488 inflateReset(&(s->stream));
489 s->crc = crc32(0L, Z_NULL, 0);
493 if (s->z_err != Z_OK || s->z_eof)
break;
495 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
497 if (len == s->stream.avail_out &&
498 (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
500 return (
int)(len - s->stream.avail_out);
508 int ZEXPORT gzgetc(file)
513 return gzread(file, &c, 1) == 1 ? c : -1;
520 int ZEXPORT gzungetc(c, file)
526 if (s == NULL || s->mode !=
'r' || c == EOF || s->back != EOF)
return EOF;
529 s->last = (s->z_err == Z_STREAM_END);
530 if (s->last) s->z_err = Z_OK;
545 char * ZEXPORT gzgets(file, buf, len)
551 if (buf == Z_NULL || len <= 0)
return Z_NULL;
553 while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ !=
'\n') ;
555 return b == buf && len > 0 ? Z_NULL : b;
559 #ifndef NO_GZCOMPRESS
564 int ZEXPORT gzwrite (file, buf, len)
571 if (s == NULL || s->mode !=
'w')
return Z_STREAM_ERROR;
573 s->stream.next_in = (Bytef*)buf;
574 s->stream.avail_in = len;
576 while (s->stream.avail_in != 0) {
578 if (s->stream.avail_out == 0) {
580 s->stream.next_out = s->outbuf;
581 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
585 s->stream.avail_out = Z_BUFSIZE;
587 s->in += s->stream.avail_in;
588 s->out += s->stream.avail_out;
589 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
590 s->in -= s->stream.avail_in;
591 s->out -= s->stream.avail_out;
592 if (s->z_err != Z_OK)
break;
594 s->crc = crc32(s->crc, (
const Bytef *)buf, len);
596 return (
int)(len - s->stream.avail_in);
608 int ZEXPORTVA gzprintf (gzFile file,
const char *format, ...)
610 char buf[Z_PRINTF_BUFSIZE];
614 buf[
sizeof(
buf) - 1] = 0;
615 va_start(va, format);
617 # ifdef HAS_vsprintf_void
618 (void)vsprintf(buf, format, va);
620 for (len = 0; len <
sizeof(
buf); len++)
621 if (buf[len] == 0)
break;
623 len = vsprintf(buf, format, va);
627 # ifdef HAS_vsnprintf_void
628 (void)vsnprintf(buf,
sizeof(buf), format, va);
632 len = vsnprintf(buf,
sizeof(buf), format, va);
636 if (len <= 0 || len >= (
int)
sizeof(buf) || buf[
sizeof(buf) - 1] != 0)
638 return gzwrite(file, buf, (
unsigned)len);
642 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
643 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
646 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
647 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
649 char buf[Z_PRINTF_BUFSIZE];
652 buf[
sizeof(
buf) - 1] = 0;
654 # ifdef HAS_sprintf_void
655 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 for (len = 0; len <
sizeof(
buf); len++)
658 if (buf[len] == 0)
break;
660 len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
661 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
664 # ifdef HAS_snprintf_void
665 snprintf(buf,
sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
666 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
669 len = snprintf(buf,
sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
670 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
673 if (len <= 0 || len >=
sizeof(buf) || buf[
sizeof(buf) - 1] != 0)
675 return gzwrite(file, buf, len);
683 int ZEXPORT gzputc(file, c)
687 unsigned char cc = (
unsigned char) c;
689 return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
698 int ZEXPORT gzputs(file, s)
702 return gzwrite(file, (
char*)s, (
unsigned)strlen(s));
710 local
int do_flush (file, flush)
718 if (s == NULL || s->mode !=
'w')
return Z_STREAM_ERROR;
720 s->stream.avail_in = 0;
723 len = Z_BUFSIZE - s->stream.avail_out;
726 if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
730 s->stream.next_out = s->outbuf;
731 s->stream.avail_out = Z_BUFSIZE;
734 s->out += s->stream.avail_out;
735 s->z_err = deflate(&(s->stream), flush);
736 s->out -= s->stream.avail_out;
739 if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
744 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
746 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
break;
748 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
751 int ZEXPORT gzflush (file, flush)
756 int err = do_flush (file, flush);
760 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
772 z_off_t ZEXPORT gzseek (file,
offset, whence)
779 if (s == NULL || whence == SEEK_END ||
780 s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
784 if (s->mode ==
'w') {
788 if (whence == SEEK_SET) {
791 if (offset < 0)
return -1L;
794 if (s->inbuf == Z_NULL) {
795 s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
796 if (s->inbuf == Z_NULL)
return -1L;
797 zmemzero(s->inbuf, Z_BUFSIZE);
800 uInt
size = Z_BUFSIZE;
801 if (offset < Z_BUFSIZE) size = (uInt)offset;
803 size = gzwrite(file, s->inbuf, size);
804 if (size == 0)
return -1L;
814 if (whence == SEEK_CUR) {
817 if (offset < 0)
return -1L;
819 if (s->transparent) {
822 s->stream.avail_in = 0;
823 s->stream.next_in = s->inbuf;
824 if (fseek(s->file, offset, SEEK_SET) < 0)
return -1L;
831 if (offset >= s->out) {
833 }
else if (gzrewind(file) < 0) {
838 if (offset != 0 && s->outbuf == Z_NULL) {
839 s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
840 if (s->outbuf == Z_NULL)
return -1L;
842 if (offset && s->back != EOF) {
846 if (s->last) s->z_err = Z_STREAM_END;
849 int size = Z_BUFSIZE;
850 if (offset < Z_BUFSIZE) size = (int)offset;
852 size = gzread(file, s->outbuf, (uInt)size);
853 if (size <= 0)
return -1L;
862 int ZEXPORT gzrewind (file)
867 if (s == NULL || s->mode !=
'r')
return -1;
872 s->stream.avail_in = 0;
873 s->stream.next_in = s->inbuf;
874 s->crc = crc32(0L, Z_NULL, 0);
875 if (!s->transparent) (void)inflateReset(&s->stream);
878 return fseek(s->file, s->start, SEEK_SET);
886 z_off_t ZEXPORT gztell (file)
889 return gzseek(file, 0L, SEEK_CUR);
896 int ZEXPORT gzeof (file)
905 if (s == NULL || s->mode !=
'r')
return 0;
906 if (s->z_eof)
return 1;
907 return s->z_err == Z_STREAM_END;
913 int ZEXPORT gzdirect (file)
918 if (s == NULL || s->mode !=
'r')
return 0;
919 return s->transparent;
925 local
void putLong (file, x)
930 for (n = 0; n < 4; n++) {
931 fputc((
int)(x & 0xff), file);
940 local uLong getLong (s)
943 uLong x = (uLong)get_byte(s);
946 x += ((uLong)get_byte(s))<<8;
947 x += ((uLong)get_byte(s))<<16;
949 if (c == EOF) s->z_err = Z_DATA_ERROR;
958 int ZEXPORT gzclose (file)
963 if (s == NULL)
return Z_STREAM_ERROR;
965 if (s->mode ==
'w') {
967 return Z_STREAM_ERROR;
969 if (do_flush (file, Z_FINISH) != Z_OK)
972 putLong (s->file, s->crc);
973 putLong (s->file, (uLong)(s->in & 0xffffffff));
980 # define zstrerror(errnum) strerror(errnum)
982 # define zstrerror(errnum) ""
992 const char * ZEXPORT gzerror (file, errnum)
1000 *errnum = Z_STREAM_ERROR;
1001 return (
const char*)ERR_MSG(Z_STREAM_ERROR);
1004 if (*errnum == Z_OK)
return (
const char*)
"";
1006 m = (
char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
1008 if (m == NULL || *m ==
'\0') m = (
char*)ERR_MSG(s->z_err);
1011 s->msg = (
char*)ALLOC(strlen(s->path) + strlen(m) + 3);
1012 if (s->msg == Z_NULL)
return (
const char*)ERR_MSG(Z_MEM_ERROR);
1013 strcpy(s->msg, s->path);
1014 strcat(s->msg,
": ");
1016 return (
const char*)s->msg;
1022 void ZEXPORT gzclearerr (file)
1027 if (s == NULL)
return;
1028 if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;