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
/* gzlib.c -- zlib functions common to reading and writing gzip files
1
/* gzlib.c -- zlib functions common to reading and writing gzip files
2
 * Copyright (C) 2004, 2010 Mark Adler
2
 * Copyright (C) 2004, 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 -... Line 6...
-
 
6
#include "gzguts.h"
-
 
7
 
-
 
8
#if defined(_WIN32) && !defined(__BORLANDC__)
6
#include "gzguts.h"
9
#  define LSEEK _lseeki64
7
 
10
#else
8
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
11
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
9
#  define LSEEK lseek64
12
#  define LSEEK lseek64
10
#else
13
#else
-
 
14
#  define LSEEK lseek
Line 11... Line 15...
11
#  define LSEEK lseek
15
#endif
12
#endif
16
#endif
13
 
17
 
Line 14... Line 18...
14
/* Local functions */
18
/* Local functions */
Line 15... Line 19...
15
local void gz_reset OF((gz_statep));
19
local void gz_reset OF((gz_statep));
16
local gzFile gz_open OF((const char *, int, const char *));
20
local gzFile gz_open OF((const void *, int, const char *));
Line 69... Line 73...
69
 
73
 
70
/* Reset gzip file state */
74
/* Reset gzip file state */
71
local void gz_reset(state)
75
local void gz_reset(state)
72
    gz_statep state;
76
    gz_statep state;
-
 
77
{
73
{
78
    state->x.have = 0;              /* no output data available */
74
    if (state->mode == GZ_READ) {   /* for reading ... */
-
 
75
        state->have = 0;            /* no output data available */
79
    if (state->mode == GZ_READ) {   /* for reading ... */
-
 
80
        state->eof = 0;             /* not at end of file */
76
        state->eof = 0;             /* not at end of file */
81
        state->past = 0;            /* have not read past end yet */
77
        state->how = LOOK;          /* look for gzip header */
-
 
78
        state->direct = 1;          /* default for empty file */
82
        state->how = LOOK;          /* look for gzip header */
79
    }
83
    }
80
    state->seek = 0;                /* no seek request pending */
84
    state->seek = 0;                /* no seek request pending */
81
    gz_error(state, Z_OK, NULL);    /* clear error */
85
    gz_error(state, Z_OK, NULL);    /* clear error */
82
    state->pos = 0;                 /* no uncompressed data yet */
86
    state->x.pos = 0;               /* no uncompressed data yet */
83
    state->strm.avail_in = 0;       /* no input data yet */
87
    state->strm.avail_in = 0;       /* no input data yet */
Line 84... Line 88...
84
}
88
}
85
 
89
 
86
/* Open a gzip file either by name or file descriptor. */
90
/* Open a gzip file either by name or file descriptor. */
87
local gzFile gz_open(path, fd, mode)
91
local gzFile gz_open(path, fd, mode)
88
    const char *path;
92
    const void *path;
89
    int fd;
93
    int fd;
90
    const char *mode;
94
    const char *mode;
-
 
95
{
-
 
96
    gz_statep state;
-
 
97
    size_t len;
-
 
98
    int oflag;
-
 
99
#ifdef O_CLOEXEC
-
 
100
    int cloexec = 0;
-
 
101
#endif
-
 
102
#ifdef O_EXCL
-
 
103
    int exclusive = 0;
-
 
104
#endif
-
 
105
 
-
 
106
    /* check input */
Line 91... Line 107...
91
{
107
    if (path == NULL)
92
    gz_statep state;
108
        return NULL;
93
 
109
 
94
    /* allocate gzFile structure to return */
110
    /* allocate gzFile structure to return */
95
    state = malloc(sizeof(gz_state));
111
    state = (gz_statep)malloc(sizeof(gz_state));
96
    if (state == NULL)
112
    if (state == NULL)
97
        return NULL;
113
        return NULL;
Line 98... Line 114...
98
    state->size = 0;            /* no buffers allocated yet */
114
    state->size = 0;            /* no buffers allocated yet */
99
    state->want = GZBUFSIZE;    /* requested buffer size */
115
    state->want = GZBUFSIZE;    /* requested buffer size */
100
    state->msg = NULL;          /* no error message yet */
116
    state->msg = NULL;          /* no error message yet */
101
 
117
 
-
 
118
    /* interpret mode */
102
    /* interpret mode */
119
    state->mode = GZ_NONE;
103
    state->mode = GZ_NONE;
120
    state->level = Z_DEFAULT_COMPRESSION;
104
    state->level = Z_DEFAULT_COMPRESSION;
121
    state->strategy = Z_DEFAULT_STRATEGY;
105
    state->strategy = Z_DEFAULT_STRATEGY;
122
    state->direct = 0;
106
    while (*mode) {
123
    while (*mode) {
Line 122... Line 139...
122
            case '+':       /* can't read and write at the same time */
139
            case '+':       /* can't read and write at the same time */
123
                free(state);
140
                free(state);
124
                return NULL;
141
                return NULL;
125
            case 'b':       /* ignore -- will request binary anyway */
142
            case 'b':       /* ignore -- will request binary anyway */
126
                break;
143
                break;
-
 
144
#ifdef O_CLOEXEC
-
 
145
            case 'e':
-
 
146
                cloexec = 1;
-
 
147
                break;
-
 
148
#endif
-
 
149
#ifdef O_EXCL
-
 
150
            case 'x':
-
 
151
                exclusive = 1;
-
 
152
                break;
-
 
153
#endif
127
            case 'f':
154
            case 'f':
128
                state->strategy = Z_FILTERED;
155
                state->strategy = Z_FILTERED;
129
                break;
156
                break;
130
            case 'h':
157
            case 'h':
131
                state->strategy = Z_HUFFMAN_ONLY;
158
                state->strategy = Z_HUFFMAN_ONLY;
Line 133... Line 160...
133
            case 'R':
160
            case 'R':
134
                state->strategy = Z_RLE;
161
                state->strategy = Z_RLE;
135
                break;
162
                break;
136
            case 'F':
163
            case 'F':
137
                state->strategy = Z_FIXED;
164
                state->strategy = Z_FIXED;
-
 
165
                break;
-
 
166
            case 'T':
-
 
167
                state->direct = 1;
-
 
168
                break;
138
            default:        /* could consider as an error, but just ignore */
169
            default:        /* could consider as an error, but just ignore */
139
                ;
170
                ;
140
            }
171
            }
141
        mode++;
172
        mode++;
142
    }
173
    }
Line 145... Line 176...
145
    if (state->mode == GZ_NONE) {
176
    if (state->mode == GZ_NONE) {
146
        free(state);
177
        free(state);
147
        return NULL;
178
        return NULL;
148
    }
179
    }
Line -... Line 180...
-
 
180
 
-
 
181
    /* can't force transparent read */
-
 
182
    if (state->mode == GZ_READ) {
-
 
183
        if (state->direct) {
-
 
184
            free(state);
-
 
185
            return NULL;
-
 
186
        }
-
 
187
        state->direct = 1;      /* for empty file */
-
 
188
    }
149
 
189
 
-
 
190
    /* save the path name for error messages */
-
 
191
#ifdef _WIN32
-
 
192
    if (fd == -2) {
-
 
193
        len = wcstombs(NULL, path, 0);
-
 
194
        if (len == (size_t)-1)
-
 
195
            len = 0;
-
 
196
    }
-
 
197
    else
-
 
198
#endif
150
    /* save the path name for error messages */
199
        len = strlen((const char *)path);
151
    state->path = malloc(strlen(path) + 1);
200
    state->path = (char *)malloc(len + 1);
152
    if (state->path == NULL) {
201
    if (state->path == NULL) {
153
        free(state);
202
        free(state);
154
        return NULL;
203
        return NULL;
-
 
204
    }
-
 
205
#ifdef _WIN32
-
 
206
    if (fd == -2)
-
 
207
        if (len)
-
 
208
            wcstombs(state->path, path, len + 1);
-
 
209
        else
-
 
210
            *(state->path) = 0;
-
 
211
    else
-
 
212
#endif
-
 
213
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
-
 
214
        snprintf(state->path, len + 1, "%s", (const char *)path);
155
    }
215
#else
-
 
216
        strcpy(state->path, path);
Line 156... Line -...
156
    strcpy(state->path, path);
-
 
157
 
217
#endif
158
    /* open the file with the appropriate mode (or just use fd) */
218
 
159
    state->fd = fd != -1 ? fd :
