-- see zlib.h -- */
| 497 | |
| 498 | /* -- see zlib.h -- */ |
| 499 | char * ZEXPORT gzgets(gzFile file, char *buf, int len) { |
| 500 | unsigned left, n; |
| 501 | char *str; |
| 502 | unsigned char *eol; |
| 503 | gz_statep state; |
| 504 | |
| 505 | /* check parameters and get internal structure */ |
| 506 | if (file == NULL || buf == NULL || len < 1) |
| 507 | return NULL; |
| 508 | state = (gz_statep)file; |
| 509 | |
| 510 | /* check that we're reading and that there's no (serious) error */ |
| 511 | if (state->mode != GZ_READ || |
| 512 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
| 513 | return NULL; |
| 514 | |
| 515 | /* process a skip request */ |
| 516 | if (state->seek) { |
| 517 | state->seek = 0; |
| 518 | if (gz_skip(state, state->skip) == -1) |
| 519 | return NULL; |
| 520 | } |
| 521 | |
| 522 | /* copy output bytes up to new line or len - 1, whichever comes first -- |
| 523 | append a terminating zero to the string (we don't check for a zero in |
| 524 | the contents, let the user worry about that) */ |
| 525 | str = buf; |
| 526 | left = (unsigned)len - 1; |
| 527 | if (left) do { |
| 528 | /* assure that something is in the output buffer */ |
| 529 | if (state->x.have == 0 && gz_fetch(state) == -1) |
| 530 | return NULL; /* error */ |
| 531 | if (state->x.have == 0) { /* end of file */ |
| 532 | state->past = 1; /* read past end */ |
| 533 | break; /* return what we have */ |
| 534 | } |
| 535 | |
| 536 | /* look for end-of-line in current output buffer */ |
| 537 | n = state->x.have > left ? left : state->x.have; |
| 538 | eol = (unsigned char *)memchr(state->x.next, '\n', n); |
| 539 | if (eol != NULL) |
| 540 | n = (unsigned)(eol - state->x.next) + 1; |
| 541 | |
| 542 | /* copy through end-of-line, or remainder if not found */ |
| 543 | memcpy(buf, state->x.next, n); |
| 544 | state->x.have -= n; |
| 545 | state->x.next += n; |
| 546 | state->x.pos += n; |
| 547 | left -= n; |
| 548 | buf += n; |
| 549 | } while (left && eol == NULL); |
| 550 | |
| 551 | /* return terminated string, or if nothing, end of file */ |
| 552 | if (buf == str) |
| 553 | return NULL; |
| 554 | buf[0] = 0; |
| 555 | return str; |
| 556 | } |