1 /* 2 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package java.util.zip; 27 28 /** 29 * This class provides support for general purpose compression using the 30 * popular ZLIB compression library. The ZLIB compression library was 31 * initially developed as part of the PNG graphics standard and is not 32 * protected by patents. It is fully described in the specifications at 33 * the <a href="package-summary.html#package_description">java.util.zip 34 * package description</a>. 35 * 36 * <p>The following code fragment demonstrates a trivial compression 37 * and decompression of a string using <tt>Deflater</tt> and 38 * <tt>Inflater</tt>. 39 * 40 * <blockquote><pre> 41 * try { 42 * // Encode a String into bytes 43 * String inputString = "blahblahblah\u20AC\u20AC"; 44 * byte[] input = inputString.getBytes("UTF-8"); 45 * 46 * // Compress the bytes 47 * byte[] output = new byte[100]; 48 * Deflater compresser = new Deflater(); 49 * compresser.setInput(input); 50 * compresser.finish(); 51 * int compressedDataLength = compresser.deflate(output); 52 * compresser.end(); 53 * 54 * // Decompress the bytes 55 * Inflater decompresser = new Inflater(); 56 * decompresser.setInput(output, 0, compressedDataLength); 57 * byte[] result = new byte[100]; 58 * int resultLength = decompresser.inflate(result); 59 * decompresser.end(); 60 * 61 * // Decode the bytes into a String 62 * String outputString = new String(result, 0, resultLength, "UTF-8"); 63 * } catch(java.io.UnsupportedEncodingException ex) { 64 * // handle 65 * } catch (java.util.zip.DataFormatException ex) { 66 * // handle 67 * } 68 * </pre></blockquote> 69 * 70 * @see Inflater 71 * @author David Connelly 72 */ 73 public 74 class Deflater { 75 private long strm; 76 private byte[] buf = new byte[0]; 77 private int off, len; 78 private int level, strategy; 79 private boolean setParams; 80 private boolean finish, finished; 81 82 /** 83 * Compression method for the deflate algorithm (the only one currently 84 * supported). 85 */ 86 public static final int DEFLATED = 8; 87 88 /** 89 * Compression level for no compression. 90 */ 91 public static final int NO_COMPRESSION = 0; 92 93 /** 94 * Compression level for fastest compression. 95 */ 96 public static final int BEST_SPEED = 1; 97 98 /** 99 * Compression level for best compression. 100 */ 101 public static final int BEST_COMPRESSION = 9; 102 103 /** 104 * Default compression level. 105 */ 106 public static final int DEFAULT_COMPRESSION = -1; 107 108 /** 109 * Compression strategy best used for data consisting mostly of small 110 * values with a somewhat random distribution. Forces more Huffman coding 111 * and less string matching. 112 */ 113 public static final int FILTERED = 1; 114 115 /** 116 * Compression strategy for Huffman coding only. 117 */ 118 public static final int HUFFMAN_ONLY = 2; 119 120 /** 121 * Default compression strategy. 122 */ 123 public static final int DEFAULT_STRATEGY = 0; 124 125 /** 126 * Compression flush mode used to achieve best compression result. 127 * 128 * @see Deflater#deflate(byte[], int, int, int) 129 * @since 1.7 130 */ 131 public static final int NO_FLUSH = 0; 132 133 /** 134 * Compression flush mode used to flush out all pending output; may 135 * degrade compression for some compression algorithms. 136 * 137 * @see Deflater#deflate(byte[], int, int, int) 138 * @since 1.7 139 */ 140 public static final int SYNC_FLUSH = 2; 141 142 /** 143 * Compression flush mode used to flush out all pending output and 144 * reset the deflater. Using this mode too often can seriously degrade 145 * compression. 146 * 147 * @see Deflater#deflate(byte[], int, int, int) 148 * @since 1.7 149 */ 150 public static final int FULL_FLUSH = 3; 151 152 static { 153 /* Zip library is loaded from System.initializeSystemClass */ 154 initIDs(); 155 } 156 157 /** 158 * Creates a new compressor using the specified compression level. 159 * If 'nowrap' is true then the ZLIB header and checksum fields will 160 * not be used in order to support the compression format used in 161 * both GZIP and PKZIP. 162 * @param level the compression level (0-9) 163 * @param nowrap if true then use GZIP compatible compression 164 */ 165 public Deflater(int level, boolean nowrap) { 166 this.level = level; 167 this.strategy = DEFAULT_STRATEGY; 168 strm = init(level, DEFAULT_STRATEGY, nowrap); 169 } 170 171 /** 172 * Creates a new compressor using the specified compression level. 173 * Compressed data will be generated in ZLIB format. 174 * @param level the compression level (0-9) 175 */ 176 public Deflater(int level) { 177 this(level, false); 178 } 179 180 /** 181 * Creates a new compressor with the default compression level. 182 * Compressed data will be generated in ZLIB format. 183 */ 184 public Deflater() { 185 this(DEFAULT_COMPRESSION, false); 186 } 187 188 /** 189 * Sets input data for compression. This should be called whenever 190 * needsInput() returns true indicating that more input data is required. 191 * @param b the input data bytes 192 * @param off the start offset of the data 193 * @param len the length of the data 194 * @see Deflater#needsInput 195 */ 196 public synchronized void setInput(byte[] b, int off, int len) { 197 if (b== null) { 198 throw new NullPointerException(); 199 } 200 if (off < 0 || len < 0 || off > b.length - len) { 201 throw new ArrayIndexOutOfBoundsException(); 202 } 203 this.buf = b; 204 this.off = off; 205 this.len = len; 206 } 207 208 /** 209 * Sets input data for compression. This should be called whenever 210 * needsInput() returns true indicating that more input data is required. 211 * @param b the input data bytes 212 * @see Deflater#needsInput 213 */ 214 public void setInput(byte[] b) { 215 setInput(b, 0, b.length); 216 } 217 218 /** 219 * Sets preset dictionary for compression. A preset dictionary is used 220 * when the history buffer can be predetermined. When the data is later 221 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 222 * in order to get the Adler-32 value of the dictionary required for 223 * decompression. 224 * @param b the dictionary data bytes 225 * @param off the start offset of the data 226 * @param len the length of the data 227 * @see Inflater#inflate 228 * @see Inflater#getAdler 229 */ 230 public synchronized void setDictionary(byte[] b, int off, int len) { 231 if (strm == 0 || b == null) { 232 throw new NullPointerException(); 233 } 234 if (off < 0 || len < 0 || off > b.length - len) { 235 throw new ArrayIndexOutOfBoundsException(); 236 } 237 setDictionary(strm, b, off, len); 238 } 239 240 /** 241 * Sets preset dictionary for compression. A preset dictionary is used 242 * when the history buffer can be predetermined. When the data is later 243 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 244 * in order to get the Adler-32 value of the dictionary required for 245 * decompression. 246 * @param b the dictionary data bytes 247 * @see Inflater#inflate 248 * @see Inflater#getAdler 249 */ 250 public void setDictionary(byte[] b) { 251 setDictionary(b, 0, b.length); 252 } 253 254 /** 255 * Sets the compression strategy to the specified value. 256 * @param strategy the new compression strategy 257 * @exception IllegalArgumentException if the compression strategy is 258 * invalid 259 */ 260 public synchronized void setStrategy(int strategy) { 261 switch (strategy) { 262 case DEFAULT_STRATEGY: 263 case FILTERED: 264 case HUFFMAN_ONLY: 265 break; 266 default: 267 throw new IllegalArgumentException(); 268 } 269 if (this.strategy != strategy) { 270 this.strategy = strategy; 271 setParams = true; 272 } 273 } 274 275 /** 276 * Sets the current compression level to the specified value. 277 * @param level the new compression level (0-9) 278 * @exception IllegalArgumentException if the compression level is invalid 279 */ 280 public synchronized void setLevel(int level) { 281 if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) { 282 throw new IllegalArgumentException("invalid compression level"); 283 } 284 if (this.level != level) { 285 this.level = level; 286 setParams = true; 287 } 288 } 289 290 /** 291 * Returns true if the input data buffer is empty and setInput() 292 * should be called in order to provide more input. 293 * @return true if the input data buffer is empty and setInput() 294 * should be called in order to provide more input 295 */ 296 public boolean needsInput() { 297 return len <= 0; 298 } 299 300 /** 301 * When called, indicates that compression should end with the current 302 * contents of the input buffer. 303 */ 304 public synchronized void finish() { 305 finish = true; 306 } 307 308 /** 309 * Returns true if the end of the compressed data output stream has 310 * been reached. 311 * @return true if the end of the compressed data output stream has 312 * been reached 313 */ 314 public synchronized boolean finished() { 315 return finished; 316 } 317 318 /** 319 * Compresses the input data and fills specified buffer with compressed 320 * data. Returns actual number of bytes of compressed data. A return value 321 * of 0 indicates that {@link needsInput() needsInput} should be called 322 * in order to determine if more input data is required. 323 * 324 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 325 * An invocation of this method of the form {@code deflater.deflate(b, off, len)} 326 * yields the same result as the invocation of 327 * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}. 328 * 329 * @param b the buffer for the compressed data 330 * @param off the start offset of the data 331 * @param len the maximum number of bytes of compressed data 332 * @return the actual number of bytes of compressed data written to the 333 * output buffer 334 */ 335 public int deflate(byte[] b, int off, int len) { 336 return deflateBytes(b, off, len, NO_FLUSH); 337 } 338 339 /** 340 * Compresses the input data and fills specified buffer with compressed 341 * data. Returns actual number of bytes of compressed data. A return value 342 * of 0 indicates that {@link needsInput() needsInput} should be called 343 * in order to determine if more input data is required. 344 * 345 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 346 * An invocation of this method of the form {@code deflater.deflate(b)} 347 * yields the same result as the invocation of 348 * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. 349 * 350 * @param b the buffer for the compressed data 351 * @return the actual number of bytes of compressed data written to the 352 * output buffer 353 */ 354 public int deflate(byte[] b) { 355 return deflate(b, 0, b.length, NO_FLUSH); 356 } 357 358 /** 359 * Compresses the input data and fills the specified buffer with compressed 360 * data. Returns actual number of bytes of data compressed. 361 * 362 * <p>Compression flush mode is one of the following three modes: 363 * 364 * <ul> 365 * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data 366 * to accumulate, before producing output, in order to achieve the best 367 * compression (should be used in normal use scenario). A return value 368 * of 0 in this flush mode indicates that {@link #needsInput()} should 369 * be called in order to determine if more input data is required. 370 * 371 * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed, 372 * to the specified output buffer, so that an inflater that works on 373 * compressed data can get all input data available so far (In particular 374 * the {@link #needsInput()} returns {@code true} after this invocation 375 * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} 376 * may degrade compression for some compression algorithms and so it 377 * should be used only when necessary. 378 * 379 * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with 380 * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater 381 * that works on the compressed output data can restart from this point 382 * if previous compressed data has been damaged or if random access is 383 * desired. Using {@link #FULL_FLUSH} too often can seriously degrade 384 * compression. 385 * </ul> 386 * 387 * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if 388 * the return value is {@code len}, the space available in output 389 * buffer {@code b}, this method should be invoked again with the same 390 * {@code flush} parameter and more output space. 391 * 392 * @param b the buffer for the compressed data 393 * @param off the start offset of the data 394 * @param len the maximum number of bytes of compressed data 395 * @param flush the compression flush mode 396 * @return the actual number of bytes of compressed data written to 397 * the output buffer 398 * 399 * @throws IllegalArgumentException if the flush mode is invalid 400 * @since 1.7 401 */ 402 public synchronized int deflate(byte[] b, int off, int len, int flush) { 403 if (b == null) { 404 throw new NullPointerException(); 405 } 406 if (off < 0 || len < 0 || off > b.length - len) { 407 throw new ArrayIndexOutOfBoundsException(); 408 } 409 if (flush == NO_FLUSH || flush == SYNC_FLUSH || 410 flush == FULL_FLUSH) 411 return deflateBytes(b, off, len, flush); 412 throw new IllegalArgumentException(); 413 } 414 415 /** 416 * Returns the ADLER-32 value of the uncompressed data. 417 * @return the ADLER-32 value of the uncompressed data 418 */ 419 public synchronized int getAdler() { 420 ensureOpen(); 421 return getAdler(strm); 422 } 423 424 /** 425 * Returns the total number of uncompressed bytes input so far. 426 * 427 * <p>Since the number of bytes may be greater than 428 * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now 429 * the preferred means of obtaining this information.</p> 430 * 431 * @return the total number of uncompressed bytes input so far 432 */ 433 public int getTotalIn() { 434 return (int) getBytesRead(); 435 } 436 437 /** 438 * Returns the total number of uncompressed bytes input so far.</p> 439 * 440 * @return the total (non-negative) number of uncompressed bytes input so far 441 * @since 1.5 442 */ 443 public synchronized long getBytesRead() { 444 ensureOpen(); 445 return getBytesRead(strm); 446 } 447 448 /** 449 * Returns the total number of compressed bytes output so far. 450 * 451 * <p>Since the number of bytes may be greater than 452 * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now 453 * the preferred means of obtaining this information.</p> 454 * 455 * @return the total number of compressed bytes output so far 456 */ 457 public int getTotalOut() { 458 return (int) getBytesWritten(); 459 } 460 461 /** 462 * Returns the total number of compressed bytes output so far.</p> 463 * 464 * @return the total (non-negative) number of compressed bytes output so far 465 * @since 1.5 466 */ 467 public synchronized long getBytesWritten() { 468 ensureOpen(); 469 return getBytesWritten(strm); 470 } 471 472 /** 473 * Resets deflater so that a new set of input data can be processed. 474 * Keeps current compression level and strategy settings. 475 */ 476 public synchronized void reset() { 477 ensureOpen(); 478 reset(strm); 479 finish = false; 480 finished = false; 481 off = len = 0; 482 } 483 484 /** 485 * Closes the compressor and discards any unprocessed input. 486 * This method should be called when the compressor is no longer 487 * being used, but will also be called automatically by the 488 * finalize() method. Once this method is called, the behavior 489 * of the Deflater object is undefined. 490 */ 491 public synchronized void end() { 492 if (strm != 0) { 493 end(strm); 494 strm = 0; 495 buf = null; 496 } 497 } 498 499 /** 500 * Closes the compressor when garbage is collected. 501 */ 502 protected void finalize() { 503 end(); 504 } 505 506 private void ensureOpen() { 507 if (strm == 0) 508 throw new NullPointerException(); 509 } 510 511 private static native void initIDs(); 512 private native static long init(int level, int strategy, boolean nowrap); 513 private native static void setDictionary(long strm, byte[] b, int off, 514 int len); 515 private native int deflateBytes(byte[] b, int off, int len, int flush); 516 private native static int getAdler(long strm); 517 private native static long getBytesRead(long strm); 518 private native static long getBytesWritten(long strm); 519 private native static void reset(long strm); 520 private native static void end(long strm); 521 }