219
    /* compute the flags for open() */
160
        open(path,
220
    oflag =
161
#ifdef O_LARGEFILE
221
#ifdef O_LARGEFILE
162
            O_LARGEFILE |
222
        O_LARGEFILE |
163
#endif
223
#endif
164
#ifdef O_BINARY
224
#ifdef O_BINARY
-
 
225
        O_BINARY |
-
 
226
#endif
-
 
227
#ifdef O_CLOEXEC
165
            O_BINARY |
228
        (cloexec ? O_CLOEXEC : 0) |
166
#endif
229
#endif
167
            (state->mode == GZ_READ ?
230
        (state->mode == GZ_READ ?
-
 
231
         O_RDONLY :
-
 
232
         (O_WRONLY | O_CREAT |
-
 
233
#ifdef O_EXCL
168
                O_RDONLY :
234
          (exclusive ? O_EXCL : 0) |
169
                (O_WRONLY | O_CREAT | (
235
#endif
170
                    state->mode == GZ_WRITE ?
236
          (state->mode == GZ_WRITE ?
-
 
237
           O_TRUNC :
-
 
238
           O_APPEND)));
171
                        O_TRUNC :
239
 
-
 
240
    /* open the file with the appropriate flags (or just use fd) */
-
 
241
    state->fd = fd > -1 ? fd : (
-
 
242
#ifdef _WIN32
-
 
243
        fd == -2 ? _wopen(path, oflag, 0666) :
172
                        O_APPEND))),
244
#endif
173
            0666);
245
        open((const char *)path, oflag, 0666));
174
    if (state->fd == -1) {
246
    if (state->fd == -1) {
175
        free(state->path);
247
        free(state->path);
176
        free(state);
248
        free(state);
Line 214... Line 286...
214
    const char *mode;
286
    const char *mode;
215
{
287
{
216
    char *path;         /* identifier for error messages */
288
    char *path;         /* identifier for error messages */
217
    gzFile gz;
289
    gzFile gz;
Line 218... Line 290...
218
 
290
 
219
    if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
291
    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
-
 
292
        return NULL;
-
 
293
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
-
 
294
    snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */
220
        return NULL;
295
#else
-
 
296
    sprintf(path, "", fd);   /* for debugging */
221
    sprintf(path, "", fd);   /* for debugging */
297
#endif
222
    gz = gz_open(path, fd, mode);
298
    gz = gz_open(path, fd, mode);
223
    free(path);
299
    free(path);
224
    return gz;
300
    return gz;
Line 225... Line 301...
225
}
301
}
-
 
302
 
-
 
303
/* -- see zlib.h -- */
-
 
304
#ifdef _WIN32
-
 
305
gzFile ZEXPORT gzopen_w(path, mode)
-
 
306
    const wchar_t *path;
-
 
307
    const char *mode;
-
 
308
{
-
 
309
    return gz_open(path, -2, mode);
-
 
310
}
-
 
311
#endif
226
 
312
 
227
/* -- see zlib.h -- */
313
/* -- see zlib.h -- */
228
int ZEXPORT gzbuffer(file, size)
314
int ZEXPORT gzbuffer(file, size)
229
    gzFile file;
315
    gzFile file;
230
    unsigned size;
316
    unsigned size;
Line 241... Line 327...
241
    /* make sure we haven't already allocated memory */
327
    /* make sure we haven't already allocated memory */
242
    if (state->size != 0)
328
    if (state->size != 0)
243
        return -1;
329
        return -1;
Line 244... Line 330...
244
 
330
 
245
    /* check and set requested size */
331
    /* check and set requested size */
246
    if (size == 0)
332
    if (size < 2)
247
        return -1;
333
        size = 2;               /* need two bytes to check magic header */
248
    state->want = size;
334
    state->want = size;
249
    return 0;
335
    return 0;
Line 250... Line 336...
250
}
336
}
Line 259... Line 345...
259
    if (file == NULL)
345
    if (file == NULL)
260
        return -1;
346
        return -1;
261
    state = (gz_statep)file;
347
    state = (gz_statep)file;
Line 262... Line 348...
262
 
348
 
263
    /* check that we're reading and that there's no error */
349
    /* check that we're reading and that there's no error */
-
 
