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)