using System; namespace Ionic.Zlib { internal sealed class InflateManager { internal bool HandleRfc1950HeaderBytes { get { return this._handleRfc1950HeaderBytes; } set { this._handleRfc1950HeaderBytes = value; } } private const int PRESET_DICT = 32; private const int Z_DEFLATED = 8; private InflateManager.InflateManagerMode mode; internal ZlibCodec _codec; internal int method; internal uint computedCheck; internal uint expectedCheck; internal int marker; private bool _handleRfc1950HeaderBytes = true; internal int wbits; internal InflateBlocks blocks; private static readonly byte[] mark = new byte[] { 0, 0, byte.MaxValue, byte.MaxValue }; private enum InflateManagerMode { METHOD, FLAG, DICT4, DICT3, DICT2, DICT1, DICT0, BLOCKS, CHECK4, CHECK3, CHECK2, CHECK1, DONE, BAD } public InflateManager() { } public InflateManager(bool expectRfc1950HeaderBytes) { this._handleRfc1950HeaderBytes = expectRfc1950HeaderBytes; } public int Reset() { this._codec.TotalBytesIn = (this._codec.TotalBytesOut = 0L); this._codec.Message = null; this.mode = (this.HandleRfc1950HeaderBytes ? InflateManager.InflateManagerMode.METHOD : InflateManager.InflateManagerMode.BLOCKS); this.blocks.Reset(); return 0; } internal int End() { bool flag = this.blocks != null; if (flag) { 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; bool flag = w < 8 || w > 15; if (flag) { this.End(); throw new ZlibException("Bad window size."); } this.wbits = w; this.blocks = new InflateBlocks(codec, this.HandleRfc1950HeaderBytes ? this : null, 1 << w); this.Reset(); return 0; } internal int Inflate(FlushType flush) { bool flag = this._codec.InputBuffer == null; if (flag) { throw new ZlibException("InputBuffer is null. "); } int num = 0; int num2 = -5; int nextIn; for (;;) { switch (this.mode) { case InflateManager.InflateManagerMode.METHOD: { bool flag2 = this._codec.AvailableBytesIn == 0; if (flag2) { goto Block_3; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; byte[] inputBuffer = this._codec.InputBuffer; ZlibCodec codec = this._codec; nextIn = codec.NextIn; codec.NextIn = nextIn + 1; bool flag3 = ((this.method = inputBuffer[nextIn]) & 15) != 8; if (flag3) { this.mode = InflateManager.InflateManagerMode.BAD; this._codec.Message = string.Format("unknown compression method (0x{0:X2})", this.method); this.marker = 5; continue; } bool flag4 = (this.method >> 4) + 8 > this.wbits; if (flag4) { this.mode = InflateManager.InflateManagerMode.BAD; this._codec.Message = string.Format("invalid window size ({0})", (this.method >> 4) + 8); this.marker = 5; continue; } this.mode = InflateManager.InflateManagerMode.FLAG; continue; } case InflateManager.InflateManagerMode.FLAG: { bool flag5 = this._codec.AvailableBytesIn == 0; if (flag5) { goto Block_6; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; byte[] inputBuffer2 = this._codec.InputBuffer; ZlibCodec codec2 = this._codec; nextIn = codec2.NextIn; codec2.NextIn = nextIn + 1; int num3 = inputBuffer2[nextIn] & 255; bool flag6 = ((this.method << 8) + num3) % 31 != 0; if (flag6) { this.mode = InflateManager.InflateManagerMode.BAD; this._codec.Message = "incorrect header check"; this.marker = 5; continue; } this.mode = (((num3 & 32) == 0) ? InflateManager.InflateManagerMode.BLOCKS : InflateManager.InflateManagerMode.DICT4); continue; } case InflateManager.InflateManagerMode.DICT4: { bool flag7 = this._codec.AvailableBytesIn == 0; if (flag7) { goto Block_9; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; byte[] inputBuffer3 = this._codec.InputBuffer; ZlibCodec codec3 = this._codec; nextIn = codec3.NextIn; codec3.NextIn = nextIn + 1; //! this.expectedCheck = (uint)(inputBuffer3[nextIn] << 24 & (long)(/*(ulong)*/-16777216)); this.mode = InflateManager.InflateManagerMode.DICT3; continue; } case InflateManager.InflateManagerMode.DICT3: { bool flag8 = this._codec.AvailableBytesIn == 0; if (flag8) { goto Block_10; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num4 = this.expectedCheck; byte[] inputBuffer4 = this._codec.InputBuffer; ZlibCodec codec4 = this._codec; nextIn = codec4.NextIn; codec4.NextIn = nextIn + 1; //! this.expectedCheck = (uint) ( num4 + (inputBuffer4[nextIn] << 16 & 16711680u)); this.mode = InflateManager.InflateManagerMode.DICT2; continue; } case InflateManager.InflateManagerMode.DICT2: { bool flag9 = this._codec.AvailableBytesIn == 0; if (flag9) { goto Block_11; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num5 = this.expectedCheck; byte[] inputBuffer5 = this._codec.InputBuffer; ZlibCodec codec5 = this._codec; nextIn = codec5.NextIn; codec5.NextIn = nextIn + 1; this.expectedCheck = (uint) (num5 + (inputBuffer5[nextIn] << 8 & 65280u)); //! this.mode = InflateManager.InflateManagerMode.DICT1; continue; } case InflateManager.InflateManagerMode.DICT1: goto IL_3EB; case InflateManager.InflateManagerMode.DICT0: goto IL_488; case InflateManager.InflateManagerMode.BLOCKS: { num2 = this.blocks.Process(num2); bool flag10 = num2 == -3; if (flag10) { this.mode = InflateManager.InflateManagerMode.BAD; this.marker = 0; continue; } bool flag11 = num2 == 0; if (flag11) { num2 = num; } bool flag12 = num2 != 1; if (flag12) { goto Block_15; } num2 = num; this.computedCheck = this.blocks.Reset(); bool flag13 = !this.HandleRfc1950HeaderBytes; if (flag13) { goto Block_16; } this.mode = InflateManager.InflateManagerMode.CHECK4; continue; } case InflateManager.InflateManagerMode.CHECK4: { bool flag14 = this._codec.AvailableBytesIn == 0; if (flag14) { goto Block_17; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; byte[] inputBuffer6 = this._codec.InputBuffer; ZlibCodec codec6 = this._codec; nextIn = codec6.NextIn; codec6.NextIn = nextIn + 1; //! this.expectedCheck = (uint)(inputBuffer6[nextIn] << 24 & (long)(-16777216)); this.mode = InflateManager.InflateManagerMode.CHECK3; continue; } case InflateManager.InflateManagerMode.CHECK3: { bool flag15 = this._codec.AvailableBytesIn == 0; if (flag15) { goto Block_18; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num6 = this.expectedCheck; byte[] inputBuffer7 = this._codec.InputBuffer; ZlibCodec codec7 = this._codec; nextIn = codec7.NextIn; codec7.NextIn = nextIn + 1; this.expectedCheck = (uint) (num6 + (inputBuffer7[nextIn] << 16 & 16711680u)); //! this.mode = InflateManager.InflateManagerMode.CHECK2; continue; } case InflateManager.InflateManagerMode.CHECK2: { bool flag16 = this._codec.AvailableBytesIn == 0; if (flag16) { goto Block_19; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num7 = this.expectedCheck; byte[] inputBuffer8 = this._codec.InputBuffer; ZlibCodec codec8 = this._codec; nextIn = codec8.NextIn; codec8.NextIn = nextIn + 1; this.expectedCheck = (uint) ( num7 + (inputBuffer8[nextIn] << 8 & 65280u) ); this.mode = InflateManager.InflateManagerMode.CHECK1; continue; } case InflateManager.InflateManagerMode.CHECK1: { bool flag17 = this._codec.AvailableBytesIn == 0; if (flag17) { goto Block_20; } num2 = num; this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num8 = this.expectedCheck; byte[] inputBuffer9 = this._codec.InputBuffer; ZlibCodec codec9 = this._codec; nextIn = codec9.NextIn; codec9.NextIn = nextIn + 1; this.expectedCheck = num8 + (inputBuffer9[nextIn] & 255u); bool flag18 = this.computedCheck != this.expectedCheck; if (flag18) { this.mode = InflateManager.InflateManagerMode.BAD; this._codec.Message = "incorrect data check"; this.marker = 5; continue; } goto IL_795; } case InflateManager.InflateManagerMode.DONE: goto IL_7A2; case InflateManager.InflateManagerMode.BAD: goto IL_7A7; } break; } throw new ZlibException("Stream error."); Block_3: return num2; Block_6: return num2; Block_9: return num2; Block_10: return num2; Block_11: return num2; IL_3EB: bool flag19 = this._codec.AvailableBytesIn == 0; if (flag19) { return num2; } this._codec.AvailableBytesIn--; this._codec.TotalBytesIn += 1L; uint num9 = this.expectedCheck; byte[] inputBuffer10 = this._codec.InputBuffer; ZlibCodec codec10 = this._codec; nextIn = codec10.NextIn; codec10.NextIn = nextIn + 1; this.expectedCheck = num9 + (inputBuffer10[nextIn] & 255u); this._codec._Adler32 = this.expectedCheck; this.mode = InflateManager.InflateManagerMode.DICT0; return 2; IL_488: this.mode = InflateManager.InflateManagerMode.BAD; this._codec.Message = "need dictionary"; this.marker = 0; return -2; Block_15: return num2; Block_16: this.mode = InflateManager.InflateManagerMode.DONE; return 1; Block_17: return num2; Block_18: return num2; Block_19: return num2; Block_20: return num2; IL_795: this.mode = InflateManager.InflateManagerMode.DONE; return 1; IL_7A2: return 1; IL_7A7: throw new ZlibException(string.Format("Bad state ({0})", this._codec.Message)); } internal int SetDictionary(byte[] dictionary) { int start = 0; int num = dictionary.Length; bool flag = this.mode != InflateManager.InflateManagerMode.DICT0; if (flag) { throw new ZlibException("Stream error."); } bool flag2 = Adler.Adler32(1u, dictionary, 0, dictionary.Length) != this._codec._Adler32; int result; if (flag2) { result = -3; } else { this._codec._Adler32 = Adler.Adler32(0u, null, 0, 0); bool flag3 = num >= 1 << this.wbits; if (flag3) { num = (1 << this.wbits) - 1; start = dictionary.Length - num; } this.blocks.SetDictionary(dictionary, start, num); this.mode = InflateManager.InflateManagerMode.BLOCKS; result = 0; } return result; } internal int Sync() { bool flag = this.mode != InflateManager.InflateManagerMode.BAD; if (flag) { this.mode = InflateManager.InflateManagerMode.BAD; this.marker = 0; } int num; bool flag2 = (num = this._codec.AvailableBytesIn) == 0; int result; if (flag2) { result = -5; } else { int num2 = this._codec.NextIn; int num3 = this.marker; while (num != 0 && num3 < 4) { bool flag3 = this._codec.InputBuffer[num2] == InflateManager.mark[num3]; if (flag3) { num3++; } else { bool flag4 = this._codec.InputBuffer[num2] > 0; if (flag4) { num3 = 0; } else { num3 = 4 - num3; } } num2++; num--; } this._codec.TotalBytesIn += (long)(num2 - this._codec.NextIn); this._codec.NextIn = num2; this._codec.AvailableBytesIn = num; this.marker = num3; bool flag5 = num3 != 4; if (flag5) { result = -3; } else { long totalBytesIn = this._codec.TotalBytesIn; long totalBytesOut = this._codec.TotalBytesOut; this.Reset(); this._codec.TotalBytesIn = totalBytesIn; this._codec.TotalBytesOut = totalBytesOut; this.mode = InflateManager.InflateManagerMode.BLOCKS; result = 0; } } return result; } internal int SyncPoint(ZlibCodec z) { return this.blocks.SyncPoint(); } } }