示例#1
0
        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"));
            }
        }
示例#2
0
        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);
        }