Lines Matching +full:- +full:state
2 * - gz_statep was converted to union to work with -Wstrict-aliasing=1 */
4 /* gzread.c -- zlib functions for reading gzip files
12 * see https://github.com/facebook/zstd/issues/1800#issuecomment-545945050 */
28 /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
29 …state.state->fd, and update state.state->eof, state.state->err, and state.state->msg as appropriat…
32 local int gz_load(state, buf, len, have) in gz_load() argument
33 gz_statep state; in gz_load()
39 unsigned get, max = ((unsigned)-1 >> 2) + 1;
43 get = len - *have;
46 ret = read(state.state->fd, buf + *have, get);
52 gz_error(state, Z_ERRNO, zstrerror());
53 return -1;
56 state.state->eof = 1;
60 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
64 If strm->avail_in != 0, then the current data is moved to the beginning of
67 local int gz_avail(state) in gz_avail() argument
68 gz_statep state; in gz_avail()
71 z_streamp strm = &(state.state->strm);
73 if (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)
74 return -1;
75 if (state.state->eof == 0) {
76 if (strm->avail_in) { /* copy what's there to the start */
77 unsigned char *p = state.state->in;
78 unsigned const char *q = strm->next_in;
79 unsigned n = strm->avail_in;
82 } while (--n);
84 if (gz_load(state, state.state->in + strm->avail_in,
85 state.state->size - strm->avail_in, &got) == -1)
86 return -1;
87 strm->avail_in += got;
88 strm->next_in = state.state->in;
93 /* Look for gzip header, set up for inflate or copy. state.state->x.have must be 0.
94 If this is the first time in, allocate required memory. state.state->how will be
100 a user buffer. If decompressing, the inflate state will be initialized.
101 gz_look() will return 0 on success or -1 on failure. */
102 local int gz_look(state) in gz_look() argument
103 gz_statep state; in gz_look()
105 z_streamp strm = &(state.state->strm);
108 if (state.state->size == 0) {
110 state.state->in = (unsigned char *)malloc(state.state->want);
111 state.state->out = (unsigned char *)malloc(state.state->want << 1);
112 if (state.state->in == NULL || state.state->out == NULL) {
113 free(state.state->out);
114 free(state.state->in);
115 gz_error(state, Z_MEM_ERROR, "out of memory");
116 return -1;
118 state.state->size = state.state->want;
121 state.state->strm.zalloc = Z_NULL;
122 state.state->strm.zfree = Z_NULL;
123 state.state->strm.opaque = Z_NULL;
124 state.state->strm.avail_in = 0;
125 state.state->strm.next_in = Z_NULL;
126 if (inflateInit2(&(state.state->strm), 15 + 16) != Z_OK) { /* gunzip */
127 free(state.state->out);
128 free(state.state->in);
129 state.state->size = 0;
130 gz_error(state, Z_MEM_ERROR, "out of memory");
131 return -1;
136 if (strm->avail_in < 2) {
137 if (gz_avail(state) == -1)
138 return -1;
139 if (strm->avail_in == 0)
143 /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
146 whether this is a single-byte file, or just a partially written gzip
147 file -- for here we assume that if a gzip file is being written, then
150 if (strm->avail_in > 1 &&
151 ((strm->next_in[0] == 31 && strm->next_in[1] == 139) /* gz header */
152 || (strm->next_in[0] == 40 && strm->next_in[1] == 181))) { /* zstd header */
154 state.state->how = GZIP;
155 state.state->direct = 0;
159 /* no gzip header -- if we were decoding gzip before, then this is trailing
161 if (state.state->direct == 0) {
162 strm->avail_in = 0;
163 state.state->eof = 1;
164 state.state->x.have = 0;
168 /* doing raw i/o, copy any leftover input to output -- this assumes that
171 state.state->x.next = state.state->out;
172 if (strm->avail_in) {
173 memcpy(state.state->x.next, strm->next_in, strm->avail_in);
174 state.state->x.have = strm->avail_in;
175 strm->avail_in = 0;
177 state.state->how = COPY;
178 state.state->direct = 1;
182 /* Decompress from input to the provided next_out and avail_out in the state.
183 On return, state.state->x.have and state.state->x.next point to the just decompressed
184 data. If the gzip stream completes, state.state->how is reset to LOOK to look for
185 the next gzip stream or raw data, once state.state->x.have is depleted. Returns 0
186 on success, -1 on failure. */
187 local int gz_decomp(state) in gz_decomp() argument
188 gz_statep state; in gz_decomp()
192 z_streamp strm = &(state.state->strm);
195 had = strm->avail_out;
198 if (strm->avail_in == 0 && gz_avail(state) == -1)
199 return -1;
200 if (strm->avail_in == 0) {
201 gz_error(state, Z_BUF_ERROR, "unexpected end of file");
208 gz_error(state, Z_STREAM_ERROR,
210 return -1;
213 gz_error(state, Z_MEM_ERROR, "out of memory");
214 return -1;
217 gz_error(state, Z_DATA_ERROR,
218 strm->msg == NULL ? "compressed data error" : strm->msg);
219 return -1;
221 } while (strm->avail_out && ret != Z_STREAM_END);
224 state.state->x.have = had - strm->avail_out;
225 state.state->x.next = strm->next_out - state.state->x.have;
229 state.state->how = LOOK;
235 /* Fetch data and put it in the output buffer. Assumes state.state->x.have is 0.
237 file depending on state.state->how. If state.state->how is LOOK, then a gzip header is
238 looked for to determine whether to copy or decompress. Returns -1 on error,
239 otherwise 0. gz_fetch() will leave state.state->how as COPY or GZIP unless the
241 local int gz_fetch(state) in gz_fetch() argument
242 gz_statep state; in gz_fetch()
244 z_streamp strm = &(state.state->strm);
247 switch(state.state->how) {
248 case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
249 if (gz_look(state) == -1)
250 return -1;
251 if (state.state->how == LOOK)
254 case COPY: /* -> COPY */
255 if (gz_load(state, state.state->out, state.state->size << 1, &(state.state->x.have))
256 == -1)
257 return -1;
258 state.state->x.next = state.state->out;
260 case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
261 strm->avail_out = state.state->size << 1;
262 strm->next_out = state.state->out;
263 if (gz_decomp(state) == -1)
264 return -1;
266 } while (state.state->x.have == 0 && (!state.state->eof || strm->avail_in));
270 /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
271 local int gz_skip(state, len) in gz_skip() argument
272 gz_statep state; in gz_skip()
277 /* skip over len bytes or reach end-of-file, whichever comes first */
280 if (state.state->x.have) {
281 n = GT_OFF(state.state->x.have) || (z_off64_t)state.state->x.have > len ?
282 (unsigned)len : state.state->x.have;
283 state.state->x.have -= n;
284 state.state->x.next += n;
285 state.state->x.pos += n;
286 len -= n;
289 /* output buffer empty -- return if we're at the end of the input */
290 else if (state.state->eof && state.state->strm.avail_in == 0)
293 /* need more data to skip -- load up output buffer */
296 if (gz_fetch(state) == -1)
297 return -1;
304 end of file was reached, or there was an error. state.state->err must be
306 local z_size_t gz_read(state, buf, len) in gz_read() argument
307 gz_statep state; in gz_read()
319 if (state.state->seek) {
320 state.state->seek = 0;
321 if (gz_skip(state, state.state->skip) == -1)
329 n = -1;
334 if (state.state->x.have) {
335 if (state.state->x.have < n)
336 n = state.state->x.have;
337 memcpy(buf, state.state->x.next, n);
338 state.state->x.next += n;
339 state.state->x.have -= n;
342 /* output buffer empty -- return if we're at the end of the input */
343 else if (state.state->eof && state.state->strm.avail_in == 0) {
344 state.state->past = 1; /* tried to read past end */
348 /* need output data -- for small len or new stream load up our output
350 else if (state.state->how == LOOK || n < (state.state->size << 1)) {
352 if (gz_fetch(state) == -1)
354 continue; /* no progress yet -- go back to copy above */
359 /* large len -- read directly into user buffer */
360 else if (state.state->how == COPY) { /* read directly */
361 if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
365 /* large len -- decompress directly into user buffer */
366 else { /* state.state->how == GZIP */
367 state.state->strm.avail_out = n;
368 state.state->strm.next_out = (unsigned char *)buf;
369 if (gz_decomp(state) == -1)
371 n = state.state->x.have;
372 state.state->x.have = 0;
376 len -= n;
379 state.state->x.pos += n;
386 /* -- see zlib.h -- */
392 gz_statep state; local
396 return -1;
397 state.file = file;
400 if (state.state->mode != GZ_READ ||
401 (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
402 return -1;
407 gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
408 return -1;
412 len = (unsigned)gz_read(state, buf, len);
415 if (len == 0 && state.state->err != Z_OK && state.state->err != Z_BUF_ERROR)
416 return -1;
422 /* -- see zlib.h -- */
430 gz_statep state; local
435 state.file = file;
438 if (state.state->mode != GZ_READ ||
439 (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
442 /* compute bytes to read -- error on overflow */
445 gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
450 return len ? gz_read(state, buf, len) / size : 0;
453 /* -- see zlib.h -- */
476 gz_statep state; local
480 return -1;
481 state.file = file;
484 if (state.state->mode != GZ_READ ||
485 (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
486 return -1;
489 if (state.state->x.have) {
490 state.state->x.have--;
491 state.state->x.pos++;
492 return *(state.state->x.next)++;
495 /* nothing there -- try gz_read() */
496 ret = (int)gz_read(state, buf, 1);
497 return ret < 1 ? -1 : buf[0];
506 /* -- see zlib.h -- */
511 gz_statep state; local
515 return -1;
516 state.file = file;
519 if (state.state->mode != GZ_READ ||
520 (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
521 return -1;
524 if (state.state->seek) {
525 state.state->seek = 0;
526 if (gz_skip(state, state.state->skip) == -1)
527 return -1;
532 return -1;
535 if (state.state->x.have == 0) {
536 state.state->x.have = 1;
537 state.state->x.next = state.state->out + (state.state->size << 1) - 1;
538 state.state->x.next[0] = (unsigned char)c;
539 state.state->x.pos--;
540 state.state->past = 0;
545 if (state.state->x.have == (state.state->size << 1)) {
546 gz_error(state, Z_DATA_ERROR, "out of room to push characters");
547 return -1;
551 if (state.state->x.next == state.state->out) {
552 unsigned char *src = state.state->out + state.state->x.have;
553 unsigned char *dest = state.state->out + (state.state->size << 1);
554 while (src > state.state->out)
555 *--dest = *--src;
556 state.state->x.next = dest;
558 state.state->x.have++;
559 state.state->x.next--;
560 state.state->x.next[0] = (unsigned char)c;
561 state.state->x.pos--;
562 state.state->past = 0;
566 /* -- see zlib.h -- */
575 gz_statep state; local
580 state.file = file;
583 if (state.state->mode != GZ_READ ||
584 (state.state->err != Z_OK && state.state->err != Z_BUF_ERROR))
588 if (state.state->seek) {
589 state.state->seek = 0;
590 if (gz_skip(state, state.state->skip) == -1)
594 /* copy output bytes up to new line or len - 1, whichever comes first --
598 left = (unsigned)len - 1;
601 if (state.state->x.have == 0 && gz_fetch(state) == -1)
603 if (state.state->x.have == 0) { /* end of file */
604 state.state->past = 1; /* read past end */
608 /* look for end-of-line in current output buffer */
609 n = state.state->x.have > left ? left : state.state->x.have;
610 eol = (unsigned char *)memchr(state.state->x.next, '\n', n);
612 n = (unsigned)(eol - state.state->x.next) + 1;
614 /* copy through end-of-line, or remainder if not found */
615 memcpy(buf, state.state->x.next, n);
616 state.state->x.have -= n;
617 state.state->x.next += n;
618 state.state->x.pos += n;
619 left -= n;
630 /* -- see zlib.h -- */
634 gz_statep state; local
639 state.file = file;
641 /* if the state is not known, but we can find out, then do so (this is
643 if (state.state->mode == GZ_READ && state.state->how == LOOK && state.state->x.have == 0)
644 (void)gz_look(state);
647 return state.state->direct;
650 /* -- see zlib.h -- */
655 gz_statep state; local
660 state.file = file;
663 if (state.state->mode != GZ_READ)
667 if (state.state->size) {
668 inflateEnd(&(state.state->strm));
669 free(state.state->out);
670 free(state.state->in);
672 err = state.state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
673 gz_error(state, Z_OK, NULL);
674 free(state.state->path);
675 ret = close(state.state->fd);
676 free(state.state);