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