private bool DecodeDynamicBlockHeader() { switch (this.state) { case InflaterState.ReadingNumLitCodes: this.literalLengthCodeCount = this.input.GetBits(5); if (this.literalLengthCodeCount < 0) { return(false); } this.literalLengthCodeCount += 257; this.state = InflaterState.ReadingNumDistCodes; goto case InflaterState.ReadingNumDistCodes; case InflaterState.ReadingNumDistCodes: this.distanceCodeCount = this.input.GetBits(5); if (this.distanceCodeCount < 0) { return(false); } ++this.distanceCodeCount; this.state = InflaterState.ReadingNumCodeLengthCodes; goto case InflaterState.ReadingNumCodeLengthCodes; case InflaterState.ReadingNumCodeLengthCodes: this.codeLengthCodeCount = this.input.GetBits(4); if (this.codeLengthCodeCount < 0) { return(false); } this.codeLengthCodeCount += 4; this.loopCounter = 0; this.state = InflaterState.ReadingCodeLengthCodes; goto case InflaterState.ReadingCodeLengthCodes; case InflaterState.ReadingCodeLengthCodes: for (; this.loopCounter < this.codeLengthCodeCount; ++this.loopCounter) { int bits = this.input.GetBits(3); if (bits < 0) { return(false); } this.codeLengthTreeCodeLength[(int)Inflater.codeOrder[this.loopCounter]] = (byte)bits; } for (int codeLengthCodeCount = this.codeLengthCodeCount; codeLengthCodeCount < Inflater.codeOrder.Length; ++codeLengthCodeCount) { this.codeLengthTreeCodeLength[(int)Inflater.codeOrder[codeLengthCodeCount]] = (byte)0; } this.codeLengthTree = new HuffmanTree(this.codeLengthTreeCodeLength); this.codeArraySize = this.literalLengthCodeCount + this.distanceCodeCount; this.loopCounter = 0; this.state = InflaterState.ReadingTreeCodesBefore; goto case InflaterState.ReadingTreeCodesBefore; case InflaterState.ReadingTreeCodesBefore: case InflaterState.ReadingTreeCodesAfter: while (this.loopCounter < this.codeArraySize) { if (this.state == InflaterState.ReadingTreeCodesBefore && (this.lengthCode = this.codeLengthTree.GetNextSymbol(this.input)) < 0) { return(false); } if (this.lengthCode <= 15) { this.codeList[this.loopCounter++] = (byte)this.lengthCode; } else { if (!this.input.EnsureBitsAvailable(7)) { this.state = InflaterState.ReadingTreeCodesAfter; return(false); } if (this.lengthCode == 16) { if (this.loopCounter == 0) { throw new InvalidDataException(); } byte code = this.codeList[this.loopCounter - 1]; int num = this.input.GetBits(2) + 3; if (this.loopCounter + num > this.codeArraySize) { throw new InvalidDataException(); } for (int index = 0; index < num; ++index) { this.codeList[this.loopCounter++] = code; } } else if (this.lengthCode == 17) { int num = this.input.GetBits(3) + 3; if (this.loopCounter + num > this.codeArraySize) { throw new InvalidDataException(); } for (int index = 0; index < num; ++index) { this.codeList[this.loopCounter++] = (byte)0; } } else { int num = this.input.GetBits(7) + 11; if (this.loopCounter + num > this.codeArraySize) { throw new InvalidDataException(); } for (int index = 0; index < num; ++index) { this.codeList[this.loopCounter++] = (byte)0; } } } this.state = InflaterState.ReadingTreeCodesBefore; } byte[] codeLengths1 = new byte[288]; byte[] codeLengths2 = new byte[32]; Array.Copy((Array)this.codeList, (Array)codeLengths1, this.literalLengthCodeCount); Array.Copy((Array)this.codeList, this.literalLengthCodeCount, (Array)codeLengths2, 0, this.distanceCodeCount); if (codeLengths1[256] == (byte)0) { throw new InvalidDataException(); } this.literalLengthTree = new HuffmanTree(codeLengths1); this.distanceTree = new HuffmanTree(codeLengths2); this.state = InflaterState.DecodeTop; return(true); default: Debug.Assert(false, "check why we are here!"); throw new InvalidDataException(SR.GetString("Unknown state")); } }
private bool Decode() { bool flag1 = false; if (this.Finished()) { return(true); } if (this.hasFormatReader) { if (this.state == InflaterState.ReadingHeader) { if (!this.formatReader.ReadHeader(this.input)) { return(false); } this.state = InflaterState.ReadingBFinal; } else if (this.state == InflaterState.StartReadingFooter || this.state == InflaterState.ReadingFooter) { if (!this.formatReader.ReadFooter(this.input)) { return(false); } this.state = InflaterState.VerifyingFooter; return(true); } } if (this.state == InflaterState.ReadingBFinal) { if (!this.input.EnsureBitsAvailable(1)) { return(false); } this.bfinal = this.input.GetBits(1); this.state = InflaterState.ReadingBType; } if (this.state == InflaterState.ReadingBType) { if (!this.input.EnsureBitsAvailable(2)) { this.state = InflaterState.ReadingBType; return(false); } this.blockType = (BlockType)this.input.GetBits(2); if (this.blockType == BlockType.Dynamic) { this.state = InflaterState.ReadingNumLitCodes; } else if (this.blockType == BlockType.Static) { this.literalLengthTree = HuffmanTree.StaticLiteralLengthTree; this.distanceTree = HuffmanTree.StaticDistanceTree; this.state = InflaterState.DecodeTop; } else { if (this.blockType != BlockType.Uncompressed) { throw new InvalidDataException(SR.GetString("Unknown block type")); } this.state = InflaterState.UncompressedAligning; } } bool flag2; if (this.blockType == BlockType.Dynamic) { flag2 = this.state >= InflaterState.DecodeTop ? this.DecodeBlock(out flag1) : this.DecodeDynamicBlockHeader(); } else if (this.blockType == BlockType.Static) { flag2 = this.DecodeBlock(out flag1); } else { if (this.blockType != BlockType.Uncompressed) { throw new InvalidDataException(SR.GetString("Unknown block type")); } flag2 = this.DecodeUncompressedBlock(out flag1); } if (flag1 && (uint)this.bfinal > 0U) { this.state = !this.hasFormatReader ? InflaterState.Done : InflaterState.StartReadingFooter; } return(flag2); }