📄 deflater.java
字号:
{ /* Exists solely for compatibility. We don't have any native state. */ } /** * Flushes the current input block. Further calls to deflate() will * produce enough output to inflate everything in the current input * block. This is not part of Sun's JDK so I have made it package * private. It is used by DeflaterOutputStream to implement * flush(). */ void flush() { state |= IS_FLUSHING; } /** * Finishes the deflater with the current input block. It is an error * to give more input after this method was called. This method must * be called to force all bytes to be flushed. */ public void finish() { state |= IS_FLUSHING | IS_FINISHING; } /** * Returns true iff the stream was finished and no more output bytes * are available. */ public boolean finished() { return state == FINISHED_STATE && pending.isFlushed(); } /** * Returns true, if the input buffer is empty. * You should then call setInput(). <br> * * <em>NOTE</em>: This method can also return true when the stream * was finished. */ public boolean needsInput() { return engine.needsInput(); } /** * Sets the data which should be compressed next. This should be only * called when needsInput indicates that more input is needed. * If you call setInput when needsInput() returns false, the * previous input that is still pending will be thrown away. * The given byte array should not be changed, before needsInput() returns * true again. * This call is equivalent to <code>setInput(input, 0, input.length)</code>. * @param input the buffer containing the input data. * @exception IllegalStateException if the buffer was finished() or ended(). */ public void setInput(byte[] input) { setInput(input, 0, input.length); } /** * Sets the data which should be compressed next. This should be * only called when needsInput indicates that more input is needed. * The given byte array should not be changed, before needsInput() returns * true again. * @param input the buffer containing the input data. * @param off the start of the data. * @param len the length of the data. * @exception IllegalStateException if the buffer was finished() or ended() * or if previous input is still pending. */ public void setInput(byte[] input, int off, int len) { if ((state & IS_FINISHING) != 0) throw new IllegalStateException("finish()/end() already called"); engine.setInput(input, off, len); } /** * Sets the compression level. There is no guarantee of the exact * position of the change, but if you call this when needsInput is * true the change of compression level will occur somewhere near * before the end of the so far given input. * @param lvl the new compression level. */ public void setLevel(int lvl) { if (lvl == DEFAULT_COMPRESSION) lvl = 6; else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) throw new IllegalArgumentException(); if (level != lvl) { level = lvl; engine.setLevel(lvl); } } /** * Sets the compression strategy. Strategy is one of * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact * position where the strategy is changed, the same as for * setLevel() applies. * @param stgy the new compression strategy. */ public void setStrategy(int stgy) { if (stgy != DEFAULT_STRATEGY && stgy != FILTERED && stgy != HUFFMAN_ONLY) throw new IllegalArgumentException(); engine.setStrategy(stgy); } /** * Deflates the current input block to the given array. It returns * the number of bytes compressed, or 0 if either * needsInput() or finished() returns true or length is zero. * @param output the buffer where to write the compressed data. */ public int deflate(byte[] output) { return deflate(output, 0, output.length); } /** * Deflates the current input block to the given array. It returns * the number of bytes compressed, or 0 if either * needsInput() or finished() returns true or length is zero. * @param output the buffer where to write the compressed data. * @param offset the offset into the output array. * @param length the maximum number of bytes that may be written. * @exception IllegalStateException if end() was called. * @exception IndexOutOfBoundsException if offset and/or length * don't match the array length. */ public int deflate(byte[] output, int offset, int length) { int origLength = length; if (state == CLOSED_STATE) throw new IllegalStateException("Deflater closed"); if (state < BUSY_STATE) { /* output header */ int header = (DEFLATED + ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8; int level_flags = (level - 1) >> 1; if (level_flags < 0 || level_flags > 3) level_flags = 3; header |= level_flags << 6; if ((state & IS_SETDICT) != 0) /* Dictionary was set */ header |= DeflaterConstants.PRESET_DICT; header += 31 - (header % 31); pending.writeShortMSB(header); if ((state & IS_SETDICT) != 0) { int chksum = engine.getAdler(); engine.resetAdler(); pending.writeShortMSB(chksum >> 16); pending.writeShortMSB(chksum & 0xffff); } state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING)); } for (;;) { int count = pending.flush(output, offset, length); offset += count; totalOut += count; length -= count; if (length == 0 || state == FINISHED_STATE) break; if (!engine.deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) { if (state == BUSY_STATE) /* We need more input now */ return origLength - length; else if (state == FLUSHING_STATE) { if (level != NO_COMPRESSION) { /* We have to supply some lookahead. 8 bit lookahead * are needed by the zlib inflater, and we must fill * the next byte, so that all bits are flushed. */ int neededbits = 8 + ((-pending.getBitCount()) & 7); while (neededbits > 0) { /* write a static tree block consisting solely of * an EOF: */ pending.writeBits(2, 10); neededbits -= 10; } } state = BUSY_STATE; } else if (state == FINISHING_STATE) { pending.alignToByte(); /* We have completed the stream */ if (!noHeader) { int adler = engine.getAdler(); pending.writeShortMSB(adler >> 16); pending.writeShortMSB(adler & 0xffff); } state = FINISHED_STATE; } } } return origLength - length; } /** * Sets the dictionary which should be used in the deflate process. * This call is equivalent to <code>setDictionary(dict, 0, * dict.length)</code>. * @param dict the dictionary. * @exception IllegalStateException if setInput () or deflate () * were already called or another dictionary was already set. */ public void setDictionary(byte[] dict) { setDictionary(dict, 0, dict.length); } /** * Sets the dictionary which should be used in the deflate process. * The dictionary should be a byte array containing strings that are * likely to occur in the data which should be compressed. The * dictionary is not stored in the compressed output, only a * checksum. To decompress the output you need to supply the same * dictionary again. * @param dict the dictionary. * @param offset an offset into the dictionary. * @param length the length of the dictionary. * @exception IllegalStateException if setInput () or deflate () were * already called or another dictionary was already set. */ public void setDictionary(byte[] dict, int offset, int length) { if (state != INIT_STATE) throw new IllegalStateException(); state = SETDICT_STATE; engine.setDictionary(dict, offset, length); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -