/[pcsx2_0.9.7]/trunk/3rdparty/zlib/gzlib.c
ViewVC logotype

Contents of /trunk/3rdparty/zlib/gzlib.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 1 month ago) by william
File MIME type: text/plain
File size: 13961 byte(s)
committing r3113 initial commit again...
1 /* gzlib.c -- zlib functions common to reading and writing gzip files
2 * Copyright (C) 2004, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6 #include "gzguts.h"
7
8 #ifdef _LARGEFILE64_SOURCE
9 # define LSEEK lseek64
10 #else
11 # define LSEEK lseek
12 #endif
13
14 /* Local functions */
15 local void gz_reset OF((gz_statep));
16 local gzFile gz_open OF((const char *, int, const char *));
17
18 #if defined UNDER_CE && defined NO_ERRNO_H
19
20 /* Map the Windows error number in ERROR to a locale-dependent error message
21 string and return a pointer to it. Typically, the values for ERROR come
22 from GetLastError.
23
24 The string pointed to shall not be modified by the application, but may be
25 overwritten by a subsequent call to gz_strwinerror
26
27 The gz_strwinerror function does not change the current setting of
28 GetLastError. */
29 char ZEXPORT *gz_strwinerror (error)
30 DWORD error;
31 {
32 static char buf[1024];
33
34 wchar_t *msgbuf;
35 DWORD lasterr = GetLastError();
36 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
37 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
38 NULL,
39 error,
40 0, /* Default language */
41 (LPVOID)&msgbuf,
42 0,
43 NULL);
44 if (chars != 0) {
45 /* If there is an \r\n appended, zap it. */
46 if (chars >= 2
47 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
48 chars -= 2;
49 msgbuf[chars] = 0;
50 }
51
52 if (chars > sizeof (buf) - 1) {
53 chars = sizeof (buf) - 1;
54 msgbuf[chars] = 0;
55 }
56
57 wcstombs(buf, msgbuf, chars + 1);
58 LocalFree(msgbuf);
59 }
60 else {
61 sprintf(buf, "unknown win32 error (%ld)", error);
62 }
63
64 SetLastError(lasterr);
65 return buf;
66 }
67
68 #endif /* UNDER_CE && NO_ERRNO_H */
69
70 /* Reset gzip file state */
71 local void gz_reset(state)
72 gz_statep state;
73 {
74 if (state->mode == GZ_READ) { /* for reading ... */
75 state->have = 0; /* no output data available */
76 state->eof = 0; /* not at end of file */
77 state->how = LOOK; /* look for gzip header */
78 state->direct = 1; /* default for empty file */
79 }
80 state->seek = 0; /* no seek request pending */
81 gz_error(state, Z_OK, NULL); /* clear error */
82 state->pos = 0; /* no uncompressed data yet */
83 state->strm.avail_in = 0; /* no input data yet */
84 }
85
86 /* Open a gzip file either by name or file descriptor. */
87 local gzFile gz_open(path, fd, mode)
88 const char *path;
89 int fd;
90 const char *mode;
91 {
92 gz_statep state;
93
94 /* allocate gzFile structure to return */
95 state = malloc(sizeof(gz_state));
96 if (state == NULL)
97 return NULL;
98 state->size = 0; /* no buffers allocated yet */
99 state->want = GZBUFSIZE; /* requested buffer size */
100 state->msg = NULL; /* no error message yet */
101
102 /* interpret mode */
103 state->mode = GZ_NONE;
104 state->level = Z_DEFAULT_COMPRESSION;
105 state->strategy = Z_DEFAULT_STRATEGY;
106 while (*mode) {
107 if (*mode >= '0' && *mode <= '9')
108 state->level = *mode - '0';
109 else
110 switch (*mode) {
111 case 'r':
112 state->mode = GZ_READ;
113 break;
114 #ifndef NO_GZCOMPRESS
115 case 'w':
116 state->mode = GZ_WRITE;
117 break;
118 case 'a':
119 state->mode = GZ_APPEND;
120 break;
121 #endif
122 case '+': /* can't read and write at the same time */
123 free(state);
124 return NULL;
125 case 'b': /* ignore -- will request binary anyway */
126 break;
127 case 'f':
128 state->strategy = Z_FILTERED;
129 break;
130 case 'h':
131 state->strategy = Z_HUFFMAN_ONLY;
132 break;
133 case 'R':
134 state->strategy = Z_RLE;
135 break;
136 case 'F':
137 state->strategy = Z_FIXED;
138 default: /* could consider as an error, but just ignore */
139 ;
140 }
141 mode++;
142 }
143
144 /* must provide an "r", "w", or "a" */
145 if (state->mode == GZ_NONE) {
146 free(state);
147 return NULL;
148 }
149
150 /* save the path name for error messages */
151 state->path = malloc(strlen(path) + 1);
152 if (state->path == NULL) {
153 free(state);
154 return NULL;
155 }
156 strcpy(state->path, path);
157
158 /* open the file with the appropriate mode (or just use fd) */
159 state->fd = fd != -1 ? fd :
160 open(path,
161 #ifdef O_LARGEFILE
162 O_LARGEFILE |
163 #endif
164 #ifdef O_BINARY
165 O_BINARY |
166 #endif
167 (state->mode == GZ_READ ?
168 O_RDONLY :
169 (O_WRONLY | O_CREAT | (
170 state->mode == GZ_WRITE ?
171 O_TRUNC :
172 O_APPEND))),
173 0666);
174 if (state->fd == -1) {
175 free(state);
176 return NULL;
177 }
178 if (state->mode == GZ_APPEND)
179 state->mode = GZ_WRITE; /* simplify later checks */
180
181 /* save the current position for rewinding (only if reading) */
182 if (state->mode == GZ_READ) {
183 state->start = LSEEK(state->fd, 0, SEEK_CUR);
184 if (state->start == -1) state->start = 0;
185 }
186
187 /* initialize stream */
188 gz_reset(state);
189
190 /* return stream */
191 return (gzFile)state;
192 }
193
194 /* -- see zlib.h -- */
195 gzFile ZEXPORT gzopen(path, mode)
196 const char *path;
197 const char *mode;
198 {
199 return gz_open(path, -1, mode);
200 }
201
202 /* -- see zlib.h -- */
203 gzFile ZEXPORT gzopen64(path, mode)
204 const char *path;
205 const char *mode;
206 {
207 return gz_open(path, -1, mode);
208 }
209
210 /* -- see zlib.h -- */
211 gzFile ZEXPORT gzdopen(fd, mode)
212 int fd;
213 const char *mode;
214 {
215 char *path; /* identifier for error messages */
216 gzFile gz;
217
218 if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
219 return NULL;
220 sprintf(path, "<fd:%d>", fd);
221 gz = gz_open(path, fd, mode);
222 free(path);
223 return gz;
224 }
225
226 /* -- see zlib.h -- */
227 int ZEXPORT gzbuffer(file, size)
228 gzFile file;
229 unsigned size;
230 {
231 gz_statep state;
232
233 /* get internal structure and check integrity */
234 if (file == NULL)
235 return -1;
236 state = (gz_statep)file;
237 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
238 return -1;
239
240 /* make sure we haven't already allocated memory */
241 if (state->size != 0)
242 return -1;
243
244 /* check and set requested size */
245 if (size == 0)
246 return -1;
247 state->want = size;
248 return 0;
249 }
250
251 /* -- see zlib.h -- */
252 int ZEXPORT gzrewind(file)
253 gzFile file;
254 {
255 gz_statep state;
256
257 /* get internal structure */
258 if (file == NULL)
259 return -1;
260 state = (gz_statep)file;
261
262 /* check that we're reading and that there's no error */
263 if (state->mode != GZ_READ || state->err != Z_OK)
264 return -1;
265
266 /* back up and start over */
267 if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
268 return -1;
269 gz_reset(state);
270 return 0;
271 }
272
273 /* -- see zlib.h -- */
274 z_off64_t ZEXPORT gzseek64(file, offset, whence)
275 gzFile file;
276 z_off64_t offset;
277 int whence;
278 {
279 unsigned n;
280 z_off64_t ret;
281 gz_statep state;
282
283 /* get internal structure and check integrity */
284 if (file == NULL)
285 return -1;
286 state = (gz_statep)file;
287 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
288 return -1;
289
290 /* check that there's no error */
291 if (state->err != Z_OK)
292 return -1;
293
294 /* can only seek from start or relative to current position */
295 if (whence != SEEK_SET && whence != SEEK_CUR)
296 return -1;
297
298 /* normalize offset to a SEEK_CUR specification */
299 if (whence == SEEK_SET)
300 offset -= state->pos;
301 else if (state->seek)
302 offset += state->skip;
303 state->seek = 0;
304
305 /* if within raw area while reading, just go there */
306 if (state->mode == GZ_READ && state->how == COPY &&
307 state->pos + offset >= state->raw) {
308 ret = LSEEK(state->fd, offset, SEEK_CUR);
309 if (ret == -1)
310 return -1;
311 state->have = 0;
312 state->eof = 0;
313 state->seek = 0;
314 gz_error(state, Z_OK, NULL);
315 state->strm.avail_in = 0;
316 state->pos += offset;
317 return state->pos;
318 }
319
320 /* calculate skip amount, rewinding if needed for back seek when reading */
321 if (offset < 0) {
322 if (state->mode != GZ_READ) /* writing -- can't go backwards */
323 return -1;
324 offset += state->pos;
325 if (offset < 0) /* before start of file! */
326 return -1;
327 if (gzrewind(file) == -1) /* rewind, then skip to offset */
328 return -1;
329 }
330
331 /* if reading, skip what's in output buffer (one less gzgetc() check) */
332 if (state->mode == GZ_READ) {
333 n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
334 (unsigned)offset : state->have;
335 state->have -= n;
336 state->next += n;
337 state->pos += n;
338 offset -= n;
339 }
340
341 /* request skip (if not zero) */
342 if (offset) {
343 state->seek = 1;
344 state->skip = offset;
345 }
346 return state->pos + offset;
347 }
348
349 /* -- see zlib.h -- */
350 z_off_t ZEXPORT gzseek(file, offset, whence)
351 gzFile file;
352 z_off_t offset;
353 int whence;
354 {
355 z_off64_t ret;
356
357 ret = gzseek64(file, (z_off64_t)offset, whence);
358 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
359 }
360
361 /* -- see zlib.h -- */
362 z_off64_t ZEXPORT gztell64(file)
363 gzFile file;
364 {
365 gz_statep state;
366
367 /* get internal structure and check integrity */
368 if (file == NULL)
369 return -1;
370 state = (gz_statep)file;
371 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
372 return -1;
373
374 /* return position */
375 return state->pos + (state->seek ? state->skip : 0);
376 }
377
378 /* -- see zlib.h -- */
379 z_off_t ZEXPORT gztell(file)
380 gzFile file;
381 {
382 z_off64_t ret;
383
384 ret = gztell64(file);
385 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
386 }
387
388 /* -- see zlib.h -- */
389 z_off64_t ZEXPORT gzoffset64(file)
390 gzFile file;
391 {
392 z_off64_t offset;
393 gz_statep state;
394
395 /* get internal structure and check integrity */
396 if (file == NULL)
397 return -1;
398 state = (gz_statep)file;
399 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
400 return -1;
401
402 /* compute and return effective offset in file */
403 offset = LSEEK(state->fd, 0, SEEK_CUR);
404 if (offset == -1)
405 return -1;
406 if (state->mode == GZ_READ) /* reading */
407 offset -= state->strm.avail_in; /* don't count buffered input */
408 return offset;
409 }
410
411 /* -- see zlib.h -- */
412 z_off_t ZEXPORT gzoffset(file)
413 gzFile file;
414 {
415 z_off64_t ret;
416
417 ret = gzoffset64(file);
418 return ret == (z_off_t)ret ? (z_off_t)ret : -1;
419 }
420
421 /* -- see zlib.h -- */
422 int ZEXPORT gzeof(file)
423 gzFile file;
424 {
425 gz_statep state;
426
427 /* get internal structure and check integrity */
428 if (file == NULL)
429 return 0;
430 state = (gz_statep)file;
431 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
432 return 0;
433
434 /* return end-of-file state */
435 return state->mode == GZ_READ ? (state->eof && state->have == 0) : 0;
436 }
437
438 /* -- see zlib.h -- */
439 const char * ZEXPORT gzerror(file, errnum)
440 gzFile file;
441 int *errnum;
442 {
443 gz_statep state;
444
445 /* get internal structure and check integrity */
446 if (file == NULL)
447 return NULL;
448 state = (gz_statep)file;
449 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
450 return NULL;
451
452 /* return error information */
453 if (errnum != NULL)
454 *errnum = state->err;
455 return state->msg == NULL ? "" : state->msg;
456 }
457
458 /* -- see zlib.h -- */
459 void ZEXPORT gzclearerr(file)
460 gzFile file;
461 {
462 gz_statep state;
463
464 /* get internal structure and check integrity */
465 if (file == NULL)
466 return;
467 state = (gz_statep)file;
468 if (state->mode != GZ_READ && state->mode != GZ_WRITE)
469 return;
470
471 /* clear error and end-of-file */
472 if (state->mode == GZ_READ)
473 state->eof = 0;
474 gz_error(state, Z_OK, NULL);
475 }
476
477 /* Create an error message in allocated memory and set state->err and
478 state->msg accordingly. Free any previous error message already there. Do
479 not try to free or allocate space if the error is Z_MEM_ERROR (out of
480 memory). Simply save the error message as a static string. If there is an
481 allocation failure constructing the error message, then convert the error to
482 out of memory. */
483 void ZEXPORT gz_error(state, err, msg)
484 gz_statep state;
485 int err;
486 const char *msg;
487 {
488 /* free previously allocated message and clear */
489 if (state->msg != NULL) {
490 if (state->err != Z_MEM_ERROR)
491 free(state->msg);
492 state->msg = NULL;
493 }
494
495 /* set error code, and if no message, then done */
496 state->err = err;
497 if (msg == NULL)
498 return;
499
500 /* for an out of memory error, save as static string */
501 if (err == Z_MEM_ERROR) {
502 state->msg = (char *)msg;
503 return;
504 }
505
506 /* construct error message with path */
507 if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
508 state->err = Z_MEM_ERROR;
509 state->msg = (char *)"out of memory";
510 return;
511 }
512 strcpy(state->msg, state->path);
513 strcat(state->msg, ": ");
514 strcat(state->msg, msg);
515 return;
516 }
517
518 #ifndef INT_MAX
519 /* portably return maximum value for an int (when limits.h presumed not
520 available) -- we need to do this to cover cases where 2's complement not
521 used, since C standard permits 1's complement and sign-bit representations,
522 otherwise we could just use ((unsigned)-1) >> 1 */
523 unsigned ZEXPORT gz_intmax()
524 {
525 unsigned p, q;
526
527 p = 1;
528 do {
529 q = p;
530 p <<= 1;
531 p++;
532 } while (p > q);
533 return q >> 1;
534 }
535 #endif

  ViewVC Help
Powered by ViewVC 1.1.22