using System; using ICSharpCode.SharpZipLib.Checksums; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; namespace ICSharpCode.SharpZipLib.Zip.Compression { // Token: 0x02000047 RID: 71 public class Inflater { // Token: 0x060002C9 RID: 713 RVA: 0x0000F5A2 File Offset: 0x0000E5A2 public Inflater() : this(false) { } // Token: 0x060002CA RID: 714 RVA: 0x0000F5AB File Offset: 0x0000E5AB public Inflater(bool noHeader) { this.noHeader = noHeader; this.adler = new Adler32(); this.input = new StreamManipulator(); this.outputWindow = new OutputWindow(); this.mode = (noHeader ? 2 : 0); } // Token: 0x060002CB RID: 715 RVA: 0x0000F5E8 File Offset: 0x0000E5E8 public void Reset() { this.mode = (this.noHeader ? 2 : 0); this.totalIn = 0L; this.totalOut = 0L; this.input.Reset(); this.outputWindow.Reset(); this.dynHeader = null; this.litlenTree = null; this.distTree = null; this.isLastBlock = false; this.adler.Reset(); } // Token: 0x060002CC RID: 716 RVA: 0x0000F654 File Offset: 0x0000E654 private bool DecodeHeader() { int num = this.input.PeekBits(16); if (num < 0) { return false; } this.input.DropBits(16); num = ((num << 8) | (num >> 8)) & 65535; if (num % 31 != 0) { throw new SharpZipBaseException("Header checksum illegal"); } if ((num & 3840) != 2048) { throw new SharpZipBaseException("Compression Method unknown"); } if ((num & 32) == 0) { this.mode = 2; } else { this.mode = 1; this.neededBits = 32; } return true; } // Token: 0x060002CD RID: 717 RVA: 0x0000F6DC File Offset: 0x0000E6DC private bool DecodeDict() { while (this.neededBits > 0) { int num = this.input.PeekBits(8); if (num < 0) { return false; } this.input.DropBits(8); this.readAdler = (this.readAdler << 8) | num; this.neededBits -= 8; } return false; } // Token: 0x060002CE RID: 718 RVA: 0x0000F734 File Offset: 0x0000E734 private bool DecodeHuffman() { int i = this.outputWindow.GetFreeSpace(); while (i >= 258) { int num; switch (this.mode) { case 7: while (((num = this.litlenTree.GetSymbol(this.input)) & -256) == 0) { this.outputWindow.Write(num); if (--i < 258) { return true; } } if (num >= 257) { try { this.repLength = Inflater.CPLENS[num - 257]; this.neededBits = Inflater.CPLEXT[num - 257]; } catch (Exception) { throw new SharpZipBaseException("Illegal rep length code"); } goto IL_C5; } if (num < 0) { return false; } this.distTree = null; this.litlenTree = null; this.mode = 2; return true; case 8: goto IL_C5; case 9: goto IL_114; case 10: break; default: throw new SharpZipBaseException("Inflater unknown mode"); } IL_154: if (this.neededBits > 0) { this.mode = 10; int num2 = this.input.PeekBits(this.neededBits); if (num2 < 0) { return false; } this.input.DropBits(this.neededBits); this.repDist += num2; } this.outputWindow.Repeat(this.repLength, this.repDist); i -= this.repLength; this.mode = 7; continue; IL_114: num = this.distTree.GetSymbol(this.input); if (num < 0) { return false; } try { this.repDist = Inflater.CPDIST[num]; this.neededBits = Inflater.CPDEXT[num]; } catch (Exception) { throw new SharpZipBaseException("Illegal rep dist code"); } goto IL_154; IL_C5: if (this.neededBits > 0) { this.mode = 8; int num3 = this.input.PeekBits(this.neededBits); if (num3 < 0) { return false; } this.input.DropBits(this.neededBits); this.repLength += num3; } this.mode = 9; goto IL_114; } return true; } // Token: 0x060002CF RID: 719 RVA: 0x0000F93C File Offset: 0x0000E93C private bool DecodeChksum() { while (this.neededBits > 0) { int num = this.input.PeekBits(8); if (num < 0) { return false; } this.input.DropBits(8); this.readAdler = (this.readAdler << 8) | num; this.neededBits -= 8; } if ((int)this.adler.Value != this.readAdler) { throw new SharpZipBaseException(string.Concat(new object[] { "Adler chksum doesn't match: ", (int)this.adler.Value, " vs. ", this.readAdler })); } this.mode = 12; return false; } // Token: 0x060002D0 RID: 720 RVA: 0x0000F9F4 File Offset: 0x0000E9F4 private bool Decode() { switch (this.mode) { case 0: return this.DecodeHeader(); case 1: return this.DecodeDict(); case 2: if (this.isLastBlock) { if (this.noHeader) { this.mode = 12; return false; } this.input.SkipToByteBoundary(); this.neededBits = 32; this.mode = 11; return true; } else { int num = this.input.PeekBits(3); if (num < 0) { return false; } this.input.DropBits(3); if ((num & 1) != 0) { this.isLastBlock = true; } switch (num >> 1) { case 0: this.input.SkipToByteBoundary(); this.mode = 3; break; case 1: this.litlenTree = InflaterHuffmanTree.defLitLenTree; this.distTree = InflaterHuffmanTree.defDistTree; this.mode = 7; break; case 2: this.dynHeader = new InflaterDynHeader(); this.mode = 6; break; default: throw new SharpZipBaseException("Unknown block type " + num); } return true; } break; case 3: if ((this.uncomprLen = this.input.PeekBits(16)) < 0) { return false; } this.input.DropBits(16); this.mode = 4; break; case 4: break; case 5: goto IL_1A9; case 6: if (!this.dynHeader.Decode(this.input)) { return false; } this.litlenTree = this.dynHeader.BuildLitLenTree(); this.distTree = this.dynHeader.BuildDistTree(); this.mode = 7; goto IL_22D; case 7: case 8: case 9: case 10: goto IL_22D; case 11: return this.DecodeChksum(); case 12: return false; default: throw new SharpZipBaseException("Inflater.Decode unknown mode"); } int num2 = this.input.PeekBits(16); if (num2 < 0) { return false; } this.input.DropBits(16); if (num2 != (this.uncomprLen ^ 65535)) { throw new SharpZipBaseException("broken uncompressed block"); } this.mode = 5; IL_1A9: int num3 = this.outputWindow.CopyStored(this.input, this.uncomprLen); this.uncomprLen -= num3; if (this.uncomprLen == 0) { this.mode = 2; return true; } return !this.input.IsNeedingInput; IL_22D: return this.DecodeHuffman(); } // Token: 0x060002D1 RID: 721 RVA: 0x0000FC41 File Offset: 0x0000EC41 public void SetDictionary(byte[] buffer) { this.SetDictionary(buffer, 0, buffer.Length); } // Token: 0x060002D2 RID: 722 RVA: 0x0000FC50 File Offset: 0x0000EC50 public void SetDictionary(byte[] buffer, int index, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (index < 0) { throw new ArgumentOutOfRangeException("index"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (!this.IsNeedingDictionary) { throw new InvalidOperationException("Dictionary is not needed"); } this.adler.Update(buffer, index, count); if ((int)this.adler.Value != this.readAdler) { throw new SharpZipBaseException("Wrong adler checksum"); } this.adler.Reset(); this.outputWindow.CopyDict(buffer, index, count); this.mode = 2; } // Token: 0x060002D3 RID: 723 RVA: 0x0000FCE9 File Offset: 0x0000ECE9 public void SetInput(byte[] buffer) { this.SetInput(buffer, 0, buffer.Length); } // Token: 0x060002D4 RID: 724 RVA: 0x0000FCF6 File Offset: 0x0000ECF6 public void SetInput(byte[] buffer, int index, int count) { this.input.SetInput(buffer, index, count); this.totalIn += (long)count; } // Token: 0x060002D5 RID: 725 RVA: 0x0000FD15 File Offset: 0x0000ED15 public int Inflate(byte[] buffer) { if (buffer == null) { throw new ArgumentNullException("buffer"); } return this.Inflate(buffer, 0, buffer.Length); } // Token: 0x060002D6 RID: 726 RVA: 0x0000FD30 File Offset: 0x0000ED30 public int Inflate(byte[] buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (count < 0) { throw new ArgumentOutOfRangeException("count", "count cannot be negative"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "offset cannot be negative"); } if (offset + count > buffer.Length) { throw new ArgumentException("count exceeds buffer bounds"); } if (count == 0) { if (!this.IsFinished) { this.Decode(); } return 0; } int num = 0; for (;;) { if (this.mode != 11) { int num2 = this.outputWindow.CopyOutput(buffer, offset, count); if (num2 > 0) { this.adler.Update(buffer, offset, num2); offset += num2; num += num2; this.totalOut += (long)num2; count -= num2; if (count == 0) { break; } } } if (!this.Decode() && (this.outputWindow.GetAvailable() <= 0 || this.mode == 11)) { return num; } } return num; } // Token: 0x17000096 RID: 150 // (get) Token: 0x060002D7 RID: 727 RVA: 0x0000FE0A File Offset: 0x0000EE0A public bool IsNeedingInput { get { return this.input.IsNeedingInput; } } // Token: 0x17000097 RID: 151 // (get) Token: 0x060002D8 RID: 728 RVA: 0x0000FE17 File Offset: 0x0000EE17 public bool IsNeedingDictionary { get { return this.mode == 1 && this.neededBits == 0; } } // Token: 0x17000098 RID: 152 // (get) Token: 0x060002D9 RID: 729 RVA: 0x0000FE2D File Offset: 0x0000EE2D public bool IsFinished { get { return this.mode == 12 && this.outputWindow.GetAvailable() == 0; } } // Token: 0x17000099 RID: 153 // (get) Token: 0x060002DA RID: 730 RVA: 0x0000FE49 File Offset: 0x0000EE49 public int Adler { get { if (!this.IsNeedingDictionary) { return (int)this.adler.Value; } return this.readAdler; } } // Token: 0x1700009A RID: 154 // (get) Token: 0x060002DB RID: 731 RVA: 0x0000FE66 File Offset: 0x0000EE66 public long TotalOut { get { return this.totalOut; } } // Token: 0x1700009B RID: 155 // (get) Token: 0x060002DC RID: 732 RVA: 0x0000FE6E File Offset: 0x0000EE6E public long TotalIn { get { return this.totalIn - (long)this.RemainingInput; } } // Token: 0x1700009C RID: 156 // (get) Token: 0x060002DD RID: 733 RVA: 0x0000FE7E File Offset: 0x0000EE7E public int RemainingInput { get { return this.input.AvailableBytes; } } // Token: 0x040001C9 RID: 457 private const int DECODE_HEADER = 0; // Token: 0x040001CA RID: 458 private const int DECODE_DICT = 1; // Token: 0x040001CB RID: 459 private const int DECODE_BLOCKS = 2; // Token: 0x040001CC RID: 460 private const int DECODE_STORED_LEN1 = 3; // Token: 0x040001CD RID: 461 private const int DECODE_STORED_LEN2 = 4; // Token: 0x040001CE RID: 462 private const int DECODE_STORED = 5; // Token: 0x040001CF RID: 463 private const int DECODE_DYN_HEADER = 6; // Token: 0x040001D0 RID: 464 private const int DECODE_HUFFMAN = 7; // Token: 0x040001D1 RID: 465 private const int DECODE_HUFFMAN_LENBITS = 8; // Token: 0x040001D2 RID: 466 private const int DECODE_HUFFMAN_DIST = 9; // Token: 0x040001D3 RID: 467 private const int DECODE_HUFFMAN_DISTBITS = 10; // Token: 0x040001D4 RID: 468 private const int DECODE_CHKSUM = 11; // Token: 0x040001D5 RID: 469 private const int FINISHED = 12; // Token: 0x040001D6 RID: 470 private static readonly int[] CPLENS = new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 }; // Token: 0x040001D7 RID: 471 private static readonly int[] CPLEXT = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; // Token: 0x040001D8 RID: 472 private static readonly int[] CPDIST = new int[] { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 }; // Token: 0x040001D9 RID: 473 private static readonly int[] CPDEXT = new int[] { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; // Token: 0x040001DA RID: 474 private int mode; // Token: 0x040001DB RID: 475 private int readAdler; // Token: 0x040001DC RID: 476 private int neededBits; // Token: 0x040001DD RID: 477 private int repLength; // Token: 0x040001DE RID: 478 private int repDist; // Token: 0x040001DF RID: 479 private int uncomprLen; // Token: 0x040001E0 RID: 480 private bool isLastBlock; // Token: 0x040001E1 RID: 481 private long totalOut; // Token: 0x040001E2 RID: 482 private long totalIn; // Token: 0x040001E3 RID: 483 private bool noHeader; // Token: 0x040001E4 RID: 484 private StreamManipulator input; // Token: 0x040001E5 RID: 485 private OutputWindow outputWindow; // Token: 0x040001E6 RID: 486 private InflaterDynHeader dynHeader; // Token: 0x040001E7 RID: 487 private InflaterHuffmanTree litlenTree; // Token: 0x040001E8 RID: 488 private InflaterHuffmanTree distTree; // Token: 0x040001E9 RID: 489 private Adler32 adler; } }