Subversion Repositories Kolibri OS

Rev

Rev 1896 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1896 Rev 3926
Line 1... Line 1...
1
/* gzread.c -- zlib functions for reading gzip files
1
/* gzread.c -- zlib functions for reading gzip files
2
 * Copyright (C) 2004, 2005, 2010 Mark Adler
2
 * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
4
 */
Line 5... Line 5...
5
 
5
 
Line 6... Line 6...
6
#include "gzguts.h"
6
#include "gzguts.h"
7
 
7
 
8
/* Local functions */
8
/* Local functions */
9
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
-
 
10
local int gz_avail OF((gz_statep));
9
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
11
local int gz_next4 OF((gz_statep, unsigned long *));
10
local int gz_avail OF((gz_statep));
12
local int gz_head OF((gz_statep));
11
local int gz_look OF((gz_statep));
13
local int gz_decomp OF((gz_statep));
12
local int gz_decomp OF((gz_statep));
Line 14... Line 13...
14
local int gz_make OF((gz_statep));
13
local int gz_fetch OF((gz_statep));
15
local int gz_skip OF((gz_statep, z_off64_t));
14
local int gz_skip OF((gz_statep, z_off64_t));
16
 
15
 
Line 44... Line 43...
44
 
43
 
45
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
44
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
46
   error, 0 otherwise.  Note that the eof flag is set when the end of the input
45
   error, 0 otherwise.  Note that the eof flag is set when the end of the input
47
   file is reached, even though there may be unused data in the buffer.  Once
46
   file is reached, even though there may be unused data in the buffer.  Once
-
 
47
   that data has been used, no more attempts will be made to read the file.
-
 
48
   If strm->avail_in != 0, then the current data is moved to the beginning of
48
   that data has been used, no more attempts will be made to read the file.
49
   the input buffer, and then the remainder of the buffer is loaded with the
49
   gz_avail() assumes that strm->avail_in == 0. */
50
   available data from the input file. */
50
local int gz_avail(state)
51
local int gz_avail(state)
51
    gz_statep state;
52
    gz_statep state;
-
 
53
{
52
{
54
    unsigned got;
Line 53... Line 55...
53
    z_streamp strm = &(state->strm);
55
    z_streamp strm = &(state->strm);
54
 
56
 
55
    if (state->err != Z_OK)
57
    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
-
 
58
        return -1;
-
 
59
    if (state->eof == 0) {
-
 
60
        if (strm->avail_in) {       /* copy what's there to the start */
-
 
61
            unsigned char *p = state->in;
-
 
62
            unsigned const char *q = strm->next_in;
-
 
63
            unsigned n = strm->avail_in;
-
 
64
            do {
-
 
65
                *p++ = *q++;
56
        return -1;
66
            } while (--n);
57
    if (state->eof == 0) {
67
        }
58
        if (gz_load(state, state->in, state->size,
68
        if (gz_load(state, state->in + strm->avail_in,
-
 
69
                    state->size - strm->avail_in, &got) == -1)
59
                (unsigned *)&(strm->avail_in)) == -1)
70
            return -1;
60
            return -1;
71
        strm->avail_in += got;
61
        strm->next_in = state->in;
72
        strm->next_in = state->in;
62
    }
73
    }
Line 63... Line -...
63
    return 0;
-
 
64
}
-
 
65
 
-
 
66
/* Get next byte from input, or -1 if end or error. */
-
 
67
#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
-
 
68
                (strm->avail_in == 0 ? -1 : \
-
 
69
                 (strm->avail_in--, *(strm->next_in)++)))
-
 
70
 
-
 
71
/* Get a four-byte little-endian integer and return 0 on success and the value
-
 
72
   in *ret.  Otherwise -1 is returned and *ret is not modified. */
-
 
73
local int gz_next4(state, ret)
-
 
74
    gz_statep state;
-
 
75
    unsigned long *ret;
-
 
76
{
-
 
77
    int ch;
-
 
78
    unsigned long val;
-
 
79
    z_streamp strm = &(state->strm);
-
 
80
 
-
 
81
    val = NEXT();
-
 
82
    val += (unsigned)NEXT() << 8;
-
 
83
    val += (unsigned long)NEXT() << 16;
-
 
84
    ch = NEXT();
-
 
85
    if (ch == -1)
-
 
86
        return -1;
-
 
87
    val += (unsigned long)ch << 24;
-
 
88
    *ret = val;
-
 
89
    return 0;
74
    return 0;
90
}
75
}
91
 
76
 
