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 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 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);
        }