00001
00002
00003
00004
00005
00006 #include "gzguts.h"
00007
00008 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
00009 # define LSEEK lseek64
00010 #else
00011 # define LSEEK lseek
00012 #endif
00013
00014
00015 local void gz_reset OF((gz_statep));
00016 local gzFile gz_open OF((const char *, int, const char *));
00017
00018 #if defined UNDER_CE
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 char ZLIB_INTERNAL *gz_strwinerror (error)
00030 DWORD error;
00031 {
00032 static char buf[1024];
00033
00034 wchar_t *msgbuf;
00035 DWORD lasterr = GetLastError();
00036 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
00037 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
00038 NULL,
00039 error,
00040 0,
00041 (LPVOID)&msgbuf,
00042 0,
00043 NULL);
00044 if (chars != 0) {
00045
00046 if (chars >= 2
00047 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
00048 chars -= 2;
00049 msgbuf[chars] = 0;
00050 }
00051
00052 if (chars > sizeof (buf) - 1) {
00053 chars = sizeof (buf) - 1;
00054 msgbuf[chars] = 0;
00055 }
00056
00057 wcstombs(buf, msgbuf, chars + 1);
00058 LocalFree(msgbuf);
00059 }
00060 else {
00061 sprintf(buf, "unknown win32 error (%ld)", error);
00062 }
00063
00064 SetLastError(lasterr);
00065 return buf;
00066 }
00067
00068 #endif
00069
00070
00071 local void gz_reset(state)
00072 gz_statep state;
00073 {
00074 if (state->mode == GZ_READ) {
00075 state->have = 0;
00076 state->eof = 0;
00077 state->how = LOOK;
00078 state->direct = 1;
00079 }
00080 state->seek = 0;
00081 gz_error(state, Z_OK, NULL);
00082 state->pos = 0;
00083 state->strm.avail_in = 0;
00084 }
00085
00086
00087 local gzFile gz_open(path, fd, mode)
00088 const char *path;
00089 int fd;
00090 const char *mode;
00091 {
00092 gz_statep state;
00093
00094
00095 state = malloc(sizeof(gz_state));
00096 if (state == NULL)
00097 return NULL;
00098 state->size = 0;
00099 state->want = GZBUFSIZE;
00100 state->msg = NULL;
00101
00102
00103 state->mode = GZ_NONE;
00104 state->level = Z_DEFAULT_COMPRESSION;
00105 state->strategy = Z_DEFAULT_STRATEGY;
00106 while (*mode) {
00107 if (*mode >= '0' && *mode <= '9')
00108 state->level = *mode - '0';
00109 else
00110 switch (*mode) {
00111 case 'r':
00112 state->mode = GZ_READ;
00113 break;
00114 #ifndef NO_GZCOMPRESS
00115 case 'w':
00116 state->mode = GZ_WRITE;
00117 break;
00118 case 'a':
00119 state->mode = GZ_APPEND;
00120 break;
00121 #endif
00122 case '+':
00123 free(state);
00124 return NULL;
00125 case 'b':
00126 break;
00127 case 'f':
00128 state->strategy = Z_FILTERED;
00129 break;
00130 case 'h':
00131 state->strategy = Z_HUFFMAN_ONLY;
00132 break;
00133 case 'R':
00134 state->strategy = Z_RLE;
00135 break;
00136 case 'F':
00137 state->strategy = Z_FIXED;
00138 default:
00139 ;
00140 }
00141 mode++;
00142 }
00143
00144
00145 if (state->mode == GZ_NONE) {
00146 free(state);
00147 return NULL;
00148 }
00149
00150
00151 state->path = malloc(strlen(path) + 1);
00152 if (state->path == NULL) {
00153 free(state);
00154 return NULL;
00155 }
00156 strcpy(state->path, path);
00157
00158
00159 state->fd = fd != -1 ? fd :
00160 open(path,
00161 #ifdef O_LARGEFILE
00162 O_LARGEFILE |
00163 #endif
00164 #ifdef O_BINARY
00165 O_BINARY |
00166 #endif
00167 (state->mode == GZ_READ ?
00168 O_RDONLY :
00169 (O_WRONLY | O_CREAT | (
00170 state->mode == GZ_WRITE ?
00171 O_TRUNC :
00172 O_APPEND))),
00173 0666);
00174 if (state->fd == -1) {
00175 free(state->path);
00176 free(state);
00177 return NULL;
00178 }
00179 if (state->mode == GZ_APPEND)
00180 state->mode = GZ_WRITE;
00181
00182
00183 if (state->mode == GZ_READ) {
00184 state->start = LSEEK(state->fd, 0, SEEK_CUR);
00185 if (state->start == -1) state->start = 0;
00186 }
00187
00188
00189 gz_reset(state);
00190
00191
00192 return (gzFile)state;
00193 }
00194
00195
00196 gzFile ZEXPORT gzopen(path, mode)
00197 const char *path;
00198 const char *mode;
00199 {
00200 return gz_open(path, -1, mode);
00201 }
00202
00203
00204 gzFile ZEXPORT gzopen64(path, mode)
00205 const char *path;
00206 const char *mode;
00207 {
00208 return gz_open(path, -1, mode);
00209 }
00210
00211
00212 gzFile ZEXPORT gzdopen(fd, mode)
00213 int fd;
00214 const char *mode;
00215 {
00216 char *path;
00217 gzFile gz;
00218
00219 if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
00220 return NULL;
00221 sprintf(path, "<fd:%d>", fd);
00222 gz = gz_open(path, fd, mode);
00223 free(path);
00224 return gz;
00225 }
00226
00227
00228 int ZEXPORT gzbuffer(file, size)
00229 gzFile file;
00230 unsigned size;
00231 {
00232 gz_statep state;
00233
00234
00235 if (file == NULL)
00236 return -1;
00237 state = (gz_statep)file;
00238 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00239 return -1;
00240
00241
00242 if (state->size != 0)
00243 return -1;
00244
00245
00246 if (size == 0)
00247 return -1;
00248 state->want = size;
00249 return 0;
00250 }
00251
00252
00253 int ZEXPORT gzrewind(file)
00254 gzFile file;
00255 {
00256 gz_statep state;
00257
00258
00259 if (file == NULL)
00260 return -1;
00261 state = (gz_statep)file;
00262
00263
00264 if (state->mode != GZ_READ || state->err != Z_OK)
00265 return -1;
00266
00267
00268 if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
00269 return -1;
00270 gz_reset(state);
00271 return 0;
00272 }
00273
00274
00275 z_off64_t ZEXPORT gzseek64(file, offset, whence)
00276 gzFile file;
00277 z_off64_t offset;
00278 int whence;
00279 {
00280 unsigned n;
00281 z_off64_t ret;
00282 gz_statep state;
00283
00284
00285 if (file == NULL)
00286 return -1;
00287 state = (gz_statep)file;
00288 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00289 return -1;
00290
00291
00292 if (state->err != Z_OK)
00293 return -1;
00294
00295
00296 if (whence != SEEK_SET && whence != SEEK_CUR)
00297 return -1;
00298
00299
00300 if (whence == SEEK_SET)
00301 offset -= state->pos;
00302 else if (state->seek)
00303 offset += state->skip;
00304 state->seek = 0;
00305
00306
00307 if (state->mode == GZ_READ && state->how == COPY &&
00308 state->pos + offset >= state->raw) {
00309 ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
00310 if (ret == -1)
00311 return -1;
00312 state->have = 0;
00313 state->eof = 0;
00314 state->seek = 0;
00315 gz_error(state, Z_OK, NULL);
00316 state->strm.avail_in = 0;
00317 state->pos += offset;
00318 return state->pos;
00319 }
00320
00321
00322 if (offset < 0) {
00323 if (state->mode != GZ_READ)
00324 return -1;
00325 offset += state->pos;
00326 if (offset < 0)
00327 return -1;
00328 if (gzrewind(file) == -1)
00329 return -1;
00330 }
00331
00332
00333 if (state->mode == GZ_READ) {
00334 n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
00335 (unsigned)offset : state->have;
00336 state->have -= n;
00337 state->next += n;
00338 state->pos += n;
00339 offset -= n;
00340 }
00341
00342
00343 if (offset) {
00344 state->seek = 1;
00345 state->skip = offset;
00346 }
00347 return state->pos + offset;
00348 }
00349
00350
00351 z_off_t ZEXPORT gzseek(file, offset, whence)
00352 gzFile file;
00353 z_off_t offset;
00354 int whence;
00355 {
00356 z_off64_t ret;
00357
00358 ret = gzseek64(file, (z_off64_t)offset, whence);
00359 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
00360 }
00361
00362
00363 z_off64_t ZEXPORT gztell64(file)
00364 gzFile file;
00365 {
00366 gz_statep state;
00367
00368
00369 if (file == NULL)
00370 return -1;
00371 state = (gz_statep)file;
00372 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00373 return -1;
00374
00375
00376 return state->pos + (state->seek ? state->skip : 0);
00377 }
00378
00379
00380 z_off_t ZEXPORT gztell(file)
00381 gzFile file;
00382 {
00383 z_off64_t ret;
00384
00385 ret = gztell64(file);
00386 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
00387 }
00388
00389
00390 z_off64_t ZEXPORT gzoffset64(file)
00391 gzFile file;
00392 {
00393 z_off64_t offset;
00394 gz_statep state;
00395
00396
00397 if (file == NULL)
00398 return -1;
00399 state = (gz_statep)file;
00400 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00401 return -1;
00402
00403
00404 offset = LSEEK(state->fd, 0, SEEK_CUR);
00405 if (offset == -1)
00406 return -1;
00407 if (state->mode == GZ_READ)
00408 offset -= state->strm.avail_in;
00409 return offset;
00410 }
00411
00412
00413 z_off_t ZEXPORT gzoffset(file)
00414 gzFile file;
00415 {
00416 z_off64_t ret;
00417
00418 ret = gzoffset64(file);
00419 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
00420 }
00421
00422
00423 int ZEXPORT gzeof(file)
00424 gzFile file;
00425 {
00426 gz_statep state;
00427
00428
00429 if (file == NULL)
00430 return 0;
00431 state = (gz_statep)file;
00432 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00433 return 0;
00434
00435
00436 return state->mode == GZ_READ ?
00437 (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
00438 }
00439
00440
00441 const char * ZEXPORT gzerror(file, errnum)
00442 gzFile file;
00443 int *errnum;
00444 {
00445 gz_statep state;
00446
00447
00448 if (file == NULL)
00449 return NULL;
00450 state = (gz_statep)file;
00451 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00452 return NULL;
00453
00454
00455 if (errnum != NULL)
00456 *errnum = state->err;
00457 return state->msg == NULL ? "" : state->msg;
00458 }
00459
00460
00461 void ZEXPORT gzclearerr(file)
00462 gzFile file;
00463 {
00464 gz_statep state;
00465
00466
00467 if (file == NULL)
00468 return;
00469 state = (gz_statep)file;
00470 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
00471 return;
00472
00473
00474 if (state->mode == GZ_READ)
00475 state->eof = 0;
00476 gz_error(state, Z_OK, NULL);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485 void ZLIB_INTERNAL gz_error(state, err, msg)
00486 gz_statep state;
00487 int err;
00488 const char *msg;
00489 {
00490
00491 if (state->msg != NULL) {
00492 if (state->err != Z_MEM_ERROR)
00493 free(state->msg);
00494 state->msg = NULL;
00495 }
00496
00497
00498 state->err = err;
00499 if (msg == NULL)
00500 return;
00501
00502
00503 if (err == Z_MEM_ERROR) {
00504 state->msg = (char *)msg;
00505 return;
00506 }
00507
00508
00509 if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
00510 state->err = Z_MEM_ERROR;
00511 state->msg = (char *)"out of memory";
00512 return;
00513 }
00514 strcpy(state->msg, state->path);
00515 strcat(state->msg, ": ");
00516 strcat(state->msg, msg);
00517 return;
00518 }
00519
00520 #ifndef INT_MAX
00521
00522
00523
00524
00525 unsigned ZLIB_INTERNAL gz_intmax()
00526 {
00527 unsigned p, q;
00528
00529 p = 1;
00530 do {
00531 q = p;
00532 p <<= 1;
00533 p++;
00534 } while (p > q);
00535 return q >> 1;
00536 }
00537 #endif