Frames | No Frames |
1: /* Deflater.java - Compress a data stream 2: Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package java.util.zip; 39: 40: import gnu.gcj.RawData; 41: 42: /** 43: * This is the Deflater class. The deflater class compresses input 44: * with the deflate algorithm described in RFC 1951. It has several 45: * compression levels and three different strategies described below. 46: * 47: * This class is <i>not</i> thread safe. This is inherent in the API, due 48: * to the split of deflate and setInput. 49: * 50: * @author Jochen Hoenicke 51: * @author Tom Tromey 52: */ 53: public class Deflater 54: { 55: /** 56: * The best and slowest compression level. This tries to find very 57: * long and distant string repetitions. 58: */ 59: public static final int BEST_COMPRESSION = 9; 60: /** 61: * The worst but fastest compression level. 62: */ 63: public static final int BEST_SPEED = 1; 64: /** 65: * The default compression level. 66: */ 67: public static final int DEFAULT_COMPRESSION = -1; 68: /** 69: * This level won't compress at all but output uncompressed blocks. 70: */ 71: public static final int NO_COMPRESSION = 0; 72: 73: /** 74: * The default strategy. 75: */ 76: public static final int DEFAULT_STRATEGY = 0; 77: /** 78: * This strategy will only allow longer string repetitions. It is 79: * useful for random data with a small character set. 80: */ 81: public static final int FILTERED = 1; 82: 83: /** 84: * This strategy will not look for string repetitions at all. It 85: * only encodes with Huffman trees (which means, that more common 86: * characters get a smaller encoding. 87: */ 88: public static final int HUFFMAN_ONLY = 2; 89: 90: /** 91: * The compression method. This is the only method supported so far. 92: * There is no need to use this constant at all. 93: */ 94: public static final int DEFLATED = 8; 95: 96: /** Compression level. */ 97: private int level; 98: 99: /** Compression strategy. */ 100: private int strategy; 101: 102: /** The zlib stream. */ 103: private RawData zstream; 104: 105: /** True if finished. */ 106: private boolean is_finished; 107: 108: /** `Flush' flag to pass to next call to deflate. */ 109: private int flush_flag; 110: 111: /** 112: * Creates a new deflater with default compression level. 113: */ 114: public Deflater() 115: { 116: this(DEFAULT_COMPRESSION, false); 117: } 118: 119: /** 120: * Creates a new deflater with given compression level. 121: * @param lvl the compression level, a value between NO_COMPRESSION 122: * and BEST_COMPRESSION, or DEFAULT_COMPRESSION. 123: * @exception IllegalArgumentException if lvl is out of range. 124: */ 125: public Deflater(int lvl) 126: { 127: this(lvl, false); 128: } 129: 130: /** 131: * Creates a new deflater with given compression level. 132: * @param lvl the compression level, a value between NO_COMPRESSION 133: * and BEST_COMPRESSION. 134: * @param nowrap true, iff we should suppress the deflate header at the 135: * beginning and the adler checksum at the end of the output. This is 136: * useful for the GZIP format. 137: * @exception IllegalArgumentException if lvl is out of range. 138: */ 139: public Deflater(int lvl, boolean noHeader) 140: { 141: this.strategy = DEFAULT_STRATEGY; 142: init(lvl, noHeader); 143: setLevel(lvl); 144: } 145: 146: private native void init(int level, boolean noHeader); 147: 148: private native void update(); 149: 150: /** 151: * Resets the deflater. The deflater acts afterwards as if it was 152: * just created with the same compression level and strategy as it 153: * had before. 154: */ 155: public native void reset(); 156: 157: /** 158: * Frees all objects allocated by the compressor. There's no 159: * reason to call this, since you can just rely on garbage 160: * collection. Exists only for compatibility against Sun's JDK, 161: * where the compressor allocates native memory. 162: * If you call any method (even reset) afterwards the behaviour is 163: * <i>undefined</i>. 164: * @deprecated Just clear all references to deflater instead. 165: */ 166: public native void end(); 167: 168: /** 169: * Gets the current adler checksum of the data that was processed so 170: * far. 171: */ 172: public native int getAdler(); 173: 174: /** 175: * Gets the number of input bytes processed so far. 176: */ 177: @Deprecated 178: public int getTotalIn() 179: { 180: return (int) getBytesRead(); 181: } 182: 183: /** 184: * Gets the number of input bytes processed so far. 185: * @since 1.5 186: */ 187: public native long getBytesRead(); 188: 189: /** 190: * Gets the number of output bytes so far. 191: */ 192: @Deprecated 193: public int getTotalOut() 194: { 195: return (int) getBytesWritten(); 196: } 197: 198: /** 199: * Gets the number of output bytes so far. 200: * @since 1.5 201: */ 202: public native long getBytesWritten(); 203: 204: /** 205: * Finalizes this object. 206: */ 207: protected void finalize() 208: { 209: end(); 210: } 211: 212: /** 213: * Finishes the deflater with the current input block. It is an error 214: * to give more input after this method was called. This method must 215: * be called to force all bytes to be flushed. 216: */ 217: public native void finish(); 218: 219: /** 220: * Returns true iff the stream was finished and no more output bytes 221: * are available. 222: */ 223: public synchronized boolean finished() 224: { 225: return is_finished; 226: } 227: 228: /** 229: * Returns true, if the input buffer is empty. 230: * You should then call setInput(). <br> 231: * 232: * <em>NOTE</em>: This method can also return true when the stream 233: * was finished. 234: */ 235: public native boolean needsInput(); 236: 237: /** 238: * Sets the data which should be compressed next. This should be only 239: * called when needsInput indicates that more input is needed. 240: * If you call setInput when needsInput() returns false, the 241: * previous input that is still pending will be thrown away. 242: * The given byte array should not be changed, before needsInput() returns 243: * true again. 244: * This call is equivalent to <code>setInput(input, 0, input.length)</code>. 245: * @param input the buffer containing the input data. 246: * @exception IllegalStateException if the buffer was finished() or ended(). 247: */ 248: public void setInput(byte[] input) 249: { 250: setInput(input, 0, input.length); 251: } 252: 253: /** 254: * Sets the data which should be compressed next. This should be 255: * only called when needsInput indicates that more input is needed. 256: * The given byte array should not be changed, before needsInput() returns 257: * true again. 258: * @param input the buffer containing the input data. 259: * @param off the start of the data. 260: * @param len the length of the data. 261: * @exception IllegalStateException if the buffer was finished() or ended() 262: * or if previous input is still pending. 263: */ 264: public native void setInput(byte[] input, int off, int len); 265: 266: /** 267: * Sets the compression level. There is no guarantee of the exact 268: * position of the change, but if you call this when needsInput is 269: * true the change of compression level will occur somewhere near 270: * before the end of the so far given input. 271: * @param lvl the new compression level. 272: */ 273: public synchronized void setLevel(int lvl) 274: { 275: if (lvl != -1 && (lvl < 0 || lvl > 9)) 276: throw new IllegalArgumentException(); 277: level = (lvl == -1) ? 6 : lvl; 278: update(); 279: } 280: 281: /** 282: * Sets the compression strategy. Strategy is one of 283: * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact 284: * position where the strategy is changed, the same as for 285: * setLevel() applies. 286: * @param stgy the new compression strategy. 287: */ 288: public synchronized void setStrategy(int stgy) 289: { 290: if (stgy != DEFAULT_STRATEGY && stgy != FILTERED 291: && stgy != HUFFMAN_ONLY) 292: throw new IllegalArgumentException(); 293: strategy = stgy; 294: update(); 295: } 296: 297: /** 298: * Deflates the current input block to the given array. It returns 299: * the number of bytes compressed, or 0 if either 300: * needsInput() or finished() returns true or length is zero. 301: * @param output the buffer where to write the compressed data. 302: */ 303: public int deflate(byte[] output) 304: { 305: return deflate(output, 0, output.length); 306: } 307: 308: /** 309: * Deflates the current input block to the given array. It returns 310: * the number of bytes compressed, or 0 if either 311: * needsInput() or finished() returns true or length is zero. 312: * @param output the buffer where to write the compressed data. 313: * @param offset the offset into the output array. 314: * @param length the maximum number of bytes that may be written. 315: * @exception IllegalStateException if end() was called. 316: * @exception IndexOutOfBoundsException if offset and/or length 317: * don't match the array length. 318: */ 319: public native int deflate(byte[] output, int off, int len); 320: 321: /** 322: * Sets the dictionary which should be used in the deflate process. 323: * This call is equivalent to <code>setDictionary(dict, 0, 324: * dict.length)</code>. 325: * @param dict the dictionary. 326: * @exception IllegalStateException if setInput () or deflate () 327: * were already called or another dictionary was already set. 328: */ 329: public void setDictionary(byte[] dict) 330: { 331: setDictionary(dict, 0, dict.length); 332: } 333: 334: /** 335: * Sets the dictionary which should be used in the deflate process. 336: * The dictionary should be a byte array containing strings that are 337: * likely to occur in the data which should be compressed. The 338: * dictionary is not stored in the compressed output, only a 339: * checksum. To decompress the output you need to supply the same 340: * dictionary again. 341: * @param dict the dictionary. 342: * @param offset an offset into the dictionary. 343: * @param length the length of the dictionary. 344: * @exception IllegalStateException if setInput () or deflate () were 345: * already called or another dictionary was already set. 346: */ 347: public native void setDictionary(byte[] buf, int off, int len); 348: 349: // Classpath's compression library supports flushing, but we 350: // don't. So this is a no-op here. 351: void flush() 352: { 353: } 354: }