350
    if (state->mode != GZ_READ ||
264
    if (state->mode != GZ_READ || state->err != Z_OK)
351
            (state->err != Z_OK && state->err != Z_BUF_ERROR))
Line 265... Line 352...
265
        return -1;
352
        return -1;
266
 
353
 
267
    /* back up and start over */
354
    /* back up and start over */
Line 287... Line 374...
287
    state = (gz_statep)file;
374
    state = (gz_statep)file;
288
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
375
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
289
        return -1;
376
        return -1;
Line 290... Line 377...
290
 
377
 
291
    /* check that there's no error */
378
    /* check that there's no error */
292
    if (state->err != Z_OK)
379
    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
Line 293... Line 380...
293
        return -1;
380
        return -1;
294
 
381
 
295
    /* can only seek from start or relative to current position */
382
    /* can only seek from start or relative to current position */
Line 296... Line 383...
296
    if (whence != SEEK_SET && whence != SEEK_CUR)
383
    if (whence != SEEK_SET && whence != SEEK_CUR)
297
        return -1;
384
        return -1;
298
 
385
 
299
    /* normalize offset to a SEEK_CUR specification */
386
    /* normalize offset to a SEEK_CUR specification */
300
    if (whence == SEEK_SET)
387
    if (whence == SEEK_SET)
301
        offset -= state->pos;
388
        offset -= state->x.pos;
Line 302... Line 389...
302
    else if (state->seek)
389
    else if (state->seek)
303
        offset += state->skip;
390
        offset += state->skip;
304
    state->seek = 0;
391
    state->seek = 0;
305
 
392
 
306
    /* if within raw area while reading, just go there */
393
    /* if within raw area while reading, just go there */
307
    if (state->mode == GZ_READ && state->how == COPY &&
394
    if (state->mode == GZ_READ && state->how == COPY &&
308
        state->pos + offset >= state->raw) {
395
            state->x.pos + offset >= 0) {
309
        ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
396
        ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
-
 
397
        if (ret == -1)
310
        if (ret == -1)
398
            return -1;
311
            return -1;
399
        state->x.have = 0;
312
        state->have = 0;
400
        state->eof = 0;
313
        state->eof = 0;
401
        state->past = 0;
314
        state->seek = 0;
402
        state->seek = 0;
315
        gz_error(state, Z_OK, NULL);
403
        gz_error(state, Z_OK, NULL);
Line 316... Line 404...
316
        state->strm.avail_in = 0;
404
        state->strm.avail_in = 0;
317
        state->pos += offset;
405
        state->x.pos += offset;
318
        return state->pos;
406
        return state->x.pos;
319
    }
407
    }
320
 
408
 
321
    /* calculate skip amount, rewinding if needed for back seek when reading */
409
    /* calculate skip amount, rewinding if needed for back seek when reading */
322
    if (offset < 0) {
410
    if (offset < 0) {
323
        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
411
        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
324
            return -1;
412
            return -1;
325
        offset += state->pos;
413
        offset += state->x.pos;
Line 326... Line 414...
326
        if (offset < 0)                     /* before start of file! */
414
        if (offset < 0)                     /* before start of file! */
327
            return -1;
415
            return -1;
328
        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
416
        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
329
            return -1;
417
            return -1;
330
    }
418
    }
331
 
419
 
332
    /* if reading, skip what's in output buffer (one less gzgetc() check) */
420
    /* if reading, skip what's in output buffer (one less gzgetc() check) */
333
    if (state->mode == GZ_READ) {
421
    if (state->mode == GZ_READ) {
334
        n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
422
        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
Line 335... Line 423...
335
            (unsigned)offset : state->have;
423
            (unsigned)offset : state->x.have;
336
        state->have -= n;
424
        state->x.have -= n;
337
        state->next += n;
425
        state->x.next += n;
338
        state->pos += n;
426
        state->x.pos += n;
339
        offset -= n;
427
        offset -= n;
340
    }
428
    }
341
 
429
 
Line 342... Line 430...
342
    /* request skip (if not zero) */
430
    /* request skip (if not zero) */
