private bool CheckDecodeState()
        {
            bool endOfBlock = false;
            bool flag;

            if (this.blockType == DeflateDecompressor.BlockType.Dynamic)
            {
                flag = this.state < DeflateDecompressor.DecompressorState.DecodeTop ? this.DecodeDynamicBlockHeader() : this.DecodeBlock(out endOfBlock);
            }
            else if (this.blockType != DeflateDecompressor.BlockType.Static)
            {
                if (this.blockType != DeflateDecompressor.BlockType.Stored)
                {
                    DeflateDecompressor.ThrowUnknownBlockType();
                }
                flag = this.DecodeUncompressedBlock(out endOfBlock);
            }
            else
            {
                flag = this.DecodeBlock(out endOfBlock);
            }
            if (endOfBlock && this.bfinal != 0)
            {
                this.state = DeflateDecompressor.DecompressorState.Done;
            }
            return(flag);
        }
        private void SetPreviousCode()
        {
            byte num1 = 0;
            int  num2;

            if (this.lengthCode == 16)
            {
                if (this.loopCounter == 0)
                {
                    DeflateDecompressor.ThrowInvalidDataGeneric();
                }
                num1 = this.codeList[this.loopCounter - 1];
                num2 = this.input.GetBits(2) + 3;
            }
            else
            {
                num2 = this.lengthCode == 17 ? this.input.GetBits(3) + 3 : this.input.GetBits(7) + 11;
            }
            if (this.loopCounter + num2 > this.codeArraySize)
            {
                DeflateDecompressor.ThrowInvalidDataGeneric();
            }
            for (int index = 0; index < num2; ++index)
            {
                this.codeList[this.loopCounter++] = num1;
            }
        }
        private bool DecodeDynamicBlockHeader()
        {
            switch (this.state)
            {
            case DeflateDecompressor.DecompressorState.ReadingNumLitCodes:
                this.literalLengthCodeCount = this.input.GetBits(5);
                if (this.literalLengthCodeCount < 0)
                {
                    return(false);
                }
                this.literalLengthCodeCount += 257;
                this.state = DeflateDecompressor.DecompressorState.ReadingNumDistCodes;
                goto case DeflateDecompressor.DecompressorState.ReadingNumDistCodes;

            case DeflateDecompressor.DecompressorState.ReadingNumDistCodes:
                this.distanceCodeCount = this.input.GetBits(5);
                if (this.distanceCodeCount < 0)
                {
                    return(false);
                }
                ++this.distanceCodeCount;
                this.state = DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes;
                goto case DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes;

            case DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes:
                this.codeLengthCodeCount = this.input.GetBits(4);
                if (this.codeLengthCodeCount < 0)
                {
                    return(false);
                }
                this.codeLengthCodeCount += 4;
                this.loopCounter          = 0;
                this.state = DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes;
                goto case DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes;

            case DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes:
                if (!this.DecodeDynamicCodes())
                {
                    return(false);
                }
                this.state = DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore;
                goto case DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore;

            case DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore:
            case DeflateDecompressor.DecompressorState.ReadingTreeCodesAfter:
                return(this.ReadTreeCodes());

            default:
                DeflateDecompressor.ThrowUnknownState();
                return(true);
            }
        }
 private void SetTreeCodes()
 {
     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)
     {
         DeflateDecompressor.ThrowInvalidDataGeneric();
     }
     this.literalLengthTree = new InflateTree(codeLengths1);
     this.distanceTree      = new InflateTree(codeLengths2);
 }
        private bool DecodeBlock(out bool endOfBlock)
        {
            int freeBytes = this.output.FreeBytes;

            endOfBlock = false;
            while (freeBytes > 258)
            {
                switch (this.state)
                {
                case DeflateDecompressor.DecompressorState.DecodeTop:
                    bool?nullable1 = this.DecodeTop(ref endOfBlock, ref freeBytes);
                    if (nullable1.HasValue)
                    {
                        return(nullable1.Value);
                    }
                    continue;

                case DeflateDecompressor.DecompressorState.HaveInitialLength:
                    bool?nullable2 = this.DecodeInitialLength();
                    if (nullable2.HasValue)
                    {
                        return(nullable2.Value);
                    }
                    continue;

                case DeflateDecompressor.DecompressorState.HaveFullLength:
                    bool?nullable3 = this.DecodeFullLength();
                    if (nullable3.HasValue)
                    {
                        return(nullable3.Value);
                    }
                    continue;

                case DeflateDecompressor.DecompressorState.HaveDistCode:
                    bool?nullable4 = this.DecodeDistanceCode(ref freeBytes);
                    if (nullable4.HasValue)
                    {
                        return(nullable4.Value);
                    }
                    continue;

                default:
                    DeflateDecompressor.ThrowUnknownState();
                    continue;
                }
            }
            return(true);
        }
 private bool?DecodeInitialLength()
 {
     if (this.extraBits > 0)
     {
         int bits = this.input.GetBits(this.extraBits);
         if (bits < 0)
         {
             return(new bool?(false));
         }
         if (this.blockLength < 0 || this.blockLength >= DeflateDecompressor.lengthBase.Length)
         {
             DeflateDecompressor.ThrowInvalidData();
         }
         this.blockLength = DeflateDecompressor.lengthBase[this.blockLength] + bits;
     }
     this.state = DeflateDecompressor.DecompressorState.HaveFullLength;
     return(new bool?());
 }
 private void DecodeDistance(ref int nextSymbol)
 {
     nextSymbol -= 257;
     if (nextSymbol < 8)
     {
         nextSymbol    += 3;
         this.extraBits = 0;
     }
     else if (nextSymbol != 28)
     {
         if (nextSymbol < 0 || nextSymbol >= Tree.ExtraLengthBits.Length)
         {
             DeflateDecompressor.ThrowInvalidData();
         }
         this.extraBits = Tree.ExtraLengthBits[nextSymbol];
     }
     else
     {
         nextSymbol     = 258;
         this.extraBits = 0;
     }
     this.blockLength = nextSymbol;
 }
        private bool DecodeUncompressedBlock(out bool endOfBlock)
        {
            endOfBlock = false;
            while (this.state != DeflateDecompressor.DecompressorState.DecodingUncompressed)
            {
                switch (this.state)
                {
                case DeflateDecompressor.DecompressorState.UncompressedAligning:
                    this.input.SkipToByteBoundary();
                    this.state = DeflateDecompressor.DecompressorState.UncompressedByte1;
                    continue;

                case DeflateDecompressor.DecompressorState.UncompressedByte1:
                case DeflateDecompressor.DecompressorState.UncompressedByte2:
                case DeflateDecompressor.DecompressorState.UncompressedByte3:
                case DeflateDecompressor.DecompressorState.UncompressedByte4:
                    if (!this.DecodeBits())
                    {
                        return(false);
                    }
                    continue;

                default:
                    DeflateDecompressor.ThrowUnknownState();
                    continue;
                }
            }
            this.blockLength -= this.output.ReadInput(this.input, this.blockLength);
            if (this.blockLength != 0)
            {
                return(this.output.FreeBytes == 0);
            }
            this.state = DeflateDecompressor.DecompressorState.ReadingBFinal;
            endOfBlock = true;
            return(true);
        }
        private void ProcessBlockType()
        {
            this.blockType = (DeflateDecompressor.BlockType) this.input.GetBits(2);
            switch (this.blockType)
            {
            case DeflateDecompressor.BlockType.Stored:
                this.state = DeflateDecompressor.DecompressorState.UncompressedAligning;
                break;

            case DeflateDecompressor.BlockType.Static:
                this.literalLengthTree = InflateTree.StaticLiteralLengthTree;
                this.distanceTree      = InflateTree.StaticDistanceTree;
                this.state             = DeflateDecompressor.DecompressorState.DecodeTop;
                break;

            case DeflateDecompressor.BlockType.Dynamic:
                this.state = DeflateDecompressor.DecompressorState.ReadingNumLitCodes;
                break;

            default:
                DeflateDecompressor.ThrowUnknownBlockType();
                break;
            }
        }