/// <summary> /// Resets this InfBlocks class instance /// </summary> internal void reset(ZStream z, long[] c) { if (c != null) { c[0] = check; } if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE) { blens = null; } if (mode == InflateBlockMode.CODES) { codes.free(z); } mode = InflateBlockMode.TYPE; BitK = 0; BitB = 0; ReadPos = WritePos = 0; if (this.needCheck) { z.adler = check = Adler32.GetAdler32Checksum(0L, null, 0, 0); } }
/// <summary> /// Block processing functions /// </summary> internal int proc(ZStream z, int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output Window WritePos pointer int m; // bytes to End of Window or ReadPos pointer // copy input/output information to locals (UPDATE macro restores) { p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; } { q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } // process input based on current state while (true) { switch (mode) { case InflateBlockMode.TYPE: while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = (int)(b & 7); last = t & 1; switch (ZLibUtil.URShift(t, 1)) { case 0: // stored { b = ZLibUtil.URShift(b, (3)); k -= (3); } t = k & 7; // go to byte boundary { b = ZLibUtil.URShift(b, (t)); k -= (t); } mode = InflateBlockMode.LENS; // get length of stored block break; case 1: // fixed { int[] bl = new int[1]; int[] bd = new int[1]; int[][] tl = new int[1][]; int[][] td = new int[1][]; InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z); } { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.CODES; break; case 2: // dynamic { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.TABLE; break; case 3: // illegal { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.BAD; z.msg = "invalid block type"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } break; case InflateBlockMode.LENS: while (k < (32)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (((ZLibUtil.URShift((~b), 16)) & 0xffff) != (b & 0xffff)) { mode = InflateBlockMode.BAD; z.msg = "invalid stored block lengths"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } left = (b & 0xffff); b = k = 0; // dump bits mode = (left != 0) ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); break; case InflateBlockMode.STORED: if (n == 0) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } if (m == 0) { if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } if (m == 0) { WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } if (m == 0) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } } } r = (int)ZLibResultCode.Z_OK; t = left; if (t > n) { t = n; } if (t > m) { t = m; } Array.Copy(z.next_in, p, Window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) { break; } mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; break; case InflateBlockMode.TABLE: while (k < (14)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } table = t = (b & 0x3fff); if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { mode = InflateBlockMode.BAD; z.msg = "too many length or distance symbols"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); blens = new int[t]; { b = ZLibUtil.URShift(b, (14)); k -= (14); } index = 0; mode = InflateBlockMode.BTREE; goto case InflateBlockMode.BTREE; case InflateBlockMode.BTREE: while (index < 4 + (ZLibUtil.URShift(table, 10))) { while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } blens[ZLibUtil.border[index++]] = b & 7; { b = ZLibUtil.URShift(b, (3)); k -= (3); } } while (index < 19) { blens[ZLibUtil.border[index++]] = 0; } bb[0] = 7; t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != (int)ZLibResultCode.Z_OK) { r = t; if (r == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } index = 0; mode = InflateBlockMode.DTREE; goto case InflateBlockMode.DTREE; case InflateBlockMode.DTREE: while (true) { t = table; if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int i, j, c; t = bb[0]; while (k < (t)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 2]; if (c < 16) { b = ZLibUtil.URShift(b, (t)); k -= (t); blens[index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } b = ZLibUtil.URShift(b, (t)); k -= (t); j += (b & ZLibUtil.inflate_mask[i]); b = ZLibUtil.URShift(b, (i)); k -= (i); i = index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { blens = null; mode = InflateBlockMode.BAD; z.msg = "invalid bit length repeat"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } c = c == 16 ? blens[i - 1] : 0; do { blens[i++] = c; }while (--j != 0); index = i; } } tb[0] = -1; { int[] bl = new int[1]; int[] bd = new int[1]; int[] tl = new int[1]; int[] td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z); if (t != (int)ZLibResultCode.Z_OK) { if (t == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } r = t; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); } blens = null; mode = InflateBlockMode.CODES; goto case InflateBlockMode.CODES; case InflateBlockMode.CODES: BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; if ((r = codes.proc(this, z, r)) != (int)ZLibResultCode.Z_STREAM_END) { return(inflate_flush(z, r)); } r = (int)ZLibResultCode.Z_OK; codes.free(z); p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (last == 0) { mode = InflateBlockMode.TYPE; break; } mode = InflateBlockMode.DRY; goto case InflateBlockMode.DRY; case InflateBlockMode.DRY: WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (ReadPos != WritePos) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } mode = InflateBlockMode.DONE; goto case InflateBlockMode.DONE; case InflateBlockMode.DONE: r = (int)ZLibResultCode.Z_STREAM_END; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); case InflateBlockMode.BAD: r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); default: r = (int)ZLibResultCode.Z_STREAM_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return(inflate_flush(z, r)); } } }
/// <summary> /// Block processing functions /// </summary> internal int proc(ZStream z, int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output Window WritePos pointer int m; // bytes to End of Window or ReadPos pointer // copy input/output information to locals (UPDATE macro restores) { p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; } { q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } // process input based on current state while (true) { switch (mode) { case InflateBlockMode.TYPE: while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = (int)(b & 7); last = t & 1; switch (ZLibUtil.URShift(t, 1)) { case 0: // stored { b = ZLibUtil.URShift(b, (3)); k -= (3); } t = k & 7; // go to byte boundary { b = ZLibUtil.URShift(b, (t)); k -= (t); } mode = InflateBlockMode.LENS; // get length of stored block break; case 1: // fixed { int[] bl = new int[1]; int[] bd = new int[1]; int[][] tl = new int[1][]; int[][] td = new int[1][]; InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z); } { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.CODES; break; case 2: // dynamic { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.TABLE; break; case 3: // illegal { b = ZLibUtil.URShift(b, (3)); k -= (3); } mode = InflateBlockMode.BAD; z.msg = "invalid block type"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } break; case InflateBlockMode.LENS: while (k < (32)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (((ZLibUtil.URShift((~b), 16)) & 0xffff) != (b & 0xffff)) { mode = InflateBlockMode.BAD; z.msg = "invalid stored block lengths"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } left = (b & 0xffff); b = k = 0; // dump bits mode = (left != 0) ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); break; case InflateBlockMode.STORED: if (n == 0) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } if (m == 0) { if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } if (m == 0) { WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (q == End && ReadPos != 0) { q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); } if (m == 0) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } } } r = (int)ZLibResultCode.Z_OK; t = left; if (t > n) t = n; if (t > m) t = m; Array.Copy(z.next_in, p, Window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) break; mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; break; case InflateBlockMode.TABLE: while (k < (14)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } table = t = (b & 0x3fff); if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { mode = InflateBlockMode.BAD; z.msg = "too many length or distance symbols"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); blens = new int[t]; { b = ZLibUtil.URShift(b, (14)); k -= (14); } index = 0; mode = InflateBlockMode.BTREE; goto case InflateBlockMode.BTREE; case InflateBlockMode.BTREE: while (index < 4 + (ZLibUtil.URShift(table, 10))) { while (k < (3)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } blens[ZLibUtil.border[index++]] = b & 7; { b = ZLibUtil.URShift(b, (3)); k -= (3); } } while (index < 19) { blens[ZLibUtil.border[index++]] = 0; } bb[0] = 7; t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != (int)ZLibResultCode.Z_OK) { r = t; if (r == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } index = 0; mode = InflateBlockMode.DTREE; goto case InflateBlockMode.DTREE; case InflateBlockMode.DTREE: while (true) { t = table; if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int i, j, c; t = bb[0]; while (k < (t)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 2]; if (c < 16) { b = ZLibUtil.URShift(b, (t)); k -= (t); blens[index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = (int)ZLibResultCode.Z_OK; } else { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } b = ZLibUtil.URShift(b, (t)); k -= (t); j += (b & ZLibUtil.inflate_mask[i]); b = ZLibUtil.URShift(b, (i)); k -= (i); i = index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { blens = null; mode = InflateBlockMode.BAD; z.msg = "invalid bit length repeat"; r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } c = c == 16 ? blens[i - 1] : 0; do { blens[i++] = c; } while (--j != 0); index = i; } } tb[0] = -1; { int[] bl = new int[1]; int[] bd = new int[1]; int[] tl = new int[1]; int[] td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z); if (t != (int)ZLibResultCode.Z_OK) { if (t == (int)ZLibResultCode.Z_DATA_ERROR) { blens = null; mode = InflateBlockMode.BAD; } r = t; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); } blens = null; mode = InflateBlockMode.CODES; goto case InflateBlockMode.CODES; case InflateBlockMode.CODES: BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; if ((r = codes.proc(this, z, r)) != (int)ZLibResultCode.Z_STREAM_END) { return inflate_flush(z, r); } r = (int)ZLibResultCode.Z_OK; codes.free(z); p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK; q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (last == 0) { mode = InflateBlockMode.TYPE; break; } mode = InflateBlockMode.DRY; goto case InflateBlockMode.DRY; case InflateBlockMode.DRY: WritePos = q; r = inflate_flush(z, r); q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q); if (ReadPos != WritePos) { BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } mode = InflateBlockMode.DONE; goto case InflateBlockMode.DONE; case InflateBlockMode.DONE: r = (int)ZLibResultCode.Z_STREAM_END; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); case InflateBlockMode.BAD: r = (int)ZLibResultCode.Z_DATA_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); default: r = (int)ZLibResultCode.Z_STREAM_ERROR; BitB = b; BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; WritePos = q; return inflate_flush(z, r); } } }