annotate zlib/gzio.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
1 /* gzio.c -- IO on .gz files
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
2 * Copyright (C) 1995 Jean-loup Gailly.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
3 * For conditions of distribution and use, see copyright notice in zlib.h
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
4 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
5
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
6 /* $Id: gzio.c,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
7
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
8 #include <stdio.h>
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
9
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
10 #include "zutil.h"
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
11
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
12 struct internal_state {int dummy;}; /* for buggy compilers */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
13
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
14 #define Z_BUFSIZE 4096
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
15
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
16 #define ALLOC(size) zcalloc((voidp)0, 1, size)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
17 #define TRYFREE(p) {if (p) zcfree((voidp)0, p);}
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
18
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
19 #define GZ_MAGIC_1 0x1f
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
20 #define GZ_MAGIC_2 0x8b
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
21
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
22 /* gzip flag byte */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
23 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
24 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
25 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
26 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
27 #define COMMENT 0x10 /* bit 4 set: file comment present */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
28 #define RESERVED 0xE0 /* bits 5..7: reserved */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
29
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
30 #ifndef SEEK_CUR
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
31 # define SEEK_CUR 1
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
32 #endif
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
33
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
34 typedef struct gz_stream {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
35 z_stream stream;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
36 int z_err; /* error code for last stream operation */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
37 int z_eof; /* set if end of input file */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
38 FILE *file; /* .gz file */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
39 Byte *inbuf; /* input buffer */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
40 Byte *outbuf; /* output buffer */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
41 uLong crc; /* crc32 of uncompressed data */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
42 char *msg; /* error message */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
43 char *path; /* path name for debugging only */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
44 int transparent; /* 1 if input file is not a .gz file */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
45 char mode; /* 'w' or 'r' */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
46 } gz_stream;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
47
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
48
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
49 local int destroy __P((gz_stream *s));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
50 local gzFile gz_open __P((char *path, char *mode, int fd));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
51 local void putLong __P((FILE *file, uLong x));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
52 local uLong getLong __P((Byte *buf));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
53
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
54 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
55 * Cleanup then free the given gz_stream. Return a zlib error code.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
56 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
57 local int destroy (s)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
58 gz_stream *s;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
59 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
60 int err = Z_OK;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
61
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
62 if (!s) return Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
63
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
64 TRYFREE(s->inbuf);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
65 TRYFREE(s->outbuf);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
66 TRYFREE(s->path);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
67 TRYFREE(s->msg);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
68
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
69 if (s->stream.state != NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
70 if (s->mode == 'w') {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
71 err = deflateEnd(&(s->stream));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
72 } else if (s->mode == 'r') {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
73 err = inflateEnd(&(s->stream));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
74 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
75 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
76 if (s->file != NULL && fclose(s->file)) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
77 err = Z_ERRNO;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
78 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
79 if (s->z_err < 0) err = s->z_err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
80 zcfree((voidp)0, s);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
81 return err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
82 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
83
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
84 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
85 Opens a gzip (.gz) file for reading or writing. The mode parameter
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
86 is as in fopen ("rb" or "wb"). The file is given either by file descritor
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
87 or path name (if fd == -1).
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
88 gz_open return NULL if the file could not be opened or if there was
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
89 insufficient memory to allocate the (de)compression state; errno
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
90 can be checked to distinguish the two cases (if errno is zero, the
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
91 zlib error is Z_MEM_ERROR).
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
92 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
93 local gzFile gz_open (path, mode, fd)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
94 char *path;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
95 char *mode;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
96 int fd;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
97 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
98 int err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
99 char *p = mode;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
100 gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
101
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
102 if (!s) return Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
103
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
104 s->stream.zalloc = (alloc_func)0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
105 s->stream.zfree = (free_func)0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
106 s->stream.next_in = s->inbuf = Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
107 s->stream.next_out = s->outbuf = Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
108 s->stream.avail_in = s->stream.avail_out = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
109 s->file = NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
110 s->z_err = Z_OK;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
111 s->z_eof = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
112 s->crc = crc32(0L, Z_NULL, 0);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
113 s->msg = NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
114 s->transparent = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
115
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
116 s->path = (char*)ALLOC(strlen(path)+1);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
117 if (s->path == NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
118 return destroy(s), (gzFile)Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
119 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
120 strcpy(s->path, path); /* do this early for debugging */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
121
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
122 s->mode = '\0';
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
123 do {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
124 if (*p == 'r') s->mode = 'r';
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
125 if (*p == 'w') s->mode = 'w';
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
126 } while (*p++);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
127 if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
128
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
129 if (s->mode == 'w') {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
130 err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION,
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
131 DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
132 /* windowBits is passed < 0 to suppress zlib header */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
133
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
134 s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
135
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
136 if (err != Z_OK || s->outbuf == Z_NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
137 return destroy(s), (gzFile)Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
138 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
139 } else {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
140 err = inflateInit2(&(s->stream), -MAX_WBITS);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
141 s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
142
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
143 if (err != Z_OK || s->inbuf == Z_NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
144 return destroy(s), (gzFile)Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
145 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
146 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
147 s->stream.avail_out = Z_BUFSIZE;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
148
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
149 errno = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
150 s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
151
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
152 if (s->file == NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
153 return destroy(s), (gzFile)Z_NULL;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
154 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
155 if (s->mode == 'w') {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
156 /* Write a very simple .gz header:
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
157 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
158 fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2,
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
159 DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
160 } else {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
161 /* Check and skip the header:
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
162 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
163 Byte c1 = 0, c2 = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
164 Byte method = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
165 Byte flags = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
166 Byte xflags = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
167 Byte time[4];
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
168 Byte osCode;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
169 int c;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
170
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
171 s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
172 if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
173 || s->inbuf[1] != GZ_MAGIC_2) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
174 s->transparent = 1;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
175 return (gzFile)s;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
176 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
177 s->stream.avail_in = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
178 fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
179
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
180 if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
181 s->z_err = Z_DATA_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
182 return (gzFile)s;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
183 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
184 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
185 long len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
186 fscanf(s->file, "%c%c", &c1, &c2);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
187 len = c1 + ((long)c2<<8);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
188 fseek(s->file, len, SEEK_CUR);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
189 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
190 if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
191 while ((c = getc(s->file)) != 0 && c != EOF) ;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
192 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
193 if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
194 while ((c = getc(s->file)) != 0 && c != EOF) ;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
195 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
196 if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
197 fscanf(s->file, "%c%c", &c1, &c2);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
198 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
199 if (feof(s->file)) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
200 s->z_err = Z_DATA_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
201 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
202 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
203 return (gzFile)s;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
204 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
205
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
206 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
207 Opens a gzip (.gz) file for reading or writing.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
208 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
209 gzFile gzopen (path, mode)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
210 char *path;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
211 char *mode;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
212 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
213 return gz_open (path, mode, -1);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
214 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
215
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
216 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
217 Associate a gzFile with the file descriptor fd.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
218 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
219 gzFile gzdopen (fd, mode)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
220 int fd;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
221 char *mode;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
222 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
223 char name[20];
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
224 sprintf(name, "<fd:%d>", fd); /* for debugging */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
225
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
226 return gz_open (name, mode, fd);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
227 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
228
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
229 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
230 Reads the given number of uncompressed bytes from the compressed file.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
231 gzread returns the number of bytes actually read (0 for end of file).
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
232 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
233 int gzread (file, buf, len)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
234 gzFile file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
235 voidp buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
236 unsigned len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
237 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
238 gz_stream *s = (gz_stream*)file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
239
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
240 if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
241
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
242 if (s->transparent) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
243 unsigned n = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
244 Byte *b = (Byte*)buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
245 /* Copy the first two (non-magic) bytes if not done already */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
246 while (s->stream.avail_in > 0 && len > 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
247 *b++ = *s->stream.next_in++;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
248 s->stream.avail_in--;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
249 len--; n++;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
250 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
251 if (len == 0) return n;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
252 return n + fread(b, 1, len, s->file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
253 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
254 if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
255 if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
256
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
257 s->stream.next_out = buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
258 s->stream.avail_out = len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
259
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
260 while (s->stream.avail_out != 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
261
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
262 if (s->stream.avail_in == 0 && !s->z_eof) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
263
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
264 errno = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
265 s->stream.avail_in =
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
266 fread(s->inbuf, 1, Z_BUFSIZE, s->file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
267 if (s->stream.avail_in == 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
268 s->z_eof = 1;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
269 } else if (s->stream.avail_in == (uInt)EOF) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
270 s->stream.avail_in = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
271 s->z_eof = 1;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
272 s->z_err = Z_ERRNO;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
273 break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
274 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
275 s->stream.next_in = s->inbuf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
276 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
277 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
278
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
279 if (s->z_err == Z_STREAM_END ||
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
280 s->z_err != Z_OK || s->z_eof) break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
281 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
282 len -= s->stream.avail_out;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
283 s->crc = crc32(s->crc, buf, len);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
284 return len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
285 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
286
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
287 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
288 Writes the given number of uncompressed bytes into the compressed file.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
289 gzwrite returns the number of bytes actually written (0 in case of error).
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
290 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
291 int gzwrite (file, buf, len)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
292 gzFile file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
293 voidp buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
294 unsigned len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
295 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
296 gz_stream *s = (gz_stream*)file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
297
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
298 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
299
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
300 s->stream.next_in = buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
301 s->stream.avail_in = len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
302
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
303 while (s->stream.avail_in != 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
304
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
305 if (s->stream.avail_out == 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
306
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
307 s->stream.next_out = s->outbuf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
308 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
309 s->z_err = Z_ERRNO;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
310 break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
311 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
312 s->stream.avail_out = Z_BUFSIZE;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
313 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
314 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
315
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
316 if (s->z_err != Z_OK) break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
317 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
318 s->crc = crc32(s->crc, buf, len);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
319
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
320 return len - s->stream.avail_in;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
321 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
322
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
323 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
324 Flushes all pending output into the compressed file. The parameter
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
325 flush is as in the deflate() function.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
326 gzflush should be called only when strictly necessary because it can
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
327 degrade compression.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
328 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
329 int gzflush (file, flush)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
330 gzFile file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
331 int flush;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
332 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
333 uInt len;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
334 int done = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
335 gz_stream *s = (gz_stream*)file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
336
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
337 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
338
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
339 s->stream.avail_in = 0; /* should be zero already anyway */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
340
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
341 for (;;) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
342 len = Z_BUFSIZE - s->stream.avail_out;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
343
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
344 if (len != 0) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
345 if (fwrite(s->outbuf, 1, len, s->file) != len) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
346 s->z_err = Z_ERRNO;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
347 return Z_ERRNO;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
348 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
349 s->stream.next_out = s->outbuf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
350 s->stream.avail_out = Z_BUFSIZE;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
351 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
352 if (done) break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
353 s->z_err = deflate(&(s->stream), flush);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
354
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
355 /* deflate has finished flushing only when it hasn't used up
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
356 * all the available space in the output buffer:
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
357 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
358 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
359
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
360 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
361 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
362 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
363 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
364
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
365 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
366 Outputs a long in LSB order to the given file
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
367 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
368 local void putLong (file, x)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
369 FILE *file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
370 uLong x;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
371 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
372 int n;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
373 for (n = 0; n < 4; n++) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
374 fputc((int)(x & 0xff), file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
375 x >>= 8;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
376 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
377 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
378
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
379 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
380 Reads a long in LSB order from the given buffer
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
381 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
382 local uLong getLong (buf)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
383 Byte *buf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
384 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
385 uLong x = 0;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
386 Byte *p = buf+4;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
387
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
388 do {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
389 x <<= 8;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
390 x |= *--p;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
391 } while (p != buf);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
392 return x;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
393 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
394
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
395 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
396 Flushes all pending output if necessary, closes the compressed file
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
397 and deallocates all the (de)compression state.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
398 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
399 int gzclose (file)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
400 gzFile file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
401 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
402 uInt n;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
403 int err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
404 gz_stream *s = (gz_stream*)file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
405
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
406 if (s == NULL) return Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
407
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
408 if (s->mode == 'w') {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
409 err = gzflush (file, Z_FINISH);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
410 if (err != Z_OK) return destroy(file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
411
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
412 putLong (s->file, s->crc);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
413 putLong (s->file, s->stream.total_in);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
414
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
415 } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
416
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
417 /* slide CRC and original size if they are at the end of inbuf */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
418 if ((n = s->stream.avail_in) < 8 && !s->z_eof) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
419 Byte *p = s->inbuf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
420 Byte *q = s->stream.next_in;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
421 while (n--) { *p++ = *q++; };
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
422
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
423 n = s->stream.avail_in;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
424 n += fread(p, 1, 8, s->file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
425 s->stream.next_in = s->inbuf;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
426 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
427 /* check CRC and original size */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
428 if (n < 8 ||
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
429 getLong(s->stream.next_in) != s->crc ||
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
430 getLong(s->stream.next_in + 4) != s->stream.total_out) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
431
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
432 s->z_err = Z_DATA_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
433 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
434 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
435 return destroy(file);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
436 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
437
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
438 /* ===========================================================================
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
439 Returns the error message for the last error which occured on the
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
440 given compressed file. errnum is set to zlib error number. If an
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
441 error occured in the file system and not in the compression library,
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
442 errnum is set to Z_ERRNO and the application may consult errno
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
443 to get the exact error code.
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
444 */
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
445 char* gzerror (file, errnum)
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
446 gzFile file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
447 int *errnum;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
448 {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
449 char *m;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
450 gz_stream *s = (gz_stream*)file;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
451
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
452 if (s == NULL) {
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
453 *errnum = Z_STREAM_ERROR;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
454 return z_errmsg[1-Z_STREAM_ERROR];
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
455 }
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
456 *errnum = s->z_err;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
457 if (*errnum == Z_OK) return "";
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
458
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
459 m = *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
460
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
461 if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
462
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
463 TRYFREE(s->msg);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
464 s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
465 strcpy(s->msg, s->path);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
466 strcat(s->msg, ": ");
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
467 strcat(s->msg, m);
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
468 return s->msg;
5a977ccbc7a9 Empty changelog
darius
parents:
diff changeset
469 }