/// <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(); } }
/// <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"); } }