source: rtems/cpukit/zlib/gzlib.c @ e371ea9

4.10.0
Last change on this file since e371ea9 was e371ea9, checked in by cvs2git <rtems-devel@…>, on 03/18/11 at 10:11:42

This commit was manufactured by cvs2svn to create tag 'rtems-4-10-0'.

Sprout from rtems-4-10-branch 2011-02-08 15:56:24 UTC Joel Sherrill <joel.sherrill@…> 'Ensure all version instances say 4.10.'
Cherrypick from rtems-4-10-branch 2011-03-18 10:11:41 UTC cvs2git <rtems-devel@…> 'This commit was manufactured by cvs2svn to create branch':

cpukit/zlib/ChangeLog
cpukit/zlib/ChangeLog.zlib
cpukit/zlib/FAQ
cpukit/zlib/Makefile.am
cpukit/zlib/README
cpukit/zlib/adler32.c
cpukit/zlib/compress.c
cpukit/zlib/crc32.c
cpukit/zlib/deflate.c
cpukit/zlib/deflate.h
cpukit/zlib/doc/algorithm.txt
cpukit/zlib/gzclose.c
cpukit/zlib/gzguts.h
cpukit/zlib/gzlib.c
cpukit/zlib/gzread.c
cpukit/zlib/gzwrite.c
cpukit/zlib/infback.c
cpukit/zlib/inffast.c
cpukit/zlib/inflate.c
cpukit/zlib/inflate.h
cpukit/zlib/inftrees.c
cpukit/zlib/inftrees.h
cpukit/zlib/trees.c
cpukit/zlib/uncompr.c
cpukit/zlib/zconf.h
cpukit/zlib/zlib.3
cpukit/zlib/zlib.h
cpukit/zlib/zutil.c
cpukit/zlib/zutil.h
testsuites/libtests/mathf/.cvsignore
testsuites/libtests/mathf/Makefile.am
testsuites/libtests/mathf/domathf.c
testsuites/libtests/mathf/init.c
testsuites/libtests/mathf/mathf.scn

  • Property mode set to 100644
