<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

InfBlocks

sealed class InfBlocks
using System; namespace Org.BouncyCastle.Utilities.Zlib { internal sealed class InfBlocks { private const int MANY = 1440; private static readonly int[] inflate_mask = new int[17] { 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535 }; private static readonly int[] border = new int[19] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; private const int Z_OK = 0; private const int Z_STREAM_END = 1; private const int Z_NEED_DICT = 2; private const int Z_ERRNO = -1; private const int Z_STREAM_ERROR = -2; private const int Z_DATA_ERROR = -3; private const int Z_MEM_ERROR = -4; private const int Z_BUF_ERROR = -5; private const int Z_VERSION_ERROR = -6; private const int TYPE = 0; private const int LENS = 1; private const int STORED = 2; private const int TABLE = 3; private const int BTREE = 4; private const int DTREE = 5; private const int CODES = 6; private const int DRY = 7; private const int DONE = 8; private const int BAD = 9; internal int mode; internal int left; internal int table; internal int index; internal int[] blens; internal int[] bb = new int[1]; internal int[] tb = new int[1]; internal InfCodes codes = new InfCodes(); private int last; internal int bitk; internal int bitb; internal int[] hufts; internal byte[] window; internal int end; internal int read; internal int write; internal object checkfn; internal long check; internal InfTree inftree = new InfTree(); internal InfBlocks(ZStream z, object checkfn, int w) { hufts = new int[4320]; window = new byte[w]; end = w; this.checkfn = checkfn; mode = 0; reset(z, null); } internal void reset(ZStream z, long[] c) { if (c != null) c[0] = check; if (mode != 4) { int mode2 = mode; } if (mode == 6) codes.free(z); mode = 0; bitk = 0; bitb = 0; read = (write = 0); if (checkfn != null) z.adler = (check = z._adler.adler32(0, null, 0, 0)); } internal int proc(ZStream z, int r) { int num = z.next_in_index; int num2 = z.avail_in; int num3 = bitb; int i = bitk; int num4 = write; int num5 = (num4 < read) ? (read - num4 - 1) : (end - num4); while (true) { switch (mode) { case 0: { for (; i < 3; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } int num7 = num3 & 7; last = (num7 & 1); switch (num7 >> 1) { case 0: num3 >>= 3; i -= 3; num7 = (i & 7); num3 >>= num7; i -= num7; mode = 1; break; case 1: { int[] array5 = new int[1]; int[] array6 = new int[1]; int[][] array7 = new int[1][]; int[][] array8 = new int[1][]; InfTree.inflate_trees_fixed(array5, array6, array7, array8, z); codes.init(array5[0], array6[0], array7[0], 0, array8[0], 0, z); num3 >>= 3; i -= 3; mode = 6; break; } case 2: num3 >>= 3; i -= 3; mode = 3; break; case 3: num3 >>= 3; i -= 3; mode = 9; z.msg = "invalid block type"; r = -3; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } break; } case 1: for (; i < 32; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } if (((~num3 >> 16) & 65535) != (num3 & 65535)) { mode = 9; z.msg = "invalid stored block lengths"; r = -3; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } left = (num3 & 65535); num3 = (i = 0); mode = ((left != 0) ? 2 : ((last != 0) ? 7 : 0)); break; case 2: { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } if (num5 == 0) { if (num4 == end && read != 0) { num4 = 0; num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); } if (num5 == 0) { write = num4; r = inflate_flush(z, r); num4 = write; num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); if (num4 == end && read != 0) { num4 = 0; num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); } if (num5 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } } } r = 0; int num7 = left; if (num7 > num2) num7 = num2; if (num7 > num5) num7 = num5; Array.Copy(z.next_in, num, window, num4, num7); num += num7; num2 -= num7; num4 += num7; num5 -= num7; if ((left -= num7) == 0) mode = ((last != 0) ? 7 : 0); break; } case 3: { for (; i < 14; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } int num7 = table = (num3 & 16383); if ((num7 & 31) > 29 || ((num7 >> 5) & 31) > 29) { mode = 9; z.msg = "too many length or distance symbols"; r = -3; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } num7 = 258 + (num7 & 31) + ((num7 >> 5) & 31); if (blens == null || blens.Length < num7) blens = new int[num7]; else { for (int j = 0; j < num7; j++) { blens[j] = 0; } } num3 >>= 14; i -= 14; index = 0; mode = 4; goto case 4; } case 4: { while (index < 4 + (table >> 10)) { for (; i < 3; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } blens[border[index++]] = (num3 & 7); num3 >>= 3; i -= 3; } while (index < 19) { blens[border[index++]] = 0; } bb[0] = 7; int num7 = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); if (num7 != 0) { r = num7; if (r == -3) { blens = null; mode = 9; } bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } index = 0; mode = 5; goto case 5; } case 5: { int num7; while (true) { num7 = table; if (index >= 258 + (num7 & 31) + ((num7 >> 5) & 31)) break; for (num7 = bb[0]; i < num7; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } int num17 = tb[0]; num7 = hufts[(tb[0] + (num3 & inflate_mask[num7])) * 3 + 1]; int num11 = hufts[(tb[0] + (num3 & inflate_mask[num7])) * 3 + 2]; if (num11 < 16) { num3 >>= num7; i -= num7; blens[index++] = num11; } else { int num12 = (num11 == 18) ? 7 : (num11 - 14); int num13 = (num11 == 18) ? 11 : 3; for (; i < num7 + num12; i += 8) { if (num2 == 0) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } r = 0; num2--; num3 |= (z.next_in[num++] & 255) << i; } num3 >>= num7; i -= num7; num13 += (num3 & inflate_mask[num12]); num3 >>= num12; i -= num12; num12 = index; num7 = table; if (num12 + num13 > 258 + (num7 & 31) + ((num7 >> 5) & 31) || (num11 == 16 && num12 < 1)) { blens = null; mode = 9; z.msg = "invalid bit length repeat"; r = -3; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } num11 = ((num11 == 16) ? blens[num12 - 1] : 0); do { blens[num12++] = num11; } while (--num13 != 0); index = num12; } } tb[0] = -1; int[] array = new int[1]; int[] array2 = new int[1]; int[] array3 = new int[1]; int[] array4 = new int[1]; array[0] = 9; array2[0] = 6; num7 = table; num7 = inftree.inflate_trees_dynamic(257 + (num7 & 31), 1 + ((num7 >> 5) & 31), blens, array, array2, array3, array4, hufts, z); switch (num7) { case -3: blens = null; mode = 9; goto default; default: r = num7; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); case 0: break; } codes.init(array[0], array2[0], hufts, array3[0], hufts, array4[0], z); mode = 6; goto case 6; } case 6: bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; if ((r = codes.proc(this, z, r)) != 1) return inflate_flush(z, r); r = 0; codes.free(z); num = z.next_in_index; num2 = z.avail_in; num3 = bitb; i = bitk; num4 = write; num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); if (last == 0) { mode = 0; break; } mode = 7; goto case 7; case 7: write = num4; r = inflate_flush(z, r); num4 = write; num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); if (read != write) { bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } mode = 8; goto case 8; case 8: r = 1; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); case 9: r = -3; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); default: r = -2; bitb = num3; bitk = i; z.avail_in = num2; z.total_in += num - z.next_in_index; z.next_in_index = num; write = num4; return inflate_flush(z, r); } } } internal void free(ZStream z) { reset(z, null); window = null; hufts = null; } internal void set_dictionary(byte[] d, int start, int n) { Array.Copy(d, start, window, 0, n); read = (write = n); } internal int sync_point() { return (mode == 1) ? 1 : 0; } internal int inflate_flush(ZStream z, int r) { int next_out_index = z.next_out_index; int num = read; int num2 = ((num <= write) ? write : end) - num; if (num2 > z.avail_out) num2 = z.avail_out; if (num2 != 0 && r == -5) r = 0; z.avail_out -= num2; z.total_out += num2; if (checkfn != null) z.adler = (check = z._adler.adler32(check, window, num, num2)); Array.Copy(window, num, z.next_out, next_out_index, num2); next_out_index += num2; num += num2; if (num == end) { num = 0; if (write == end) write = 0; num2 = write - num; if (num2 > z.avail_out) num2 = z.avail_out; if (num2 != 0 && r == -5) r = 0; z.avail_out -= num2; z.total_out += num2; if (checkfn != null) z.adler = (check = z._adler.adler32(check, window, num, num2)); Array.Copy(window, num, z.next_out, next_out_index, num2); next_out_index += num2; num += num2; } z.next_out_index = next_out_index; read = num; return r; } } }