92
/* Look for gzip header, set up for inflate or copy.  state->have must be zero.
77
/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
93
   If this is the first time in, allocate required memory.  state->how will be
78
   If this is the first time in, allocate required memory.  state->how will be
94
   left unchanged if there is no more input data available, will be set to COPY
79
   left unchanged if there is no more input data available, will be set to COPY
95
   if there is no gzip header and direct copying will be performed, or it will
80
   if there is no gzip header and direct copying will be performed, or it will
96
   be set to GZIP for decompression, and the gzip header will be skipped so
81
   be set to GZIP for decompression.  If direct copying, then leftover input
97
   that the next available input data is the raw deflate stream.  If direct
-
 
98
   copying, then leftover input data from the input buffer will be copied to
-
 
99
   the output buffer.  In that case, all further file reads will be directly to
82
   data from the input buffer will be copied to the output buffer.  In that
100
   either the output buffer or a user buffer.  If decompressing, the inflate
-
 
101
   state and the check value will be initialized.  gz_head() will return 0 on
83
   case, all further file reads will be directly to either the output buffer or
102
   success or -1 on failure.  Failures may include read errors or gzip header
84
   a user buffer.  If decompressing, the inflate state will be initialized.
103
   errors.  */
85
   gz_look() will return 0 on success or -1 on failure. */
104
local int gz_head(state)
86
local int gz_look(state)
105
    gz_statep state;
-
 
