aboutsummaryrefslogtreecommitdiff
path: root/gzread.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-26 22:50:28 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-26 22:50:28 -0700
commitacfc85772a811f4c0efec835a3087b53f83f6079 (patch)
treefda6596291da38d9d3c8eaf5c521413b2b32fcd8 /gzread.c
parent8e0d212910a42b3f856bbaebed970e8ddc081ca3 (diff)
downloadzlib-acfc85772a811f4c0efec835a3087b53f83f6079.tar.gz
zlib-acfc85772a811f4c0efec835a3087b53f83f6079.tar.bz2
zlib-acfc85772a811f4c0efec835a3087b53f83f6079.zip
Change gzgetc() to a macro for speed (~40% speedup in testing).
Diffstat (limited to 'gzread.c')
-rw-r--r--gzread.c119
1 files changed, 61 insertions, 58 deletions
diff --git a/gzread.c b/gzread.c
index a41e5d9..22eb627 100644
--- a/gzread.c
+++ b/gzread.c
@@ -68,7 +68,7 @@ local int gz_avail(state)
68 return 0; 68 return 0;
69} 69}
70 70
71/* Look for gzip header, set up for inflate or copy. state->have must be zero. 71/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
72 If this is the first time in, allocate required memory. state->how will be 72 If this is the first time in, allocate required memory. state->how will be
73 left unchanged if there is no more input data available, will be set to COPY 73 left unchanged if there is no more input data available, will be set to COPY
74 if there is no gzip header and direct copying will be performed, or it will 74 if there is no gzip header and direct copying will be performed, or it will
@@ -140,17 +140,17 @@ local int gz_look(state)
140 if (state->direct == 0) { 140 if (state->direct == 0) {
141 strm->avail_in = 0; 141 strm->avail_in = 0;
142 state->eof = 1; 142 state->eof = 1;
143 state->have = 0; 143 state->x.have = 0;
144 return 0; 144 return 0;
145 } 145 }
146 146
147 /* doing raw i/o, copy any leftover input to output -- this assumes that 147 /* doing raw i/o, copy any leftover input to output -- this assumes that
148 the output buffer is larger than the input buffer, which also assures 148 the output buffer is larger than the input buffer, which also assures
149 space for gzungetc() */ 149 space for gzungetc() */
150 state->next = state->out; 150 state->x.next = state->out;
151 if (strm->avail_in) { 151 if (strm->avail_in) {
152 memcpy(state->next, strm->next_in, strm->avail_in); 152 memcpy(state->x.next, strm->next_in, strm->avail_in);
153 state->have = strm->avail_in; 153 state->x.have = strm->avail_in;
154 strm->avail_in = 0; 154 strm->avail_in = 0;
155 } 155 }
156 state->how = COPY; 156 state->how = COPY;
@@ -159,10 +159,10 @@ local int gz_look(state)
159} 159}
160 160
161/* Decompress from input to the provided next_out and avail_out in the state. 161/* Decompress from input to the provided next_out and avail_out in the state.
162 state->have and state->next are set to point to the just decompressed data, 162 On return, state->x.have and state->x.next point to the just decompressed
163 If the gzip stream completes, state->how is reset to LOOK to look for the 163 data. If the gzip stream completes, state->how is reset to LOOK to look for
164 next gzip stream or raw data, once state->have is depleted. Returns 0 on 164 the next gzip stream or raw data, once state->x.have is depleted. Returns 0
165 success, -1 on failure. */ 165 on success, -1 on failure. */
166local int gz_decomp(state) 166local int gz_decomp(state)
167 gz_statep state; 167 gz_statep state;
168{ 168{
@@ -200,8 +200,8 @@ local int gz_decomp(state)
200 } while (strm->avail_out && ret != Z_STREAM_END); 200 } while (strm->avail_out && ret != Z_STREAM_END);
201 201
202 /* update available output */ 202 /* update available output */
203 state->have = had - strm->avail_out; 203 state->x.have = had - strm->avail_out;
204 state->next = strm->next_out - state->have; 204 state->x.next = strm->next_out - state->x.have;
205 205
206 /* if the gzip stream completed successfully, look for another */ 206 /* if the gzip stream completed successfully, look for another */
207 if (ret == Z_STREAM_END) 207 if (ret == Z_STREAM_END)
@@ -211,7 +211,7 @@ local int gz_decomp(state)
211 return 0; 211 return 0;
212} 212}
213 213
214/* Fetch data and put it in the output buffer. Assumes that state->have == 0. 214/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
215 Data is either copied from the input file or decompressed from the input 215 Data is either copied from the input file or decompressed from the input
216 file depending on state->how. If state->how is LOOK, then a gzip header is 216 file depending on state->how. If state->how is LOOK, then a gzip header is
217 looked for to determine whether to copy or decompress. Returns -1 on error, 217 looked for to determine whether to copy or decompress. Returns -1 on error,
@@ -231,10 +231,10 @@ local int gz_fetch(state)
231 return 0; 231 return 0;
232 break; 232 break;
233 case COPY: /* -> COPY */ 233 case COPY: /* -> COPY */
234 if (gz_load(state, state->out, state->size << 1, &(state->have)) 234 if (gz_load(state, state->out, state->size << 1, &(state->x.have))
235 == -1) 235 == -1)
236 return -1; 236 return -1;
237 state->next = state->out; 237 state->x.next = state->out;
238 return 0; 238 return 0;
239 case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ 239 case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
240 strm->avail_out = state->size << 1; 240 strm->avail_out = state->size << 1;
@@ -242,7 +242,7 @@ local int gz_fetch(state)
242 if (gz_decomp(state) == -1) 242 if (gz_decomp(state) == -1)
243 return -1; 243 return -1;
244 } 244 }
245 } while (state->have == 0); 245 } while (state->x.have == 0);
246 return 0; 246 return 0;
247} 247}
248 248
@@ -256,12 +256,12 @@ local int gz_skip(state, len)
256 /* skip over len bytes or reach end-of-file, whichever comes first */ 256 /* skip over len bytes or reach end-of-file, whichever comes first */
257 while (len) 257 while (len)
258 /* skip over whatever is in output buffer */ 258 /* skip over whatever is in output buffer */
259 if (state->have) { 259 if (state->x.have) {
260 n = GT_OFF(state->have) || (z_off64_t)state->have > len ? 260 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
261 (unsigned)len : state->have; 261 (unsigned)len : state->x.have;
262 state->have -= n; 262 state->x.have -= n;
263 state->next += n; 263 state->x.next += n;
264 state->pos += n; 264 state->x.pos += n;
265 len -= n; 265 len -= n;
266 } 266 }
267 267
@@ -321,11 +321,11 @@ int ZEXPORT gzread(file, buf, len)
321 got = 0; 321 got = 0;
322 do { 322 do {
323 /* first just try copying data from the output buffer */ 323 /* first just try copying data from the output buffer */
324 if (state->have) { 324 if (state->x.have) {
325 n = state->have > len ? len : state->have; 325 n = state->x.have > len ? len : state->x.have;
326 memcpy(buf, state->next, n); 326 memcpy(buf, state->x.next, n);
327 state->next += n; 327 state->x.next += n;
328 state->have -= n; 328 state->x.have -= n;
329 } 329 }
330 330
331 /* output buffer empty -- return if we're at the end of the input */ 331 /* output buffer empty -- return if we're at the end of the input */
@@ -355,15 +355,15 @@ int ZEXPORT gzread(file, buf, len)
355 strm->next_out = buf; 355 strm->next_out = buf;
356 if (gz_decomp(state) == -1) 356 if (gz_decomp(state) == -1)
357 return -1; 357 return -1;
358 n = state->have; 358 n = state->x.have;
359 state->have = 0; 359 state->x.have = 0;
360 } 360 }
361 361
362 /* update progress */ 362 /* update progress */
363 len -= n; 363 len -= n;
364 buf = (char *)buf + n; 364 buf = (char *)buf + n;
365 got += n; 365 got += n;
366 state->pos += n; 366 state->x.pos += n;
367 } while (len); 367 } while (len);
368 368
369 /* return number of bytes read into user buffer (will fit in int) */ 369 /* return number of bytes read into user buffer (will fit in int) */
@@ -371,7 +371,7 @@ int ZEXPORT gzread(file, buf, len)
371} 371}
372 372
373/* -- see zlib.h -- */ 373/* -- see zlib.h -- */
374int ZEXPORT gzgetc(file) 374int ZEXPORT gzgetc_(file)
375 gzFile file; 375 gzFile file;
376{ 376{
377 int ret; 377 int ret;
@@ -388,11 +388,14 @@ int ZEXPORT gzgetc(file)
388 (state->err != Z_OK && state->err != Z_BUF_ERROR)) 388 (state->err != Z_OK && state->err != Z_BUF_ERROR))
389 return -1; 389 return -1;
390 390
391 /* try output buffer (no need to check for skip request) */ 391 /* try output buffer (no need to check for skip request) -- while
392 if (state->have) { 392 this check really isn't required since the gzgetc() macro has
393 state->have--; 393 already determined that x.have is zero, we leave it in for
394 state->pos++; 394 completeness. */
395 return *(state->next)++; 395 if (state->x.have) {
396 state->x.have--;
397 state->x.pos++;
398 return *(state->x.next)++;
396 } 399 }
397 400
398 /* nothing there -- try gzread() */ 401 /* nothing there -- try gzread() */
@@ -429,32 +432,32 @@ int ZEXPORT gzungetc(c, file)
429 return -1; 432 return -1;
430 433
431 /* if output buffer empty, put byte at end (allows more pushing) */ 434 /* if output buffer empty, put byte at end (allows more pushing) */
432 if (state->have == 0) { 435 if (state->x.have == 0) {
433 state->have = 1; 436 state->x.have = 1;
434 state->next = state->out + (state->size << 1) - 1; 437 state->x.next = state->out + (state->size << 1) - 1;
435 state->next[0] = c; 438 state->x.next[0] = c;
436 state->pos--; 439 state->x.pos--;
437 return c; 440 return c;
438 } 441 }
439 442
440 /* if no room, give up (must have already done a gzungetc()) */ 443 /* if no room, give up (must have already done a gzungetc()) */
441 if (state->have == (state->size << 1)) { 444 if (state->x.have == (state->size << 1)) {
442 gz_error(state, Z_BUF_ERROR, "out of room to push characters"); 445 gz_error(state, Z_BUF_ERROR, "out of room to push characters");
443 return -1; 446 return -1;
444 } 447 }
445 448
446 /* slide output data if needed and insert byte before existing data */ 449 /* slide output data if needed and insert byte before existing data */
447 if (state->next == state->out) { 450 if (state->x.next == state->out) {
448 unsigned char *src = state->out + state->have; 451 unsigned char *src = state->out + state->x.have;
449 unsigned char *dest = state->out + (state->size << 1); 452 unsigned char *dest = state->out + (state->size << 1);
450 while (src > state->out) 453 while (src > state->out)
451 *--dest = *--src; 454 *--dest = *--src;
452 state->next = dest; 455 state->x.next = dest;
453 } 456 }
454 state->have++; 457 state->x.have++;
455 state->next--; 458 state->x.next--;
456 state->next[0] = c; 459 state->x.next[0] = c;
457 state->pos--; 460 state->x.pos--;
458 return c; 461 return c;
459} 462}
460 463
@@ -493,25 +496,25 @@ char * ZEXPORT gzgets(file, buf, len)
493 left = (unsigned)len - 1; 496 left = (unsigned)len - 1;
494 if (left) do { 497 if (left) do {
495 /* assure that something is in the output buffer */ 498 /* assure that something is in the output buffer */
496 if (state->have == 0 && gz_fetch(state) == -1) 499 if (state->x.have == 0 && gz_fetch(state) == -1)
497 return NULL; /* error */ 500 return NULL; /* error */
498 if (state->have == 0) { /* end of file */ 501 if (state->x.have == 0) { /* end of file */
499 if (buf == str) /* got bupkus */ 502 if (buf == str) /* got bupkus */
500 return NULL; 503 return NULL;
501 break; /* got something -- return it */ 504 break; /* got something -- return it */
502 } 505 }
503 506
504 /* look for end-of-line in current output buffer */ 507 /* look for end-of-line in current output buffer */
505 n = state->have > left ? left : state->have; 508 n = state->x.have > left ? left : state->x.have;
506 eol = memchr(state->next, '\n', n); 509 eol = memchr(state->x.next, '\n', n);
507 if (eol != NULL) 510 if (eol != NULL)
508 n = (unsigned)(eol - state->next) + 1; 511 n = (unsigned)(eol - state->x.next) + 1;
509 512
510 /* copy through end-of-line, or remainder if not found */ 513 /* copy through end-of-line, or remainder if not found */
511 memcpy(buf, state->next, n); 514 memcpy(buf, state->x.next, n);
512 state->have -= n; 515 state->x.have -= n;
513 state->next += n; 516 state->x.next += n;
514 state->pos += n; 517 state->x.pos += n;
515 left -= n; 518 left -= n;
516 buf += n; 519 buf += n;
517 } while (left && eol == NULL); 520 } while (left && eol == NULL);
@@ -538,7 +541,7 @@ int ZEXPORT gzdirect(file)
538 541
539 /* if the state is not known, but we can find out, then do so (this is 542 /* if the state is not known, but we can find out, then do so (this is
540 mainly for right after a gzopen() or gzdopen()) */ 543 mainly for right after a gzopen() or gzdopen()) */
541 if (state->how == LOOK && state->have == 0) 544 if (state->how == LOOK && state->x.have == 0)
542 (void)gz_look(state); 545 (void)gz_look(state);
543 546
544 /* return 1 if reading direct, 0 if decompressing a gzip stream */ 547 /* return 1 if reading direct, 0 if decompressing a gzip stream */