/// <summary> /// Constructor which takes literal, distance trees, corresponding bites decoded for branches and a ZStream object /// </summary> internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z) { mode = InflateCodesMode.START; lbits = (byte)bl; dbits = (byte)bd; ltree = tl; ltree_index = 0; dtree = td; dtree_index = 0; }
/// <summary> /// Block processing method /// </summary> /// <param name="s">An instance of the InfBlocks class</param> /// <param name="z">A ZStream object</param> /// <param name="r">A result code</param> 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 WritePos pointer int m; // bytes to End of Window or ReadPos 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.WritePos; m = q < s.ReadPos?s.ReadPos - 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 InflateCodesMode.START: // x: set up for InflateCodesMode.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.WritePos = 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.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (r != (int)ZLibResultCode.Z_OK) { mode = r == (int)ZLibResultCode.Z_STREAM_END? InflateCodesMode.WASH: InflateCodesMode.BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = InflateCodesMode.LEN; goto case InflateCodesMode.LEN; case InflateCodesMode.LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.inflate_mask[j])) * 3; b = ZLibUtil.URShift(b, (tree[tindex + 1])); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = InflateCodesMode.LIT; break; } if ((e & 16) != 0) { // length get_Renamed = e & 15; count = tree[tindex + 2]; mode = InflateCodesMode.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 = InflateCodesMode.WASH; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid literal/length code"; r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.LENEXT: // i: getting length extra (have base) j = get_Renamed; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } count += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = InflateCodesMode.DIST; goto case InflateCodesMode.DIST; case InflateCodesMode.DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.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 = InflateCodesMode.DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid distance code"; r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.DISTEXT: // i: getting distance extra j = get_Renamed; while (k < (j)) { if (n != 0) r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; mode = InflateCodesMode.COPY; goto case InflateCodesMode.COPY; case InflateCodesMode.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 (count != 0) { if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - 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.WritePos = q; return s.inflate_flush(z, r); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) f = 0; count--; } mode = InflateCodesMode.START; break; case InflateCodesMode.LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - 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.WritePos = q; return s.inflate_flush(z, r); } } } r = (int)ZLibResultCode.Z_OK; s.Window[q++] = (byte) lit; m--; mode = InflateCodesMode.START; break; case InflateCodesMode.WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (s.ReadPos != s.WritePos) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return s.inflate_flush(z, r); } mode = InflateCodesMode.END; goto case InflateCodesMode.END; case InflateCodesMode.END: r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); case InflateCodesMode.BADCODE: // x: got error r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); default: r = (int)ZLibResultCode.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.WritePos = q; return s.inflate_flush(z, r); } } }
/// <summary> /// Constructor which takes literal, distance trees, corresponding bites decoded for branches and a ZStream object /// </summary> internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z) { mode = InflateCodesMode.START; lbits = (byte) bl; dbits = (byte) bd; ltree = tl; ltree_index = 0; dtree = td; dtree_index = 0; }
/// <summary> /// Block processing method /// </summary> /// <param name="s">An instance of the InfBlocks class</param> /// <param name="z">A ZStream object</param> /// <param name="r">A result code</param> 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 WritePos pointer int m; // bytes to End of Window or ReadPos 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.WritePos; m = q < s.ReadPos?s.ReadPos - 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 InflateCodesMode.START: // x: set up for InflateCodesMode.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.WritePos = 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.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (r != (int)ZLibResultCode.Z_OK) { mode = r == (int)ZLibResultCode.Z_STREAM_END? InflateCodesMode.WASH: InflateCodesMode.BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = InflateCodesMode.LEN; goto case InflateCodesMode.LEN; case InflateCodesMode.LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) { r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.inflate_mask[j])) * 3; b = ZLibUtil.URShift(b, (tree[tindex + 1])); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = InflateCodesMode.LIT; break; } if ((e & 16) != 0) { // length get_Renamed = e & 15; count = tree[tindex + 2]; mode = InflateCodesMode.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 = InflateCodesMode.WASH; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid literal/length code"; r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); case InflateCodesMode.LENEXT: // i: getting length extra (have base) j = get_Renamed; while (k < (j)) { if (n != 0) { r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } count += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = InflateCodesMode.DIST; goto case InflateCodesMode.DIST; case InflateCodesMode.DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) { r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & ZLibUtil.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 = InflateCodesMode.DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = InflateCodesMode.BADCODE; // invalid code z.msg = "invalid distance code"; r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); case InflateCodesMode.DISTEXT: // i: getting distance extra j = get_Renamed; while (k < (j)) { if (n != 0) { r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & ZLibUtil.inflate_mask[j]); b >>= j; k -= j; mode = InflateCodesMode.COPY; goto case InflateCodesMode.COPY; case InflateCodesMode.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 (count != 0) { if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - 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.WritePos = q; return(s.inflate_flush(z, r)); } } } s.Window[q++] = s.Window[f++]; m--; if (f == s.End) { f = 0; } count--; } mode = InflateCodesMode.START; break; case InflateCodesMode.LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; } if (m == 0) { s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (q == s.End && s.ReadPos != 0) { q = 0; m = q < s.ReadPos?s.ReadPos - 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.WritePos = q; return(s.inflate_flush(z, r)); } } } r = (int)ZLibResultCode.Z_OK; s.Window[q++] = (byte)lit; m--; mode = InflateCodesMode.START; break; case InflateCodesMode.WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.WritePos = q; r = s.inflate_flush(z, r); q = s.WritePos; m = q < s.ReadPos?s.ReadPos - q - 1:s.End - q; if (s.ReadPos != s.WritePos) { s.BitB = b; s.BitK = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.WritePos = q; return(s.inflate_flush(z, r)); } mode = InflateCodesMode.END; goto case InflateCodesMode.END; case InflateCodesMode.END: r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); case InflateCodesMode.BADCODE: // x: got error r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); default: r = (int)ZLibResultCode.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.WritePos = q; return(s.inflate_flush(z, r)); } } }