internal int inflateInit(ZStream z, int w) { z.msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) nowrap = 0; if (w < 0) { w = -w; nowrap = 1; } // set window size if (w < 8 || w > 15) { inflateEnd(z); return(Z_STREAM_ERROR); } wbits = w; z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0?null:this, 1 << w); // reset state inflateReset(z); return(Z_OK); }
internal ZlibCompressionState InflateInit(ZStream z, int w) { z.Msg = null; this.Blocks = null; // handle undocumented nowrap option (no zlib header or check) this.Nowrap = 0; if (w < 0) { w = -w; this.Nowrap = 1; } // set window size if (w < 8 || w > 15) { _ = this.InflateEnd(z); return(ZlibCompressionState.ZSTREAMERROR); } this.Wbits = w; z.Istate.Blocks = new InfBlocks(z, z.Istate.Nowrap != 0 ? null : this, 1 << w); // reset state _ = InflateReset(z); return(ZlibCompressionState.ZOK); }
internal int InflateInit(ZStream z, int w) { z.Msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) Nowrap = 0; if (w < 0) { w = -w; Nowrap = 1; } // set window size if (w < 8 || w > 15) { InflateEnd(z); return(ZStreamError); } Wbits = w; z.Istate.blocks = new InfBlocks(z, z.Istate.Nowrap != 0 ? null : this, 1 << w); // reset state InflateReset(z); return(ZOk); }
internal int inflateEnd(ZStream z) { if (blocks != null) blocks.free(z); blocks = null; // ZFREE(z, z->state); return Z_OK; }
internal int inflateEnd(ZStream z) { if (blocks != null) { blocks.free(z); } blocks = null; return(0); }
internal int inflateEnd(ZStream z) { if (blocks != null) { blocks.free(z); } blocks = null; // ZFREE(z, z->state); return(Z_OK); }
internal ZlibCompressionState InflateEnd(ZStream z) { if (this.Blocks != null) { this.Blocks.Free(z); } this.Blocks = null; // ZFREE(z, z->state); return(ZlibCompressionState.ZOK); }
internal int inflateInit(ZStream z, int w) { z.msg = null; blocks = null; nowrap = 0; if (w < 0) { w = -w; nowrap = 1; } if (w < 8 || w > 15) { inflateEnd(z); return(-2); } wbits = w; z.istate.blocks = new InfBlocks(z, (z.istate.nowrap == 0) ? this : null, 1 << w); inflateReset(z); return(0); }
internal int inflateInit(ZStream z, int w) { z.msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) nowrap = 0; if (w < 0) { w = -w; nowrap = 1; } // set window size if (w < 8 || w > 15) { inflateEnd(z); return Z_STREAM_ERROR; } wbits = w; z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0 ? null : this, 1 << w); // reset state inflateReset(z); return Z_OK; }
// Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ // distance pair plus four bytes for overloading the bit buffer. internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer int tp_index_t_3; // (tp_index+t)*3 // load input, output, bit values p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; // do until not enough input or output space for fast loop do // assume called with m >= 258 && n >= 10 // get literal/length code { while (k < (20)) // max bits for literal/length code { n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & ml; tp = tl; tp_index = tl_index; tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = (byte)tp[tp_index_t_3 + 2]; m--; continue; } do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[tp_index_t_3 + 2] + ((int)b & inflate_mask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) // max bits for distance code { n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & md; tp = td; tp_index = td_index; tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) // get extra bits (up to 13) { n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) // offset before dest // just copy { r = q - d; if (q - r > 0 && 2 > (q - r)) { s.window[q++] = s.window[r++]; // minimum count is three, s.window[q++] = s.window[r++]; // so unroll loop a little c -= 2; } else { System.Array.Copy(s.window, r, s.window, q, 2); q += 2; r += 2; c -= 2; } } else // else offset after destination { r = q - d; do { r += s.end; // force pointer in window }while(r < 0); // covers invalid distances e = s.end - r; if (c > e) // if source crosses, { c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.window[q++] = s.window[r++]; }while(--e != 0); } else { System.Array.Copy(s.window, r, s.window, q, e); q += e; r += e; e = 0; } r = 0; // copy rest from start of window } } // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.window[q++] = s.window[r++]; }while(--c != 0); } else { System.Array.Copy(s.window, r, s.window, q, c); q += c; r += c; c = 0; } break; } else if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; } else { z.msg = "invalid distance code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(Z_DATA_ERROR); } }while(true); break; } if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = (byte)tp[tp_index_t_3 + 2]; m--; break; } } else if ((e & 32) != 0) { c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(Z_STREAM_END); } else { z.msg = "invalid literal/length code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(Z_DATA_ERROR); } }while(true); }while(m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(Z_OK); }
internal int proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; // process input and output based on current state while (true) { switch (mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case START: // x: set up for LEN if (m >= 258 && n >= 10) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (r != Z_OK) { mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = LEN; goto case LEN; case LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>= (tree[tindex + 1]); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) // literal { lit = tree[tindex + 2]; mode = LIT; break; } if ((e & 16) != 0) // length { get = e & 15; len = tree[tindex + 2]; mode = LENEXT; break; } if ((e & 64) == 0) // next table { need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } if ((e & 32) != 0) // end of block { mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); case LENEXT: // i: getting length extra (have base) j = get; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } len += (b & inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = DIST; goto case DIST; case DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 16) != 0) // distance { get = e & 15; dist = tree[tindex + 2]; mode = DISTEXT; break; } if ((e & 64) == 0) // next table { need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); case DISTEXT: // i: getting distance extra j = get; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & inflate_mask[j]); b >>= j; k -= j; mode = COPY; goto case COPY; case COPY: // o: copying bytes in window, waiting for space f = q - dist; while (f < 0) // modulo window size-"while" instead { f += s.end; // of "if" handles invalid distances } while (len != 0) { if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } } } s.window[q++] = s.window[f++]; m--; if (f == s.end) { f = 0; } len--; } mode = START; break; case LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } } } r = Z_OK; s.window[q++] = (byte)lit; m--; mode = START; break; case WASH: // o: got eob, possibly more output if (k > 7) // return unused byte, if any { k -= 8; n++; p--; // can always return one } s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (s.read != s.write) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } mode = END; goto case END; case END: r = Z_STREAM_END; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); case BADCODE: // x: got error r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); default: r = Z_STREAM_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return(s.inflate_flush(z, r)); } } }
internal int proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage //int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; // process input and output based on current state while (true) { switch (mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case START: // x: set up for LEN if (m >= 258 && n >= 10) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (r != Z_OK) { mode = r == Z_STREAM_END?WASH:BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = LEN; goto case LEN; case LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b = SupportClass.URShift(b, (tree[tindex + 1])); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = LIT; break; } if ((e & 16) != 0) { // length get_Renamed = e & 15; len = tree[tindex + 2]; mode = LENEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); case LENEXT: // i: getting length extra (have base) j = get_Renamed; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } len += (b & inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = DIST; goto case DIST; case DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 16) != 0) { // distance get_Renamed = e & 15; dist = tree[tindex + 2]; mode = DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); case DISTEXT: // i: getting distance extra j = get_Renamed; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & inflate_mask[j]); b >>= j; k -= j; mode = COPY; goto case COPY; case COPY: // o: copying bytes in window, waiting for space f = q - dist; while (f < 0) { // modulo window size-"while" instead f += s.end; // of "if" handles invalid distances } while (len != 0) { if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } } } s.window[q++] = s.window[f++]; m--; if (f == s.end) f = 0; len--; } mode = START; break; case LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read?s.read - q - 1:s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } } } r = Z_OK; s.window[q++] = (byte) lit; m--; mode = START; break; case WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.write = q; r = s.inflate_flush(z, r); q = s.write; m = q < s.read?s.read - q - 1:s.end - q; if (s.read != s.write) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } mode = END; goto case END; case END: r = Z_STREAM_END; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); case BADCODE: // x: got error r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); default: r = Z_STREAM_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(z, r); } } }
// Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ // distance pair plus four bytes for overloading the bit buffer. internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer // load input, output, bit values p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read?s.read - q - 1:s.end - q; // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; // do until not enough input or output space for fast loop do { // assume called with m >= 258 && n >= 10 // get literal/length code while (k < (20)) { // max bits for literal/length code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & ml; tp = tl; tp_index = tl_index; if ((e = tp[(tp_index + t) * 3]) == 0) { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); s.window[q++] = (byte) tp[(tp_index + t) * 3 + 2]; m--; continue; } do { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[(tp_index + t) * 3 + 2] + ((int) b & inflate_mask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) { // max bits for distance code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & md; tp = td; tp_index = td_index; e = tp[(tp_index + t) * 3]; do { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) { // get extra bits (up to 13) n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } d = tp[(tp_index + t) * 3 + 2] + (b & inflate_mask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) { // offset before dest // just copy r = q - d; if (q - r > 0 && 2 > (q - r)) { s.window[q++] = s.window[r++]; c--; // minimum count is three, s.window[q++] = s.window[r++]; c--; // so unroll loop a little } else { Array.Copy(s.window, r, s.window, q, 2); q += 2; r += 2; c -= 2; } } else { // else offset after destination r = q - d; do { r += s.end; // force pointer in window } while (r < 0); // covers invalid distances e = s.end - r; if (c > e) { // if source crosses, c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--e != 0); } else { Array.Copy(s.window, r, s.window, q, e); q += e; r += e; e = 0; } r = 0; // copy rest from start of window } } // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--c != 0); } else { Array.Copy(s.window, r, s.window, q, c); q += c; r += c; c = 0; } break; } else if ((e & 64) == 0) { t += tp[(tp_index + t) * 3 + 2]; t += (b & inflate_mask[e]); e = tp[(tp_index + t) * 3]; } else { z.msg = "invalid distance code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } while (true); break; } if ((e & 64) == 0) { t += tp[(tp_index + t) * 3 + 2]; t += (b & inflate_mask[e]); if ((e = tp[(tp_index + t) * 3]) == 0) { b >>= (tp[(tp_index + t) * 3 + 1]); k -= (tp[(tp_index + t) * 3 + 1]); s.window[q++] = (byte) tp[(tp_index + t) * 3 + 2]; m--; break; } } else if ((e & 32) != 0) { c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_STREAM_END; } else { z.msg = "invalid literal/length code"; c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } while (true); } while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.avail_in - n; c = (k >> 3) < c?k >> 3:c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_OK; }
internal int Proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; // process input and output based on current state while (true) { switch (_mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case Start: // x: set up for LEN if (m >= 258 && n >= 10) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; r = inflate_fast(_lbits, _dbits, _ltree, _ltreeIndex, _dtree, _dtreeIndex, s, z); p = z.NextInIndex; n = z.AvailIn; b = s.Bitb; k = s.Bitk; q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (r != ZOk) { _mode = r == ZStreamEnd ? Wash : Badcode; break; } } _need = _lbits; _tree = _ltree; _treeIndex = _ltreeIndex; _mode = Len; goto case Len; case Len: // i: get length/literal/eob next j = _need; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } tindex = (_treeIndex + (b & _inflateMask[j])) * 3; b >>= (_tree[tindex + 1]); k -= (_tree[tindex + 1]); e = _tree[tindex]; if (e == 0) { // literal _lit = _tree[tindex + 2]; _mode = Lit; break; } if ((e & 16) != 0) { // length _get = e & 15; _len = _tree[tindex + 2]; _mode = Lenext; break; } if ((e & 64) == 0) { // next table _need = e; _treeIndex = tindex / 3 + _tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block _mode = Wash; break; } _mode = Badcode; // invalid code z.Msg = "invalid literal/length code"; r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Lenext: // i: getting length extra (have base) j = _get; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } _len += (b & _inflateMask[j]); b >>= j; k -= j; _need = _dbits; _tree = _dtree; _treeIndex = _dtreeIndex; _mode = Dist; goto case Dist; case Dist: // i: get distance next j = _need; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } tindex = (_treeIndex + (b & _inflateMask[j])) * 3; b >>= _tree[tindex + 1]; k -= _tree[tindex + 1]; e = (_tree[tindex]); if ((e & 16) != 0) { // distance _get = e & 15; _dist = _tree[tindex + 2]; _mode = Distext; break; } if ((e & 64) == 0) { // next table _need = e; _treeIndex = tindex / 3 + _tree[tindex + 2]; break; } _mode = Badcode; // invalid code z.Msg = "invalid distance code"; r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Distext: // i: getting distance extra j = _get; while (k < (j)) { if (n != 0) { r = ZOk; } else { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } n--; b |= (z.NextIn[p++] & 0xff) << k; k += 8; } _dist += (b & _inflateMask[j]); b >>= j; k -= j; _mode = Copy; goto case Copy; case Copy: // o: copying bytes in window, waiting for space f = q - _dist; while (f < 0) { // modulo window size-"while" instead f += s.End; // of "if" handles invalid distances } while (_len != 0) { if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) { f = 0; } _len--; } _mode = Start; break; case Lit: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (q == s.End && s.Read != 0) { q = 0; m = q < s.Read ? s.Read - q - 1 : s.End - q; } if (m == 0) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } } r = ZOk; s.Window[q++] = (byte)_lit; m--; _mode = Start; break; case Wash: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.Write = q; r = s.inflate_flush(z, r); q = s.Write; m = q < s.Read ? s.Read - q - 1 : s.End - q; if (s.Read != s.Write) { s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } _mode = End; goto case End; case End: r = ZStreamEnd; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); case Badcode: // x: got error r = ZDataError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); default: r = ZStreamError; s.Bitb = b; s.Bitk = k; z.AvailIn = n; z.TotalIn += p - z.NextInIndex; z.NextInIndex = p; s.Write = q; return(s.inflate_flush(z, r)); } } }