1 /* gzio.c -- IO on .gz files
2 * Copyright (C) 1995-2006 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
5 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
10 #ifdef _LARGEFILE64_SOURCE
11 # ifndef _LARGEFILE_SOURCE
12 # define _LARGEFILE_SOURCE
14 # ifdef _FILE_OFFSET_BITS
15 # undef _FILE_OFFSET_BITS
22 #ifdef NO_DEFLATE /* for compatibility with old definition */
23 # define NO_GZCOMPRESS
27 struct internal_state
{int dummy
;}; /* for buggy compilers */
32 # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
34 # define Z_BUFSIZE 16384
37 #ifndef Z_PRINTF_BUFSIZE
38 # define Z_PRINTF_BUFSIZE 4096
42 # pragma map (fdopen , "\174\174FDOPEN")
43 FILE *fdopen(int, const char *);
47 extern voidp malloc
OF((uInt size
));
48 extern void free
OF((voidpf ptr
));
59 #define ALLOC(size) malloc(size)
60 #define TRYFREE(p) {if (p) free(p);}
62 static int const gz_magic
[2] = {0x1f, 0x8b}; /* gzip magic header */
65 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
66 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
67 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
68 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
69 #define COMMENT 0x10 /* bit 4 set: file comment present */
70 #define RESERVED 0xE0 /* bits 5..7: reserved */
72 typedef struct gz_stream
{
74 int z_err
; /* error code for last stream operation */
75 int z_eof
; /* set if end of input file */
76 FILE *file
; /* .gz file */
77 Byte
*inbuf
; /* input buffer */
78 Byte
*outbuf
; /* output buffer */
79 uLong crc
; /* crc32 of uncompressed data */
80 char *msg
; /* error message */
81 char *path
; /* path name for debugging only */
82 int transparent
; /* 1 if input file is not a .gz file */
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 */
89 z_off_t start
; /* start of compressed data in file (header skipped) */
90 z_off_t in
; /* bytes into deflate or inflate */
91 z_off_t out
; /* bytes out of deflate or inflate */
93 int back
; /* one character push-back */
94 int last
; /* true if push-back is last character */
98 local gzFile gz_open
OF((const char *path
, const char *mode
, int fd
,
100 #ifdef _LARGEFILE64_SOURCE
101 local off64_t gz_seek
OF((gzFile file
, off64_t offset
, int whence
, int use64
));
103 local z_off_t gz_seek
OF((gzFile file
, z_off_t offset
, int whence
, int use64
));
105 local
int do_flush
OF((gzFile file
, int flush
));
106 local
int get_byte
OF((gz_stream
*s
));
107 local
void check_header
OF((gz_stream
*s
));
108 local
int destroy
OF((gz_stream
*s
));
109 local
void putLong
OF((FILE *file
, uLong x
));
110 local uLong getLong
OF((gz_stream
*s
));
112 /* ===========================================================================
113 Opens a gzip (.gz) file for reading or writing. The mode parameter
114 is as in fopen ("rb" or "wb"). The file is given either by file descriptor
115 or path name (if fd == -1).
116 gz_open returns NULL if the file could not be opened or if there was
117 insufficient memory to allocate the (de)compression state; errno
118 can be checked to distinguish the two cases (if errno is zero, the
119 zlib error is Z_MEM_ERROR).
121 local gzFile
gz_open (path
, mode
, fd
, use64
)
128 int level
= Z_DEFAULT_COMPRESSION
; /* compression level */
129 int strategy
= Z_DEFAULT_STRATEGY
; /* compression strategy */
130 char *p
= (char*)mode
;
132 char fmode
[80]; /* copy of mode, without the compression level */
135 if (!path
|| !mode
) return Z_NULL
;
137 s
= (gz_stream
*)ALLOC(sizeof(gz_stream
));
138 if (!s
) return Z_NULL
;
140 s
->stream
.zalloc
= (alloc_func
)0;
141 s
->stream
.zfree
= (free_func
)0;
142 s
->stream
.opaque
= (voidpf
)0;
143 s
->stream
.next_in
= s
->inbuf
= Z_NULL
;
144 s
->stream
.next_out
= s
->outbuf
= Z_NULL
;
145 s
->stream
.avail_in
= s
->stream
.avail_out
= 0;
152 s
->crc
= crc32(0L, Z_NULL
, 0);
156 s
->path
= (char*)ALLOC(strlen(path
)+1);
157 if (s
->path
== NULL
) {
158 return destroy(s
), (gzFile
)Z_NULL
;
160 strcpy(s
->path
, path
); /* do this early for debugging */
164 if (*p
== 'r') s
->mode
= 'r';
165 if (*p
== 'w' || *p
== 'a') s
->mode
= 'w';
166 if (*p
>= '0' && *p
<= '9') {
168 } else if (*p
== 'f') {
169 strategy
= Z_FILTERED
;
170 } else if (*p
== 'h') {
171 strategy
= Z_HUFFMAN_ONLY
;
172 } else if (*p
== 'R') {
175 *m
++ = *p
; /* copy the mode */
177 } while (*p
++ && m
!= fmode
+ sizeof(fmode
));
178 if (s
->mode
== '\0') return destroy(s
), (gzFile
)Z_NULL
;
180 if (s
->mode
== 'w') {
182 err
= Z_STREAM_ERROR
;
184 err
= deflateInit2(&(s
->stream
), level
,
185 Z_DEFLATED
, -MAX_WBITS
, DEF_MEM_LEVEL
, strategy
);
186 /* windowBits is passed < 0 to suppress zlib header */
188 s
->stream
.next_out
= s
->outbuf
= (Byte
*)ALLOC(Z_BUFSIZE
);
190 if (err
!= Z_OK
|| s
->outbuf
== Z_NULL
) {
191 return destroy(s
), (gzFile
)Z_NULL
;
194 s
->stream
.next_in
= s
->inbuf
= (Byte
*)ALLOC(Z_BUFSIZE
);
196 err
= inflateInit2(&(s
->stream
), -MAX_WBITS
);
197 /* windowBits is passed < 0 to tell that there is no zlib header */
198 if (err
!= Z_OK
|| s
->inbuf
== Z_NULL
) {
199 return destroy(s
), (gzFile
)Z_NULL
;
202 s
->stream
.avail_out
= Z_BUFSIZE
;
205 s
->file
= fd
< 0 ? (use64
? F_OPEN64(path
, fmode
) : F_OPEN(path
, fmode
)) :
206 (FILE*)fdopen(fd
, fmode
);
208 if (s
->file
== NULL
) {
209 return destroy(s
), (gzFile
)Z_NULL
;
211 if (s
->mode
== 'w') {
212 /* Write a very simple .gz header:
214 fprintf(s
->file
, "%c%c%c%c%c%c%c%c%c%c", gz_magic
[0], gz_magic
[1],
215 Z_DEFLATED
, 0 /*flags*/, 0,0,0,0 /*time*/, level
== 9 ? 2 :
216 (strategy
>= Z_HUFFMAN_ONLY
||
217 (level
!= Z_DEFAULT_COMPRESSION
&& level
< 2) ?
218 4 : 0) /*xflags*/, OS_CODE
);
220 /* We use 10L instead of ftell(s->file) to because ftell causes an
221 * fflush on some systems. This version of the library doesn't use
222 * start anyway in write mode, so this initialization is not
226 check_header(s
); /* skip the .gz header */
227 s
->start
= FTELL(s
->file
) - s
->stream
.avail_in
;
233 /* ===========================================================================
234 Opens a gzip (.gz) file for reading or writing.
236 gzFile ZEXPORT
gzopen (path
, mode
)
240 return gz_open (path
, mode
, -1, 0);
243 /* ===========================================================================
244 Opens a gzip (.gz) file for reading or writing for 64-bit offsets
246 gzFile ZEXPORT
gzopen64 (path
, mode
)
250 return gz_open (path
, mode
, -1, 1);
253 /* ===========================================================================
254 Associate a gzFile with the file descriptor fd. fd is not dup'ed here
255 to mimic the behavio(u)r of fdopen.
257 gzFile ZEXPORT
gzdopen (fd
, mode
)
261 char name
[46]; /* allow for up to 128-bit integers */
263 if (fd
< 0) return (gzFile
)Z_NULL
;
264 sprintf(name
, "<fd:%d>", fd
); /* for debugging */
266 return gz_open (name
, mode
, fd
, 0);
269 /* ===========================================================================
270 * Update the compression level and strategy
272 int ZEXPORT
gzsetparams (file
, level
, strategy
)
277 gz_stream
*s
= (gz_stream
*)file
;
279 if (s
== NULL
|| s
->mode
!= 'w') return Z_STREAM_ERROR
;
281 /* Make room to allow flushing */
282 if (s
->stream
.avail_out
== 0) {
284 s
->stream
.next_out
= s
->outbuf
;
285 if (fwrite(s
->outbuf
, 1, Z_BUFSIZE
, s
->file
) != Z_BUFSIZE
) {
288 s
->stream
.avail_out
= Z_BUFSIZE
;
291 return deflateParams (&(s
->stream
), level
, strategy
);
294 /* ===========================================================================
295 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
297 IN assertion: the stream s has been successfully opened for reading.
299 local
int get_byte(s
)
302 if (s
->z_eof
) return EOF
;
303 if (s
->stream
.avail_in
== 0) {
305 s
->stream
.avail_in
= (uInt
)fread(s
->inbuf
, 1, Z_BUFSIZE
, s
->file
);
306 if (s
->stream
.avail_in
== 0) {
308 if (ferror(s
->file
)) s
->z_err
= Z_ERRNO
;
311 s
->stream
.next_in
= s
->inbuf
;
313 s
->stream
.avail_in
--;
314 return *(s
->stream
.next_in
)++;
317 /* ===========================================================================
318 Check the gzip header of a gz_stream opened for reading. Set the stream
319 mode to transparent if the gzip magic header is not present; set s->err
320 to Z_DATA_ERROR if the magic header is present but the rest of the header
322 IN assertion: the stream s has already been created successfully;
323 s->stream.avail_in is zero for the first time, but may be non-zero
324 for concatenated .gz files.
326 local
void check_header(s
)
329 int method
; /* method byte */
330 int flags
; /* flags byte */
334 /* Assure two bytes in the buffer so we can peek ahead -- handle case
335 where first byte of header is at the end of the buffer after the last
337 len
= s
->stream
.avail_in
;
339 if (len
) s
->inbuf
[0] = s
->stream
.next_in
[0];
341 len
= (uInt
)fread(s
->inbuf
+ len
, 1, Z_BUFSIZE
>> len
, s
->file
);
342 if (len
== 0) s
->z_eof
= 1;
343 if (len
== 0 && ferror(s
->file
)) s
->z_err
= Z_ERRNO
;
344 s
->stream
.avail_in
+= len
;
345 s
->stream
.next_in
= s
->inbuf
;
346 if (s
->stream
.avail_in
< 2) {
347 s
->transparent
= s
->stream
.avail_in
;
352 /* Peek ahead to check the gzip magic header */
353 if (s
->stream
.next_in
[0] != gz_magic
[0] ||
354 s
->stream
.next_in
[1] != gz_magic
[1]) {
358 s
->stream
.avail_in
-= 2;
359 s
->stream
.next_in
+= 2;
361 /* Check the rest of the gzip header */
362 method
= get_byte(s
);
364 if (method
!= Z_DEFLATED
|| (flags
& RESERVED
) != 0) {
365 s
->z_err
= Z_DATA_ERROR
;
369 /* Discard time, xflags and OS code: */
370 for (len
= 0; len
< 6; len
++) (void)get_byte(s
);
372 if ((flags
& EXTRA_FIELD
) != 0) { /* skip the extra field */
373 len
= (uInt
)get_byte(s
);
374 len
+= ((uInt
)get_byte(s
))<<8;
375 /* len is garbage if EOF but the loop below will quit anyway */
376 while (len
-- != 0 && get_byte(s
) != EOF
) ;
378 if ((flags
& ORIG_NAME
) != 0) { /* skip the original file name */
379 while ((c
= get_byte(s
)) != 0 && c
!= EOF
) ;
381 if ((flags
& COMMENT
) != 0) { /* skip the .gz file comment */
382 while ((c
= get_byte(s
)) != 0 && c
!= EOF
) ;
384 if ((flags
& HEAD_CRC
) != 0) { /* skip the header crc */
385 for (len
= 0; len
< 2; len
++) (void)get_byte(s
);
387 s
->z_err
= s
->z_eof
? Z_DATA_ERROR
: Z_OK
;
390 /* ===========================================================================
391 * Cleanup then free the given gz_stream. Return a zlib error code.
392 Try freeing in the reverse order of allocations.
394 local
int destroy (s
)
399 if (!s
) return Z_STREAM_ERROR
;
403 if (s
->stream
.state
!= NULL
) {
404 if (s
->mode
== 'w') {
406 err
= Z_STREAM_ERROR
;
408 err
= deflateEnd(&(s
->stream
));
410 } else if (s
->mode
== 'r') {
411 err
= inflateEnd(&(s
->stream
));
414 if (s
->file
!= NULL
&& fclose(s
->file
)) {
416 if (errno
!= ESPIPE
) /* fclose is broken for pipes in HP/UX */
420 if (s
->z_err
< 0) err
= s
->z_err
;
429 /* ===========================================================================
430 Reads the given number of uncompressed bytes from the compressed file.
431 gzread returns the number of bytes actually read (0 for end of file).
433 int ZEXPORT
gzread (file
, buf
, len
)
438 gz_stream
*s
= (gz_stream
*)file
;
439 Bytef
*start
= (Bytef
*)buf
; /* starting point for crc computation */
440 Byte
*next_out
; /* == stream.next_out but not forced far (for MSDOS) */
442 if (s
== NULL
|| s
->mode
!= 'r') return Z_STREAM_ERROR
;
444 if (s
->z_err
== Z_DATA_ERROR
|| s
->z_err
== Z_ERRNO
) return -1;
445 if (s
->z_err
== Z_STREAM_END
) return 0; /* EOF */
447 next_out
= (Byte
*)buf
;
448 s
->stream
.next_out
= (Bytef
*)buf
;
449 s
->stream
.avail_out
= len
;
451 if (s
->stream
.avail_out
&& s
->back
!= EOF
) {
452 *next_out
++ = s
->back
;
453 s
->stream
.next_out
++;
454 s
->stream
.avail_out
--;
459 s
->z_err
= Z_STREAM_END
;
464 while (s
->stream
.avail_out
!= 0) {
466 if (s
->transparent
) {
467 /* Copy first the lookahead bytes: */
468 uInt n
= s
->stream
.avail_in
;
469 if (n
> s
->stream
.avail_out
) n
= s
->stream
.avail_out
;
471 zmemcpy(s
->stream
.next_out
, s
->stream
.next_in
, n
);
473 s
->stream
.next_out
= next_out
;
474 s
->stream
.next_in
+= n
;
475 s
->stream
.avail_out
-= n
;
476 s
->stream
.avail_in
-= n
;
478 if (s
->stream
.avail_out
> 0 && !feof(s
->file
)) {
479 s
->stream
.avail_out
-=
480 (uInt
)fread(next_out
, 1, s
->stream
.avail_out
, s
->file
);
482 len
-= s
->stream
.avail_out
;
485 if (len
== 0) s
->z_eof
= 1;
488 if (s
->stream
.avail_in
== 0 && !s
->z_eof
) {
491 s
->stream
.avail_in
= (uInt
)fread(s
->inbuf
, 1, Z_BUFSIZE
, s
->file
);
492 if (s
->stream
.avail_in
== 0) {
494 if (ferror(s
->file
)) {
499 s
->stream
.next_in
= s
->inbuf
;
501 s
->in
+= s
->stream
.avail_in
;
502 s
->out
+= s
->stream
.avail_out
;
503 s
->z_err
= inflate(&(s
->stream
), Z_NO_FLUSH
);
504 s
->in
-= s
->stream
.avail_in
;
505 s
->out
-= s
->stream
.avail_out
;
507 if (s
->z_err
== Z_STREAM_END
) {
508 /* Check CRC and original size */
509 s
->crc
= crc32(s
->crc
, start
, (uInt
)(s
->stream
.next_out
- start
));
510 start
= s
->stream
.next_out
;
512 if (getLong(s
) != s
->crc
) {
513 s
->z_err
= Z_DATA_ERROR
;
516 /* The uncompressed length returned by above getlong() may be
517 * different from s->out in case of concatenated .gz files.
518 * Check for such files:
521 if (s
->z_err
== Z_OK
) {
522 inflateReset(&(s
->stream
));
523 s
->crc
= crc32(0L, Z_NULL
, 0);
527 if (s
->z_err
!= Z_OK
|| s
->z_eof
) break;
529 s
->crc
= crc32(s
->crc
, start
, (uInt
)(s
->stream
.next_out
- start
));
531 if (len
== s
->stream
.avail_out
&&
532 (s
->z_err
== Z_DATA_ERROR
|| s
->z_err
== Z_ERRNO
))
534 return (int)(len
- s
->stream
.avail_out
);
538 /* ===========================================================================
539 Reads one byte from the compressed file. gzgetc returns this byte
540 or -1 in case of end of file or error.
542 int ZEXPORT
gzgetc(file
)
547 return gzread(file
, &c
, 1) == 1 ? c
: -1;
551 /* ===========================================================================
552 Push one byte back onto the stream.
554 int ZEXPORT
gzungetc(c
, file
)
558 gz_stream
*s
= (gz_stream
*)file
;
560 if (s
== NULL
|| s
->mode
!= 'r' || c
== EOF
|| s
->back
!= EOF
) return EOF
;
563 s
->last
= (s
->z_err
== Z_STREAM_END
);
564 if (s
->last
) s
->z_err
= Z_OK
;
570 /* ===========================================================================
571 Reads bytes from the compressed file until len-1 characters are
572 read, or a newline character is read and transferred to buf, or an
573 end-of-file condition is encountered. The string is then terminated
574 with a null character.
575 gzgets returns buf, or Z_NULL in case of error.
577 The current implementation is not optimized at all.
579 char * ZEXPORT
gzgets(file
, buf
, len
)
585 if (buf
== Z_NULL
|| len
<= 0) return Z_NULL
;
587 while (--len
> 0 && gzread(file
, buf
, 1) == 1 && *buf
++ != '\n') ;
589 return b
== buf
&& len
> 0 ? Z_NULL
: b
;
593 #ifndef NO_GZCOMPRESS
594 /* ===========================================================================
595 Writes the given number of uncompressed bytes into the compressed file.
596 gzwrite returns the number of bytes actually written (0 in case of error).
598 int ZEXPORT
gzwrite (file
, buf
, len
)
603 gz_stream
*s
= (gz_stream
*)file
;
605 if (s
== NULL
|| s
->mode
!= 'w') return Z_STREAM_ERROR
;
607 s
->stream
.next_in
= (Bytef
*)buf
;
608 s
->stream
.avail_in
= len
;
610 while (s
->stream
.avail_in
!= 0) {
612 if (s
->stream
.avail_out
== 0) {
614 s
->stream
.next_out
= s
->outbuf
;
615 if (fwrite(s
->outbuf
, 1, Z_BUFSIZE
, s
->file
) != Z_BUFSIZE
) {
619 s
->stream
.avail_out
= Z_BUFSIZE
;
621 s
->in
+= s
->stream
.avail_in
;
622 s
->out
+= s
->stream
.avail_out
;
623 s
->z_err
= deflate(&(s
->stream
), Z_NO_FLUSH
);
624 s
->in
-= s
->stream
.avail_in
;
625 s
->out
-= s
->stream
.avail_out
;
626 if (s
->z_err
!= Z_OK
) break;
628 s
->crc
= crc32(s
->crc
, (const Bytef
*)buf
, len
);
630 return (int)(len
- s
->stream
.avail_in
);
634 /* ===========================================================================
635 Converts, formats, and writes the args to the compressed file under
636 control of the format string, as in fprintf. gzprintf returns the number of
637 uncompressed bytes actually written (0 in case of error).
642 int ZEXPORTVA
gzprintf (gzFile file
, const char *format
, /* args */ ...)
644 char buf
[Z_PRINTF_BUFSIZE
];
648 buf
[sizeof(buf
) - 1] = 0;
649 va_start(va
, format
);
651 # ifdef HAS_vsprintf_void
652 (void)vsprintf(buf
, format
, va
);
654 for (len
= 0; len
< sizeof(buf
); len
++)
655 if (buf
[len
] == 0) break;
657 len
= vsprintf(buf
, format
, va
);
661 # ifdef HAS_vsnprintf_void
662 (void)vsnprintf(buf
, sizeof(buf
), format
, va
);
666 len
= vsnprintf(buf
, sizeof(buf
), format
, va
);
670 if (len
<= 0 || len
>= (int)sizeof(buf
) || buf
[sizeof(buf
) - 1] != 0)
672 return gzwrite(file
, buf
, (unsigned)len
);
674 #else /* not ANSI C */
676 int ZEXPORTVA
gzprintf (file
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
,
677 a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
)
680 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
,
681 a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
;
683 char buf
[Z_PRINTF_BUFSIZE
];
686 buf
[sizeof(buf
) - 1] = 0;
688 # ifdef HAS_sprintf_void
689 sprintf(buf
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
690 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
691 for (len
= 0; len
< sizeof(buf
); len
++)
692 if (buf
[len
] == 0) break;
694 len
= sprintf(buf
, format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
695 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
698 # ifdef HAS_snprintf_void
699 snprintf(buf
, sizeof(buf
), format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
700 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
703 len
= snprintf(buf
, sizeof(buf
), format
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
,
704 a9
, a10
, a11
, a12
, a13
, a14
, a15
, a16
, a17
, a18
, a19
, a20
);
707 if (len
<= 0 || len
>= sizeof(buf
) || buf
[sizeof(buf
) - 1] != 0)
709 return gzwrite(file
, buf
, len
);
713 /* ===========================================================================
714 Writes c, converted to an unsigned char, into the compressed file.
715 gzputc returns the value that was written, or -1 in case of error.
717 int ZEXPORT
gzputc(file
, c
)
721 unsigned char cc
= (unsigned char) c
; /* required for big endian systems */
723 return gzwrite(file
, &cc
, 1) == 1 ? (int)cc
: -1;
727 /* ===========================================================================
728 Writes the given null-terminated string to the compressed file, excluding
729 the terminating null character.
730 gzputs returns the number of characters written, or -1 in case of error.
732 int ZEXPORT
gzputs(file
, s
)
736 return gzwrite(file
, (char*)s
, (unsigned)strlen(s
));
740 /* ===========================================================================
741 Flushes all pending output into the compressed file. The parameter
742 flush is as in the deflate() function.
744 local
int do_flush (file
, flush
)
750 gz_stream
*s
= (gz_stream
*)file
;
752 if (s
== NULL
|| s
->mode
!= 'w') return Z_STREAM_ERROR
;
754 s
->stream
.avail_in
= 0; /* should be zero already anyway */
757 len
= Z_BUFSIZE
- s
->stream
.avail_out
;
760 if ((uInt
)fwrite(s
->outbuf
, 1, len
, s
->file
) != len
) {
764 s
->stream
.next_out
= s
->outbuf
;
765 s
->stream
.avail_out
= Z_BUFSIZE
;
768 s
->out
+= s
->stream
.avail_out
;
769 s
->z_err
= deflate(&(s
->stream
), flush
);
770 s
->out
-= s
->stream
.avail_out
;
772 /* Ignore the second of two consecutive flushes: */
773 if (len
== 0 && s
->z_err
== Z_BUF_ERROR
) s
->z_err
= Z_OK
;
775 /* deflate has finished flushing only when it hasn't used up
776 * all the available space in the output buffer:
778 done
= (s
->stream
.avail_out
!= 0 || s
->z_err
== Z_STREAM_END
);
780 if (s
->z_err
!= Z_OK
&& s
->z_err
!= Z_STREAM_END
) break;
782 return s
->z_err
== Z_STREAM_END
? Z_OK
: s
->z_err
;
785 int ZEXPORT
gzflush (file
, flush
)
789 gz_stream
*s
= (gz_stream
*)file
;
790 int err
= do_flush (file
, flush
);
794 return s
->z_err
== Z_STREAM_END
? Z_OK
: s
->z_err
;
796 #endif /* NO_GZCOMPRESS */
798 /* ===========================================================================
799 Sets the starting position for the next gzread or gzwrite on the given
800 compressed file. The offset represents a number of bytes in the
801 gzseek returns the resulting offset location as measured in bytes from
802 the beginning of the uncompressed stream, or -1 in case of error.
803 SEEK_END is not implemented, returns error.
804 In this version of the library, gzseek can be extremely slow.
806 #ifdef _LARGEFILE64_SOURCE
807 local off64_t
gz_seek (file
, offset
, whence
, use64
)
811 local z_off_t
gz_seek (file
, offset
, whence
, use64
)
818 gz_stream
*s
= (gz_stream
*)file
;
820 if (s
== NULL
|| whence
== SEEK_END
||
821 s
->z_err
== Z_ERRNO
|| s
->z_err
== Z_DATA_ERROR
) {
825 if (s
->mode
== 'w') {
829 if (whence
== SEEK_SET
) {
832 if (offset
< 0) return -1L;
834 /* At this point, offset is the number of zero bytes to write. */
835 if (s
->inbuf
== Z_NULL
) {
836 s
->inbuf
= (Byte
*)ALLOC(Z_BUFSIZE
); /* for seeking */
837 if (s
->inbuf
== Z_NULL
) return -1L;
838 zmemzero(s
->inbuf
, Z_BUFSIZE
);
841 uInt size
= Z_BUFSIZE
;
842 if (offset
< Z_BUFSIZE
) size
= (uInt
)offset
;
844 size
= gzwrite(file
, s
->inbuf
, size
);
845 if (size
== 0) return -1L;
852 /* Rest of function is for reading only */
854 /* compute absolute position */
855 if (whence
== SEEK_CUR
) {
858 if (offset
< 0) return -1L;
860 if (s
->transparent
) {
863 s
->stream
.avail_in
= 0;
864 s
->stream
.next_in
= s
->inbuf
;
865 #ifdef _LARGEFILE64_SOURCE
866 if ((use64
? fseeko64(s
->file
, offset
, SEEK_SET
) :
867 FSEEK(s
->file
, offset
, SEEK_SET
)) < 0)
870 if (FSEEK(s
->file
, offset
, SEEK_SET
) < 0) return -1L;
873 s
->in
= s
->out
= offset
;
877 /* For a negative seek, rewind and use positive seek */
878 if (offset
>= s
->out
) {
880 } else if (gzrewind(file
) < 0) {
883 /* offset is now the number of bytes to skip. */
885 if (offset
!= 0 && s
->outbuf
== Z_NULL
) {
886 s
->outbuf
= (Byte
*)ALLOC(Z_BUFSIZE
);
887 if (s
->outbuf
== Z_NULL
) return -1L;
889 if (offset
&& s
->back
!= EOF
) {
893 if (s
->last
) s
->z_err
= Z_STREAM_END
;
896 int size
= Z_BUFSIZE
;
897 if (offset
< Z_BUFSIZE
) size
= (int)offset
;
899 size
= gzread(file
, s
->outbuf
, (uInt
)size
);
900 if (size
<= 0) return -1L;
906 /* ===========================================================================
907 Define external functions gzseek() and gzseek64() using local gz_seek().
909 z_off_t ZEXPORT
gzseek (file
, offset
, whence
)
914 return (z_off_t
)gz_seek(file
, offset
, whence
, 0);
917 #ifdef _LARGEFILE64_SOURCE
918 off64_t ZEXPORT
gzseek64 (file
, offset
, whence
)
923 return gz_seek(file
, offset
, whence
, 1);
926 z_off_t ZEXPORT
gzseek64 (file
, offset
, whence
)
931 return gz_seek(file
, offset
, whence
, 0);
935 /* ===========================================================================
938 int ZEXPORT
gzrewind (file
)
941 gz_stream
*s
= (gz_stream
*)file
;
943 if (s
== NULL
|| s
->mode
!= 'r') return -1;
948 s
->stream
.avail_in
= 0;
949 s
->stream
.next_in
= s
->inbuf
;
950 s
->crc
= crc32(0L, Z_NULL
, 0);
951 if (!s
->transparent
) (void)inflateReset(&s
->stream
);
954 return FSEEK(s
->file
, s
->start
, SEEK_SET
);
957 /* ===========================================================================
958 Returns the starting position for the next gzread or gzwrite on the
959 given compressed file. This position represents a number of bytes in the
960 uncompressed data stream.
962 z_off_t ZEXPORT
gztell (file
)
965 return gzseek(file
, 0L, SEEK_CUR
);
968 /* ===========================================================================
971 #ifdef _LARGEFILE64_SOURCE
972 off64_t ZEXPORT
gztell64 (file
)
974 z_off_t ZEXPORT
gztell64 (file
)
978 return gzseek64(file
, 0L, SEEK_CUR
);
981 /* ===========================================================================
982 Returns 1 when EOF has previously been detected reading the given
983 input stream, otherwise zero.
985 int ZEXPORT
gzeof (file
)
988 gz_stream
*s
= (gz_stream
*)file
;
990 /* With concatenated compressed files that can have embedded
991 * crc trailers, z_eof is no longer the only/best indicator of EOF
992 * on a gz_stream. Handle end-of-stream error explicitly here.
994 if (s
== NULL
|| s
->mode
!= 'r') return 0;
995 if (s
->z_eof
) return 1;
996 return s
->z_err
== Z_STREAM_END
;
999 /* ===========================================================================
1000 Returns 1 if reading and doing so transparently, otherwise zero.
1002 int ZEXPORT
gzdirect (file
)
1005 gz_stream
*s
= (gz_stream
*)file
;
1007 if (s
== NULL
|| s
->mode
!= 'r') return 0;
1008 return s
->transparent
;
1011 /* ===========================================================================
1012 Outputs a long in LSB order to the given file
1014 local
void putLong (file
, x
)
1019 for (n
= 0; n
< 4; n
++) {
1020 fputc((int)(x
& 0xff), file
);
1025 /* ===========================================================================
1026 Reads a long in LSB order from the given gz_stream. Sets z_err in case
1029 local uLong
getLong (s
)
1032 uLong x
= (uLong
)get_byte(s
);
1035 x
+= ((uLong
)get_byte(s
))<<8;
1036 x
+= ((uLong
)get_byte(s
))<<16;
1038 if (c
== EOF
) s
->z_err
= Z_DATA_ERROR
;
1039 x
+= ((uLong
)c
)<<24;
1043 /* ===========================================================================
1044 Flushes all pending output if necessary, closes the compressed file
1045 and deallocates all the (de)compression state.
1047 int ZEXPORT
gzclose (file
)
1050 gz_stream
*s
= (gz_stream
*)file
;
1052 if (s
== NULL
) return Z_STREAM_ERROR
;
1054 if (s
->mode
== 'w') {
1055 #ifdef NO_GZCOMPRESS
1056 return Z_STREAM_ERROR
;
1058 if (do_flush (file
, Z_FINISH
) != Z_OK
)
1059 return destroy((gz_stream
*)file
);
1061 putLong (s
->file
, s
->crc
);
1062 putLong (s
->file
, (uLong
)(s
->in
& 0xffffffff));
1065 return destroy((gz_stream
*)file
);
1068 #if defined(STDC) && !defined(_WIN32_WCE)
1069 # define zstrerror(errnum) strerror(errnum)
1071 # define zstrerror(errnum) ""
1074 /* ===========================================================================
1075 Returns the error message for the last error which occurred on the
1076 given compressed file. errnum is set to zlib error number. If an
1077 error occurred in the file system and not in the compression library,
1078 errnum is set to Z_ERRNO and the application may consult errno
1079 to get the exact error code.
1081 const char * ZEXPORT
gzerror (file
, errnum
)
1086 gz_stream
*s
= (gz_stream
*)file
;
1089 *errnum
= Z_STREAM_ERROR
;
1090 return (const char*)ERR_MSG(Z_STREAM_ERROR
);
1093 if (*errnum
== Z_OK
) return (const char*)"";
1095 m
= (char*)(*errnum
== Z_ERRNO
? zstrerror(errno
) : s
->stream
.msg
);
1097 if (m
== NULL
|| *m
== '\0') m
= (char*)ERR_MSG(s
->z_err
);
1100 s
->msg
= (char*)ALLOC(strlen(s
->path
) + strlen(m
) + 3);
1101 if (s
->msg
== Z_NULL
) return (const char*)ERR_MSG(Z_MEM_ERROR
);
1102 strcpy(s
->msg
, s
->path
);
1103 strcat(s
->msg
, ": ");
1105 return (const char*)s
->msg
;
1108 /* ===========================================================================
1109 Clear the error and end-of-file flags, and do the same for the real file.
1111 void ZEXPORT
gzclearerr (file
)
1114 gz_stream
*s
= (gz_stream
*)file
;
1116 if (s
== NULL
) return;
1117 if (s
->z_err
!= Z_STREAM_END
) s
->z_err
= Z_OK
;