コード例 #1
0
 /// <summary>
 /// Resets the inflater so that a new stream can be decompressed.  All
 /// pending input and output will be discarded.
 /// </summary>
 public void Reset()
 {
     mode     = noHeader ? State.Blocks : State.Header;
     totalIn  = 0;
     TotalOut = 0;
     input.Reset();
     outputWindow.Reset();
     dynHeader   = null;
     litlenTree  = null;
     distTree    = null;
     isLastBlock = false;
     adler.Reset();
 }
コード例 #2
0
        /// <summary>
        /// Decodes the deflated stream.
        /// </summary>
        /// <returns>
        /// false if more input is needed, or if State.Done.
        /// </returns>
        /// <exception cref="InvalidDataException">
        /// if deflated stream is invalid.
        /// </exception>
        bool Decode()
        {
            switch (mode)
            {
            case State.Header:
                return(DecodeHeader());

            case State.Dictionary:
                return(DecodeDict());

            case State.Checksum:
                return(DecodeChksum());

            case State.Blocks:
                if (isLastBlock)
                {
                    if (noHeader)
                    {
                        mode = State.Done;
                        return(false);
                    }
                    else
                    {
                        input.SkipToByteBoundary();
                        neededBits = 32;
                        mode       = State.Checksum;
                        return(true);
                    }
                }

                var type = input.PeekBits(3);
                if (type < 0)
                {
                    return(false);
                }

                input.DropBits(3);

                isLastBlock |= (type & 1) != 0;
                switch (type >> 1)
                {
                case DeflaterConstants.StoredBlock:
                    input.SkipToByteBoundary();
                    mode = State.StoredLen1;
                    break;

                case DeflaterConstants.StaticTree:
                    litlenTree = InflaterHuffmanTree.DefLitLenTree;
                    distTree   = InflaterHuffmanTree.DefDistTree;
                    mode       = State.Huffman;
                    break;

                case DeflaterConstants.DynamicTree:
                    dynHeader = new InflaterDynHeader();
                    mode      = State.DynamicHeader;
                    break;

                default:
                    throw new NotSupportedException("Unknown block type " + type);
                }

                return(true);

            case State.StoredLen1:
            {
                if ((uncomprLen = input.PeekBits(16)) < 0)
                {
                    return(false);
                }

                input.DropBits(16);
                mode = State.StoredLen2;
            }

                goto case State.StoredLen2; // fall through

            case State.StoredLen2:
            {
                var nlen = input.PeekBits(16);
                if (nlen < 0)
                {
                    return(false);
                }

                input.DropBits(16);
                if (nlen != (uncomprLen ^ 0xffff))
                {
                    throw new InvalidDataException("broken uncompressed block");
                }

                mode = State.Stored;
                goto case State.Stored;     // fall through
            }

            case State.Stored:
            {
                var more = outputWindow.CopyStored(input, uncomprLen);
                uncomprLen -= more;
                if (uncomprLen == 0)
                {
                    mode = State.Blocks;
                    return(true);
                }

                return(!input.IsNeedingInput);
            }

            case State.DynamicHeader:
                if (!dynHeader.Decode(input))
                {
                    return(false);
                }

                litlenTree = dynHeader.BuildLitLenTree();
                distTree   = dynHeader.BuildDistTree();
                mode       = State.Huffman;
                goto case State.Huffman;     // fall through

            case State.Huffman:
            case State.HuffmanLenBits:
            case State.HuffmanDist:
            case State.HuffmanDistBits:
                return(DecodeHuffman());

            case State.Done:
                return(false);

            default:
                throw new InvalidDataException("Inflater.Decode unknown mode");
            }
        }