-- see zlib.h -- */
(file, offset, whence)
| 367 | |
| 368 | /* -- see zlib.h -- */ |
| 369 | z_off64_t ZEXPORT gzseek64(file, offset, whence) |
| 370 | gzFile file; |
| 371 | z_off64_t offset; |
| 372 | int whence; |
| 373 | { |
| 374 | unsigned n; |
| 375 | z_off64_t ret; |
| 376 | gz_statep state; |
| 377 | |
| 378 | /* get internal structure and check integrity */ |
| 379 | if (file == NULL) |
| 380 | return -1; |
| 381 | state.file = file; |
| 382 | if (state.state->mode != GZ_READ && state.state->mode != GZ_WRITE) |
| 383 | return -1; |
| 384 | |
| 385 | /* check that there's no error */ |
| 386 | if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR) |
| 387 | return -1; |
| 388 | |
| 389 | /* can only seek from start or relative to current position */ |
| 390 | if (whence != SEEK_SET && whence != SEEK_CUR) |
| 391 | return -1; |
| 392 | |
| 393 | /* normalize offset to a SEEK_CUR specification */ |
| 394 | if (whence == SEEK_SET) |
| 395 | offset -= state.state->x.pos; |
| 396 | else if (state.state->seek) |
| 397 | offset += state.state->skip; |
| 398 | state.state->seek = 0; |
| 399 | |
| 400 | /* if within raw area while reading, just go there */ |
| 401 | if (state.state->mode == GZ_READ && state.state->how == COPY && |
| 402 | state.state->x.pos + offset >= 0) { |
| 403 | ret = LSEEK(state.state->fd, offset - state.state->x.have, SEEK_CUR); |
| 404 | if (ret == -1) |
| 405 | return -1; |
| 406 | state.state->x.have = 0; |
| 407 | state.state->eof = 0; |
| 408 | state.state->past = 0; |
| 409 | state.state->seek = 0; |
| 410 | gz_error(state, Z_OK, NULL); |
| 411 | state.state->strm.avail_in = 0; |
| 412 | state.state->x.pos += offset; |
| 413 | return state.state->x.pos; |
| 414 | } |
| 415 | |
| 416 | /* calculate skip amount, rewinding if needed for back seek when reading */ |
| 417 | if (offset < 0) { |
| 418 | if (state.state->mode != GZ_READ) /* writing -- can't go backwards */ |
| 419 | return -1; |
| 420 | offset += state.state->x.pos; |
| 421 | if (offset < 0) /* before start of file! */ |
| 422 | return -1; |
| 423 | if (gzrewind(file) == -1) /* rewind, then skip to offset */ |
| 424 | return -1; |
| 425 | } |
| 426 |