1 /* 2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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"; 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 76 private final ZStreamRef zsRef; 77 private byte[] buf = new byte[0]; 78 private int off, len; 79 private int level, strategy; 80 private boolean setParams; 81 private boolean finish, finished; 82 private long bytesRead; 83 private long bytesWritten; 84 85 /** 86 * Compression method for the deflate algorithm (the only one currently 87 * supported). 88 */ 89 public static final int DEFLATED = 8; 90 91 /** 92 * Compression level for no compression. 93 */ 94 public static final int NO_COMPRESSION = 0; 95 96 /** 97 * Compression level for fastest compression. 98 */ 99 public static final int BEST_SPEED = 1; 100 101 /** 102 * Compression level for best compression. 103 */ 104 public static final int BEST_COMPRESSION = 9; 105 106 /** 107 * Default compression level. 108 */ 109 public static final int DEFAULT_COMPRESSION = -1; 110 111 /** 112 * Compression strategy best used for data consisting mostly of small 113 * values with a somewhat random distribution. Forces more Huffman coding 114 * and less string matching. 115 */ 116 public static final int FILTERED = 1; 117 118 /** 119 * Compression strategy for Huffman coding only. 120 */ 121 public static final int HUFFMAN_ONLY = 2; 122 123 /** 124 * Default compression strategy. 125 */ 126 public static final int DEFAULT_STRATEGY = 0; 127 128 /** 129 * Compression flush mode used to achieve best compression result. 130 * 131 * @see Deflater#deflate(byte[], int, int, int) 132 * @since 1.7 133 */ 134 public static final int NO_FLUSH = 0; 135 136 /** 137 * Compression flush mode used to flush out all pending output; may 138 * degrade compression for some compression algorithms. 139 * 140 * @see Deflater#deflate(byte[], int, int, int) 141 * @since 1.7 142 */ 143 public static final int SYNC_FLUSH = 2; 144 145 /** 146 * Compression flush mode used to flush out all pending output and 147 * reset the deflater. Using this mode too often can seriously degrade 148 * compression. 149 * 150 * @see Deflater#deflate(byte[], int, int, int) 151 * @since 1.7 152 */ 153 public static final int FULL_FLUSH = 3; 154 155 static { 156 /* Zip library is loaded from System.initializeSystemClass */ 157 initIDs(); 158 } 159 160 /** 161 * Creates a new compressor using the specified compression level. 162 * If 'nowrap' is true then the ZLIB header and checksum fields will 163 * not be used in order to support the compression format used in 164 * both GZIP and PKZIP. 165 * @param level the compression level (0-9) 166 * @param nowrap if true then use GZIP compatible compression 167 */ 168 public Deflater(int level, boolean nowrap) { 169 this.level = level; 170 this.strategy = DEFAULT_STRATEGY; 171 this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); 172 } 173 174 /** 175 * Creates a new compressor using the specified compression level. 176 * Compressed data will be generated in ZLIB format. 177 * @param level the compression level (0-9) 178 */ 179 public Deflater(int level) { 180 this(level, false); 181 } 182 183 /** 184 * Creates a new compressor with the default compression level. 185 * Compressed data will be generated in ZLIB format. 186 */ 187 public Deflater() { 188 this(DEFAULT_COMPRESSION, false); 189 } 190 191 /** 192 * Sets input data for compression. This should be called whenever 193 * needsInput() returns true indicating that more input data is required. 194 * @param b the input data bytes 195 * @param off the start offset of the data 196 * @param len the length of the data 197 * @see Deflater#needsInput 198 */ 199 public void setInput(byte[] b, int off, int len) { 200 if (b== null) { 201 throw new NullPointerException(); 202 } 203 if (off < 0 || len < 0 || off > b.length - len) { 204 throw new ArrayIndexOutOfBoundsException(); 205 } 206 synchronized (zsRef) { 207 this.buf = b; 208 this.off = off; 209 this.len = len; 210 } 211 } 212 213 /** 214 * Sets input data for compression. This should be called whenever 215 * needsInput() returns true indicating that more input data is required. 216 * @param b the input data bytes 217 * @see Deflater#needsInput 218 */ 219 public void setInput(byte[] b) { 220 setInput(b, 0, b.length); 221 } 222 223 /** 224 * Sets preset dictionary for compression. A preset dictionary is used 225 * when the history buffer can be predetermined. When the data is later 226 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 227 * in order to get the Adler-32 value of the dictionary required for 228 * decompression. 229 * @param b the dictionary data bytes 230 * @param off the start offset of the data 231 * @param len the length of the data 232 * @see Inflater#inflate 233 * @see Inflater#getAdler 234 */ 235 public void setDictionary(byte[] b, int off, int len) { 236 if (b == null) { 237 throw new NullPointerException(); 238 } 239 if (off < 0 || len < 0 || off > b.length - len) { 240 throw new ArrayIndexOutOfBoundsException(); 241 } 242 synchronized (zsRef) { 243 ensureOpen(); 244 setDictionary(zsRef.address(), b, off, len); 245 } 246 } 247 248 /** 249 * Sets preset dictionary for compression. A preset dictionary is used 250 * when the history buffer can be predetermined. When the data is later 251 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 252 * in order to get the Adler-32 value of the dictionary required for 253 * decompression. 254 * @param b the dictionary data bytes 255 * @see Inflater#inflate 256 * @see Inflater#getAdler 257 */ 258 public void setDictionary(byte[] b) { 259 setDictionary(b, 0, b.length); 260 } 261 262 /** 263 * Sets the compression strategy to the specified value. 264 * @param strategy the new compression strategy 265 * @exception IllegalArgumentException if the compression strategy is 266 * invalid 267 */ 268 public void setStrategy(int strategy) { 269 switch (strategy) { 270 case DEFAULT_STRATEGY: 271 case FILTERED: 272 case HUFFMAN_ONLY: 273 break; 274 default: 275 throw new IllegalArgumentException(); 276 } 277 synchronized (zsRef) { 278 if (this.strategy != strategy) { 279 this.strategy = strategy; 280 setParams = true; 281 } 282 } 283 } 284 285 /** 286 * Sets the current compression level to the specified value. 287 * @param level the new compression level (0-9) 288 * @exception IllegalArgumentException if the compression level is invalid 289 */ 290 public void setLevel(int level) { 291 if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) { 292 throw new IllegalArgumentException("invalid compression level"); 293 } 294 synchronized (zsRef) { 295 if (this.level != level) { 296 this.level = level; 297 setParams = true; 298 } 299 } 300 } 301 302 /** 303 * Returns true if the input data buffer is empty and setInput() 304 * should be called in order to provide more input. 305 * @return true if the input data buffer is empty and setInput() 306 * should be called in order to provide more input 307 */ 308 public boolean needsInput() { 309 return len <= 0; 310 } 311 312 /** 313 * When called, indicates that compression should end with the current 314 * contents of the input buffer. 315 */ 316 public void finish() { 317 synchronized (zsRef) { 318 finish = true; 319 } 320 } 321 322 /** 323 * Returns true if the end of the compressed data output stream has 324 * been reached. 325 * @return true if the end of the compressed data output stream has 326 * been reached 327 */ 328 public boolean finished() { 329 synchronized (zsRef) { 330 return finished; 331 } 332 } 333 334 /** 335 * Compresses the input data and fills specified buffer with compressed 336 * data. Returns actual number of bytes of compressed data. A return value 337 * of 0 indicates that {@link #needsInput() needsInput} should be called 338 * in order to determine if more input data is required. 339 * 340 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 341 * An invocation of this method of the form {@code deflater.deflate(b, off, len)} 342 * yields the same result as the invocation of 343 * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}. 344 * 345 * @param b the buffer for the compressed data 346 * @param off the start offset of the data 347 * @param len the maximum number of bytes of compressed data 348 * @return the actual number of bytes of compressed data written to the 349 * output buffer 350 */ 351 public int deflate(byte[] b, int off, int len) { 352 return deflate(b, off, len, NO_FLUSH); 353 } 354 355 /** 356 * Compresses the input data and fills specified buffer with compressed 357 * data. Returns actual number of bytes of compressed data. A return value 358 * of 0 indicates that {@link #needsInput() needsInput} should be called 359 * in order to determine if more input data is required. 360 * 361 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 362 * An invocation of this method of the form {@code deflater.deflate(b)} 363 * yields the same result as the invocation of 364 * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. 365 * 366 * @param b the buffer for the compressed data 367 * @return the actual number of bytes of compressed data written to the 368 * output buffer 369 */ 370 public int deflate(byte[] b) { 371 return deflate(b, 0, b.length, NO_FLUSH); 372 } 373 374 /** 375 * Compresses the input data and fills the specified buffer with compressed 376 * data. Returns actual number of bytes of data compressed. 377 * 378 * <p>Compression flush mode is one of the following three modes: 379 * 380 * <ul> 381 * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data 382 * to accumulate, before producing output, in order to achieve the best 383 * compression (should be used in normal use scenario). A return value 384 * of 0 in this flush mode indicates that {@link #needsInput()} should 385 * be called in order to determine if more input data is required. 386 * 387 * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed, 388 * to the specified output buffer, so that an inflater that works on 389 * compressed data can get all input data available so far (In particular 390 * the {@link #needsInput()} returns {@code true} after this invocation 391 * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} 392 * may degrade compression for some compression algorithms and so it 393 * should be used only when necessary. 394 * 395 * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with 396 * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater 397 * that works on the compressed output data can restart from this point 398 * if previous compressed data has been damaged or if random access is 399 * desired. Using {@link #FULL_FLUSH} too often can seriously degrade 400 * compression. 401 * </ul> 402 * 403 * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if 404 * the return value is {@code len}, the space available in output 405 * buffer {@code b}, this method should be invoked again with the same 406 * {@code flush} parameter and more output space. 407 * 408 * @param b the buffer for the compressed data 409 * @param off the start offset of the data 410 * @param len the maximum number of bytes of compressed data 411 * @param flush the compression flush mode 412 * @return the actual number of bytes of compressed data written to 413 * the output buffer 414 * 415 * @throws IllegalArgumentException if the flush mode is invalid 416 * @since 1.7 417 */ 418 public int deflate(byte[] b, int off, int len, int flush) { 419 if (b == null) { 420 throw new NullPointerException(); 421 } 422 if (off < 0 || len < 0 || off > b.length - len) { 423 throw new ArrayIndexOutOfBoundsException(); 424 } 425 synchronized (zsRef) { 426 ensureOpen(); 427 if (flush == NO_FLUSH || flush == SYNC_FLUSH || 428 flush == FULL_FLUSH) { 429 int thisLen = this.len; 430 int n = deflateBytes(zsRef.address(), b, off, len, flush); 431 bytesWritten += n; 432 bytesRead += (thisLen - this.len); 433 return n; 434 } 435 throw new IllegalArgumentException(); 436 } 437 } 438 439 /** 440 * Returns the ADLER-32 value of the uncompressed data. 441 * @return the ADLER-32 value of the uncompressed data 442 */ 443 public int getAdler() { 444 synchronized (zsRef) { 445 ensureOpen(); 446 return getAdler(zsRef.address()); 447 } 448 } 449 450 /** 451 * Returns the total number of uncompressed bytes input so far. 452 * 453 * <p>Since the number of bytes may be greater than 454 * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now 455 * the preferred means of obtaining this information.</p> 456 * 457 * @return the total number of uncompressed bytes input so far 458 */ 459 public int getTotalIn() { 460 return (int) getBytesRead(); 461 } 462 463 /** 464 * Returns the total number of uncompressed bytes input so far. 465 * 466 * @return the total (non-negative) number of uncompressed bytes input so far 467 * @since 1.5 468 */ 469 public long getBytesRead() { 470 synchronized (zsRef) { 471 ensureOpen(); 472 return bytesRead; 473 } 474 } 475 476 /** 477 * Returns the total number of compressed bytes output so far. 478 * 479 * <p>Since the number of bytes may be greater than 480 * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now 481 * the preferred means of obtaining this information.</p> 482 * 483 * @return the total number of compressed bytes output so far 484 */ 485 public int getTotalOut() { 486 return (int) getBytesWritten(); 487 } 488 489 /** 490 * Returns the total number of compressed bytes output so far. 491 * 492 * @return the total (non-negative) number of compressed bytes output so far 493 * @since 1.5 494 */ 495 public long getBytesWritten() { 496 synchronized (zsRef) { 497 ensureOpen(); 498 return bytesWritten; 499 } 500 } 501 502 /** 503 * Resets deflater so that a new set of input data can be processed. 504 * Keeps current compression level and strategy settings. 505 */ 506 public void reset() { 507 synchronized (zsRef) { 508 ensureOpen(); 509 reset(zsRef.address()); 510 finish = false; 511 finished = false; 512 off = len = 0; 513 bytesRead = bytesWritten = 0; 514 } 515 } 516 517 /** 518 * Closes the compressor and discards any unprocessed input. 519 * This method should be called when the compressor is no longer 520 * being used, but will also be called automatically by the 521 * finalize() method. Once this method is called, the behavior 522 * of the Deflater object is undefined. 523 */ 524 public void end() { 525 synchronized (zsRef) { 526 long addr = zsRef.address(); 527 zsRef.clear(); 528 if (addr != 0) { 529 end(addr); 530 buf = null; 531 } 532 } 533 } 534 535 /** 536 * Closes the compressor when garbage is collected. 537 */ 538 protected void finalize() { 539 end(); 540 } 541 542 private void ensureOpen() { 543 assert Thread.holdsLock(zsRef); 544 if (zsRef.address() == 0) 545 throw new NullPointerException("Deflater has been closed"); 546 } 547 548 private static native void initIDs(); 549 private native static long init(int level, int strategy, boolean nowrap); 550 private native static void setDictionary(long addr, byte[] b, int off, int len); 551 private native int deflateBytes(long addr, byte[] b, int off, int len, 552 int flush); 553 private native static int getAdler(long addr); 554 private native static void reset(long addr); 555 private native static void end(long addr); 556 }