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