-- see zlib.h -- */
(c, file)
| 505 | |
| 506 | /* -- see zlib.h -- */ |
| 507 | int ZEXPORT gzungetc(c, file) |
| 508 | int c; |
| 509 | gzFile file; |
| 510 | { |
| 511 | gz_statep state; |
| 512 | |
| 513 | /* get internal structure */ |
| 514 | if (file == NULL) |
| 515 | return -1; |
| 516 | state.file = file; |
| 517 | |
| 518 | /* check that we're reading and that there's no (serious) error */ |
| 519 | if (state.state->mode != GZ_READ || |
| 520 | (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)) |
| 521 | return -1; |
| 522 | |
| 523 | /* process a skip request */ |
| 524 | if (state.state->seek) { |
| 525 | state.state->seek = 0; |
| 526 | if (gz_skip(state, state.state->skip) == -1) |
| 527 | return -1; |
| 528 | } |
| 529 | |
| 530 | /* can't push EOF */ |
| 531 | if (c < 0) |
| 532 | return -1; |
| 533 | |
| 534 | /* if output buffer empty, put byte at end (allows more pushing) */ |
| 535 | if (state.state->x.have == 0) { |
| 536 | state.state->x.have = 1; |
| 537 | state.state->x.next = state.state->out + (state.state->size << 1) - 1; |
| 538 | state.state->x.next[0] = (unsigned char)c; |
| 539 | state.state->x.pos--; |
| 540 | state.state->past = 0; |
| 541 | return c; |
| 542 | } |
| 543 | |
| 544 | /* if no room, give up (must have already done a gzungetc()) */ |
| 545 | if (state.state->x.have == (state.state->size << 1)) { |
| 546 | gz_error(state, Z_DATA_ERROR, "out of room to push characters"); |
| 547 | return -1; |
| 548 | } |
| 549 | |
| 550 | /* slide output data if needed and insert byte before existing data */ |
| 551 | if (state.state->x.next == state.state->out) { |
| 552 | unsigned char *src = state.state->out + state.state->x.have; |
| 553 | unsigned char *dest = state.state->out + (state.state->size << 1); |
| 554 | while (src > state.state->out) |
| 555 | *--dest = *--src; |
| 556 | state.state->x.next = dest; |
| 557 | } |
| 558 | state.state->x.have++; |
| 559 | state.state->x.next--; |
| 560 | state.state->x.next[0] = (unsigned char)c; |
| 561 | state.state->x.pos--; |
| 562 | state.state->past = 0; |
| 563 | return c; |
| 564 | } |