106
{
-
 
Line 107... Line 87...
107
    z_streamp strm = &(state->strm);
87
    gz_statep state;
108
    int flags;
88
{
109
    unsigned len;
89
    z_streamp strm = &(state->strm);
110
 
90
 
111
    /* allocate read buffers and inflate memory */
91
    /* allocate read buffers and inflate memory */
112
    if (state->size == 0) {
92
    if (state->size == 0) {
113
        /* allocate buffers */
93
        /* allocate buffers */
114
        state->in = malloc(state->want);
94
        state->in = (unsigned char *)malloc(state->want);
115
        state->out = malloc(state->want << 1);
95
        state->out = (unsigned char *)malloc(state->want << 1);
116
        if (state->in == NULL || state->out == NULL) {
96
        if (state->in == NULL || state->out == NULL) {
Line 127... Line 107...
127
        state->strm.zalloc = Z_NULL;
107
        state->strm.zalloc = Z_NULL;
128
        state->strm.zfree = Z_NULL;
108
        state->strm.zfree = Z_NULL;
129
        state->strm.opaque = Z_NULL;
109
        state->strm.opaque = Z_NULL;
130
        state->strm.avail_in = 0;
110
        state->strm.avail_in = 0;
131
        state->strm.next_in = Z_NULL;
111
        state->strm.next_in = Z_NULL;
132
        if (inflateInit2(&(state->strm), -15) != Z_OK) {    /* raw inflate */
112
        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
133
            free(state->out);
113
            free(state->out);
134
            free(state->in);
114
            free(state->in);
135
            state->size = 0;
115
            state->size = 0;
136
            gz_error(state, Z_MEM_ERROR, "out of memory");
116
            gz_error(state, Z_MEM_ERROR, "out of memory");
137
            return -1;
117
            return -1;
138
        }
118
        }
139
    }
119
    }
Line 140... Line 120...
140
 
120
 
141
    /* get some data in the input buffer */
121
    /* get at least the magic bytes in the input buffer */
142
    if (strm->avail_in == 0) {
122
    if (strm->avail_in < 2) {
143
        if (gz_avail(state) == -1)
123
        if (gz_avail(state) == -1)
144
            return -1;
124
            return -1;
145
        if (strm->avail_in == 0)
125
        if (strm->avail_in == 0)
146
            return 0;
126
            return 0;
Line 147... Line 127...
147
    }
127
    }
148
 
-
 
149
    /* look for the gzip magic header bytes 31 and 139 */
-
 
150
    if (strm->next_in[0] == 31) {
-
 
151
        strm->avail_in--;
-
 
152
        strm->next_in++;
-
 
153
        if (strm->avail_in == 0 && gz_avail(state) == -1)
-
 
154
            return -1;
128
 
155
        if (strm->avail_in && strm->next_in[0] == 139) {
-
 
156
            /* we have a gzip header, woo hoo! */
-
 
157
            strm->avail_in--;
-
 
158
            strm->next_in++;
-
 
159
 
129
    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
160
            /* skip rest of header */
-
 
161
            if (NEXT() != 8) {      /* compression method */
-
 
162
                gz_error(state, Z_DATA_ERROR, "unknown compression method");
-
 
163
                return -1;
-
 
164
            }
130
       a logical dilemma here when considering the case of a partially written
165
            flags = NEXT();
-
 
166
            if (flags & 0xe0) {     /* reserved flag bits */
-
 
167
                gz_error(state, Z_DATA_ERROR, "unknown header flags set");
-
 
168
                return -1;
131
       gzip file, to wit, if a single 31 byte is written, then we cannot tell
169
            }
-
 
170
            NEXT();                 /* modification time */
-
 
171
            NEXT();
-
 
172
            NEXT();
-
 
173
            NEXT();
132
       whether this is a single-byte file, or just a partially written gzip
174
            NEXT();                 /* extra flags */
133
       file -- for here we assume that if a gzip file is being written, then
175
            NEXT();                 /* operating system */
-
 
176
            if (flags & 4) {        /* extra field */
-
 
177
                len = (unsigned)NEXT();
134
       the header will be written in a single operation, so that reading a
178
                len += (unsigned)NEXT() << 8;
-
 
179
                while (len--)
-
 
180
                    if (NEXT() < 0)
-
 
181
                        break;
-
 
182
            }
-
 
183
            if (flags & 8)          /* file name */
-
 
184
                while (NEXT() > 0)
-
 
185
                    ;
-
 
186
            if (flags & 16)         /* comment */
-
 
187
                while (NEXT() > 0)
-
 
188
                    ;
-
 
189
            if (flags & 2) {        /* header crc */
-
 
190
                NEXT();
-
 
191
                NEXT();
-
 
192
            }
135
       single byte is sufficient indication that it is not a gzip file) */
193
            /* an unexpected end of file is not checked for here -- it will be
-
 
194
               noticed on the first request for uncompressed data */
-
 
195
 
136
    if (strm->avail_in > 1 &&
196
            /* set up for decompression */
-
 
197
            inflateReset(strm);
137
            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
198
            strm->adler = crc32(0L, Z_NULL, 0);
138
        inflateReset(strm);
199
            state->how = GZIP;
139
        state->how = GZIP;
200
            state->direct = 0;
140
        state->direct = 0;
-
 
141
        return 0;
-
 
142
    }
-
 
143
 
201
            return 0;
144
    /* no gzip header -- if we were decoding gzip before, then this is trailing
202
        }
145
       garbage.  Ignore the trailing garbage and finish. */
203
        else {
146
    if (state->direct == 0) {
204
            /* not a gzip file -- save first byte (31) and fall to raw i/o */
147
        strm->avail_in = 0;
205
            state->out[0] = 31;
148
        state->eof = 1;
206
            state->have = 1;
149
        state->x.have = 0;
Line 207... Line 150...
207
        }
150
        return 0;
208
    }
151
    }
209
 
152
 
210
    /* doing raw i/o, save start of raw data for seeking, copy any leftover
-
 
211
       input to output -- this assumes that the output buffer is larger than
153
    /* doing raw i/o, copy any leftover input to output -- this assumes that
212
       the input buffer, which also assures space for gzungetc() */
154
       the output buffer is larger than the input buffer, which also assures
213
    state->raw = state->pos;
155
       space for gzungetc() */
214
    state->next = state->out;
156
    state->x.next = state->out;
215
    if (strm->avail_in) {
157
    if (strm->avail_in) {
216
        memcpy(state->next + state->have, strm->next_in, strm->avail_in);
158
        memcpy(state->x.next, strm->next_in, strm->avail_in);
217
        state->have += strm->avail_in;
159
        state->x.have = strm->avail_in;
218
        strm->avail_in = 0;
160
        strm->avail_in = 0;
219
    }
161
    }
220
    state->how = COPY;
162
    state->how = COPY;
Line 221... Line 163...
221
    state->direct = 1;
163
    state->direct = 1;
222
    return 0;
-
 
223
}
164
    return 0;
224
 
-
 
225
/* Decompress from input to the provided next_out and avail_out in the state.
165
}
226
   If the end of the compressed data is reached, then verify the gzip trailer
166
 
227
   check value and length (modulo 2^32).  state->have and state->next are set
-
 
228
   to point to the just decompressed data, and the crc is updated.  If the
167
/* Decompress from input to the provided next_out and avail_out in the state.
229
   trailer is verified, state->how is reset to LOOK to look for the next gzip
168
   On return, state->x.have and state->x.next point to the just decompressed
230
   stream or raw data, once state->have is depleted.  Returns 0 on success, -1
169
   data.  If the gzip stream completes, state->how is reset to LOOK to look for
231
   on failure.  Failures may include invalid compressed data or a failed gzip
170
   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
232
   trailer verification. */
171
   on success, -1 on failure. */
233
local int gz_decomp(state)
172
local int gz_decomp(state)
234
    gz_statep state;
-
 
235
{
173
    gz_statep state;
Line 236... Line 174...
236
    int ret;
174
{
237
    unsigned had;
175
    int ret = Z_OK;
238
    unsigned long crc, len;
176
    unsigned had;
239
    z_streamp strm = &(state->strm);
177
    z_streamp strm = &(state->strm);
240
 
178
 
241
    /* fill output buffer up to end of deflate stream */
179
    /* fill output buffer up to end of deflate stream */
242
    had = strm->avail_out;
180
    had = strm->avail_out;
243
    do {
181
    do {
244
        /* get more input for inflate() */
182
        /* get more input for inflate() */
245
        if (strm->avail_in == 0 && gz_avail(state) == -1)
183
        if (strm->avail_in == 0 && gz_avail(state) == -1)
Line 246... Line 184...
246
            return -1;
184
            return -1;
247
        if (strm->avail_in == 0) {
185
        if (strm->avail_in == 0) {
248
            gz_error(state, Z_DATA_ERROR, "unexpected end of file");
186
            gz_error(state, Z_BUF_ERROR, "unexpected end of file");
Line 265... Line 203...
265
                      strm->msg == NULL ? "compressed data error" : strm->msg);
203
                     strm->msg == NULL ? "compressed data error" : strm->msg);
266
            return -1;
204
            return -1;
267
        }
205
        }
268
    } while (strm->avail_out && ret != Z_STREAM_END);
206
    } while (strm->avail_out && ret != Z_STREAM_END);
Line 269... Line 207...
269
 
207
 
270
    /* update available output and crc check value */
208
    /* update available output */
271
    state->have = had - strm->avail_out;
209
    state->x.have = had - strm->avail_out;
272
    state->next = strm->next_out - state->have;
-
 
273
    strm->adler = crc32(strm->adler, state->next, state->have);
210
    state->x.next = strm->next_out - state->x.have;
274
 
211
 
275
    /* check gzip trailer if at end of deflate stream */
212
    /* if the gzip stream completed successfully, look for another */
276
    if (ret == Z_STREAM_END) {
-
 
277
        if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
-
 
278
            gz_error(state, Z_DATA_ERROR, "unexpected end of file");
-
 
279
            return -1;
-
 
280
        }
-
 
281
        if (crc != strm->adler) {
-
 
282
            gz_error(state, Z_DATA_ERROR, "incorrect data check");
-
 
283
            return -1;
-
 
284
        }
-
 
285
        if (len != (strm->total_out & 0xffffffffL)) {
-
 
286
            gz_error(state, Z_DATA_ERROR, "incorrect length check");
213
    if (ret == Z_STREAM_END)
287
            return -1;
-
 
288
        }
-
 
289
        state->how = LOOK;      /* ready for next stream, once have is 0 (leave
-
 
290
                                   state->direct unchanged to remember how) */
-
 
Line 291... Line 214...
291
    }
214
        state->how = LOOK;
292
 
215
 
293
    /* good decompression */
216
    /* good decompression */
Line 294... Line 217...
294
    return 0;
217
    return 0;
295
}
218
}
296
 
