Mercurial > repos > blastem
comparison zlib/gzread.c @ 2690:9ef72ee5c0b0
Update vendored zlib to 1.3.1
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 15 Jun 2025 15:39:33 -0700 |
parents | 00d788dac91a |
children |
comparison
equal
deleted
inserted
replaced
2689:bd6e33de0972 | 2690:9ef72ee5c0b0 |
---|---|
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, 2016 Mark Adler | 2 * Copyright (C) 2004-2017 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 | |
8 /* Local functions */ | |
9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); | |
10 local int gz_avail OF((gz_statep)); | |
11 local int gz_look OF((gz_statep)); | |
12 local int gz_decomp OF((gz_statep)); | |
13 local int gz_fetch OF((gz_statep)); | |
14 local int gz_skip OF((gz_statep, z_off64_t)); | |
15 local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); | |
16 | 7 |
17 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from | 8 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from |
18 state->fd, and update state->eof, state->err, and state->msg as appropriate. | 9 state->fd, and update state->eof, state->err, and state->msg as appropriate. |
19 This function needs to loop on read(), since read() is not guaranteed to | 10 This function needs to loop on read(), since read() is not guaranteed to |
20 read the number of bytes requested, depending on the type of descriptor. */ | 11 read the number of bytes requested, depending on the type of descriptor. */ |
21 local int gz_load(state, buf, len, have) | 12 local int gz_load(gz_statep state, unsigned char *buf, unsigned len, |
22 gz_statep state; | 13 unsigned *have) { |
23 unsigned char *buf; | |
24 unsigned len; | |
25 unsigned *have; | |
26 { | |
27 int ret; | 14 int ret; |
28 unsigned get, max = ((unsigned)-1 >> 2) + 1; | 15 unsigned get, max = ((unsigned)-1 >> 2) + 1; |
29 | 16 |
30 *have = 0; | 17 *have = 0; |
31 do { | 18 do { |
51 file is reached, even though there may be unused data in the buffer. Once | 38 file is reached, even though there may be unused data in the buffer. Once |
52 that data has been used, no more attempts will be made to read the file. | 39 that data has been used, no more attempts will be made to read the file. |
53 If strm->avail_in != 0, then the current data is moved to the beginning of | 40 If strm->avail_in != 0, then the current data is moved to the beginning of |
54 the input buffer, and then the remainder of the buffer is loaded with the | 41 the input buffer, and then the remainder of the buffer is loaded with the |
55 available data from the input file. */ | 42 available data from the input file. */ |
56 local int gz_avail(state) | 43 local int gz_avail(gz_statep state) { |
57 gz_statep state; | |
58 { | |
59 unsigned got; | 44 unsigned got; |
60 z_streamp strm = &(state->strm); | 45 z_streamp strm = &(state->strm); |
61 | 46 |
62 if (state->err != Z_OK && state->err != Z_BUF_ERROR) | 47 if (state->err != Z_OK && state->err != Z_BUF_ERROR) |
63 return -1; | 48 return -1; |
86 be set to GZIP for decompression. If direct copying, then leftover input | 71 be set to GZIP for decompression. If direct copying, then leftover input |
87 data from the input buffer will be copied to the output buffer. In that | 72 data from the input buffer will be copied to the output buffer. In that |
88 case, all further file reads will be directly to either the output buffer or | 73 case, all further file reads will be directly to either the output buffer or |
89 a user buffer. If decompressing, the inflate state will be initialized. | 74 a user buffer. If decompressing, the inflate state will be initialized. |
90 gz_look() will return 0 on success or -1 on failure. */ | 75 gz_look() will return 0 on success or -1 on failure. */ |
91 local int gz_look(state) | 76 local int gz_look(gz_statep state) { |
92 gz_statep state; | |
93 { | |
94 z_streamp strm = &(state->strm); | 77 z_streamp strm = &(state->strm); |
95 | 78 |
96 /* allocate read buffers and inflate memory */ | 79 /* allocate read buffers and inflate memory */ |
97 if (state->size == 0) { | 80 if (state->size == 0) { |
98 /* allocate buffers */ | 81 /* allocate buffers */ |
155 | 138 |
156 /* doing raw i/o, copy any leftover input to output -- this assumes that | 139 /* doing raw i/o, copy any leftover input to output -- this assumes that |
157 the output buffer is larger than the input buffer, which also assures | 140 the output buffer is larger than the input buffer, which also assures |
158 space for gzungetc() */ | 141 space for gzungetc() */ |
159 state->x.next = state->out; | 142 state->x.next = state->out; |
160 if (strm->avail_in) { | 143 memcpy(state->x.next, strm->next_in, strm->avail_in); |
161 memcpy(state->x.next, strm->next_in, strm->avail_in); | 144 state->x.have = strm->avail_in; |
162 state->x.have = strm->avail_in; | 145 strm->avail_in = 0; |
163 strm->avail_in = 0; | |
164 } | |
165 state->how = COPY; | 146 state->how = COPY; |
166 state->direct = 1; | 147 state->direct = 1; |
167 return 0; | 148 return 0; |
168 } | 149 } |
169 | 150 |
170 /* Decompress from input to the provided next_out and avail_out in the state. | 151 /* Decompress from input to the provided next_out and avail_out in the state. |
171 On return, state->x.have and state->x.next point to the just decompressed | 152 On return, state->x.have and state->x.next point to the just decompressed |
172 data. If the gzip stream completes, state->how is reset to LOOK to look for | 153 data. If the gzip stream completes, state->how is reset to LOOK to look for |
173 the next gzip stream or raw data, once state->x.have is depleted. Returns 0 | 154 the next gzip stream or raw data, once state->x.have is depleted. Returns 0 |
174 on success, -1 on failure. */ | 155 on success, -1 on failure. */ |
175 local int gz_decomp(state) | 156 local int gz_decomp(gz_statep state) { |
176 gz_statep state; | |
177 { | |
178 int ret = Z_OK; | 157 int ret = Z_OK; |
179 unsigned had; | 158 unsigned had; |
180 z_streamp strm = &(state->strm); | 159 z_streamp strm = &(state->strm); |
181 | 160 |
182 /* fill output buffer up to end of deflate stream */ | 161 /* fill output buffer up to end of deflate stream */ |
224 Data is either copied from the input file or decompressed from the input | 203 Data is either copied from the input file or decompressed from the input |
225 file depending on state->how. If state->how is LOOK, then a gzip header is | 204 file depending on state->how. If state->how is LOOK, then a gzip header is |
226 looked for to determine whether to copy or decompress. Returns -1 on error, | 205 looked for to determine whether to copy or decompress. Returns -1 on error, |
227 otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the | 206 otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the |
228 end of the input file has been reached and all data has been processed. */ | 207 end of the input file has been reached and all data has been processed. */ |
229 local int gz_fetch(state) | 208 local int gz_fetch(gz_statep state) { |
230 gz_statep state; | |
231 { | |
232 z_streamp strm = &(state->strm); | 209 z_streamp strm = &(state->strm); |
233 | 210 |
234 do { | 211 do { |
235 switch(state->how) { | 212 switch(state->how) { |
236 case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ | 213 case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ |
254 } while (state->x.have == 0 && (!state->eof || strm->avail_in)); | 231 } while (state->x.have == 0 && (!state->eof || strm->avail_in)); |
255 return 0; | 232 return 0; |
256 } | 233 } |
257 | 234 |
258 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ | 235 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ |
259 local int gz_skip(state, len) | 236 local int gz_skip(gz_statep state, z_off64_t len) { |
260 gz_statep state; | |
261 z_off64_t len; | |
262 { | |
263 unsigned n; | 237 unsigned n; |
264 | 238 |
265 /* skip over len bytes or reach end-of-file, whichever comes first */ | 239 /* skip over len bytes or reach end-of-file, whichever comes first */ |
266 while (len) | 240 while (len) |
267 /* skip over whatever is in output buffer */ | 241 /* skip over whatever is in output buffer */ |
289 | 263 |
290 /* Read len bytes into buf from file, or less than len up to the end of the | 264 /* Read len bytes into buf from file, or less than len up to the end of the |
291 input. Return the number of bytes read. If zero is returned, either the | 265 input. Return the number of bytes read. If zero is returned, either the |
292 end of file was reached, or there was an error. state->err must be | 266 end of file was reached, or there was an error. state->err must be |
293 consulted in that case to determine which. */ | 267 consulted in that case to determine which. */ |
294 local z_size_t gz_read(state, buf, len) | 268 local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { |
295 gz_statep state; | |
296 voidp buf; | |
297 z_size_t len; | |
298 { | |
299 z_size_t got; | 269 z_size_t got; |
300 unsigned n; | 270 unsigned n; |
301 | 271 |
302 /* if len is zero, avoid unnecessary operations */ | 272 /* if len is zero, avoid unnecessary operations */ |
303 if (len == 0) | 273 if (len == 0) |
312 | 282 |
313 /* get len bytes to buf, or less than len if at the end */ | 283 /* get len bytes to buf, or less than len if at the end */ |
314 got = 0; | 284 got = 0; |
315 do { | 285 do { |
316 /* set n to the maximum amount of len that fits in an unsigned int */ | 286 /* set n to the maximum amount of len that fits in an unsigned int */ |
317 n = -1; | 287 n = (unsigned)-1; |
318 if (n > len) | 288 if (n > len) |
319 n = len; | 289 n = (unsigned)len; |
320 | 290 |
321 /* first just try copying data from the output buffer */ | 291 /* first just try copying data from the output buffer */ |
322 if (state->x.have) { | 292 if (state->x.have) { |
323 if (state->x.have < n) | 293 if (state->x.have < n) |
324 n = state->x.have; | 294 n = state->x.have; |
370 /* return number of bytes read into user buffer */ | 340 /* return number of bytes read into user buffer */ |
371 return got; | 341 return got; |
372 } | 342 } |
373 | 343 |
374 /* -- see zlib.h -- */ | 344 /* -- see zlib.h -- */ |
375 int ZEXPORT gzread(file, buf, len) | 345 int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { |
376 gzFile file; | |
377 voidp buf; | |
378 unsigned len; | |
379 { | |
380 gz_statep state; | 346 gz_statep state; |
381 | 347 |
382 /* get internal structure */ | 348 /* get internal structure */ |
383 if (file == NULL) | 349 if (file == NULL) |
384 return -1; | 350 return -1; |
395 gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); | 361 gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); |
396 return -1; | 362 return -1; |
397 } | 363 } |
398 | 364 |
399 /* read len or fewer bytes to buf */ | 365 /* read len or fewer bytes to buf */ |
400 len = gz_read(state, buf, len); | 366 len = (unsigned)gz_read(state, buf, len); |
401 | 367 |
402 /* check for an error */ | 368 /* check for an error */ |
403 if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) | 369 if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) |
404 return -1; | 370 return -1; |
405 | 371 |
406 /* return the number of bytes read (this is assured to fit in an int) */ | 372 /* return the number of bytes read (this is assured to fit in an int) */ |
407 return (int)len; | 373 return (int)len; |
408 } | 374 } |
409 | 375 |
410 /* -- see zlib.h -- */ | 376 /* -- see zlib.h -- */ |
411 z_size_t ZEXPORT gzfread(buf, size, nitems, file) | 377 z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { |
412 voidp buf; | |
413 z_size_t size; | |
414 z_size_t nitems; | |
415 gzFile file; | |
416 { | |
417 z_size_t len; | 378 z_size_t len; |
418 gz_statep state; | 379 gz_statep state; |
419 | 380 |
420 /* get internal structure */ | 381 /* get internal structure */ |
421 if (file == NULL) | 382 if (file == NULL) |
442 #ifdef Z_PREFIX_SET | 403 #ifdef Z_PREFIX_SET |
443 # undef z_gzgetc | 404 # undef z_gzgetc |
444 #else | 405 #else |
445 # undef gzgetc | 406 # undef gzgetc |
446 #endif | 407 #endif |
447 int ZEXPORT gzgetc(file) | 408 int ZEXPORT gzgetc(gzFile file) { |
448 gzFile file; | |
449 { | |
450 int ret; | |
451 unsigned char buf[1]; | 409 unsigned char buf[1]; |
452 gz_statep state; | 410 gz_statep state; |
453 | 411 |
454 /* get internal structure */ | 412 /* get internal structure */ |
455 if (file == NULL) | 413 if (file == NULL) |
467 state->x.pos++; | 425 state->x.pos++; |
468 return *(state->x.next)++; | 426 return *(state->x.next)++; |
469 } | 427 } |
470 | 428 |
471 /* nothing there -- try gz_read() */ | 429 /* nothing there -- try gz_read() */ |
472 ret = gz_read(state, buf, 1); | 430 return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; |
473 return ret < 1 ? -1 : buf[0]; | 431 } |
474 } | 432 |
475 | 433 int ZEXPORT gzgetc_(gzFile file) { |
476 int ZEXPORT gzgetc_(file) | |
477 gzFile file; | |
478 { | |
479 return gzgetc(file); | 434 return gzgetc(file); |
480 } | 435 } |
481 | 436 |
482 /* -- see zlib.h -- */ | 437 /* -- see zlib.h -- */ |
483 int ZEXPORT gzungetc(c, file) | 438 int ZEXPORT gzungetc(int c, gzFile file) { |
484 int c; | |
485 gzFile file; | |
486 { | |
487 gz_statep state; | 439 gz_statep state; |
488 | 440 |
489 /* get internal structure */ | 441 /* get internal structure */ |
490 if (file == NULL) | 442 if (file == NULL) |
491 return -1; | 443 return -1; |
492 state = (gz_statep)file; | 444 state = (gz_statep)file; |
445 | |
446 /* in case this was just opened, set up the input buffer */ | |
447 if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) | |
448 (void)gz_look(state); | |
493 | 449 |
494 /* check that we're reading and that there's no (serious) error */ | 450 /* check that we're reading and that there's no (serious) error */ |
495 if (state->mode != GZ_READ || | 451 if (state->mode != GZ_READ || |
496 (state->err != Z_OK && state->err != Z_BUF_ERROR)) | 452 (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
497 return -1; | 453 return -1; |
538 state->past = 0; | 494 state->past = 0; |
539 return c; | 495 return c; |
540 } | 496 } |
541 | 497 |
542 /* -- see zlib.h -- */ | 498 /* -- see zlib.h -- */ |
543 char * ZEXPORT gzgets(file, buf, len) | 499 char * ZEXPORT gzgets(gzFile file, char *buf, int len) { |
544 gzFile file; | |
545 char *buf; | |
546 int len; | |
547 { | |
548 unsigned left, n; | 500 unsigned left, n; |
549 char *str; | 501 char *str; |
550 unsigned char *eol; | 502 unsigned char *eol; |
551 gz_statep state; | 503 gz_statep state; |
552 | 504 |
602 buf[0] = 0; | 554 buf[0] = 0; |
603 return str; | 555 return str; |
604 } | 556 } |
605 | 557 |
606 /* -- see zlib.h -- */ | 558 /* -- see zlib.h -- */ |
607 int ZEXPORT gzdirect(file) | 559 int ZEXPORT gzdirect(gzFile file) { |
608 gzFile file; | |
609 { | |
610 gz_statep state; | 560 gz_statep state; |
611 | 561 |
612 /* get internal structure */ | 562 /* get internal structure */ |
613 if (file == NULL) | 563 if (file == NULL) |
614 return 0; | 564 return 0; |
622 /* return 1 if transparent, 0 if processing a gzip stream */ | 572 /* return 1 if transparent, 0 if processing a gzip stream */ |
623 return state->direct; | 573 return state->direct; |
624 } | 574 } |
625 | 575 |
626 /* -- see zlib.h -- */ | 576 /* -- see zlib.h -- */ |
627 int ZEXPORT gzclose_r(file) | 577 int ZEXPORT gzclose_r(gzFile file) { |
628 gzFile file; | |
629 { | |
630 int ret, err; | 578 int ret, err; |
631 gz_statep state; | 579 gz_statep state; |
632 | 580 |
633 /* get internal structure */ | 581 /* get internal structure */ |
634 if (file == NULL) | 582 if (file == NULL) |