/** * Resets the inflater so that a new stream can be decompressed. All * pending input and output will be discarded. */ public void reset() { mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER; totalIn = totalOut = 0; input.reset(); outputWindow.reset(); dynHeader = null; litlenTree = null; distTree = null; isLastBlock = false; adler.reset(); }
/** * Decodes the deflated stream. * @return false if more input is needed, or if finished. * @exception DataFormatException if deflated stream is invalid. */ private bool decode() { switch (mode) { case DECODE_HEADER: return decodeHeader(); case DECODE_DICT: return decodeDict(); case DECODE_CHKSUM: return decodeChksum(); case DECODE_BLOCKS: if (isLastBlock) { if (nowrap) { mode = FINISHED; return false; } else { input.skipToByteBoundary(); neededBits = 32; mode = DECODE_CHKSUM; return true; } } int type = input.peekBits(3); if (type < 0) return false; input.dropBits(3); if ((type & 1) != 0) isLastBlock = true; switch (type >> 1) { case DeflaterConstants.STORED_BLOCK: input.skipToByteBoundary(); mode = DECODE_STORED_LEN1; break; case DeflaterConstants.STATIC_TREES: litlenTree = InflaterHuffmanTree.defLitLenTree; distTree = InflaterHuffmanTree.defDistTree; mode = DECODE_HUFFMAN; break; case DeflaterConstants.DYN_TREES: dynHeader = new InflaterDynHeader(); mode = DECODE_DYN_HEADER; break; default: throw new System.Exception("Unknown block type " + type); } return true; case DECODE_STORED_LEN1: { if ((uncomprLen = input.peekBits(16)) < 0) return false; input.dropBits(16); mode = DECODE_STORED_LEN2; } /* fall through */ goto case DECODE_STORED_LEN2; case DECODE_STORED_LEN2: { int nlen = input.peekBits(16); if (nlen < 0) return false; input.dropBits(16); if (nlen != (uncomprLen ^ 0xffff)) throw new System.Exception("broken uncompressed block"); mode = DECODE_STORED; } /* fall through */ goto case DECODE_STORED; case DECODE_STORED: { int more = outputWindow.copyStored(input, uncomprLen); uncomprLen -= more; if (uncomprLen == 0) { mode = DECODE_BLOCKS; return true; } return !input.needsInput(); } //goto case DECODE_DYN_HEADER; case DECODE_DYN_HEADER: if (!dynHeader.decode(input)) return false; litlenTree = dynHeader.buildLitLenTree(); distTree = dynHeader.buildDistTree(); mode = DECODE_HUFFMAN; /* fall through */ goto case DECODE_HUFFMAN; case DECODE_HUFFMAN: case DECODE_HUFFMAN_LENBITS: case DECODE_HUFFMAN_DIST: case DECODE_HUFFMAN_DISTBITS: return decodeHuffman(); case FINISHED: return false; default: throw new System.Exception(); } }
/** * Frees all objects allocated by the inflater. There's no reason * to call this, since you can just rely on garbage collection (even * for the Sun implementation). Exists only for compatibility * with Sun's JDK, where the compressor allocates native memory. * If you call any method (even reset) afterwards the behaviour is * <i>undefined</i>. */ public void end() { outputWindow = null; input = null; dynHeader = null; litlenTree = null; distTree = null; adler = null; }