// package net.sf.zipme; class Deflater { /** * Gets the number of input bytes processed so far. */ public int getTotalIn(){ return (int)engine.getTotalIn(); } /** * Gets the number of input bytes processed so far. * @since 1.5 */ public long getBytesRead(){ return engine.getTotalIn(); } /** * Gets the number of output bytes so far. * @since 1.5 */ public long getBytesWritten(){ return totalOut; } /** * 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){ return new Deflater_deflate2(this,output,offset,length).execute(); } /** * 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); } protected void hook24( int lvl){ setStrategy(DEFAULT_STRATEGY); setLevel(lvl); original(lvl); } protected void hook25(){ engine=new DeflaterEngine(pending); original(); } /** * Resets the deflater. The deflater acts afterwards as if it was * just created with the same compression level and strategy as it * had before. */ public void reset(){ original(); engine.reset(); } /** * Frees all objects allocated by the compressor. There's no * reason to call this, since you can just rely on garbage * collection. Exists only for compatibility against 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(){ engine=null; original(); } }