summaryrefslogtreecommitdiff
path: root/gzio.c
diff options
context:
space:
mode:
Diffstat (limited to 'gzio.c')
-rw-r--r--gzio.c121
1 files changed, 106 insertions, 15 deletions
diff --git a/gzio.c b/gzio.c
index a8130ef..df34620 100644
--- a/gzio.c
+++ b/gzio.c
@@ -7,6 +7,15 @@
7 7
8/* @(#) $Id$ */ 8/* @(#) $Id$ */
9 9
10#ifdef _LARGEFILE64_SOURCE
11# ifndef _LARGEFILE_SOURCE
12# define _LARGEFILE_SOURCE
13# endif
14# ifdef _FILE_OFFSET_BITS
15# undef _FILE_OFFSET_BITS
16# endif
17#endif
18
10#include "zutil.h" 19#include "zutil.h"
11#include <stdio.h> 20#include <stdio.h>
12 21
@@ -39,6 +48,14 @@ extern voidp malloc OF((uInt size));
39extern void free OF((voidpf ptr)); 48extern void free OF((voidpf ptr));
40#endif 49#endif
41 50
51#ifdef NO_FSEEKO
52# define FSEEK fseek
53# define FTELL ftell
54#else
55# define FSEEK fseeko
56# define FTELL ftello
57#endif
58
42#define ALLOC(size) malloc(size) 59#define ALLOC(size) malloc(size)
43#define TRYFREE(p) {if (p) free(p);} 60#define TRYFREE(p) {if (p) free(p);}
44 61
@@ -64,15 +81,27 @@ typedef struct gz_stream {
64 char *path; /* path name for debugging only */ 81 char *path; /* path name for debugging only */
65 int transparent; /* 1 if input file is not a .gz file */ 82 int transparent; /* 1 if input file is not a .gz file */
66 char mode; /* 'w' or 'r' */ 83 char mode; /* 'w' or 'r' */
84#ifdef _LARGEFILE64_SOURCE
85 off64_t start; /* start of compressed data in file (header skipped) */
86 off64_t in; /* bytes into deflate or inflate */
87 off64_t out; /* bytes out of deflate or inflate */
88#else
67 z_off_t start; /* start of compressed data in file (header skipped) */ 89 z_off_t start; /* start of compressed data in file (header skipped) */
68 z_off_t in; /* bytes into deflate or inflate */ 90 z_off_t in; /* bytes into deflate or inflate */
69 z_off_t out; /* bytes out of deflate or inflate */ 91 z_off_t out; /* bytes out of deflate or inflate */
92#endif
70 int back; /* one character push-back */ 93 int back; /* one character push-back */
71 int last; /* true if push-back is last character */ 94 int last; /* true if push-back is last character */
72} gz_stream; 95} gz_stream;
73 96
74 97
75local gzFile gz_open OF((const char *path, const char *mode, int fd)); 98local gzFile gz_open OF((const char *path, const char *mode, int fd,
99 int use64));
100#ifdef _LARGEFILE64_SOURCE
101local off64_t gz_seek OF((gzFile file, off64_t offset, int whence, int use64));
102#else
103local z_off_t gz_seek OF((gzFile file, z_off_t offset, int whence, int use64));
104#endif
76local int do_flush OF((gzFile file, int flush)); 105local int do_flush OF((gzFile file, int flush));
77local int get_byte OF((gz_stream *s)); 106local int get_byte OF((gz_stream *s));
78local void check_header OF((gz_stream *s)); 107local void check_header OF((gz_stream *s));
@@ -89,10 +118,11 @@ local uLong getLong OF((gz_stream *s));
89 can be checked to distinguish the two cases (if errno is zero, the 118 can be checked to distinguish the two cases (if errno is zero, the
90 zlib error is Z_MEM_ERROR). 119 zlib error is Z_MEM_ERROR).
91*/ 120*/
92local gzFile gz_open (path, mode, fd) 121local gzFile gz_open (path, mode, fd, use64)
93 const char *path; 122 const char *path;
94 const char *mode; 123 const char *mode;
95 int fd; 124 int fd;
125 int use64;
96{ 126{
97 int err; 127 int err;
98 int level = Z_DEFAULT_COMPRESSION; /* compression level */ 128 int level = Z_DEFAULT_COMPRESSION; /* compression level */
@@ -164,12 +194,7 @@ local gzFile gz_open (path, mode, fd)
164 s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); 194 s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
165 195
166 err = inflateInit2(&(s->stream), -MAX_WBITS); 196 err = inflateInit2(&(s->stream), -MAX_WBITS);
167 /* windowBits is passed < 0 to tell that there is no zlib header. 197 /* windowBits is passed < 0 to tell that there is no zlib header */
168 * Note that in this case inflate *requires* an extra "dummy" byte
169 * after the compressed stream in order to complete decompression and
170 * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
171 * present after the compressed stream.
172 */
173 if (err != Z_OK || s->inbuf == Z_NULL) { 198 if (err != Z_OK || s->inbuf == Z_NULL) {
174 return destroy(s), (gzFile)Z_NULL; 199 return destroy(s), (gzFile)Z_NULL;
175 } 200 }
@@ -177,7 +202,8 @@ local gzFile gz_open (path, mode, fd)
177 s->stream.avail_out = Z_BUFSIZE; 202 s->stream.avail_out = Z_BUFSIZE;
178 203
179 errno = 0; 204 errno = 0;
180 s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); 205 s->file = fd < 0 ? (use64 ? F_OPEN64(path, fmode) : F_OPEN(path, fmode)) :
206 (FILE*)fdopen(fd, fmode);
181 207
182 if (s->file == NULL) { 208 if (s->file == NULL) {
183 return destroy(s), (gzFile)Z_NULL; 209 return destroy(s), (gzFile)Z_NULL;
@@ -198,7 +224,7 @@ local gzFile gz_open (path, mode, fd)
198 */ 224 */
199 } else { 225 } else {
200 check_header(s); /* skip the .gz header */ 226 check_header(s); /* skip the .gz header */
201 s->start = ftell(s->file) - s->stream.avail_in; 227 s->start = FTELL(s->file) - s->stream.avail_in;
202 } 228 }
203 229
204 return (gzFile)s; 230 return (gzFile)s;
@@ -211,7 +237,17 @@ gzFile ZEXPORT gzopen (path, mode)
211 const char *path; 237 const char *path;
212 const char *mode; 238 const char *mode;
213{ 239{
214 return gz_open (path, mode, -1); 240 return gz_open (path, mode, -1, 0);
241}
242
243/* ===========================================================================
244 Opens a gzip (.gz) file for reading or writing for 64-bit offsets
245*/
246gzFile ZEXPORT gzopen64 (path, mode)
247 const char *path;
248 const char *mode;
249{
250 return gz_open (path, mode, -1, 1);
215} 251}
216 252
217/* =========================================================================== 253/* ===========================================================================
@@ -227,7 +263,7 @@ gzFile ZEXPORT gzdopen (fd, mode)
227 if (fd < 0) return (gzFile)Z_NULL; 263 if (fd < 0) return (gzFile)Z_NULL;
228 sprintf(name, "<fd:%d>", fd); /* for debugging */ 264 sprintf(name, "<fd:%d>", fd); /* for debugging */
229 265
230 return gz_open (name, mode, fd); 266 return gz_open (name, mode, fd, 0);
231} 267}
232 268
233/* =========================================================================== 269/* ===========================================================================
@@ -767,10 +803,17 @@ int ZEXPORT gzflush (file, flush)
767 SEEK_END is not implemented, returns error. 803 SEEK_END is not implemented, returns error.
768 In this version of the library, gzseek can be extremely slow. 804 In this version of the library, gzseek can be extremely slow.
769*/ 805*/
770z_off_t ZEXPORT gzseek (file, offset, whence) 806#ifdef _LARGEFILE64_SOURCE
807local off64_t gz_seek (file, offset, whence, use64)
808 gzFile file;
809 off64_t offset;
810#else
811local z_off_t gz_seek (file, offset, whence, use64)
771 gzFile file; 812 gzFile file;
772 z_off_t offset; 813 z_off_t offset;
814#endif
773 int whence; 815 int whence;
816 int use64;
774{ 817{
775 gz_stream *s = (gz_stream*)file; 818 gz_stream *s = (gz_stream*)file;
776 819
@@ -819,7 +862,13 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
819 s->back = EOF; 862 s->back = EOF;
820 s->stream.avail_in = 0; 863 s->stream.avail_in = 0;
821 s->stream.next_in = s->inbuf; 864 s->stream.next_in = s->inbuf;
822 if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; 865#ifdef _LARGEFILE64_SOURCE
866 if ((use64 ? fseeko64(s->file, offset, SEEK_SET) :
867 FSEEK(s->file, offset, SEEK_SET)) < 0)
868 return -1L;
869#else
870 if (FSEEK(s->file, offset, SEEK_SET) < 0) return -1L;
871#endif
823 872
824 s->in = s->out = offset; 873 s->in = s->out = offset;
825 return offset; 874 return offset;
@@ -855,6 +904,35 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
855} 904}
856 905
857/* =========================================================================== 906/* ===========================================================================
907 Define external functions gzseek() and gzseek64() using local gz_seek().
908*/
909z_off_t ZEXPORT gzseek (file, offset, whence)
910 gzFile file;
911 z_off_t offset;
912 int whence;
913{
914 return (z_off_t)gz_seek(file, offset, whence, 0);
915}
916
917#ifdef _LARGEFILE64_SOURCE
918off64_t ZEXPORT gzseek64 (file, offset, whence)
919 gzFile file;
920 off64_t offset;
921 int whence;
922{
923 return gz_seek(file, offset, whence, 1);
924}
925#else
926z_off_t ZEXPORT gzseek64 (file, offset, whence)
927 gzFile file;
928 z_off_t offset;
929 int whence;
930{
931 return gz_seek(file, offset, whence, 0);
932}
933#endif
934
935/* ===========================================================================
858 Rewinds input file. 936 Rewinds input file.
859*/ 937*/
860int ZEXPORT gzrewind (file) 938int ZEXPORT gzrewind (file)
@@ -873,7 +951,7 @@ int ZEXPORT gzrewind (file)
873 if (!s->transparent) (void)inflateReset(&s->stream); 951 if (!s->transparent) (void)inflateReset(&s->stream);
874 s->in = 0; 952 s->in = 0;
875 s->out = 0; 953 s->out = 0;
876 return fseek(s->file, s->start, SEEK_SET); 954 return FSEEK(s->file, s->start, SEEK_SET);
877} 955}
878 956
879/* =========================================================================== 957/* ===========================================================================
@@ -888,6 +966,19 @@ z_off_t ZEXPORT gztell (file)
888} 966}
889 967
890/* =========================================================================== 968/* ===========================================================================
969 64-bit version
970*/
971#ifdef _LARGEFILE64_SOURCE
972off64_t ZEXPORT gztell64 (file)
973#else
974z_off_t ZEXPORT gztell64 (file)
975#endif
976 gzFile file;
977{
978 return gzseek64(file, 0L, SEEK_CUR);
979}
980
981/* ===========================================================================
891 Returns 1 when EOF has previously been detected reading the given 982 Returns 1 when EOF has previously been detected reading the given
892 input stream, otherwise zero. 983 input stream, otherwise zero.
893*/ 984*/