summaryrefslogtreecommitdiff
path: root/gzio.c
diff options
context:
space:
mode:
Diffstat (limited to 'gzio.c')
-rw-r--r--gzio.c90
1 files changed, 70 insertions, 20 deletions
diff --git a/gzio.c b/gzio.c
index 1f561ac..14fc33c 100644
--- a/gzio.c
+++ b/gzio.c
@@ -11,7 +11,9 @@
11 11
12#include "zutil.h" 12#include "zutil.h"
13 13
14#ifndef NO_DUMMY_DECL
14struct internal_state {int dummy;}; /* for buggy compilers */ 15struct internal_state {int dummy;}; /* for buggy compilers */
16#endif
15 17
16#ifndef Z_BUFSIZE 18#ifndef Z_BUFSIZE
17# ifdef MAXSEG_64K 19# ifdef MAXSEG_64K
@@ -55,6 +57,8 @@ typedef struct gz_stream {
55 int transparent; /* 1 if input file is not a .gz file */ 57 int transparent; /* 1 if input file is not a .gz file */
56 char mode; /* 'w' or 'r' */ 58 char mode; /* 'w' or 'r' */
57 long startpos; /* start of compressed data in file (header skipped) */ 59 long startpos; /* start of compressed data in file (header skipped) */
60 int back; /* one character push-back */
61 int last; /* true if push-back is last character */
58} gz_stream; 62} gz_stream;
59 63
60 64
@@ -102,6 +106,7 @@ local gzFile gz_open (path, mode, fd)
102 s->file = NULL; 106 s->file = NULL;
103 s->z_err = Z_OK; 107 s->z_err = Z_OK;
104 s->z_eof = 0; 108 s->z_eof = 0;
109 s->back = EOF;
105 s->crc = crc32(0L, Z_NULL, 0); 110 s->crc = crc32(0L, Z_NULL, 0);
106 s->msg = NULL; 111 s->msg = NULL;
107 s->transparent = 0; 112 s->transparent = 0;
@@ -391,6 +396,18 @@ int ZEXPORT gzread (file, buf, len)
391 s->stream.next_out = (Bytef*)buf; 396 s->stream.next_out = (Bytef*)buf;
392 s->stream.avail_out = len; 397 s->stream.avail_out = len;
393 398
399 if (s->stream.avail_out && s->back != EOF) {
400 *next_out++ = s->back;
401 s->stream.next_out++;
402 s->stream.avail_out--;
403 s->back = EOF;
404 s->stream.total_out++;
405 if (s->last) {
406 s->z_err = Z_STREAM_END;
407 return 1;
408 }
409 }
410
394 while (s->stream.avail_out != 0) { 411 while (s->stream.avail_out != 0) {
395 412
396 if (s->transparent) { 413 if (s->transparent) {
@@ -477,6 +494,24 @@ int ZEXPORT gzgetc(file)
477 494
478 495
479/* =========================================================================== 496/* ===========================================================================
497 Push one byte back onto the stream.
498*/
499int ZEXPORT gzungetc(c, file)
500 int c;
501 gzFile file;
502{
503 gz_stream *s = (gz_stream*)file;
504
505 if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
506 s->back = c;
507 s->stream.total_out--;
508 s->last = (s->z_err == Z_STREAM_END);
509 if (s->z_eof) s->z_eof = 0;
510 return c;
511}
512
513
514/* ===========================================================================
480 Reads bytes from the compressed file until len-1 characters are 515 Reads bytes from the compressed file until len-1 characters are
481 read, or a newline character is read and transferred to buf, or an 516 read, or a newline character is read and transferred to buf, or an
482 end-of-file condition is encountered. The string is then terminated 517 end-of-file condition is encountered. The string is then terminated
@@ -535,6 +570,7 @@ int ZEXPORT gzwrite (file, buf, len)
535 return (int)(len - s->stream.avail_in); 570 return (int)(len - s->stream.avail_in);
536} 571}
537 572
573
538/* =========================================================================== 574/* ===========================================================================
539 Converts, formats, and writes the args to the compressed file under 575 Converts, formats, and writes the args to the compressed file under
540 control of the format string, as in fprintf. gzprintf returns the number of 576 control of the format string, as in fprintf. gzprintf returns the number of
@@ -549,34 +585,30 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
549 va_list va; 585 va_list va;
550 int len; 586 int len;
551 587
588 buf[sizeof(buf) - 1] = 0;
552 va_start(va, format); 589 va_start(va, format);
553#ifdef NO_vsnprintf 590#ifdef NO_vsnprintf
554# ifdef HAS_vsprintf_void 591# ifdef HAS_vsprintf_void
555 (void)vsprintf(buf, format, va); 592 (void)vsprintf(buf, format, va);
556 va_end(va); 593 va_end(va);
557 len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ 594 for (len = 0; len < sizeof(buf); len++)
558 if (len <= 0) return 0; 595 if (buf[len] == 0) break;
559# else 596# else
560 len = vsprintf(buf, format, va); 597 len = vsprintf(buf, format, va);
561 va_end(va); 598 va_end(va);
562 if (len <= 0 || len >= sizeof(buf))
563 return 0;
564# endif 599# endif
565#else 600#else
566# ifdef HAS_vsnprintf_void 601# ifdef HAS_vsnprintf_void
567 (void)vsnprintf(buf, sizeof(buf), format, va); 602 (void)vsnprintf(buf, sizeof(buf), format, va);
568 va_end(va); 603 va_end(va);
569 len = strlen(buf); 604 len = strlen(buf);
570 if (len <= 0)
571 return 0;
572# else 605# else
573 len = vsnprintf(buf, sizeof(buf), format, va); 606 len = vsnprintf(buf, sizeof(buf), format, va);
574 va_end(va); 607 va_end(va);
575 if (len <= 0 || len >= sizeof(buf))
576 return 0;
577# endif 608# endif
578#endif 609#endif
579 610 if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
611 return 0;
580 return gzwrite(file, buf, (unsigned)len); 612 return gzwrite(file, buf, (unsigned)len);
581} 613}
582#else /* not ANSI C */ 614#else /* not ANSI C */
@@ -591,33 +623,29 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
591 char buf[Z_PRINTF_BUFSIZE]; 623 char buf[Z_PRINTF_BUFSIZE];
592 int len; 624 int len;
593 625
626 buf[sizeof(buf) - 1] = 0;
594#ifdef NO_snprintf 627#ifdef NO_snprintf
595# ifdef HAS_sprintf_void 628# ifdef HAS_sprintf_void
596 sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 629 sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
597 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 630 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
598 len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ 631 for (len = 0; len < sizeof(buf); len++)
599 if (len <= 0) return 0; 632 if (buf[len] == 0) break;
600# else 633# else
601 len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 634 len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
602 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 635 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
603 if (len <= 0 || len >= sizeof(buf))
604 return 0;
605# endif 636# endif
606#else 637#else
607# ifdef HAS_snprintf_void 638# ifdef HAS_snprintf_void
608 snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 639 snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
609 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 640 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
610 len = strlen(buf); 641 len = strlen(buf);
611 if (len <= 0)
612 return 0;
613# else 642# else
614 len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 643 len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
615 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 644 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
616 if (len <= 0 || len >= sizeof(buf))
617 return 0;
618# endif 645# endif
619#endif 646#endif
620 647 if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
648 return 0;
621 return gzwrite(file, buf, len); 649 return gzwrite(file, buf, len);
622} 650}
623#endif 651#endif
@@ -762,6 +790,7 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
762 790
763 if (s->transparent) { 791 if (s->transparent) {
764 /* map to fseek */ 792 /* map to fseek */
793 s->back = EOF;
765 s->stream.avail_in = 0; 794 s->stream.avail_in = 0;
766 s->stream.next_in = s->inbuf; 795 s->stream.next_in = s->inbuf;
767 if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; 796 if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
@@ -782,6 +811,12 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
782 s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 811 s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
783 if (s->outbuf == Z_NULL) return -1L; 812 if (s->outbuf == Z_NULL) return -1L;
784 } 813 }
814 if (offset && s->back != EOF) {
815 s->back == EOF;
816 s->stream.total_out++;
817 offset--;
818 if (s->last) s->z_err = Z_STREAM_END;
819 }
785 while (offset > 0) { 820 while (offset > 0) {
786 int size = Z_BUFSIZE; 821 int size = Z_BUFSIZE;
787 if (offset < Z_BUFSIZE) size = (int)offset; 822 if (offset < Z_BUFSIZE) size = (int)offset;
@@ -805,12 +840,13 @@ int ZEXPORT gzrewind (file)
805 840
806 s->z_err = Z_OK; 841 s->z_err = Z_OK;
807 s->z_eof = 0; 842 s->z_eof = 0;
843 s->back = EOF;
808 s->stream.avail_in = 0; 844 s->stream.avail_in = 0;
809 s->stream.next_in = s->inbuf; 845 s->stream.next_in = s->inbuf;
810 s->crc = crc32(0L, Z_NULL, 0); 846 s->crc = crc32(0L, Z_NULL, 0);
811 847
812 if (s->startpos == 0) { /* not a compressed file */ 848 if (s->startpos == 0) { /* not a compressed file */
813 rewind(s->file); 849 fseek(s->file, 0L, SEEK_SET); /* rewind() is not always available */
814 return 0; 850 return 0;
815 } 851 }
816 852
@@ -906,7 +942,7 @@ int ZEXPORT gzclose (file)
906 errnum is set to Z_ERRNO and the application may consult errno 942 errnum is set to Z_ERRNO and the application may consult errno
907 to get the exact error code. 943 to get the exact error code.
908*/ 944*/
909const char* ZEXPORT gzerror (file, errnum) 945const char * ZEXPORT gzerror (file, errnum)
910 gzFile file; 946 gzFile file;
911 int *errnum; 947 int *errnum;
912{ 948{
@@ -932,3 +968,17 @@ const char* ZEXPORT gzerror (file, errnum)
932 strcat(s->msg, m); 968 strcat(s->msg, m);
933 return (const char*)s->msg; 969 return (const char*)s->msg;
934} 970}
971
972/* ===========================================================================
973 Clear the error and end-of-file flags, and do the same for the real file.
974*/
975void ZEXPORT gzclearerr (file)
976 gzFile file;
977{
978 gz_stream *s = (gz_stream*)file;
979
980 if (s == NULL) return;
981 if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
982 s->z_eof = 0;
983 clearerr(s->file);
984}