Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/zlib/gzread.c

Issue 2079313002: Revert of Update Zlib to version 1.2.8 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/zlib/gzlib.c ('k') | third_party/zlib/gzwrite.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* gzread.c -- zlib functions for reading gzip files 1 /* gzread.c -- zlib functions for reading gzip files
2 * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler 2 * Copyright (C) 2004, 2005, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6 #include "gzguts.h" 6 #include "gzguts.h"
7 7
8 /* Local functions */ 8 /* Local functions */
9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); 9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
10 local int gz_avail OF((gz_statep)); 10 local int gz_avail OF((gz_statep));
11 local int gz_look OF((gz_statep)); 11 local int gz_next4 OF((gz_statep, unsigned long *));
12 local int gz_head OF((gz_statep));
12 local int gz_decomp OF((gz_statep)); 13 local int gz_decomp OF((gz_statep));
13 local int gz_fetch OF((gz_statep)); 14 local int gz_make OF((gz_statep));
14 local int gz_skip OF((gz_statep, z_off64_t)); 15 local int gz_skip OF((gz_statep, z_off64_t));
15 16
16 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from 17 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
17 state->fd, and update state->eof, state->err, and state->msg as appropriate. 18 state->fd, and update state->eof, state->err, and state->msg as appropriate.
18 This function needs to loop on read(), since read() is not guaranteed to 19 This function needs to loop on read(), since read() is not guaranteed to
19 read the number of bytes requested, depending on the type of descriptor. */ 20 read the number of bytes requested, depending on the type of descriptor. */
20 local int gz_load(state, buf, len, have) 21 local int gz_load(state, buf, len, have)
21 gz_statep state; 22 gz_statep state;
22 unsigned char *buf; 23 unsigned char *buf;
23 unsigned len; 24 unsigned len;
(...skipping 14 matching lines...) Expand all
38 } 39 }
39 if (ret == 0) 40 if (ret == 0)
40 state->eof = 1; 41 state->eof = 1;
41 return 0; 42 return 0;
42 } 43 }
43 44
44 /* Load up input buffer and set eof flag if last data loaded -- return -1 on 45 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
45 error, 0 otherwise. Note that the eof flag is set when the end of the input 46 error, 0 otherwise. Note that the eof flag is set when the end of the input
46 file is reached, even though there may be unused data in the buffer. Once 47 file is reached, even though there may be unused data in the buffer. Once
47 that data has been used, no more attempts will be made to read the file. 48 that data has been used, no more attempts will be made to read the file.
48 If strm->avail_in != 0, then the current data is moved to the beginning of 49 gz_avail() assumes that strm->avail_in == 0. */
49 the input buffer, and then the remainder of the buffer is loaded with the
50 available data from the input file. */
51 local int gz_avail(state) 50 local int gz_avail(state)
52 gz_statep state; 51 gz_statep state;
53 { 52 {
54 unsigned got;
55 z_streamp strm = &(state->strm); 53 z_streamp strm = &(state->strm);
56 54
57 if (state->err != Z_OK && state->err != Z_BUF_ERROR) 55 if (state->err != Z_OK)
58 return -1; 56 return -1;
59 if (state->eof == 0) { 57 if (state->eof == 0) {
60 if (strm->avail_in) { /* copy what's there to the start */ 58 if (gz_load(state, state->in, state->size,
61 unsigned char *p = state->in; 59 (unsigned *)&(strm->avail_in)) == -1)
62 unsigned const char *q = strm->next_in;
63 unsigned n = strm->avail_in;
64 do {
65 *p++ = *q++;
66 } while (--n);
67 }
68 if (gz_load(state, state->in + strm->avail_in,
69 state->size - strm->avail_in, &got) == -1)
70 return -1; 60 return -1;
71 strm->avail_in += got;
72 strm->next_in = state->in; 61 strm->next_in = state->in;
73 } 62 }
74 return 0; 63 return 0;
75 } 64 }
76 65
77 /* Look for gzip header, set up for inflate or copy. state->x.have must be 0. 66 /* Get next byte from input, or -1 if end or error. */
67 #define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
68 (strm->avail_in == 0 ? -1 : \
69 (strm->avail_in--, *(strm->next_in)++)))
70
71 /* Get a four-byte little-endian integer and return 0 on success and the value
72 in *ret. Otherwise -1 is returned and *ret is not modified. */
73 local int gz_next4(state, ret)
74 gz_statep state;
75 unsigned long *ret;
76 {
77 int ch;
78 unsigned long val;
79 z_streamp strm = &(state->strm);
80
81 val = NEXT();
82 val += (unsigned)NEXT() << 8;
83 val += (unsigned long)NEXT() << 16;
84 ch = NEXT();
85 if (ch == -1)
86 return -1;
87 val += (unsigned long)ch << 24;
88 *ret = val;
89 return 0;
90 }
91
92 /* Look for gzip header, set up for inflate or copy. state->have must be zero.
78 If this is the first time in, allocate required memory. state->how will be 93 If this is the first time in, allocate required memory. state->how will be
79 left unchanged if there is no more input data available, will be set to COPY 94 left unchanged if there is no more input data available, will be set to COPY
80 if there is no gzip header and direct copying will be performed, or it will 95 if there is no gzip header and direct copying will be performed, or it will
81 be set to GZIP for decompression. If direct copying, then leftover input 96 be set to GZIP for decompression, and the gzip header will be skipped so
82 data from the input buffer will be copied to the output buffer. In that 97 that the next available input data is the raw deflate stream. If direct
83 case, all further file reads will be directly to either the output buffer or 98 copying, then leftover input data from the input buffer will be copied to
84 a user buffer. If decompressing, the inflate state will be initialized. 99 the output buffer. In that case, all further file reads will be directly to
85 gz_look() will return 0 on success or -1 on failure. */ 100 either the output buffer or a user buffer. If decompressing, the inflate
86 local int gz_look(state) 101 state and the check value will be initialized. gz_head() will return 0 on
102 success or -1 on failure. Failures may include read errors or gzip header
103 errors. */
104 local int gz_head(state)
87 gz_statep state; 105 gz_statep state;
88 { 106 {
89 z_streamp strm = &(state->strm); 107 z_streamp strm = &(state->strm);
108 int flags;
109 unsigned len;
90 110
91 /* allocate read buffers and inflate memory */ 111 /* allocate read buffers and inflate memory */
92 if (state->size == 0) { 112 if (state->size == 0) {
93 /* allocate buffers */ 113 /* allocate buffers */
94 state->in = (unsigned char *)malloc(state->want); 114 state->in = malloc(state->want);
95 state->out = (unsigned char *)malloc(state->want << 1); 115 state->out = malloc(state->want << 1);
96 if (state->in == NULL || state->out == NULL) { 116 if (state->in == NULL || state->out == NULL) {
97 if (state->out != NULL) 117 if (state->out != NULL)
98 free(state->out); 118 free(state->out);
99 if (state->in != NULL) 119 if (state->in != NULL)
100 free(state->in); 120 free(state->in);
101 gz_error(state, Z_MEM_ERROR, "out of memory"); 121 gz_error(state, Z_MEM_ERROR, "out of memory");
102 return -1; 122 return -1;
103 } 123 }
104 state->size = state->want; 124 state->size = state->want;
105 125
106 /* allocate inflate memory */ 126 /* allocate inflate memory */
107 state->strm.zalloc = Z_NULL; 127 state->strm.zalloc = Z_NULL;
108 state->strm.zfree = Z_NULL; 128 state->strm.zfree = Z_NULL;
109 state->strm.opaque = Z_NULL; 129 state->strm.opaque = Z_NULL;
110 state->strm.avail_in = 0; 130 state->strm.avail_in = 0;
111 state->strm.next_in = Z_NULL; 131 state->strm.next_in = Z_NULL;
112 if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ 132 if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
113 free(state->out); 133 free(state->out);
114 free(state->in); 134 free(state->in);
115 state->size = 0; 135 state->size = 0;
116 gz_error(state, Z_MEM_ERROR, "out of memory"); 136 gz_error(state, Z_MEM_ERROR, "out of memory");
117 return -1; 137 return -1;
118 } 138 }
119 } 139 }
120 140
121 /* get at least the magic bytes in the input buffer */ 141 /* get some data in the input buffer */
122 if (strm->avail_in < 2) { 142 if (strm->avail_in == 0) {
123 if (gz_avail(state) == -1) 143 if (gz_avail(state) == -1)
124 return -1; 144 return -1;
125 if (strm->avail_in == 0) 145 if (strm->avail_in == 0)
126 return 0; 146 return 0;
127 } 147 }
128 148
129 /* look for gzip magic bytes -- if there, do gzip decoding (note: there is 149 /* look for the gzip magic header bytes 31 and 139 */
130 a logical dilemma here when considering the case of a partially written 150 if (strm->next_in[0] == 31) {
131 gzip file, to wit, if a single 31 byte is written, then we cannot tell 151 strm->avail_in--;
132 whether this is a single-byte file, or just a partially written gzip 152 strm->next_in++;
133 file -- for here we assume that if a gzip file is being written, then 153 if (strm->avail_in == 0 && gz_avail(state) == -1)
134 the header will be written in a single operation, so that reading a 154 return -1;
135 single byte is sufficient indication that it is not a gzip file) */ 155 if (strm->avail_in && strm->next_in[0] == 139) {
136 if (strm->avail_in > 1 && 156 /* we have a gzip header, woo hoo! */
137 strm->next_in[0] == 31 && strm->next_in[1] == 139) { 157 strm->avail_in--;
138 inflateReset(strm); 158 strm->next_in++;
139 state->how = GZIP; 159
140 state->direct = 0; 160 /* skip rest of header */
141 return 0; 161 if (NEXT() != 8) { /* compression method */
162 gz_error(state, Z_DATA_ERROR, "unknown compression method");
163 return -1;
164 }
165 flags = NEXT();
166 if (flags & 0xe0) { /* reserved flag bits */
167 gz_error(state, Z_DATA_ERROR, "unknown header flags set");
168 return -1;
169 }
170 NEXT(); /* modification time */
171 NEXT();
172 NEXT();
173 NEXT();
174 NEXT(); /* extra flags */
175 NEXT(); /* operating system */
176 if (flags & 4) { /* extra field */
177 len = (unsigned)NEXT();
178 len += (unsigned)NEXT() << 8;
179 while (len--)
180 if (NEXT() < 0)
181 break;
182 }
183 if (flags & 8) /* file name */
184 while (NEXT() > 0)
185 ;
186 if (flags & 16) /* comment */
187 while (NEXT() > 0)
188 ;
189 if (flags & 2) { /* header crc */
190 NEXT();
191 NEXT();
192 }
193 /* an unexpected end of file is not checked for here -- it will be
194 noticed on the first request for uncompressed data */
195
196 /* set up for decompression */
197 inflateReset(strm);
198 strm->adler = crc32(0L, Z_NULL, 0);
199 state->how = GZIP;
200 state->direct = 0;
201 return 0;
202 }
203 else {
204 /* not a gzip file -- save first byte (31) and fall to raw i/o */
205 state->out[0] = 31;
206 state->have = 1;
207 }
142 } 208 }
143 209
144 /* no gzip header -- if we were decoding gzip before, then this is trailing 210 /* doing raw i/o, save start of raw data for seeking, copy any leftover
145 garbage. Ignore the trailing garbage and finish. */ 211 input to output -- this assumes that the output buffer is larger than
146 if (state->direct == 0) { 212 the input buffer, which also assures space for gzungetc() */
147 strm->avail_in = 0; 213 state->raw = state->pos;
148 state->eof = 1; 214 state->next = state->out;
149 state->x.have = 0;
150 return 0;
151 }
152
153 /* doing raw i/o, copy any leftover input to output -- this assumes that
154 the output buffer is larger than the input buffer, which also assures
155 space for gzungetc() */
156 state->x.next = state->out;
157 if (strm->avail_in) { 215 if (strm->avail_in) {
158 memcpy(state->x.next, strm->next_in, strm->avail_in); 216 memcpy(state->next + state->have, strm->next_in, strm->avail_in);
159 state->x.have = strm->avail_in; 217 state->have += strm->avail_in;
160 strm->avail_in = 0; 218 strm->avail_in = 0;
161 } 219 }
162 state->how = COPY; 220 state->how = COPY;
163 state->direct = 1; 221 state->direct = 1;
164 return 0; 222 return 0;
165 } 223 }
166 224
167 /* Decompress from input to the provided next_out and avail_out in the state. 225 /* Decompress from input to the provided next_out and avail_out in the state.
168 On return, state->x.have and state->x.next point to the just decompressed 226 If the end of the compressed data is reached, then verify the gzip trailer
169 data. If the gzip stream completes, state->how is reset to LOOK to look for 227 check value and length (modulo 2^32). state->have and state->next are set
170 the next gzip stream or raw data, once state->x.have is depleted. Returns 0 228 to point to the just decompressed data, and the crc is updated. If the
171 on success, -1 on failure. */ 229 trailer is verified, state->how is reset to LOOK to look for the next gzip
230 stream or raw data, once state->have is depleted. Returns 0 on success, -1
231 on failure. Failures may include invalid compressed data or a failed gzip
232 trailer verification. */
172 local int gz_decomp(state) 233 local int gz_decomp(state)
173 gz_statep state; 234 gz_statep state;
174 { 235 {
175 int ret = Z_OK; 236 int ret;
176 unsigned had; 237 unsigned had;
238 unsigned long crc, len;
177 z_streamp strm = &(state->strm); 239 z_streamp strm = &(state->strm);
178 240
179 /* fill output buffer up to end of deflate stream */ 241 /* fill output buffer up to end of deflate stream */
180 had = strm->avail_out; 242 had = strm->avail_out;
181 do { 243 do {
182 /* get more input for inflate() */ 244 /* get more input for inflate() */
183 if (strm->avail_in == 0 && gz_avail(state) == -1) 245 if (strm->avail_in == 0 && gz_avail(state) == -1)
184 return -1; 246 return -1;
185 if (strm->avail_in == 0) { 247 if (strm->avail_in == 0) {
186 gz_error(state, Z_BUF_ERROR, "unexpected end of file"); 248 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
187 break; 249 return -1;
188 } 250 }
189 251
190 /* decompress and handle errors */ 252 /* decompress and handle errors */
191 ret = inflate(strm, Z_NO_FLUSH); 253 ret = inflate(strm, Z_NO_FLUSH);
192 if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { 254 if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
193 gz_error(state, Z_STREAM_ERROR, 255 gz_error(state, Z_STREAM_ERROR,
194 "internal error: inflate stream corrupt"); 256 "internal error: inflate stream corrupt");
195 return -1; 257 return -1;
196 } 258 }
197 if (ret == Z_MEM_ERROR) { 259 if (ret == Z_MEM_ERROR) {
198 gz_error(state, Z_MEM_ERROR, "out of memory"); 260 gz_error(state, Z_MEM_ERROR, "out of memory");
199 return -1; 261 return -1;
200 } 262 }
201 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ 263 if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
202 gz_error(state, Z_DATA_ERROR, 264 gz_error(state, Z_DATA_ERROR,
203 strm->msg == NULL ? "compressed data error" : strm->msg); 265 strm->msg == NULL ? "compressed data error" : strm->msg);
204 return -1; 266 return -1;
205 } 267 }
206 } while (strm->avail_out && ret != Z_STREAM_END); 268 } while (strm->avail_out && ret != Z_STREAM_END);
207 269
208 /* update available output */ 270 /* update available output and crc check value */
209 state->x.have = had - strm->avail_out; 271 state->have = had - strm->avail_out;
210 state->x.next = strm->next_out - state->x.have; 272 state->next = strm->next_out - state->have;
273 strm->adler = crc32(strm->adler, state->next, state->have);
211 274
212 /* if the gzip stream completed successfully, look for another */ 275 /* check gzip trailer if at end of deflate stream */
213 if (ret == Z_STREAM_END) 276 if (ret == Z_STREAM_END) {
214 state->how = LOOK; 277 if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
278 gz_error(state, Z_DATA_ERROR, "unexpected end of file");
279 return -1;
280 }
281 if (crc != strm->adler) {
282 gz_error(state, Z_DATA_ERROR, "incorrect data check");
283 return -1;
284 }
285 if (len != (strm->total_out & 0xffffffffL)) {
286 gz_error(state, Z_DATA_ERROR, "incorrect length check");
287 return -1;
288 }
289 state->how = LOOK; /* ready for next stream, once have is 0 (leave
290 state->direct unchanged to remember how) */
291 }
215 292
216 /* good decompression */ 293 /* good decompression */
217 return 0; 294 return 0;
218 } 295 }
219 296
220 /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. 297 /* Make data and put in the output buffer. Assumes that state->have == 0.
221 Data is either copied from the input file or decompressed from the input 298 Data is either copied from the input file or decompressed from the input
222 file depending on state->how. If state->how is LOOK, then a gzip header is 299 file depending on state->how. If state->how is LOOK, then a gzip header is
223 looked for to determine whether to copy or decompress. Returns -1 on error, 300 looked for (and skipped if found) to determine wither to copy or decompress.
224 otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the 301 Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
225 end of the input file has been reached and all data has been processed. */ 302 or GZIP unless the end of the input file has been reached and all data has
226 local int gz_fetch(state) 303 been processed. */
304 local int gz_make(state)
227 gz_statep state; 305 gz_statep state;
228 { 306 {
229 z_streamp strm = &(state->strm); 307 z_streamp strm = &(state->strm);
230 308
231 do { 309 if (state->how == LOOK) { /* look for gzip header */
232 switch(state->how) { 310 if (gz_head(state) == -1)
233 case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ 311 return -1;
234 if (gz_look(state) == -1) 312 if (state->have) /* got some data from gz_head() */
235 return -1;
236 if (state->how == LOOK)
237 return 0;
238 break;
239 case COPY: /* -> COPY */
240 if (gz_load(state, state->out, state->size << 1, &(state->x.have))
241 == -1)
242 return -1;
243 state->x.next = state->out;
244 return 0; 313 return 0;
245 case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ 314 }
246 strm->avail_out = state->size << 1; 315 if (state->how == COPY) { /* straight copy */
247 strm->next_out = state->out; 316 if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
248 if (gz_decomp(state) == -1) 317 return -1;
249 return -1; 318 state->next = state->out;
250 } 319 }
251 } while (state->x.have == 0 && (!state->eof || strm->avail_in)); 320 else if (state->how == GZIP) { /* decompress */
321 strm->avail_out = state->size << 1;
322 strm->next_out = state->out;
323 if (gz_decomp(state) == -1)
324 return -1;
325 }
252 return 0; 326 return 0;
253 } 327 }
254 328
255 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ 329 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
256 local int gz_skip(state, len) 330 local int gz_skip(state, len)
257 gz_statep state; 331 gz_statep state;
258 z_off64_t len; 332 z_off64_t len;
259 { 333 {
260 unsigned n; 334 unsigned n;
261 335
262 /* skip over len bytes or reach end-of-file, whichever comes first */ 336 /* skip over len bytes or reach end-of-file, whichever comes first */
263 while (len) 337 while (len)
264 /* skip over whatever is in output buffer */ 338 /* skip over whatever is in output buffer */
265 if (state->x.have) { 339 if (state->have) {
266 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? 340 n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
267 (unsigned)len : state->x.have; 341 (unsigned)len : state->have;
268 state->x.have -= n; 342 state->have -= n;
269 state->x.next += n; 343 state->next += n;
270 state->x.pos += n; 344 state->pos += n;
271 len -= n; 345 len -= n;
272 } 346 }
273 347
274 /* output buffer empty -- return if we're at the end of the input */ 348 /* output buffer empty -- return if we're at the end of the input */
275 else if (state->eof && state->strm.avail_in == 0) 349 else if (state->eof && state->strm.avail_in == 0)
276 break; 350 break;
277 351
278 /* need more data to skip -- load up output buffer */ 352 /* need more data to skip -- load up output buffer */
279 else { 353 else {
280 /* get more output, looking for header if required */ 354 /* get more output, looking for header if required */
281 if (gz_fetch(state) == -1) 355 if (gz_make(state) == -1)
282 return -1; 356 return -1;
283 } 357 }
284 return 0; 358 return 0;
285 } 359 }
286 360
287 /* -- see zlib.h -- */ 361 /* -- see zlib.h -- */
288 int ZEXPORT gzread(file, buf, len) 362 int ZEXPORT gzread(file, buf, len)
289 gzFile file; 363 gzFile file;
290 voidp buf; 364 voidp buf;
291 unsigned len; 365 unsigned len;
292 { 366 {
293 unsigned got, n; 367 unsigned got, n;
294 gz_statep state; 368 gz_statep state;
295 z_streamp strm; 369 z_streamp strm;
296 370
297 /* get internal structure */ 371 /* get internal structure */
298 if (file == NULL) 372 if (file == NULL)
299 return -1; 373 return -1;
300 state = (gz_statep)file; 374 state = (gz_statep)file;
301 strm = &(state->strm); 375 strm = &(state->strm);
302 376
303 /* check that we're reading and that there's no (serious) error */ 377 /* check that we're reading and that there's no error */
304 if (state->mode != GZ_READ || 378 if (state->mode != GZ_READ || state->err != Z_OK)
305 (state->err != Z_OK && state->err != Z_BUF_ERROR))
306 return -1; 379 return -1;
307 380
308 /* since an int is returned, make sure len fits in one, otherwise return 381 /* since an int is returned, make sure len fits in one, otherwise return
309 with an error (this avoids the flaw in the interface) */ 382 with an error (this avoids the flaw in the interface) */
310 if ((int)len < 0) { 383 if ((int)len < 0) {
311 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 384 gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
312 return -1; 385 return -1;
313 } 386 }
314 387
315 /* if len is zero, avoid unnecessary operations */ 388 /* if len is zero, avoid unnecessary operations */
316 if (len == 0) 389 if (len == 0)
317 return 0; 390 return 0;
318 391
319 /* process a skip request */ 392 /* process a skip request */
320 if (state->seek) { 393 if (state->seek) {
321 state->seek = 0; 394 state->seek = 0;
322 if (gz_skip(state, state->skip) == -1) 395 if (gz_skip(state, state->skip) == -1)
323 return -1; 396 return -1;
324 } 397 }
325 398
326 /* get len bytes to buf, or less than len if at the end */ 399 /* get len bytes to buf, or less than len if at the end */
327 got = 0; 400 got = 0;
328 do { 401 do {
329 /* first just try copying data from the output buffer */ 402 /* first just try copying data from the output buffer */
330 if (state->x.have) { 403 if (state->have) {
331 n = state->x.have > len ? len : state->x.have; 404 n = state->have > len ? len : state->have;
332 memcpy(buf, state->x.next, n); 405 memcpy(buf, state->next, n);
333 state->x.next += n; 406 state->next += n;
334 state->x.have -= n; 407 state->have -= n;
335 } 408 }
336 409
337 /* output buffer empty -- return if we're at the end of the input */ 410 /* output buffer empty -- return if we're at the end of the input */
338 else if (state->eof && strm->avail_in == 0) { 411 else if (state->eof && strm->avail_in == 0)
339 state->past = 1; /* tried to read past end */
340 break; 412 break;
341 }
342 413
343 /* need output data -- for small len or new stream load up our output 414 /* need output data -- for small len or new stream load up our output
344 buffer */ 415 buffer */
345 else if (state->how == LOOK || len < (state->size << 1)) { 416 else if (state->how == LOOK || len < (state->size << 1)) {
346 /* get more output, looking for header if required */ 417 /* get more output, looking for header if required */
347 if (gz_fetch(state) == -1) 418 if (gz_make(state) == -1)
348 return -1; 419 return -1;
349 continue; /* no progress yet -- go back to copy above */ 420 continue; /* no progress yet -- go back to memcpy() above */
350 /* the copy above assures that we will leave with space in the 421 /* the copy above assures that we will leave with space in the
351 output buffer, allowing at least one gzungetc() to succeed */ 422 output buffer, allowing at least one gzungetc() to succeed */
352 } 423 }
353 424
354 /* large len -- read directly into user buffer */ 425 /* large len -- read directly into user buffer */
355 else if (state->how == COPY) { /* read directly */ 426 else if (state->how == COPY) { /* read directly */
356 if (gz_load(state, (unsigned char *)buf, len, &n) == -1) 427 if (gz_load(state, buf, len, &n) == -1)
357 return -1; 428 return -1;
358 } 429 }
359 430
360 /* large len -- decompress directly into user buffer */ 431 /* large len -- decompress directly into user buffer */
361 else { /* state->how == GZIP */ 432 else { /* state->how == GZIP */
362 strm->avail_out = len; 433 strm->avail_out = len;
363 strm->next_out = (unsigned char *)buf; 434 strm->next_out = buf;
364 if (gz_decomp(state) == -1) 435 if (gz_decomp(state) == -1)
365 return -1; 436 return -1;
366 n = state->x.have; 437 n = state->have;
367 state->x.have = 0; 438 state->have = 0;
368 } 439 }
369 440
370 /* update progress */ 441 /* update progress */
371 len -= n; 442 len -= n;
372 buf = (char *)buf + n; 443 buf = (char *)buf + n;
373 got += n; 444 got += n;
374 state->x.pos += n; 445 state->pos += n;
375 } while (len); 446 } while (len);
376 447
377 /* return number of bytes read into user buffer (will fit in int) */ 448 /* return number of bytes read into user buffer (will fit in int) */
378 return (int)got; 449 return (int)got;
379 } 450 }
380 451
381 /* -- see zlib.h -- */ 452 /* -- see zlib.h -- */
382 #ifdef Z_PREFIX_SET
383 # undef z_gzgetc
384 #else
385 # undef gzgetc
386 # ifdef MOZZCONF_H
387 # define gzgetc MOZ_Z_gzgetc
388 # endif
389 #endif
390
391 int ZEXPORT gzgetc(file) 453 int ZEXPORT gzgetc(file)
392 gzFile file; 454 gzFile file;
393 { 455 {
394 int ret; 456 int ret;
395 unsigned char buf[1]; 457 unsigned char buf[1];
396 gz_statep state; 458 gz_statep state;
397 459
398 /* get internal structure */ 460 /* get internal structure */
399 if (file == NULL) 461 if (file == NULL)
400 return -1; 462 return -1;
401 state = (gz_statep)file; 463 state = (gz_statep)file;
402 464
403 /* check that we're reading and that there's no (serious) error */ 465 /* check that we're reading and that there's no error */
404 if (state->mode != GZ_READ || 466 if (state->mode != GZ_READ || state->err != Z_OK)
405 (state->err != Z_OK && state->err != Z_BUF_ERROR))
406 return -1; 467 return -1;
407 468
408 /* try output buffer (no need to check for skip request) */ 469 /* try output buffer (no need to check for skip request) */
409 if (state->x.have) { 470 if (state->have) {
410 state->x.have--; 471 state->have--;
411 state->x.pos++; 472 state->pos++;
412 return *(state->x.next)++; 473 return *(state->next)++;
413 } 474 }
414 475
415 /* nothing there -- try gzread() */ 476 /* nothing there -- try gzread() */
416 ret = gzread(file, buf, 1); 477 ret = gzread(file, buf, 1);
417 return ret < 1 ? -1 : buf[0]; 478 return ret < 1 ? -1 : buf[0];
418 } 479 }
419 480
420 int ZEXPORT gzgetc_(file)
421 gzFile file;
422 {
423 return gzgetc(file);
424 }
425
426 /* -- see zlib.h -- */ 481 /* -- see zlib.h -- */
427 int ZEXPORT gzungetc(c, file) 482 int ZEXPORT gzungetc(c, file)
428 int c; 483 int c;
429 gzFile file; 484 gzFile file;
430 { 485 {
431 gz_statep state; 486 gz_statep state;
432 487
433 /* get internal structure */ 488 /* get internal structure */
434 if (file == NULL) 489 if (file == NULL)
435 return -1; 490 return -1;
436 state = (gz_statep)file; 491 state = (gz_statep)file;
437 492
438 /* check that we're reading and that there's no (serious) error */ 493 /* check that we're reading and that there's no error */
439 if (state->mode != GZ_READ || 494 if (state->mode != GZ_READ || state->err != Z_OK)
440 (state->err != Z_OK && state->err != Z_BUF_ERROR))
441 return -1; 495 return -1;
442 496
443 /* process a skip request */ 497 /* process a skip request */
444 if (state->seek) { 498 if (state->seek) {
445 state->seek = 0; 499 state->seek = 0;
446 if (gz_skip(state, state->skip) == -1) 500 if (gz_skip(state, state->skip) == -1)
447 return -1; 501 return -1;
448 } 502 }
449 503
450 /* can't push EOF */ 504 /* can't push EOF */
451 if (c < 0) 505 if (c < 0)
452 return -1; 506 return -1;
453 507
454 /* if output buffer empty, put byte at end (allows more pushing) */ 508 /* if output buffer empty, put byte at end (allows more pushing) */
455 if (state->x.have == 0) { 509 if (state->have == 0) {
456 state->x.have = 1; 510 state->have = 1;
457 state->x.next = state->out + (state->size << 1) - 1; 511 state->next = state->out + (state->size << 1) - 1;
458 state->x.next[0] = c; 512 state->next[0] = c;
459 state->x.pos--; 513 state->pos--;
460 state->past = 0;
461 return c; 514 return c;
462 } 515 }
463 516
464 /* if no room, give up (must have already done a gzungetc()) */ 517 /* if no room, give up (must have already done a gzungetc()) */
465 if (state->x.have == (state->size << 1)) { 518 if (state->have == (state->size << 1)) {
466 gz_error(state, Z_DATA_ERROR, "out of room to push characters"); 519 gz_error(state, Z_BUF_ERROR, "out of room to push characters");
467 return -1; 520 return -1;
468 } 521 }
469 522
470 /* slide output data if needed and insert byte before existing data */ 523 /* slide output data if needed and insert byte before existing data */
471 if (state->x.next == state->out) { 524 if (state->next == state->out) {
472 unsigned char *src = state->out + state->x.have; 525 unsigned char *src = state->out + state->have;
473 unsigned char *dest = state->out + (state->size << 1); 526 unsigned char *dest = state->out + (state->size << 1);
474 while (src > state->out) 527 while (src > state->out)
475 *--dest = *--src; 528 *--dest = *--src;
476 state->x.next = dest; 529 state->next = dest;
477 } 530 }
478 state->x.have++; 531 state->have++;
479 state->x.next--; 532 state->next--;
480 state->x.next[0] = c; 533 state->next[0] = c;
481 state->x.pos--; 534 state->pos--;
482 state->past = 0;
483 return c; 535 return c;
484 } 536 }
485 537
486 /* -- see zlib.h -- */ 538 /* -- see zlib.h -- */
487 char * ZEXPORT gzgets(file, buf, len) 539 char * ZEXPORT gzgets(file, buf, len)
488 gzFile file; 540 gzFile file;
489 char *buf; 541 char *buf;
490 int len; 542 int len;
491 { 543 {
492 unsigned left, n; 544 unsigned left, n;
493 char *str; 545 char *str;
494 unsigned char *eol; 546 unsigned char *eol;
495 gz_statep state; 547 gz_statep state;
496 548
497 /* check parameters and get internal structure */ 549 /* check parameters and get internal structure */
498 if (file == NULL || buf == NULL || len < 1) 550 if (file == NULL || buf == NULL || len < 1)
499 return NULL; 551 return NULL;
500 state = (gz_statep)file; 552 state = (gz_statep)file;
501 553
502 /* check that we're reading and that there's no (serious) error */ 554 /* check that we're reading and that there's no error */
503 if (state->mode != GZ_READ || 555 if (state->mode != GZ_READ || state->err != Z_OK)
504 (state->err != Z_OK && state->err != Z_BUF_ERROR))
505 return NULL; 556 return NULL;
506 557
507 /* process a skip request */ 558 /* process a skip request */
508 if (state->seek) { 559 if (state->seek) {
509 state->seek = 0; 560 state->seek = 0;
510 if (gz_skip(state, state->skip) == -1) 561 if (gz_skip(state, state->skip) == -1)
511 return NULL; 562 return NULL;
512 } 563 }
513 564
514 /* copy output bytes up to new line or len - 1, whichever comes first -- 565 /* copy output bytes up to new line or len - 1, whichever comes first --
515 append a terminating zero to the string (we don't check for a zero in 566 append a terminating zero to the string (we don't check for a zero in
516 the contents, let the user worry about that) */ 567 the contents, let the user worry about that) */
517 str = buf; 568 str = buf;
518 left = (unsigned)len - 1; 569 left = (unsigned)len - 1;
519 if (left) do { 570 if (left) do {
520 /* assure that something is in the output buffer */ 571 /* assure that something is in the output buffer */
521 if (state->x.have == 0 && gz_fetch(state) == -1) 572 if (state->have == 0) {
522 return NULL; /* error */ 573 if (gz_make(state) == -1)
523 if (state->x.have == 0) { /* end of file */ 574 return NULL; /* error */
524 state->past = 1; /* read past end */ 575 if (state->have == 0) { /* end of file */
525 break; /* return what we have */ 576 if (buf == str) /* got bupkus */
577 return NULL;
578 break; /* got something -- return it */
579 }
526 } 580 }
527 581
528 /* look for end-of-line in current output buffer */ 582 /* look for end-of-line in current output buffer */
529 n = state->x.have > left ? left : state->x.have; 583 n = state->have > left ? left : state->have;
530 eol = (unsigned char *)memchr(state->x.next, '\n', n); 584 eol = memchr(state->next, '\n', n);
531 if (eol != NULL) 585 if (eol != NULL)
532 n = (unsigned)(eol - state->x.next) + 1; 586 n = (unsigned)(eol - state->next) + 1;
533 587
534 /* copy through end-of-line, or remainder if not found */ 588 /* copy through end-of-line, or remainder if not found */
535 memcpy(buf, state->x.next, n); 589 memcpy(buf, state->next, n);
536 state->x.have -= n; 590 state->have -= n;
537 state->x.next += n; 591 state->next += n;
538 state->x.pos += n; 592 state->pos += n;
539 left -= n; 593 left -= n;
540 buf += n; 594 buf += n;
541 } while (left && eol == NULL); 595 } while (left && eol == NULL);
542 596
543 /* return terminated string, or if nothing, end of file */ 597 /* found end-of-line or out of space -- terminate string and return it */
544 if (buf == str)
545 return NULL;
546 buf[0] = 0; 598 buf[0] = 0;
547 return str; 599 return str;
548 } 600 }
549 601
550 /* -- see zlib.h -- */ 602 /* -- see zlib.h -- */
551 int ZEXPORT gzdirect(file) 603 int ZEXPORT gzdirect(file)
552 gzFile file; 604 gzFile file;
553 { 605 {
554 gz_statep state; 606 gz_statep state;
555 607
556 /* get internal structure */ 608 /* get internal structure */
557 if (file == NULL) 609 if (file == NULL)
558 return 0; 610 return 0;
559 state = (gz_statep)file; 611 state = (gz_statep)file;
560 612
613 /* check that we're reading */
614 if (state->mode != GZ_READ)
615 return 0;
616
561 /* if the state is not known, but we can find out, then do so (this is 617 /* if the state is not known, but we can find out, then do so (this is
562 mainly for right after a gzopen() or gzdopen()) */ 618 mainly for right after a gzopen() or gzdopen()) */
563 if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) 619 if (state->how == LOOK && state->have == 0)
564 (void)gz_look(state); 620 (void)gz_head(state);
565 621
566 /* return 1 if transparent, 0 if processing a gzip stream */ 622 /* return 1 if reading direct, 0 if decompressing a gzip stream */
567 return state->direct; 623 return state->direct;
568 } 624 }
569 625
570 /* -- see zlib.h -- */ 626 /* -- see zlib.h -- */
571 int ZEXPORT gzclose_r(file) 627 int ZEXPORT gzclose_r(file)
572 gzFile file; 628 gzFile file;
573 { 629 {
574 int ret, err; 630 int ret;
575 gz_statep state; 631 gz_statep state;
576 632
577 /* get internal structure */ 633 /* get internal structure */
578 if (file == NULL) 634 if (file == NULL)
579 return Z_STREAM_ERROR; 635 return Z_STREAM_ERROR;
580 state = (gz_statep)file; 636 state = (gz_statep)file;
581 637
582 /* check that we're reading */ 638 /* check that we're reading */
583 if (state->mode != GZ_READ) 639 if (state->mode != GZ_READ)
584 return Z_STREAM_ERROR; 640 return Z_STREAM_ERROR;
585 641
586 /* free memory and close file */ 642 /* free memory and close file */
587 if (state->size) { 643 if (state->size) {
588 inflateEnd(&(state->strm)); 644 inflateEnd(&(state->strm));
589 free(state->out); 645 free(state->out);
590 free(state->in); 646 free(state->in);
591 } 647 }
592 err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
593 gz_error(state, Z_OK, NULL); 648 gz_error(state, Z_OK, NULL);
594 free(state->path); 649 free(state->path);
595 ret = close(state->fd); 650 ret = close(state->fd);
596 free(state); 651 free(state);
597 return ret ? Z_ERRNO : err; 652 return ret ? Z_ERRNO : Z_OK;
598 } 653 }
OLDNEW
« no previous file with comments | « third_party/zlib/gzlib.c ('k') | third_party/zlib/gzwrite.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698