Beispiel #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()
 {
     this.mode     = this.noHeader ? DECODE_BLOCKS : DECODE_HEADER;
     this.totalIn  = 0;
     this.totalOut = 0;
     this.input.Reset();
     this.outputWindow.Reset();
     this.dynHeader   = null;
     this.litlenTree  = null;
     this.distTree    = null;
     this.isLastBlock = false;
     if (this.adler != null)
     {
         this.adler.Reset();
     }
 }
Beispiel #2
0
        /// <summary>
        /// Decodes the deflated stream.
        /// </summary>
        /// <returns>
        /// false if more input is needed, or if finished.
        /// </returns>
        /// <exception cref="SharpZipBaseException">
        /// if deflated stream is invalid.
        /// </exception>
        private bool Decode()
        {
            switch (this.mode)
            {
            case DECODE_HEADER:
                return(this.DecodeHeader());

            case DECODE_DICT:
                return(this.DecodeDict());

            case DECODE_CHKSUM:
                return(this.DecodeChksum());

            case DECODE_BLOCKS:
                if (this.isLastBlock)
                {
                    if (this.noHeader)
                    {
                        this.mode = FINISHED;
                        return(false);
                    }
                    else
                    {
                        this.input.SkipToByteBoundary();
                        this.neededBits = 32;
                        this.mode       = DECODE_CHKSUM;
                        return(true);
                    }
                }

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

                this.isLastBlock |= (type & 1) != 0;
                switch (type >> 1)
                {
                case DeflaterConstants.STORED_BLOCK:
                    this.input.SkipToByteBoundary();
                    this.mode = DECODE_STORED_LEN1;
                    break;

                case DeflaterConstants.STATIC_TREES:
                    this.litlenTree = InflaterHuffmanTree.defLitLenTree;
                    this.distTree   = InflaterHuffmanTree.defDistTree;
                    this.mode       = DECODE_HUFFMAN;
                    break;

                case DeflaterConstants.DYN_TREES:
                    this.dynHeader = new InflaterDynHeader(this.input);
                    this.mode      = DECODE_DYN_HEADER;
                    break;

                default:
                    throw new SharpZipBaseException("Unknown block type " + type);
                }
                return(true);

            case DECODE_STORED_LEN1:
            {
                if ((this.uncomprLen = this.input.PeekBits(16)) < 0)
                {
                    return(false);
                }
                this.input.DropBits(16);
                this.mode = DECODE_STORED_LEN2;
            }
                goto case DECODE_STORED_LEN2;                         // fall through

            case DECODE_STORED_LEN2:
            {
                int nlen = this.input.PeekBits(16);
                if (nlen < 0)
                {
                    return(false);
                }
                this.input.DropBits(16);
                if (nlen != (this.uncomprLen ^ 0xffff))
                {
                    throw new SharpZipBaseException("broken uncompressed block");
                }
                this.mode = DECODE_STORED;
            }
                goto case DECODE_STORED;                         // fall through

            case DECODE_STORED:
            {
                int more = this.outputWindow.CopyStored(this.input, this.uncomprLen);
                this.uncomprLen -= more;
                if (this.uncomprLen == 0)
                {
                    this.mode = DECODE_BLOCKS;
                    return(true);
                }
                return(!this.input.IsNeedingInput);
            }

            case DECODE_DYN_HEADER:
                if (!this.dynHeader.AttemptRead())
                {
                    return(false);
                }

                this.litlenTree = this.dynHeader.LiteralLengthTree;
                this.distTree   = this.dynHeader.DistanceTree;
                this.mode       = DECODE_HUFFMAN;
                goto case DECODE_HUFFMAN;                         // fall through

            case DECODE_HUFFMAN:
            case DECODE_HUFFMAN_LENBITS:
            case DECODE_HUFFMAN_DIST:
            case DECODE_HUFFMAN_DISTBITS:
                return(this.DecodeHuffman());

            case FINISHED:
                return(false);

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