internal int End() { if (this.blocks != null) { this.blocks.Free(); } this.blocks = null; return(0); }
internal int Initialize(ZlibCodec codec, int w) { this._codec = codec; this._codec.Message = null; this.blocks = null; if ((w < 8) || (w > 15)) { this.End(); throw new ZlibException("Bad window size."); } this.wbits = w; this.blocks = new InflateBlocks(codec, !this.HandleRfc1950HeaderBytes ? null : this, 1 << (w & 0x1f)); this.Reset(); return(0); }
internal int Process(InflateBlocks blocks, 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 ZlibCodec z = blocks._codec; // copy input/output information to locals (UPDATE macro restores) p = z.NextIn; n = z.AvailableBytesIn; b = blocks.bitb; k = blocks.bitk; q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.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) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z); p = z.NextIn; n = z.AvailableBytesIn; b = blocks.bitb; k = blocks.bitk; q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if (r != ZlibConstants.Z_OK) { mode = (r == ZlibConstants.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 = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } n--; b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & InternalInflateConstants.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 bitsToGet = 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.Message = "invalid literal/length code"; r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); case LENEXT: // i: getting length extra (have base) j = bitsToGet; while (k < j) { if (n != 0) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } n--; b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; } len += (b & InternalInflateConstants.InflateMask[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 = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } n--; b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 0x10) != 0) { // distance bitsToGet = 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.Message = "invalid distance code"; r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); case DISTEXT: // i: getting distance extra j = bitsToGet; while (k < j) { if (n != 0) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } n--; b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; } dist += (b & InternalInflateConstants.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 += blocks.end; // of "if" handles invalid distances } while (len != 0) { if (m == 0) { if (q == blocks.end && blocks.readAt != 0) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if (m == 0) { blocks.writeAt = q; r = blocks.Flush(r); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if (q == blocks.end && blocks.readAt != 0) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if (m == 0) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } } } blocks.window[q++] = blocks.window[f++]; m--; if (f == blocks.end) f = 0; len--; } mode = START; break; case LIT: // o: got literal, waiting for output space if (m == 0) { if (q == blocks.end && blocks.readAt != 0) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if (m == 0) { blocks.writeAt = q; r = blocks.Flush(r); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if (q == blocks.end && blocks.readAt != 0) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if (m == 0) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } } } r = ZlibConstants.Z_OK; blocks.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 } blocks.writeAt = q; r = blocks.Flush(r); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if (blocks.readAt != blocks.writeAt) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } mode = END; goto case END; case END: r = ZlibConstants.Z_STREAM_END; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); case BADCODE: // x: got error r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); default: r = ZlibConstants.Z_STREAM_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush(r); } } }
internal int Initialize(ZlibCodec codec, int w) { _codec = codec; _codec.Message = 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) { End(); throw new ZlibException("Bad window size."); //return ZlibConstants.Z_STREAM_ERROR; } wbits = w; blocks = new InflateBlocks(codec, HandleRfc1950HeaderBytes ? this : null, 1 << w); // reset state Reset(); return ZlibConstants.Z_OK; }
internal int End() { if (blocks != null) blocks.Free(); blocks = null; return ZlibConstants.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 InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec 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.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk; q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q; // initialize masks ml = InternalInflateConstants.InflateMask[bl]; md = InternalInflateConstants.InflateMask[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.InputBuffer[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] + (b & InternalInflateConstants.InflateMask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < 15) { // max bits for distance code n--; b |= (z.InputBuffer[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.InputBuffer[p++] & 0xff) << k; k += 8; } d = tp[tp_index_t_3 + 2] + (b & InternalInflateConstants.InflateMask[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 { 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 & InternalInflateConstants.InflateMask[e]); tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; } else { z.Message = "invalid distance code"; c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_DATA_ERROR; } } while (true); break; } if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & InternalInflateConstants.InflateMask[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.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_STREAM_END; } else { z.Message = "invalid literal/length code"; c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_DATA_ERROR; } } while (true); } while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_OK; }
internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z) { int nextIn = z.NextIn; int availableBytesIn = z.AvailableBytesIn; int bitb = s.bitb; int bitk = s.bitk; int writeAt = s.writeAt; int num9 = (writeAt >= s.readAt) ? (s.end - writeAt) : ((s.readAt - writeAt) - 1); int num10 = InternalInflateConstants.InflateMask[bl]; int num11 = InternalInflateConstants.InflateMask[bd]; while (true) { int num12; if (bitk < 20) { availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; continue; } int num = bitb & num10; int[] numArray = tl; int num2 = tl_index; int index = (num2 + num) * 3; int num3 = numArray[index]; if (num3 == 0) { bitb = bitb >> (numArray[index + 1] & 0x1f); bitk -= numArray[index + 1]; s.window[writeAt++] = (byte)numArray[index + 2]; num9--; } else { while (true) { bitb = bitb >> (numArray[index + 1] & 0x1f); bitk -= numArray[index + 1]; if ((num3 & 0x10) == 0) { if ((num3 & 0x40) != 0) { if ((num3 & 0x20) != 0) { num12 = z.AvailableBytesIn - availableBytesIn; num12 = ((bitk >> 3) >= num12) ? num12 : (bitk >> 3); availableBytesIn += num12; nextIn -= num12; bitk -= num12 << 3; s.bitb = bitb; s.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; s.writeAt = writeAt; return(1); } z.Message = "invalid literal/length code"; num12 = z.AvailableBytesIn - availableBytesIn; num12 = ((bitk >> 3) >= num12) ? num12 : (bitk >> 3); availableBytesIn += num12; nextIn -= num12; bitk -= num12 << 3; s.bitb = bitb; s.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; s.writeAt = writeAt; return(-3); } index = (num2 + ((num + numArray[index + 2]) + (bitb & InternalInflateConstants.InflateMask[num3]))) * 3; num3 = numArray[index]; if (num3 != 0) { continue; } bitb = bitb >> (numArray[index + 1] & 0x1f); bitk -= numArray[index + 1]; s.window[writeAt++] = (byte)numArray[index + 2]; num9--; } else { num3 &= 15; num12 = numArray[index + 2] + (bitb & InternalInflateConstants.InflateMask[num3]); bitb = bitb >> (num3 & 0x1f); bitk -= num3; while (true) { if (bitk >= 15) { num = bitb & num11; numArray = td; num2 = td_index; index = (num2 + num) * 3; num3 = numArray[index]; while (true) { bitb = bitb >> (numArray[index + 1] & 0x1f); bitk -= numArray[index + 1]; if ((num3 & 0x10) != 0) { num3 &= 15; while (true) { if (bitk >= num3) { int num14; int num13 = numArray[index + 2] + (bitb & InternalInflateConstants.InflateMask[num3]); bitb = bitb >> (num3 & 0x1f); bitk -= num3; num9 -= num12; if (writeAt >= num13) { num14 = writeAt - num13; if (((writeAt - num14) > 0) && (2 > (writeAt - num14))) { s.window[writeAt++] = s.window[num14++]; s.window[writeAt++] = s.window[num14++]; num12 -= 2; } else { Array.Copy(s.window, num14, s.window, writeAt, 2); writeAt += 2; num14 += 2; num12 -= 2; } } else { num14 = writeAt - num13; while (true) { num14 += s.end; if (num14 >= 0) { num3 = s.end - num14; if (num12 > num3) { num12 -= num3; if (((writeAt - num14) <= 0) || (num3 <= (writeAt - num14))) { Array.Copy(s.window, num14, s.window, writeAt, num3); writeAt += num3; num14 += num3; num3 = 0; } else { do { s.window[writeAt++] = s.window[num14++]; }while (--num3 != 0); } num14 = 0; } break; } } } if (((writeAt - num14) <= 0) || (num12 <= (writeAt - num14))) { Array.Copy(s.window, num14, s.window, writeAt, num12); writeAt += num12; num14 += num12; num12 = 0; } else { do { s.window[writeAt++] = s.window[num14++]; }while (--num12 != 0); } break; } availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } break; } if ((num3 & 0x40) != 0) { z.Message = "invalid distance code"; num12 = z.AvailableBytesIn - availableBytesIn; num12 = ((bitk >> 3) >= num12) ? num12 : (bitk >> 3); availableBytesIn += num12; nextIn -= num12; bitk -= num12 << 3; s.bitb = bitb; s.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; s.writeAt = writeAt; return(-3); } index = (num2 + ((num + numArray[index + 2]) + (bitb & InternalInflateConstants.InflateMask[num3]))) * 3; num3 = numArray[index]; } break; } availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } } break; } } if ((num9 < 0x102) || (availableBytesIn < 10)) { num12 = z.AvailableBytesIn - availableBytesIn; num12 = ((bitk >> 3) >= num12) ? num12 : (bitk >> 3); availableBytesIn += num12; nextIn -= num12; bitk -= num12 << 3; s.bitb = bitb; s.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; s.writeAt = writeAt; return(0); } } }
internal int Process(InflateBlocks blocks, int r) { int bitsToGet; int num2; int num3; int bitb = 0; int bitk = 0; int nextIn = 0; ZlibCodec z = blocks._codec; nextIn = z.NextIn; int availableBytesIn = z.AvailableBytesIn; bitb = blocks.bitb; bitk = blocks.bitk; int writeAt = blocks.writeAt; int num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); goto TR_0058; TR_0011: bitsToGet = this.need; while (true) { if (bitk >= bitsToGet) { num2 = (this.tree_index + (bitb & InternalInflateConstants.InflateMask[bitsToGet])) * 3; bitb = bitb >> (this.tree[num2 + 1] & 0x1f); bitk -= this.tree[num2 + 1]; num3 = this.tree[num2]; if (num3 == 0) { this.lit = this.tree[num2 + 2]; this.mode = 6; } else if ((num3 & 0x10) != 0) { this.bitsToGet = num3 & 15; this.len = this.tree[num2 + 2]; this.mode = 2; } else if ((num3 & 0x40) == 0) { this.need = num3; this.tree_index = (num2 / 3) + this.tree[num2 + 2]; } else { if ((num3 & 0x20) == 0) { this.mode = 9; z.Message = "invalid literal/length code"; r = -3; blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } this.mode = 7; } break; } if (availableBytesIn == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } r = 0; availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } goto TR_0058; TR_0021: bitsToGet = this.need; while (true) { if (bitk >= bitsToGet) { num2 = (this.tree_index + (bitb & InternalInflateConstants.InflateMask[bitsToGet])) * 3; bitb = bitb >> (this.tree[num2 + 1] & 0x1f); bitk -= this.tree[num2 + 1]; num3 = this.tree[num2]; if ((num3 & 0x10) != 0) { this.bitsToGet = num3 & 15; this.dist = this.tree[num2 + 2]; this.mode = 4; } else { if ((num3 & 0x40) != 0) { this.mode = 9; z.Message = "invalid distance code"; r = -3; blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } this.need = num3; this.tree_index = (num2 / 3) + this.tree[num2 + 2]; } break; } if (availableBytesIn == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } r = 0; availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } goto TR_0058; TR_004F: r = 1; blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); TR_0058: while (true) { int mode = this.mode; switch (mode) { case 0: if ((num9 >= 0x102) && (availableBytesIn >= 10)) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; r = this.InflateFast(this.lbits, this.dbits, this.ltree, this.ltree_index, this.dtree, this.dtree_index, blocks, z); nextIn = z.NextIn; availableBytesIn = z.AvailableBytesIn; bitb = blocks.bitb; bitk = blocks.bitk; writeAt = blocks.writeAt; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); if (r != 0) { this.mode = (r != 1) ? 9 : 7; continue; } } this.need = this.lbits; this.tree = this.ltree; this.tree_index = this.ltree_index; this.mode = 1; goto TR_0011; case 1: goto TR_0011; case 2: bitsToGet = this.bitsToGet; while (true) { if (bitk >= bitsToGet) { this.len += bitb & InternalInflateConstants.InflateMask[bitsToGet]; bitb = bitb >> (bitsToGet & 0x1f); bitk -= bitsToGet; this.need = this.dbits; this.tree = this.dtree; this.tree_index = this.dtree_index; this.mode = 3; break; } if (availableBytesIn == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } r = 0; availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } goto TR_0021; case 3: goto TR_0021; case 4: bitsToGet = this.bitsToGet; while (true) { if (bitk >= bitsToGet) { this.dist += bitb & InternalInflateConstants.InflateMask[bitsToGet]; bitb = bitb >> (bitsToGet & 0x1f); bitk -= bitsToGet; this.mode = 5; break; } if (availableBytesIn == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } r = 0; availableBytesIn--; bitb |= (z.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f); bitk += 8; } break; case 5: break; case 6: { if (num9 == 0) { if ((writeAt == blocks.end) && (blocks.readAt != 0)) { writeAt = 0; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); } if (num9 == 0) { blocks.writeAt = writeAt; r = blocks.Flush(r); writeAt = blocks.writeAt; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); if ((writeAt == blocks.end) && (blocks.readAt != 0)) { writeAt = 0; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); } if (num9 == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } } } r = 0; blocks.window[writeAt++] = (byte)this.lit; num9--; this.mode = 0; continue; } case 7: if (bitk > 7) { bitk -= 8; availableBytesIn++; nextIn--; } blocks.writeAt = writeAt; r = blocks.Flush(r); writeAt = blocks.writeAt; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); if (blocks.readAt != blocks.writeAt) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } this.mode = 8; goto TR_004F; case 8: goto TR_004F; case 9: r = -3; blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); default: r = -2; blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } int num10 = writeAt - this.dist; while (true) { if (num10 >= 0) { while (true) { if (this.len == 0) { this.mode = 0; break; } if (num9 == 0) { if ((writeAt == blocks.end) && (blocks.readAt != 0)) { writeAt = 0; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); } if (num9 == 0) { blocks.writeAt = writeAt; r = blocks.Flush(r); writeAt = blocks.writeAt; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); if ((writeAt == blocks.end) && (blocks.readAt != 0)) { writeAt = 0; num9 = (writeAt >= blocks.readAt) ? (blocks.end - writeAt) : ((blocks.readAt - writeAt) - 1); } if (num9 == 0) { blocks.bitb = bitb; blocks.bitk = bitk; z.AvailableBytesIn = availableBytesIn; z.TotalBytesIn += nextIn - z.NextIn; z.NextIn = nextIn; blocks.writeAt = writeAt; return(blocks.Flush(r)); } } } blocks.window[writeAt++] = blocks.window[num10++]; num9--; if (num10 == blocks.end) { num10 = 0; } this.len--; } break; } num10 += blocks.end; } } goto TR_004F; }