001/* Deflater.java - Compress a data stream 002 Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package java.util.zip; 039 040import gnu.gcj.RawData; 041 042/** 043 * This is the Deflater class. The deflater class compresses input 044 * with the deflate algorithm described in RFC 1951. It has several 045 * compression levels and three different strategies described below. 046 * 047 * This class is <i>not</i> thread safe. This is inherent in the API, due 048 * to the split of deflate and setInput. 049 * 050 * @author Jochen Hoenicke 051 * @author Tom Tromey 052 */ 053public class Deflater 054{ 055 /** 056 * The best and slowest compression level. This tries to find very 057 * long and distant string repetitions. 058 */ 059 public static final int BEST_COMPRESSION = 9; 060 /** 061 * The worst but fastest compression level. 062 */ 063 public static final int BEST_SPEED = 1; 064 /** 065 * The default compression level. 066 */ 067 public static final int DEFAULT_COMPRESSION = -1; 068 /** 069 * This level won't compress at all but output uncompressed blocks. 070 */ 071 public static final int NO_COMPRESSION = 0; 072 073 /** 074 * The default strategy. 075 */ 076 public static final int DEFAULT_STRATEGY = 0; 077 /** 078 * This strategy will only allow longer string repetitions. It is 079 * useful for random data with a small character set. 080 */ 081 public static final int FILTERED = 1; 082 083 /** 084 * This strategy will not look for string repetitions at all. It 085 * only encodes with Huffman trees (which means, that more common 086 * characters get a smaller encoding. 087 */ 088 public static final int HUFFMAN_ONLY = 2; 089 090 /** 091 * The compression method. This is the only method supported so far. 092 * There is no need to use this constant at all. 093 */ 094 public static final int DEFLATED = 8; 095 096 /** Compression level. */ 097 private int level; 098 099 /** 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}