zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
gzlib.c
Go to the documentation of this file.
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 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
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
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 ZLIB_INTERNAL *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 */
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. */
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->path);
176  free(state);
177  return NULL;
178  }
179  if (state->mode == GZ_APPEND)
180  state->mode = GZ_WRITE; /* simplify later checks */
181 
182  /* save the current position for rewinding (only if reading) */
183  if (state->mode == GZ_READ) {
184  state->start = LSEEK(state->fd, 0, SEEK_CUR);
185  if (state->start == -1) state->start = 0;
186  }
187 
188  /* initialize stream */
189  gz_reset(state);
190 
191  /* return stream */
192  return (gzFile)state;
193 }
194 
195 /* -- see zlib.h -- */
197  const char *path;
198  const char *mode;
199 {
200  return gz_open(path, -1, mode);
201 }
202 
203 /* -- see zlib.h -- */
205  const char *path;
206  const char *mode;
207 {
208  return gz_open(path, -1, mode);
209 }
210 
211 /* -- see zlib.h -- */
213  int fd;
214  const char *mode;
215 {
216  char *path; /* identifier for error messages */
217  gzFile gz;
218 
219  if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
220  return NULL;
221  sprintf(path, "<fd:%d>", fd); /* for debugging */
222  gz = gz_open(path, fd, mode);
223  free(path);
224  return gz;
225 }
226 
227 /* -- see zlib.h -- */
229  gzFile file;
230  unsigned size;
231 {
232  gz_statep state;
233 
234  /* get internal structure and check integrity */
235  if (file == NULL)
236  return -1;
237  state = (gz_statep)file;
238  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
239  return -1;
240 
241  /* make sure we haven't already allocated memory */
242  if (state->size != 0)
243  return -1;
244 
245  /* check and set requested size */
246  if (size == 0)
247  return -1;
248  state->want = size;
249  return 0;
250 }
251 
252 /* -- see zlib.h -- */
254  gzFile file;
255 {
256  gz_statep state;
257 
258  /* get internal structure */
259  if (file == NULL)
260  return -1;
261  state = (gz_statep)file;
262 
263  /* check that we're reading and that there's no error */
264  if (state->mode != GZ_READ || state->err != Z_OK)
265  return -1;
266 
267  /* back up and start over */
268  if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
269  return -1;
270  gz_reset(state);
271  return 0;
272 }
273 
274 /* -- see zlib.h -- */
276  gzFile file;
278  int whence;
279 {
280  unsigned n;
281  z_off64_t ret;
282  gz_statep state;
283 
284  /* get internal structure and check integrity */
285  if (file == NULL)
286  return -1;
287  state = (gz_statep)file;
288  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
289  return -1;
290 
291  /* check that there's no error */
292  if (state->err != Z_OK)
293  return -1;
294 
295  /* can only seek from start or relative to current position */
296  if (whence != SEEK_SET && whence != SEEK_CUR)
297  return -1;
298 
299  /* normalize offset to a SEEK_CUR specification */
300  if (whence == SEEK_SET)
301  offset -= state->pos;
302  else if (state->seek)
303  offset += state->skip;
304  state->seek = 0;
305 
306  /* if within raw area while reading, just go there */
307  if (state->mode == GZ_READ && state->how == COPY &&
308  state->pos + offset >= state->raw) {
309  ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
310  if (ret == -1)
311  return -1;
312  state->have = 0;
313  state->eof = 0;
314  state->seek = 0;
315  gz_error(state, Z_OK, NULL);
316  state->strm.avail_in = 0;
317  state->pos += offset;
318  return state->pos;
319  }
320 
321  /* calculate skip amount, rewinding if needed for back seek when reading */
322  if (offset < 0) {
323  if (state->mode != GZ_READ) /* writing -- can't go backwards */
324  return -1;
325  offset += state->pos;
326  if (offset < 0) /* before start of file! */
327  return -1;
328  if (gzrewind(file) == -1) /* rewind, then skip to offset */
329  return -1;
330  }
331 
332  /* if reading, skip what's in output buffer (one less gzgetc() check) */
333  if (state->mode == GZ_READ) {
334  n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
335  (unsigned)offset : state->have;
336  state->have -= n;
337  state->next += n;
338  state->pos += n;
339  offset -= n;
340  }
341 
342  /* request skip (if not zero) */
343  if (offset) {
344  state->seek = 1;
345  state->skip = offset;
346  }
347  return state->pos + offset;
348 }
349 
350 /* -- see zlib.h -- */
352  gzFile file;
353  z_off_t offset;
354  int whence;
355 {
356  z_off64_t ret;
357 
358  ret = gzseek64(file, (z_off64_t)offset, whence);
359  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
360 }
361 
362 /* -- see zlib.h -- */
364  gzFile file;
365 {
366  gz_statep state;
367 
368  /* get internal structure and check integrity */
369  if (file == NULL)
370  return -1;
371  state = (gz_statep)file;
372  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
373  return -1;
374 
375  /* return position */
376  return state->pos + (state->seek ? state->skip : 0);
377 }
378 
379 /* -- see zlib.h -- */
381  gzFile file;
382 {
383  z_off64_t ret;
384 
385  ret = gztell64(file);
386  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
387 }
388 
389 /* -- see zlib.h -- */
391  gzFile file;
392 {
394  gz_statep state;
395 
396  /* get internal structure and check integrity */
397  if (file == NULL)
398  return -1;
399  state = (gz_statep)file;
400  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
401  return -1;
402 
403  /* compute and return effective offset in file */
404  offset = LSEEK(state->fd, 0, SEEK_CUR);
405  if (offset == -1)
406  return -1;
407  if (state->mode == GZ_READ) /* reading */
408  offset -= state->strm.avail_in; /* don't count buffered input */
409  return offset;
410 }
411 
412 /* -- see zlib.h -- */
414  gzFile file;
415 {
416  z_off64_t ret;
417 
418  ret = gzoffset64(file);
419  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
420 }
421 
422 /* -- see zlib.h -- */
424  gzFile file;
425 {
426  gz_statep state;
427 
428  /* get internal structure and check integrity */
429  if (file == NULL)
430  return 0;
431  state = (gz_statep)file;
432  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
433  return 0;
434 
435  /* return end-of-file state */
436  return state->mode == GZ_READ ?
437  (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
438 }
439 
440 /* -- see zlib.h -- */
441 const char * ZEXPORT gzerror(file, errnum)
442  gzFile file;
443  int *errnum;
444 {
445  gz_statep state;
446 
447  /* get internal structure and check integrity */
448  if (file == NULL)
449  return NULL;
450  state = (gz_statep)file;
451  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
452  return NULL;
453 
454  /* return error information */
455  if (errnum != NULL)
456  *errnum = state->err;
457  return state->msg == NULL ? "" : state->msg;
458 }
459 
460 /* -- see zlib.h -- */
462  gzFile file;
463 {
464  gz_statep state;
465 
466  /* get internal structure and check integrity */
467  if (file == NULL)
468  return;
469  state = (gz_statep)file;
470  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
471  return;
472 
473  /* clear error and end-of-file */
474  if (state->mode == GZ_READ)
475  state->eof = 0;
476  gz_error(state, Z_OK, NULL);
477 }
478 
479 /* Create an error message in allocated memory and set state->err and
480  state->msg accordingly. Free any previous error message already there. Do
481  not try to free or allocate space if the error is Z_MEM_ERROR (out of
482  memory). Simply save the error message as a static string. If there is an
483  allocation failure constructing the error message, then convert the error to
484  out of memory. */
485 void ZLIB_INTERNAL gz_error(state, err, msg)
486  gz_statep state;
487  int err;
488  const char *msg;
489 {
490  /* free previously allocated message and clear */
491  if (state->msg != NULL) {
492  if (state->err != Z_MEM_ERROR)
493  free(state->msg);
494  state->msg = NULL;
495  }
496 
497  /* set error code, and if no message, then done */
498  state->err = err;
499  if (msg == NULL)
500  return;
501 
502  /* for an out of memory error, save as static string */
503  if (err == Z_MEM_ERROR) {
504  state->msg = (char *)msg;
505  return;
506  }
507 
508  /* construct error message with path */
509  if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
510  state->err = Z_MEM_ERROR;
511  state->msg = (char *)"out of memory";
512  return;
513  }
514  strcpy(state->msg, state->path);
515  strcat(state->msg, ": ");
516  strcat(state->msg, msg);
517  return;
518 }
519 
520 #ifndef INT_MAX
521 /* portably return maximum value for an int (when limits.h presumed not
522  available) -- we need to do this to cover cases where 2's complement not
523  used, since C standard permits 1's complement and sign-bit representations,
524  otherwise we could just use ((unsigned)-1) >> 1 */
526 {
527  unsigned p, q;
528 
529  p = 1;
530  do {
531  q = p;
532  p <<= 1;
533  p++;
534  } while (p > q);
535  return q >> 1;
536 }
537 #endif
voidp gzFile
Definition: zlib.h:1165
#define GZ_NONE
Definition: gzguts.h:75
#define NULL
Definition: ftobjs.h:61
#define Z_RLE
Definition: zlib.h:194
GLclampd n
Definition: glew.h:7287
#define GT_OFF(x)
Definition: gzguts.h:131
z_off64_t ZEXPORT gzoffset64(gzFile file)
Definition: gzlib.c:390
#define local
Definition: zutil.h:30
#define GZ_APPEND
Definition: gzguts.h:78
#define GZ_READ
Definition: gzguts.h:76
SDL_EventEntry * free
Definition: SDL_events.c:80
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzio.c:219
FILE * file
Definition: visualinfo.c:88
#define Z_FILTERED
Definition: zlib.h:151
#define ZEXPORT(x)
Definition: zconf.h:202
#define ZLIB_INTERNAL
Definition: compress.c:8
#define Z_HUFFMAN_ONLY
Definition: zlib.h:152
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:148
local gzFile gz_open(char *path, const char *mode, int fd) const
Definition: gzio.c:93
GLsizei const GLchar *const * path
Definition: glew.h:5828
ret
Definition: glew_str_glx.c:2
#define Z_OK
Definition: zlib.h:132
z_off64_t ZEXPORT gztell64(gzFile file)
Definition: gzlib.c:363
#define SEEK_CUR
Definition: zconf.h:250
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzio.c:208
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.c:485
int
Definition: SDL_systhread.c:37
#define z_off64_t
Definition: zconf.h:400
FT_Error error
Definition: cffdrivr.c:407
int ZEXPORT gzbuffer(gzFile file, unsigned size)
Definition: gzlib.c:228
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzio.c:987
#define GZ_WRITE
Definition: gzguts.h:77
#define LSEEK
Definition: gzlib.c:11
GLfloat GLfloat p
Definition: glew.h:14938
#define z_off_t
Definition: zconf.h:254
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:153
#define Z_FIXED
Definition: zlib.h:195
int ZEXPORT gzrewind(gzFile file)
Definition: gzio.c:857
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define SEEK_SET
Definition: zconf.h:249
#define OF(args)
Definition: zconf.h:146
z_off_t ZEXPORT gzoffset(gzFile file)
Definition: gzlib.c:413
int ZEXPORT gzeof(gzFile file)
Definition: gzio.c:891
#define malloc
Definition: SDL_malloc.c:635
z_off_t ZEXPORT gztell(gzFile file)
Definition: gzio.c:881
#define const
Definition: zconf.h:91
#define LOOK
Definition: gzguts.h:81
local void gz_reset(gz_statep state)
Definition: gzlib.c:71
void ZEXPORT gzclearerr(gzFile file)
Definition: gzio.c:1017
GLintptr offset
Definition: glew.h:1668
#define GZBUFSIZE
Definition: gzguts.h:72
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
gzFile ZEXPORT gzopen64(char *path, const char *mode) const
Definition: gzlib.c:204
GLdouble GLdouble GLdouble GLdouble q
Definition: glew.h:1400
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
#define COPY
Definition: gzguts.h:82
gz_state FAR * gz_statep
Definition: gzguts.h:116
#define Z_MEM_ERROR
Definition: zlib.h:138
unsigned ZLIB_INTERNAL gz_intmax()
Definition: gzlib.c:525
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence)
Definition: gzio.c:767
z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence)
Definition: gzlib.c:275
GLenum mode
Definition: glew.h:2394
GLsizei size
Definition: gl2ext.h:1467