343
    if (offset) {
431
    if (offset) {
344
        state->seek = 1;
432
        state->seek = 1;
Line 371... Line 459...
371
    state = (gz_statep)file;
459
    state = (gz_statep)file;
372
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
460
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
373
        return -1;
461
        return -1;
Line 374... Line 462...
374
 
462
 
375
    /* return position */
463
    /* return position */
376
    return state->pos + (state->seek ? state->skip : 0);
464
    return state->x.pos + (state->seek ? state->skip : 0);
Line 377... Line 465...
377
}
465
}
378
 
466
 
379
/* -- see zlib.h -- */
467
/* -- see zlib.h -- */
Line 431... Line 519...
431
    state = (gz_statep)file;
519
    state = (gz_statep)file;
432
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
520
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
433
        return 0;
521
        return 0;
Line 434... Line 522...
434
 
522
 
435
    /* return end-of-file state */
523
    /* return end-of-file state */
436
    return state->mode == GZ_READ ?
-
 
437
        (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
524
    return state->mode == GZ_READ ? state->past : 0;
Line 438... Line 525...
438
}
525
}
439
 
526
 
440
/* -- see zlib.h -- */
527
/* -- see zlib.h -- */
Line 452... Line 539...
452
        return NULL;
539
        return NULL;
Line 453... Line 540...
453
 
540
 
454
    /* return error information */
541
    /* return error information */
455
    if (errnum != NULL)
542
    if (errnum != NULL)
456
        *errnum = state->err;
543
        *errnum = state->err;
-
 
544
    return state->err == Z_MEM_ERROR ? "out of memory" :
457
    return state->msg == NULL ? "" : state->msg;
545
                                       (state->msg == NULL ? "" : state->msg);
Line 458... Line 546...
458
}
546
}
459
 
547
 
460
/* -- see zlib.h -- */
548
/* -- see zlib.h -- */
Line 469... Line 557...
469
    state = (gz_statep)file;
557
    state = (gz_statep)file;
470
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
558
    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
471
        return;
559
        return;
Line 472... Line 560...
472
 
560
 
473
    /* clear error and end-of-file */
561
    /* clear error and end-of-file */
474
    if (state->mode == GZ_READ)
562
    if (state->mode == GZ_READ) {
-
 
563
        state->eof = 0;
-
 
564
        state->past = 0;
475
        state->eof = 0;
565
    }
476
    gz_error(state, Z_OK, NULL);
566
    gz_error(state, Z_OK, NULL);
Line 477... Line 567...
477
}
567
}
478
 
568
 
Line 492... Line 582...
492
        if (state->err != Z_MEM_ERROR)
582
        if (state->err != Z_MEM_ERROR)
493
            free(state->msg);
583
            free(state->msg);
494
        state->msg = NULL;
584
        state->msg = NULL;
495
    }
585
    }
Line -... Line 586...
-
 
586
 
-
 
587
    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
-
 
588
    if (err != Z_OK && err != Z_BUF_ERROR)
-
 
589
        state->x.have = 0;
496
 
590
 
497
    /* set error code, and if no message, then done */
591
    /* set error code, and if no message, then done */
498
    state->err = err;
592
    state->err = err;
499
    if (msg == NULL)
593
    if (msg == NULL)
Line 500... Line 594...
500
        return;
594
        return;
501
 
595
 
502
    /* for an out of memory error, save as static string */
-
 
503
    if (err == Z_MEM_ERROR) {
596
    /* for an out of memory error, return literal string when requested */
504
        state->msg = (char *)msg;
-
 
Line 505... Line 597...
505
        return;
597
    if (err == Z_MEM_ERROR)
506
    }
598
        return;
-
 
599
 
507
 
600
    /* construct error message with path */
508
    /* construct error message with path */
-
 
509
    if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
601
    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
510
        state->err = Z_MEM_ERROR;
602
            NULL) {
-
 
603
        state->err = Z_MEM_ERROR;
-
 
604
        return;
-
 
605
    }
-
 
606
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
511
        state->msg = (char *)"out of memory";
607
    snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
512
        return;
608
             "%s%s%s", state->path, ": ", msg);
513
    }
609
#else
-
 
610
    strcpy(state->msg, state->path);
514
    strcpy(state->msg, state->path);
611
    strcat(state->msg, ": ");
515
    strcat(state->msg, ": ");
612
    strcat(state->msg, msg);
Line 516... Line 613...
516
    strcat(state->msg, msg);
613
#endif
517
    return;
614
    return;