File size: 13.8 KB
Line 
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 */
15local void gz_reset OF((gz_statep));
16local 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. */
29char 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 */
71local 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. */
87local 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 -- */
195gzFile ZEXPORT gzopen(path, mode)
196    const char *path;
197    const char *mode;
198{
199    return gz_open(path, -1, mode);
200}
201
202#if (defined(_LARGEFILE64_SOURCE)||(_FILE_OFFSET_BITS == 64))
203/* -- see zlib.h -- */
204gzFile ZEXPORT gzopen64(path, mode)
205    const char *path;
206    const char *mode;
207{
208    return gz_open(path, -1, mode);
209}
210#endif /* (defined(_LARGEFILE64_SOURCE)||(_FILE_OFFSET_BITS == 64)) */
211
212/* -- see zlib.h -- */
213gzFile ZEXPORT gzdopen(fd, mode)
214    int fd;
215    const char *mode;
216{
217    char *path;         /* identifier for error messages */
218    gzFile gz;
219
220    if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
221        return NULL;
222    sprintf(path, "<fd:%d>", fd);
223    gz = gz_open(path, fd, mode);
224    free(path);
225    return gz;
226}
227
228/* -- see zlib.h -- */
229int ZEXPORT gzbuffer(file, size)
230    gzFile file;
231    unsigned size;
232{
233    gz_statep state;
234
235    /* get internal structure and check integrity */
236    if (file == NULL)
237        return -1;
238    state = (gz_statep)file;
239    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
240        return -1;
241
242    /* make sure we haven't already allocated memory */
243    if (state->size != 0)
244        return -1;
245
246    /* check and set requested size */
247    if (size == 0)
248        return -1;
249    state->want = size;
250    return 0;
251}
252
253/* -- see zlib.h -- */
254int ZEXPORT gzrewind(file)
255    gzFile file;
256{
257    gz_statep state;
258
259    /* get internal structure */
260    if (file == NULL)
261        return -1;
262    state = (gz_statep)file;
263
264    /* check that we're reading and that there's no error */
265    if (state->mode != GZ_READ || state->err != Z_OK)
266        return -1;
267
268    /* back up and start over */
269    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
270        return -1;
271    gz_reset(state);
272    return 0;
273}
274
275/* -- see zlib.h -- */
276z_off64_t ZEXPORT gzseek64(file, offset, whence)
277    gzFile file;
278    z_off64_t offset;
279    int whence;
280{
281    unsigned n;
282    z_off64_t ret;
283    gz_statep state;
284
285    /* get internal structure and check integrity */
286    if (file == NULL)
287        return -1;
288    state = (gz_statep)file;
289    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
290        return -1;
291
292    /* check that there's no error */
293    if (state->err != Z_OK)
294        return -1;
295
296    /* can only seek from start or relative to current position */
297    if (whence != SEEK_SET && whence != SEEK_CUR)
298        return -1;
299
300    /* normalize offset to a SEEK_CUR specification */
301    if (whence == SEEK_SET)
302        offset -= state->pos;
303    else if (state->seek)
304        offset += state->skip;
305    state->seek = 0;
306
307    /* if within raw area while reading, just go there */
308    if (state->mode == GZ_READ && state->how == COPY &&
309        state->pos + offset >= state->raw) {
310        ret = LSEEK(state->fd, offset, SEEK_CUR);
311        if (ret == -1)
312            return -1;
313        state->have = 0;
314        state->eof = 0;
315        state->seek = 0;
316        gz_error(state, Z_OK, NULL);
317        state->strm.avail_in = 0;
318        state->pos += offset;
319        return state->pos;
320    }
321
322    /* calculate skip amount, rewinding if needed for back seek when reading */
323    if (offset < 0) {
324        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
325            return -1;
326        offset += state->pos;
327        if (offset < 0)                     /* before start of file! */
328            return -1;
329        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
330            return -1;
331    }
332
333    /* if reading, skip what's in output buffer (one less gzgetc() check) */
334    if (state->mode == GZ_READ) {
335        n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
336            (unsigned)offset : state->have;
337        state->have -= n;
338        state->next += n;
339        state->pos += n;
340        offset -= n;
341    }
342
343    /* request skip (if not zero) */
344    if (offset) {
345        state->seek = 1;
346        state->skip = offset;
347    }
348    return state->pos + offset;
349}
350
351/* -- see zlib.h -- */
352z_off_t ZEXPORT gzseek(file, offset, whence)
353    gzFile file;
354    z_off_t offset;
355    int whence;
356{
357    z_off64_t ret;
358
359    ret = gzseek64(file, (z_off64_t)offset, whence);
360    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
361}
362
363/* -- see zlib.h -- */
364z_off64_t ZEXPORT gztell64(file)
365    gzFile file;
366{
367    gz_statep state;
368
369    /* get internal structure and check integrity */
370    if (file == NULL)
371        return -1;
372    state = (gz_statep)file;
373    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
374        return -1;
375
376    /* return position */
377    return state->pos + (state->seek ? state->skip : 0);
378}
379
380/* -- see zlib.h -- */
381z_off_t ZEXPORT gztell(file)
382    gzFile file;
383{
384    z_off64_t ret;
385
386    ret = gztell64(file);
387    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
388}
389
390/* -- see zlib.h -- */
391
392z_off64_t ZEXPORT gzoffset64(file)
393    gzFile file;
394{
395    z_off64_t offset;
396    gz_statep state;
397
398    /* get internal structure and check integrity */
399    if (file == NULL)
400        return -1;
401    state = (gz_statep)file;
402    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
403        return -1;
404
405    /* compute and return effective offset in file */
406    offset = LSEEK(state->fd, 0, SEEK_CUR);
407    if (offset == -1)
408        return -1;
409    if (state->mode == GZ_READ)             /* reading */
410        offset -= state->strm.avail_in;     /* don't count buffered input */
411    return offset;
412}
413
414/* -- see zlib.h -- */
415z_off_t ZEXPORT gzoffset(file)
416    gzFile file;
417{
418    z_off64_t ret;
419
420    ret = gzoffset64(file);
421    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
422}
423
424/* -- see zlib.h -- */
425int ZEXPORT gzeof(file)
426    gzFile file;
427{
428    gz_statep state;
429
430    /* get internal structure and check integrity */
431    if (file == NULL)
432        return 0;
433    state = (gz_statep)file;
434    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
435        return 0;
436
437    /* return end-of-file state */
438    return state->mode == GZ_READ ? (state->eof && state->have == 0) : 0;
439}
440
441/* -- see zlib.h -- */
442const char * ZEXPORT gzerror(file, errnum)
443    gzFile file;
444    int *errnum;
445{
446    gz_statep state;
447
448    /* get internal structure and check integrity */
449    if (file == NULL)
450        return NULL;
451    state = (gz_statep)file;
452    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
453        return NULL;
454
455    /* return error information */
456    if (errnum != NULL)
457        *errnum = state->err;
458    return state->msg == NULL ? "" : state->msg;
459}
460
461/* -- see zlib.h -- */
462void ZEXPORT gzclearerr(file)
463    gzFile file;
464{
465    gz_statep state;
466
467    /* get internal structure and check integrity */
468    if (file == NULL)
469        return;
470    state = (gz_statep)file;
471    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
472        return;
473
474    /* clear error and end-of-file */
475    if (state->mode == GZ_READ)
476        state->eof = 0;
477    gz_error(state, Z_OK, NULL);
478}
479
480/* Create an error message in allocated memory and set state->err and
481   state->msg accordingly.  Free any previous error message already there.  Do
482   not try to free or allocate space if the error is Z_MEM_ERROR (out of
483   memory).  Simply save the error message as a static string.  If there is an
484   allocation failure constructing the error message, then convert the error to
485   out of memory. */
486void ZEXPORT gz_error(state, err, msg)
487    gz_statep state;
488    int err;
489    const char *msg;
490{
491    /* free previously allocated message and clear */
492    if (state->msg != NULL) {
493        if (state->err != Z_MEM_ERROR)
494            free(state->msg);
495        state->msg = NULL;
496    }
497
498    /* set error code, and if no message, then done */
499    state->err = err;
500    if (msg == NULL)
501        return;
502
503    /* for an out of memory error, save as static string */
504    if (err == Z_MEM_ERROR) {
505        state->msg = (char *)msg;
506        return;
507    }
508
509    /* construct error message with path */
510    if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
511        state->err = Z_MEM_ERROR;
512        state->msg = (char *)"out of memory";
513        return;
514    }
515    strcpy(state->msg, state->path);
516    strcat(state->msg, ": ");
517    strcat(state->msg, msg);
518    return;
519}
520
521#ifndef INT_MAX
522/* portably return maximum value for an int (when limits.h presumed not
523   available) -- we need to do this to cover cases where 2's complement not
524   used, since C standard permits 1's complement and sign-bit representations,
525   otherwise we could just use ((unsigned)-1) >> 1 */
526unsigned ZEXPORT gz_intmax()
527{
528    unsigned p, q;
529
530    p = 1;
531    do {
532        q = p;
533        p <<= 1;
534        p++;
535    } while (p > q);
536    return q >> 1;
537}
538#endif
Note: See TracBrowser for help on using the repository browser.