aboutsummaryrefslogtreecommitdiff
path: root/gzread.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2025-02-21 14:22:16 -0800
committerMark Adler <madler@alumni.caltech.edu>2025-02-25 00:31:37 -0800
commita4e4521ee1303b756a8f96c18cdf4729327b687d (patch)
tree6f2e178d078a420fe9731976944874cbaf10f438 /gzread.c
parentaa27ba467717707881e4ae925849e6229ceabf38 (diff)
downloadzlib-a4e4521ee1303b756a8f96c18cdf4729327b687d.tar.gz
zlib-a4e4521ee1303b756a8f96c18cdf4729327b687d.tar.bz2
zlib-a4e4521ee1303b756a8f96c18cdf4729327b687d.zip
Have gz_skip() update how far it got for later continuation.
This also simplifies seek processing in general.
Diffstat (limited to 'gzread.c')
-rw-r--r--gzread.c36
1 files changed, 15 insertions, 21 deletions
diff --git a/gzread.c b/gzread.c
index d2ab6b17..5edecbfc 100644
--- a/gzread.c
+++ b/gzread.c
@@ -234,20 +234,22 @@ local int gz_fetch(gz_statep state) {
234 return 0; 234 return 0;
235} 235}
236 236
237/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ 237/* Skip state->skip (> 0) uncompressed bytes of output. Return -1 on error, 0
238local int gz_skip(gz_statep state, z_off64_t len) { 238 on success. */
239local int gz_skip(gz_statep state) {
239 unsigned n; 240 unsigned n;
240 241
241 /* skip over len bytes or reach end-of-file, whichever comes first */ 242 /* skip over len bytes or reach end-of-file, whichever comes first */
242 while (len) 243 do {
243 /* skip over whatever is in output buffer */ 244 /* skip over whatever is in output buffer */
244 if (state->x.have) { 245 if (state->x.have) {
245 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? 246 n = GT_OFF(state->x.have) ||
246 (unsigned)len : state->x.have; 247 (z_off64_t)state->x.have > state->skip ?
248 (unsigned)state->skip : state->x.have;
247 state->x.have -= n; 249 state->x.have -= n;
248 state->x.next += n; 250 state->x.next += n;
249 state->x.pos += n; 251 state->x.pos += n;
250 len -= n; 252 state->skip -= n;
251 } 253 }
252 254
253 /* output buffer empty -- return if we're at the end of the input */ 255 /* output buffer empty -- return if we're at the end of the input */
@@ -260,6 +262,7 @@ local int gz_skip(gz_statep state, z_off64_t len) {
260 if (gz_fetch(state) == -1) 262 if (gz_fetch(state) == -1)
261 return -1; 263 return -1;
262 } 264 }
265 } while (state->skip);
263 return 0; 266 return 0;
264} 267}
265 268
@@ -276,11 +279,8 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
276 return 0; 279 return 0;
277 280
278 /* process a skip request */ 281 /* process a skip request */
279 if (state->seek) { 282 if (state->skip && gz_skip(state) == -1)
280 state->seek = 0; 283 return 0;
281 if (gz_skip(state, state->skip) == -1)
282 return 0;
283 }
284 284
285 /* get len bytes to buf, or less than len if at the end */ 285 /* get len bytes to buf, or less than len if at the end */
286 got = 0; 286 got = 0;
@@ -456,11 +456,8 @@ int ZEXPORT gzungetc(int c, gzFile file) {
456 return -1; 456 return -1;
457 457
458 /* process a skip request */ 458 /* process a skip request */
459 if (state->seek) { 459 if (state->skip && gz_skip(state) == -1)
460 state->seek = 0; 460 return -1;
461 if (gz_skip(state, state->skip) == -1)
462 return -1;
463 }
464 461
465 /* can't push EOF */ 462 /* can't push EOF */
466 if (c < 0) 463 if (c < 0)
@@ -516,11 +513,8 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
516 return NULL; 513 return NULL;
517 514
518 /* process a skip request */ 515 /* process a skip request */
519 if (state->seek) { 516 if (state->skip && gz_skip(state) == -1)
520 state->seek = 0; 517 return NULL;
521 if (gz_skip(state, state->skip) == -1)
522 return NULL;
523 }
524 518
525 /* copy output bytes up to new line or len - 1, whichever comes first -- 519 /* copy output bytes up to new line or len - 1, whichever comes first --
526 append a terminating zero to the string (we don't check for a zero in 520 append a terminating zero to the string (we don't check for a zero in