|
|
| version 1.1.1.1, 2012/02/21 16:23:02 | version 1.1.1.2, 2013/07/22 10:46:14 |
|---|---|
| Line 1 | Line 1 |
| /* gzlib.c -- zlib functions common to reading and writing gzip files | /* gzlib.c -- zlib functions common to reading and writing gzip files |
| * Copyright (C) 2004, 2010 Mark Adler | * Copyright (C) 2004, 2010, 2011 Mark Adler |
| * For conditions of distribution and use, see copyright notice in zlib.h | * For conditions of distribution and use, see copyright notice in zlib.h |
| */ | */ |
| #include "gzguts.h" | #include "gzguts.h" |
| #if defined(_WIN32) && !defined(__BORLANDC__) | |
| # define LSEEK _lseeki64 | |
| #else | |
| #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 | #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 |
| # define LSEEK lseek64 | # define LSEEK lseek64 |
| #else | #else |
| # define LSEEK lseek | # define LSEEK lseek |
| #endif | #endif |
| #endif | |
| /* Local functions */ | /* Local functions */ |
| local void gz_reset OF((gz_statep)); | local void gz_reset OF((gz_statep)); |
| Line 71 char ZLIB_INTERNAL *gz_strwinerror (error) | Line 75 char ZLIB_INTERNAL *gz_strwinerror (error) |
| local void gz_reset(state) | local void gz_reset(state) |
| gz_statep state; | gz_statep state; |
| { | { |
| state->x.have = 0; /* no output data available */ | |
| if (state->mode == GZ_READ) { /* for reading ... */ | if (state->mode == GZ_READ) { /* for reading ... */ |
| state->have = 0; /* no output data available */ | |
| state->eof = 0; /* not at end of file */ | state->eof = 0; /* not at end of file */ |
| state->past = 0; /* have not read past end yet */ | |
| state->how = LOOK; /* look for gzip header */ | state->how = LOOK; /* look for gzip header */ |
| state->direct = 1; /* default for empty file */ | |
| } | } |
| state->seek = 0; /* no seek request pending */ | state->seek = 0; /* no seek request pending */ |
| gz_error(state, Z_OK, NULL); /* clear error */ | gz_error(state, Z_OK, NULL); /* clear error */ |
| state->pos = 0; /* no uncompressed data yet */ | state->x.pos = 0; /* no uncompressed data yet */ |
| state->strm.avail_in = 0; /* no input data yet */ | state->strm.avail_in = 0; /* no input data yet */ |
| } | } |
| Line 91 local gzFile gz_open(path, fd, mode) | Line 95 local gzFile gz_open(path, fd, mode) |
| { | { |
| gz_statep state; | gz_statep state; |
| /* check input */ | |
| if (path == NULL) | |
| return NULL; | |
| /* allocate gzFile structure to return */ | /* allocate gzFile structure to return */ |
| state = malloc(sizeof(gz_state)); | state = malloc(sizeof(gz_state)); |
| if (state == NULL) | if (state == NULL) |
| Line 103 local gzFile gz_open(path, fd, mode) | Line 111 local gzFile gz_open(path, fd, mode) |
| state->mode = GZ_NONE; | state->mode = GZ_NONE; |
| state->level = Z_DEFAULT_COMPRESSION; | state->level = Z_DEFAULT_COMPRESSION; |
| state->strategy = Z_DEFAULT_STRATEGY; | state->strategy = Z_DEFAULT_STRATEGY; |
| state->direct = 0; | |
| while (*mode) { | while (*mode) { |
| if (*mode >= '0' && *mode <= '9') | if (*mode >= '0' && *mode <= '9') |
| state->level = *mode - '0'; | state->level = *mode - '0'; |
| Line 135 local gzFile gz_open(path, fd, mode) | Line 144 local gzFile gz_open(path, fd, mode) |
| break; | break; |
| case 'F': | case 'F': |
| state->strategy = Z_FIXED; | state->strategy = Z_FIXED; |
| case 'T': | |
| state->direct = 1; | |
| default: /* could consider as an error, but just ignore */ | default: /* could consider as an error, but just ignore */ |
| ; | ; |
| } | } |
| Line 147 local gzFile gz_open(path, fd, mode) | Line 158 local gzFile gz_open(path, fd, mode) |
| return NULL; | return NULL; |
| } | } |
| /* can't force transparent read */ | |
| if (state->mode == GZ_READ) { | |
| if (state->direct) { | |
| free(state); | |
| return NULL; | |
| } | |
| state->direct = 1; /* for empty file */ | |
| } | |
| /* save the path name for error messages */ | /* save the path name for error messages */ |
| state->path = malloc(strlen(path) + 1); | state->path = malloc(strlen(path) + 1); |
| if (state->path == NULL) { | if (state->path == NULL) { |
| Line 243 int ZEXPORT gzbuffer(file, size) | Line 263 int ZEXPORT gzbuffer(file, size) |
| return -1; | return -1; |
| /* check and set requested size */ | /* check and set requested size */ |
| if (size == 0) | if (size < 2) |
| return -1; | size = 2; /* need two bytes to check magic header */ |
| state->want = size; | state->want = size; |
| return 0; | return 0; |
| } | } |
| Line 261 int ZEXPORT gzrewind(file) | Line 281 int ZEXPORT gzrewind(file) |
| state = (gz_statep)file; | state = (gz_statep)file; |
| /* check that we're reading and that there's no error */ | /* check that we're reading and that there's no error */ |
| if (state->mode != GZ_READ || state->err != Z_OK) | if (state->mode != GZ_READ || |
| (state->err != Z_OK && state->err != Z_BUF_ERROR)) | |
| return -1; | return -1; |
| /* back up and start over */ | /* back up and start over */ |
| Line 289 z_off64_t ZEXPORT gzseek64(file, offset, whence) | Line 310 z_off64_t ZEXPORT gzseek64(file, offset, whence) |
| return -1; | return -1; |
| /* check that there's no error */ | /* check that there's no error */ |
| if (state->err != Z_OK) | if (state->err != Z_OK && state->err != Z_BUF_ERROR) |
| return -1; | return -1; |
| /* can only seek from start or relative to current position */ | /* can only seek from start or relative to current position */ |
| Line 298 z_off64_t ZEXPORT gzseek64(file, offset, whence) | Line 319 z_off64_t ZEXPORT gzseek64(file, offset, whence) |
| /* normalize offset to a SEEK_CUR specification */ | /* normalize offset to a SEEK_CUR specification */ |
| if (whence == SEEK_SET) | if (whence == SEEK_SET) |
| offset -= state->pos; | offset -= state->x.pos; |
| else if (state->seek) | else if (state->seek) |
| offset += state->skip; | offset += state->skip; |
| state->seek = 0; | state->seek = 0; |
| /* if within raw area while reading, just go there */ | /* if within raw area while reading, just go there */ |
| if (state->mode == GZ_READ && state->how == COPY && | if (state->mode == GZ_READ && state->how == COPY && |
| state->pos + offset >= state->raw) { | state->x.pos + offset >= 0) { |
| ret = LSEEK(state->fd, offset - state->have, SEEK_CUR); | ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); |
| if (ret == -1) | if (ret == -1) |
| return -1; | return -1; |
| state->have = 0; | state->x.have = 0; |
| state->eof = 0; | state->eof = 0; |
| state->past = 0; | |
| state->seek = 0; | state->seek = 0; |
| gz_error(state, Z_OK, NULL); | gz_error(state, Z_OK, NULL); |
| state->strm.avail_in = 0; | state->strm.avail_in = 0; |
| state->pos += offset; | state->x.pos += offset; |
| return state->pos; | return state->x.pos; |
| } | } |
| /* calculate skip amount, rewinding if needed for back seek when reading */ | /* calculate skip amount, rewinding if needed for back seek when reading */ |
| if (offset < 0) { | if (offset < 0) { |
| if (state->mode != GZ_READ) /* writing -- can't go backwards */ | if (state->mode != GZ_READ) /* writing -- can't go backwards */ |
| return -1; | return -1; |
| offset += state->pos; | offset += state->x.pos; |
| if (offset < 0) /* before start of file! */ | if (offset < 0) /* before start of file! */ |
| return -1; | return -1; |
| if (gzrewind(file) == -1) /* rewind, then skip to offset */ | if (gzrewind(file) == -1) /* rewind, then skip to offset */ |
| Line 331 z_off64_t ZEXPORT gzseek64(file, offset, whence) | Line 353 z_off64_t ZEXPORT gzseek64(file, offset, whence) |
| /* if reading, skip what's in output buffer (one less gzgetc() check) */ | /* if reading, skip what's in output buffer (one less gzgetc() check) */ |
| if (state->mode == GZ_READ) { | if (state->mode == GZ_READ) { |
| n = GT_OFF(state->have) || (z_off64_t)state->have > offset ? | n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? |
| (unsigned)offset : state->have; | (unsigned)offset : state->x.have; |
| state->have -= n; | state->x.have -= n; |
| state->next += n; | state->x.next += n; |
| state->pos += n; | state->x.pos += n; |
| offset -= n; | offset -= n; |
| } | } |
| Line 344 z_off64_t ZEXPORT gzseek64(file, offset, whence) | Line 366 z_off64_t ZEXPORT gzseek64(file, offset, whence) |
| state->seek = 1; | state->seek = 1; |
| state->skip = offset; | state->skip = offset; |
| } | } |
| return state->pos + offset; | return state->x.pos + offset; |
| } | } |
| /* -- see zlib.h -- */ | /* -- see zlib.h -- */ |
| Line 373 z_off64_t ZEXPORT gztell64(file) | Line 395 z_off64_t ZEXPORT gztell64(file) |
| return -1; | return -1; |
| /* return position */ | /* return position */ |
| return state->pos + (state->seek ? state->skip : 0); | return state->x.pos + (state->seek ? state->skip : 0); |
| } | } |
| /* -- see zlib.h -- */ | /* -- see zlib.h -- */ |
| Line 433 int ZEXPORT gzeof(file) | Line 455 int ZEXPORT gzeof(file) |
| return 0; | return 0; |
| /* return end-of-file state */ | /* return end-of-file state */ |
| return state->mode == GZ_READ ? | return state->mode == GZ_READ ? state->past : 0; |
| (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; | |
| } | } |
| /* -- see zlib.h -- */ | /* -- see zlib.h -- */ |
| Line 471 void ZEXPORT gzclearerr(file) | Line 492 void ZEXPORT gzclearerr(file) |
| return; | return; |
| /* clear error and end-of-file */ | /* clear error and end-of-file */ |
| if (state->mode == GZ_READ) | if (state->mode == GZ_READ) { |
| state->eof = 0; | state->eof = 0; |
| state->past = 0; | |
| } | |
| gz_error(state, Z_OK, NULL); | gz_error(state, Z_OK, NULL); |
| } | } |
| Line 493 void ZLIB_INTERNAL gz_error(state, err, msg) | Line 516 void ZLIB_INTERNAL gz_error(state, err, msg) |
| free(state->msg); | free(state->msg); |
| state->msg = NULL; | state->msg = NULL; |
| } | } |
| /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ | |
| if (err != Z_OK && err != Z_BUF_ERROR) | |
| state->x.have = 0; | |
| /* set error code, and if no message, then done */ | /* set error code, and if no message, then done */ |
| state->err = err; | state->err = err; |