windowBitsisintherange8..15,andwindowisauser-supplied windowandoutputbufferthatis2**windowBitsbytes.
*/ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsignedchar FAR *window, constchar *version, int stream_size) { struct inflate_state FAR *state;
/* do this just once */
virgin = 0;
} #else/* !BUILDFIXED */ # include "inffixed.h" #endif/* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */ #define LOAD() \ do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */ #define INITBITS() \ do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \
have = in(in_desc, &next); \ if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \ goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */ #define PULLBYTE() \ do { \
PULL(); \
have--; \
hold += (unsignedlong)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is notenoughavailableinputtodothat,thenreturnfrominflateBack()with
an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window ifit'sfull.Ifthewritefails,returnfrominflateBack()witha
Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \ if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \ goto inf_leave; \
} \
} \
} while (0)
in()shouldreturnzeroonfailure.out()shouldreturnnon-zeroon failure.Ifeitherin()orout()fails,thaninflateBack()returnsa Z_BUF_ERROR.strm->next_incanbecheckedforZ_NULLtoseewhetherit wasin()orout()thatcausedintheerror.Otherwise,inflateBack() returnsZ_STREAM_ENDonsuccess,Z_DATA_ERRORforandeflateformat error,orZ_MEM_ERRORifitcouldnotallocatememoryforthestate. inflateBack()canalsoreturnZ_STREAM_ERRORiftheinputparameters arenotcorrect,i.e.strmisZ_NULLorthestatewasnotinitialized.
*/ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc) { struct inflate_state FAR *state;
z_const unsignedchar FAR *next; /* next input */ unsignedchar FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsignedlong hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsignedchar FAR *from; /* where to copy match bytes from */
code here; /* current decoding table entry */
code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ staticconstunsignedshort order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* get length and distance code code lengths */
state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) {
here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
} if (here.val < 16) {
DROPBITS(here.bits);
state->lens[state->have++] = here.val;
} else { if (here.val == 16) {
NEEDBITS(here.bits + 2);
DROPBITS(here.bits); if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD; break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
} elseif (here.val == 17) {
NEEDBITS(here.bits + 3);
DROPBITS(here.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
} else {
NEEDBITS(here.bits + 7);
DROPBITS(here.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
} if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD; break;
} while (copy--)
state->lens[state->have++] = (unsignedshort)len;
}
}
/* handle error breaks in while */ if (state->mode == BAD) break;
/* check for end-of-block code (better have one) */ if (state->lens[256] == 0) {
strm->msg = (char *)"invalid code -- missing end-of-block";
state->mode = BAD; break;
}
/* build code tables -- note: do not change the lenbits or distbits valueshere(9and6)withoutreadingthecommentsininftrees.h
concerning the ENOUGH constants, which depend on those values */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work); if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD; break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work); if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD; break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN; /* fallthrough */
case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) {
RESTORE(); if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD(); break;
}
/* get a literal, length, or end-of-block code */ for (;;) {
here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
} if (here.op && (here.op & 0xf0) == 0) {
last = here; for (;;) {
here = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(here.bits);
state->length = (unsigned)here.val;
/* length code -- get extra bits, if any */
state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */ for (;;) {
here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break;
PULLBYTE();
} if ((here.op & 0xf0) == 0) {
last = here; for (;;) {
here = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(here.bits); if (here.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD; break;
}
state->offset = (unsigned)here.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
} if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD; break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */ do {
ROOM();
copy = state->wsize - state->offset; if (copy < left) {
from = put + copy;
copy = left - copy;
} else {
from = put - state->offset;
copy = left;
} if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy; do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0); break;
case DONE: /* inflate stream terminated properly */
ret = Z_STREAM_END; goto inf_leave;
case BAD:
ret = Z_DATA_ERROR; goto inf_leave;
default: /* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR; goto inf_leave;
}
/* Write leftover output and return unused input */
inf_leave: if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left) &&
ret == Z_STREAM_END)
ret = Z_BUF_ERROR;
}
strm->next_in = next;
strm->avail_in = have; return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.