219
 
297
/* Make data and put in the output buffer.  Assumes that state->have == 0.
220
/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
298
   Data is either copied from the input file or decompressed from the input
221
   Data is either copied from the input file or decompressed from the input
299
   file depending on state->how.  If state->how is LOOK, then a gzip header is
222
   file depending on state->how.  If state->how is LOOK, then a gzip header is
300
   looked for (and skipped if found) to determine wither to copy or decompress.
-
 
301
   Returns -1 on error, otherwise 0.  gz_make() will leave state->have as COPY
223
   looked for to determine whether to copy or decompress.  Returns -1 on error,
302
   or GZIP unless the end of the input file has been reached and all data has
224
   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
303
   been processed.  */
225
   end of the input file has been reached and all data has been processed.  */
304
local int gz_make(state)
226
local int gz_fetch(state)
Line -... Line 227...
-
 
227
    gz_statep state;
-
 
228
{
305
    gz_statep state;
229
    z_streamp strm = &(state->strm);
306
{
230
 
307
    z_streamp strm = &(state->strm);
231
    do {
308
 
232
        switch(state->how) {
309
    if (state->how == LOOK) {           /* look for gzip header */
233
        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
310
        if (gz_head(state) == -1)
234
            if (gz_look(state) == -1)
311
            return -1;
235
                return -1;
312
        if (state->have)                /* got some data from gz_head() */
236
            if (state->how == LOOK)
-
 
237
                return 0;
313
            return 0;
238
            break;
314
    }
239
        case COPY:      /* -> COPY */
315
    if (state->how == COPY) {           /* straight copy */
240
            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
316
        if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
241
                    == -1)
317
            return -1;
242
                return -1;
318
        state->next = state->out;
243
            state->x.next = state->out;
319
    }
244
            return 0;
320
    else if (state->how == GZIP) {      /* decompress */
245
        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
321
        strm->avail_out = state->size << 1;
246
            strm->avail_out = state->size << 1;
-
 
247
            strm->next_out = state->out;
322
        strm->next_out = state->out;
248
            if (gz_decomp(state) == -1)
323
        if (gz_decomp(state) == -1)
249
                return -1;
Line 324... Line 250...
324
            return -1;
250
        }
325
    }
251
    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
Line 334... Line 260...
334
    unsigned n;
260
    unsigned n;
Line 335... Line 261...
335
 
261
 
336
    /* skip over len bytes or reach end-of-file, whichever comes first */
262
    /* skip over len bytes or reach end-of-file, whichever comes first */
337
    while (len)
263
    while (len)
338
        /* skip over whatever is in output buffer */
264
        /* skip over whatever is in output buffer */
339
        if (state->have) {
265
        if (state->x.have) {
340
            n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
266
            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
341
                (unsigned)len : state->have;
267
                (unsigned)len : state->x.have;
342
            state->have -= n;
268
            state->x.have -= n;
343
            state->next += n;
269
            state->x.next += n;
344
            state->pos += n;
270
            state->x.pos += n;
345
            len -= n;
271
            len -= n;
Line 346... Line 272...
346
        }
272
        }
347
 
273
 
348
        /* output buffer empty -- return if we're at the end of the input */
274
        /* output buffer empty -- return if we're at the end of the input */
Line 349... Line 275...
349
        else if (state->eof && state->strm.avail_in == 0)
275
        else if (state->eof && state->strm.avail_in == 0)
350
            break;
276
            break;
351
 
277
 
352
        /* need more data to skip -- load up output buffer */
278
        /* need more data to skip -- load up output buffer */
353
        else {
279
        else {
354
            /* get more output, looking for header if required */
280
            /* get more output, looking for header if required */
355
            if (gz_make(state) == -1)
281
            if (gz_fetch(state) == -1)
356
                return -1;
282
                return -1;
Line 372... Line 298...
372
    if (file == NULL)
298
    if (file == NULL)
373
        return -1;
299
        return -1;
374
    state = (gz_statep)file;
300
    state = (gz_statep)file;
375
    strm = &(state->strm);
301
    strm = &(state->strm);
Line 376... Line 302...
376
 
302
 
377
    /* check that we're reading and that there's no error */
303
    /* check that we're reading and that there's no (serious) error */
-
 
304
    if (state->mode != GZ_READ ||
378
    if (state->mode != GZ_READ || state->err != Z_OK)
305
            (state->err != Z_OK && state->err != Z_BUF_ERROR))
Line 379... Line 306...
379
        return -1;
306
        return -1;
380
 
307
 
381
    /* since an int is returned, make sure len fits in one, otherwise return
308
    /* since an int is returned, make sure len fits in one, otherwise return
382
       with an error (this avoids the flaw in the interface) */
309
       with an error (this avoids the flaw in the interface) */
383
    if ((int)len < 0) {
310
    if ((int)len < 0) {
384
        gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
311
        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
Line 385... Line 312...
385
        return -1;
312
        return -1;
386
    }
313
    }
Line 398... Line 325...
398
 
325
 
399
    /* get len bytes to buf, or less than len if at the end */
326
    /* get len bytes to buf, or less than len if at the end */
400
    got = 0;
327
    got = 0;
401
    do {
328
    do {
402
        /* first just try copying data from the output buffer */
329
        /* first just try copying data from the output buffer */
403
        if (state->have) {
330
        if (state->x.have) {
404
            n = state->have > len ? len : state->have;
331
            n = state->x.have > len ? len : state->x.have;
405
            memcpy(buf, state->next, n);
332
            memcpy(buf, state->x.next, n);
406
            state->next += n;
333
            state->x.next += n;
407
            state->have -= n;
334
            state->x.have -= n;
Line 408... Line 335...
408
        }
335
        }
409
 
336
 
-
 
337
        /* output buffer empty -- return if we're at the end of the input */
410
        /* output buffer empty -- return if we're at the end of the input */
338
        else if (state->eof && strm->avail_in == 0) {
-
 
339
            state->past = 1;        /* tried to read past end */
Line 411... Line 340...
411
        else if (state->eof && strm->avail_in == 0)
340
            break;
412
            break;
341
        }
413
 
342
 
414
        /* need output data -- for small len or new stream load up our output
343
        /* need output data -- for small len or new stream load up our output
415
           buffer */
344
           buffer */
416
        else if (state->how == LOOK || len < (state->size << 1)) {
345
        else if (state->how == LOOK || len < (state->size << 1)) {
417
            /* get more output, looking for header if required */
346
            /* get more output, looking for header if required */
418
            if (gz_make(state) == -1)
347
            if (gz_fetch(state) == -1)
419
                return -1;
348
                return -1;
420
            continue;       /* no progress yet -- go back to memcpy() above */
349
            continue;       /* no progress yet -- go back to copy above */
Line 421... Line 350...
421
            /* the copy above assures that we will leave with space in the
350
            /* the copy above assures that we will leave with space in the
422
               output buffer, allowing at least one gzungetc() to succeed */
351
               output buffer, allowing at least one gzungetc() to succeed */
423
        }
352
        }
424
 
353
 
425
        /* large len -- read directly into user buffer */
354
        /* large len -- read directly into user buffer */
Line 426... Line 355...
426
        else if (state->how == COPY) {      /* read directly */
355
        else if (state->how == COPY) {      /* read directly */
427
            if (gz_load(state, buf, len, &n) == -1)
356
            if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
428
                return -1;
357
                return -1;
429
        }
358
        }
430
 
359
 
431
        /* large len -- decompress directly into user buffer */
360
        /* large len -- decompress directly into user buffer */
432
        else {  /* state->how == GZIP */
361
        else {  /* state->how == GZIP */
433
            strm->avail_out = len;
362
            strm->avail_out = len;
434
            strm->next_out = buf;
363
            strm->next_out = (unsigned char *)buf;
Line 435... Line 364...
435
            if (gz_decomp(state) == -1)
364
            if (gz_decomp(state) == -1)
436
                return -1;
365
                return -1;
437
            n = state->have;
366
            n = state->x.have;
438
            state->have = 0;
367
            state->x.have = 0;
439
        }
368
        }
440
 
369
 
Line 441... Line 370...
441
        /* update progress */
370
        /* update progress */
442
        len -= n;
371
        len -= n;
443
        buf = (char *)buf + n;
372
        buf = (char *)buf + n;
Line 444... Line 373...
444
        got += n;
373
        got += n;
-
 
374
        state->x.pos += n;
-
 
375
    } while (len);
-
 
376
 
-
 
377
    /* return number of bytes read into user buffer (will fit in int) */
-
 
378
    return (int)got;
445
        state->pos += n;
379
}
446
    } while (len);
380
 
447
 
381
/* -- see zlib.h -- */
448
    /* return number of bytes read into user buffer (will fit in int) */
382
#ifdef Z_PREFIX_SET
449
    return (int)got;
383
#  undef z_gzgetc
Line 460... Line 394...
460
    /* get internal structure */
394
    /* get internal structure */
461
    if (file == NULL)
395
    if (file == NULL)
462
        return -1;
396
        return -1;
463
    state = (gz_statep)file;
397
    state = (gz_statep)file;
Line 464... Line 398...
464
 
398
 
-
 
399
    /* check that we're reading and that there's no (serious) error */
465
    /* check that we're reading and that there's no error */
400
    if (state->mode != GZ_READ ||
466
    if (state->mode != GZ_READ || state->err != Z_OK)
401
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
Line 467... Line 402...
467
        return -1;
402
        return -1;
468
 
403
 
469
    /* try output buffer (no need to check for skip request) */
404
    /* try output buffer (no need to check for skip request) */
470
    if (state->have) {
405
    if (state->x.have) {
471
        state->have--;
406
        state->x.have--;
472
        state->pos++;
407
        state->x.pos++;
Line 473... Line 408...
473
        return *(state->next)++;
408
        return *(state->x.next)++;
474
    }
409
    }
475
 
410
 
476
    /* nothing there -- try gzread() */
411
    /* nothing there -- try gzread() */
Line -... Line 412...
-
 
412
    ret = gzread(file, buf, 1);
-
 
413
    return ret < 1 ? -1 : buf[0];
-
 
414
}
-
 
415
 
-
 
416
int ZEXPORT gzgetc_(file)
-
 
417
gzFile file;
477
    ret = gzread(file, buf, 1);
418
{
478
    return ret < 1 ? -1 : buf[0];
419
    return gzgetc(file);
479
}
420
}
480
 
421
 
481
/* -- see zlib.h -- */
422
/* -- see zlib.h -- */
Line 488... Line 429...
488
    /* get internal structure */
429
    /* get internal structure */
489
    if (file == NULL)
430
    if (file == NULL)
490
        return -1;
431
        return -1;
491
    state = (gz_statep)file;
432
    state = (gz_statep)file;
Line 492... Line 433...
492
 
433
 
-
 
434
    /* check that we're reading and that there's no (serious) error */
493
    /* check that we're reading and that there's no error */
435
    if (state->mode != GZ_READ ||
494
    if (state->mode != GZ_READ || state->err != Z_OK)
436
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
Line 495... Line 437...
495
        return -1;
437
        return -1;
496
 
438
 
497
    /* process a skip request */
439
    /* process a skip request */
Line 504... Line 446...
504
    /* can't push EOF */
446
    /* can't push EOF */
505
    if (c < 0)
447
    if (c < 0)
506
        return -1;
448
        return -1;
Line 507... Line 449...
507
 
449
 
508
    /* if output buffer empty, put byte at end (allows more pushing) */
450
    /* if output buffer empty, put byte at end (allows more pushing) */
509
    if (state->have == 0) {
451
    if (state->x.have == 0) {
510
        state->have = 1;
452
        state->x.have = 1;
511
        state->next = state->out + (state->size << 1) - 1;
453
        state->x.next = state->out + (state->size << 1) - 1;
512
        state->next[0] = c;
454
        state->x.next[0] = c;
-
 
455
        state->x.pos--;
513
        state->pos--;
456
        state->past = 0;
514
        return c;
457
        return c;
Line 515... Line 458...
515
    }
458
    }
516
 
459
 
517
    /* if no room, give up (must have already done a gzungetc()) */
460
    /* if no room, give up (must have already done a gzungetc()) */
518
    if (state->have == (state->size << 1)) {
461
    if (state->x.have == (state->size << 1)) {
519
        gz_error(state, Z_BUF_ERROR, "out of room to push characters");
462
        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
Line 520... Line 463...
520
        return -1;
463
        return -1;
521
    }
464
    }
522
 
465
 
523
    /* slide output data if needed and insert byte before existing data */
466
    /* slide output data if needed and insert byte before existing data */
524
    if (state->next == state->out) {
467
    if (state->x.next == state->out) {
525
        unsigned char *src = state->out + state->have;
468
        unsigned char *src = state->out + state->x.have;
526
        unsigned char *dest = state->out + (state->size << 1);
469
        unsigned char *dest = state->out + (state->size << 1);
527
        while (src > state->out)
470
        while (src > state->out)
528
            *--dest = *--src;
471
            *--dest = *--src;
529
        state->next = dest;
472
        state->x.next = dest;
530
    }
473
    }
531
    state->have++;
474
    state->x.have++;
-
 
475
    state->x.next--;
532
    state->next--;
476
    state->x.next[0] = c;
533
    state->next[0] = c;
477
    state->x.pos--;
Line 534... Line 478...
534
    state->pos--;
478
    state->past = 0;
535
    return c;
479
    return c;
Line 549... Line 493...
549
    /* check parameters and get internal structure */
493
    /* check parameters and get internal structure */
550
    if (file == NULL || buf == NULL || len < 1)
494
    if (file == NULL || buf == NULL || len < 1)
551
        return NULL;
495
        return NULL;
552
    state = (gz_statep)file;
496
    state = (gz_statep)file;
Line 553... Line 497...
553
 
497
 
-
 
498
    /* check that we're reading and that there's no (serious) error */
554
    /* check that we're reading and that there's no error */
499
    if (state->mode != GZ_READ ||
555
    if (state->mode != GZ_READ || state->err != Z_OK)
500
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
Line 556... Line 501...
556
        return NULL;
501
        return NULL;
557
 
502
 
558
    /* process a skip request */
503
    /* process a skip request */
Line 567... Line 512...
567
       the contents, let the user worry about that) */
512
       the contents, let the user worry about that) */
568
    str = buf;
513
    str = buf;
569
    left = (unsigned)len - 1;
514
    left = (unsigned)len - 1;
570
    if (left) do {
515
    if (left) do {
571
        /* assure that something is in the output buffer */
516
        /* assure that something is in the output buffer */
572
        if (state->have == 0) {
-
 
573
            if (gz_make(state) == -1)
517
        if (state->x.have == 0 && gz_fetch(state) == -1)
574
                return NULL;            /* error */
518
            return NULL;                /* error */
575
            if (state->have == 0) {     /* end of file */
519
        if (state->x.have == 0) {       /* end of file */
576
                if (buf == str)         /* got bupkus */
520
            state->past = 1;            /* read past end */
577
                    return NULL;
-
 
578
                break;                  /* got something -- return it */
521
            break;                      /* return what we have */
579
            }
-
 
580
        }
522
        }
Line 581... Line 523...
581
 
523
 
582
        /* look for end-of-line in current output buffer */
524
        /* look for end-of-line in current output buffer */
583
        n = state->have > left ? left : state->have;
525
        n = state->x.have > left ? left : state->x.have;
584
        eol = memchr(state->next, '\n', n);
526
        eol = (unsigned char *)memchr(state->x.next, '\n', n);
585
        if (eol != NULL)
527
        if (eol != NULL)
Line 586... Line 528...
586
            n = (unsigned)(eol - state->next) + 1;
528
            n = (unsigned)(eol - state->x.next) + 1;
587
 
529
 
588
        /* copy through end-of-line, or remainder if not found */
530
        /* copy through end-of-line, or remainder if not found */
589
        memcpy(buf, state->next, n);
531
        memcpy(buf, state->x.next, n);
590
        state->have -= n;
532
        state->x.have -= n;
591
        state->next += n;
533
        state->x.next += n;
592
        state->pos += n;
534
        state->x.pos += n;
593
        left -= n;
535
        left -= n;
Line 594... Line 536...
594
        buf += n;
536
        buf += n;
-
 
537
    } while (left && eol == NULL);
-
 
538
 
595
    } while (left && eol == NULL);
539
    /* return terminated string, or if nothing, end of file */
596
 
540
    if (buf == str)
597
    /* found end-of-line or out of space -- terminate string and return it */
541
        return NULL;
Line 598... Line 542...
598
    buf[0] = 0;
542
    buf[0] = 0;
Line 608... Line 552...
608
    /* get internal structure */
552
    /* get internal structure */
609
    if (file == NULL)
553
    if (file == NULL)
610
        return 0;
554
        return 0;
611
    state = (gz_statep)file;
555
    state = (gz_statep)file;
Line 612... Line -...
612
 
-
 
613
    /* check that we're reading */
-
 
614
    if (state->mode != GZ_READ)
-
 
615
        return 0;
-
 
616
 
556
 
617
    /* if the state is not known, but we can find out, then do so (this is
557
    /* if the state is not known, but we can find out, then do so (this is
618
       mainly for right after a gzopen() or gzdopen()) */
558
       mainly for right after a gzopen() or gzdopen()) */
619
    if (state->how == LOOK && state->have == 0)
559
    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
Line 620... Line 560...
620
        (void)gz_head(state);
560
        (void)gz_look(state);
621
 
561
 
622
    /* return 1 if reading direct, 0 if decompressing a gzip stream */
562
    /* return 1 if transparent, 0 if processing a gzip stream */
Line 623... Line 563...
623
    return state->direct;
563
    return state->direct;
624
}
564
}
625
 
565
 
626
/* -- see zlib.h -- */
566
/* -- see zlib.h -- */
627
int ZEXPORT gzclose_r(file)
567
int ZEXPORT gzclose_r(file)
628
    gzFile file;
568
    gzFile file;
Line 629... Line 569...
629
{
569
{
630
    int ret;
570
    int ret, err;
631
    gz_statep state;
571
    gz_statep state;
Line 643... Line 583...
643
    if (state->size) {
583
    if (state->size) {
644
        inflateEnd(&(state->strm));
584
        inflateEnd(&(state->strm));
645
        free(state->out);
585
        free(state->out);
646
        free(state->in);
586
        free(state->in);
647
    }
587
    }
-
 
588
    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
648
    gz_error(state, Z_OK, NULL);
589
    gz_error(state, Z_OK, NULL);
649
    free(state->path);
590
    free(state->path);
650
    ret = close(state->fd);
591
    ret = close(state->fd);
651
    free(state);
592
    free(state);
652
    return ret ? Z_ERRNO : Z_OK;
593
    return ret ? Z_ERRNO : err;
653
}
594
}