ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
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>
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 */
23local 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. */
36char 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. */
92local 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 -- */
198gzFile ZEXPORT gzopen(const char *path, const char *mode)
199{
200 return gz_open(path, -1, mode);
201}
202
203/* -- see zlib.h -- */
204gzFile ZEXPORT gzopen64(const char *path, const char *mode)
205{
206 return gz_open(path, -1, mode);
207}
208
209/* -- see zlib.h -- */
210gzFile 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 -- */
224int 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 -- */
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 -- */
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 -- */
423const 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. */
464void 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
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define local
Definition adler32.c:17
#define ZLIB_INTERNAL
Definition compress_.c:8
Cube * p
Definition exorList.c:222
gz_state FAR * gz_statep
Definition gzguts.h:129
#define GZ_WRITE
Definition gzguts.h:90
#define LOOK
Definition gzguts.h:94
#define GT_OFF(x)
Definition gzguts.h:144
#define GZ_READ
Definition gzguts.h:89
#define COPY
Definition gzguts.h:95
#define GZ_APPEND
Definition gzguts.h:91
#define GZBUFSIZE
Definition gzguts.h:85
#define GZ_NONE
Definition gzguts.h:88
void ZEXPORT gzclearerr(gzFile file)
Definition gzlib.c:441
z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence)
Definition gzlib.c:268
local gzFile gz_open(const char *path, int fd, const char *mode)
Definition gzlib.c:92
int ZEXPORT gzrewind(gzFile file)
Definition gzlib.c:247
z_off64_t ZEXPORT gztell64(gzFile file)
Definition gzlib.c:350
unsigned ZLIB_INTERNAL gz_intmax()
Definition gzlib.c:501
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence)
Definition gzlib.c:341
gzFile ZEXPORT gzopen64(const char *path, const char *mode)
Definition gzlib.c:204
int ZEXPORT gzeof(gzFile file)
Definition gzlib.c:406
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition gzlib.c:210
z_off64_t ZEXPORT gzoffset64(gzFile file)
Definition gzlib.c:375
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition gzlib.c:423
z_off_t ZEXPORT gzoffset(gzFile file)
Definition gzlib.c:397
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition gzlib.c:464
gzFile ZEXPORT gzopen(const char *path, const char *mode)
Definition gzlib.c:198
z_off_t ZEXPORT gztell(gzFile file)
Definition gzlib.c:366
#define LSEEK
Definition gzlib.c:18
int ZEXPORT gzbuffer(gzFile file, unsigned size)
Definition gzlib.c:224
local void gz_reset(gz_statep state)
Definition gzlib.c:77
Definition file.h:23
Definition mode.h:11
int strlen()
char * sprintf()
char * strcpy()
VOID_HACK free()
char * strcat()
char * malloc()
#define SEEK_SET
Definition zconf.h:390
#define ZEXPORT
Definition zconf.h:322
#define SEEK_CUR
Definition zconf.h:391
#define z_off_t
Definition zconf.h:396
#define OF(args)
Definition zconf.h:242
#define z_off64_t
Definition zconf.h:402
#define Z_HUFFMAN_ONLY
Definition zlib.h:201
#define Z_DEFAULT_STRATEGY
Definition zlib.h:204
#define Z_OK
Definition zlib.h:181
#define Z_FIXED
Definition zlib.h:203
voidp gzFile
Definition zlib.h:1173
#define Z_MEM_ERROR
Definition zlib.h:187
#define Z_FILTERED
Definition zlib.h:200
#define Z_RLE
Definition zlib.h:202
#define Z_DEFAULT_COMPRESSION
Definition zlib.h:197