1 /* 2 * Copyright (c) 1996, 2017, 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 import java.lang.ref.Cleaner.Cleanable; 29 import jdk.internal.ref.CleanerFactory; 30 31 /** 32 * This class provides support for general purpose compression using the 33 * popular ZLIB compression library. The ZLIB compression library was 34 * initially developed as part of the PNG graphics standard and is not 35 * protected by patents. It is fully described in the specifications at 36 * the <a href="package-summary.html#package.description">java.util.zip 37 * package description</a>. 38 * 39 * <p>The following code fragment demonstrates a trivial compression 40 * and decompression of a string using {@code Deflater} and 41 * {@code Inflater}. 42 * 43 * <blockquote><pre> 44 * try { 45 * // Encode a String into bytes 46 * String inputString = "blahblahblah"; 47 * byte[] input = inputString.getBytes("UTF-8"); 48 * 49 * // Compress the bytes 50 * byte[] output = new byte[100]; 51 * Deflater compresser = new Deflater(); 52 * compresser.setInput(input); 53 * compresser.finish(); 54 * int compressedDataLength = compresser.deflate(output); 55 * compresser.end(); 56 * 57 * // Decompress the bytes 58 * Inflater decompresser = new Inflater(); 59 * decompresser.setInput(output, 0, compressedDataLength); 60 * byte[] result = new byte[100]; 61 * int resultLength = decompresser.inflate(result); 62 * decompresser.end(); 63 * 64 * // Decode the bytes into a String 65 * String outputString = new String(result, 0, resultLength, "UTF-8"); 66 * } catch(java.io.UnsupportedEncodingException ex) { 67 * // handle 68 * } catch (java.util.zip.DataFormatException ex) { 69 * // handle 70 * } 71 * </pre></blockquote> 72 * 73 * @apiNote 74 * To release resources used by this {@code Deflater}, the {@link #end()} method 75 * should be called explicitly. Subclasses are responsible for the cleanup of resources 76 * acquired by the subclass. Subclasses that override {@link #finalize()} in order 77 * to perform cleanup should be modified to use alternative cleanup mechanisms such 78 * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. 79 * 80 * @implSpec 81 * If this {@code Deflater} has been subclassed and the {@code end} method has been 82 * overridden, the {@code end} method will be called by the finalization when the 83 * deflater is unreachable. But the subclasses should not depend on this specific 84 * implementation; the finalization is not reliable and the {@code finalize} method 85 * is deprecated to be removed. 86 * 87 * @see Inflater 88 * @author David Connelly 89 * @since 1.1 90 */ 91 92 public class Deflater { 93 94 private final DeflaterZStreamRef zsRef; 95 private byte[] buf = new byte[0]; 96 private int off, len; 97 private int level, strategy; 98 private boolean setParams; 99 private boolean finish, finished; 100 private long bytesRead; 101 private long bytesWritten; 102 103 /** 104 * Compression method for the deflate algorithm (the only one currently 105 * supported). 106 */ 107 public static final int DEFLATED = 8; 108 109 /** 110 * Compression level for no compression. 111 */ 112 public static final int NO_COMPRESSION = 0; 113 114 /** 115 * Compression level for fastest compression. 116 */ 117 public static final int BEST_SPEED = 1; 118 119 /** 120 * Compression level for best compression. 121 */ 122 public static final int BEST_COMPRESSION = 9; 123 124 /** 125 * Default compression level. 126 */ 127 public static final int DEFAULT_COMPRESSION = -1; 128 129 /** 130 * Compression strategy best used for data consisting mostly of small 131 * values with a somewhat random distribution. Forces more Huffman coding 132 * and less string matching. 133 */ 134 public static final int FILTERED = 1; 135 136 /** 137 * Compression strategy for Huffman coding only. 138 */ 139 public static final int HUFFMAN_ONLY = 2; 140 141 /** 142 * Default compression strategy. 143 */ 144 public static final int DEFAULT_STRATEGY = 0; 145 146 /** 147 * Compression flush mode used to achieve best compression result. 148 * 149 * @see Deflater#deflate(byte[], int, int, int) 150 * @since 1.7 151 */ 152 public static final int NO_FLUSH = 0; 153 154 /** 155 * Compression flush mode used to flush out all pending output; may 156 * degrade compression for some compression algorithms. 157 * 158 * @see Deflater#deflate(byte[], int, int, int) 159 * @since 1.7 160 */ 161 public static final int SYNC_FLUSH = 2; 162 163 /** 164 * Compression flush mode used to flush out all pending output and 165 * reset the deflater. Using this mode too often can seriously degrade 166 * compression. 167 * 168 * @see Deflater#deflate(byte[], int, int, int) 169 * @since 1.7 170 */ 171 public static final int FULL_FLUSH = 3; 172 173 static { 174 ZipUtils.loadLibrary(); 175 initIDs(); 176 } 177 178 /** 179 * Creates a new compressor using the specified compression level. 180 * If 'nowrap' is true then the ZLIB header and checksum fields will 181 * not be used in order to support the compression format used in 182 * both GZIP and PKZIP. 183 * @param level the compression level (0-9) 184 * @param nowrap if true then use GZIP compatible compression 185 */ 186 public Deflater(int level, boolean nowrap) { 187 this.level = level; 188 this.strategy = DEFAULT_STRATEGY; 189 this.zsRef = DeflaterZStreamRef.get(this, 190 init(level, DEFAULT_STRATEGY, nowrap)); 191 } 192 193 /** 194 * Creates a new compressor using the specified compression level. 195 * Compressed data will be generated in ZLIB format. 196 * @param level the compression level (0-9) 197 */ 198 public Deflater(int level) { 199 this(level, false); 200 } 201 202 /** 203 * Creates a new compressor with the default compression level. 204 * Compressed data will be generated in ZLIB format. 205 */ 206 public Deflater() { 207 this(DEFAULT_COMPRESSION, false); 208 } 209 210 /** 211 * Sets input data for compression. This should be called whenever 212 * needsInput() returns true indicating that more input data is required. 213 * @param b the input data bytes 214 * @param off the start offset of the data 215 * @param len the length of the data 216 * @see Deflater#needsInput 217 */ 218 public void setInput(byte[] b, int off, int len) { 219 if (b== null) { 220 throw new NullPointerException(); 221 } 222 if (off < 0 || len < 0 || off > b.length - len) { 223 throw new ArrayIndexOutOfBoundsException(); 224 } 225 synchronized (zsRef) { 226 this.buf = b; 227 this.off = off; 228 this.len = len; 229 } 230 } 231 232 /** 233 * Sets input data for compression. This should be called whenever 234 * needsInput() returns true indicating that more input data is required. 235 * @param b the input data bytes 236 * @see Deflater#needsInput 237 */ 238 public void setInput(byte[] b) { 239 setInput(b, 0, b.length); 240 } 241 242 /** 243 * Sets preset dictionary for compression. A preset dictionary is used 244 * when the history buffer can be predetermined. When the data is later 245 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 246 * in order to get the Adler-32 value of the dictionary required for 247 * decompression. 248 * @param b the dictionary data bytes 249 * @param off the start offset of the data 250 * @param len the length of the data 251 * @see Inflater#inflate 252 * @see Inflater#getAdler 253 */ 254 public void setDictionary(byte[] b, int off, int len) { 255 if (b == null) { 256 throw new NullPointerException(); 257 } 258 if (off < 0 || len < 0 || off > b.length - len) { 259 throw new ArrayIndexOutOfBoundsException(); 260 } 261 synchronized (zsRef) { 262 ensureOpen(); 263 setDictionary(zsRef.address(), b, off, len); 264 } 265 } 266 267 /** 268 * Sets preset dictionary for compression. A preset dictionary is used 269 * when the history buffer can be predetermined. When the data is later 270 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 271 * in order to get the Adler-32 value of the dictionary required for 272 * decompression. 273 * @param b the dictionary data bytes 274 * @see Inflater#inflate 275 * @see Inflater#getAdler 276 */ 277 public void setDictionary(byte[] b) { 278 setDictionary(b, 0, b.length); 279 } 280 281 /** 282 * Sets the compression strategy to the specified value. 283 * 284 * <p> If the compression strategy is changed, the next invocation 285 * of {@code deflate} will compress the input available so far with 286 * the old strategy (and may be flushed); the new strategy will take 287 * effect only after that invocation. 288 * 289 * @param strategy the new compression strategy 290 * @exception IllegalArgumentException if the compression strategy is 291 * invalid 292 */ 293 public void setStrategy(int strategy) { 294 switch (strategy) { 295 case DEFAULT_STRATEGY: 296 case FILTERED: 297 case HUFFMAN_ONLY: 298 break; 299 default: 300 throw new IllegalArgumentException(); 301 } 302 synchronized (zsRef) { 303 if (this.strategy != strategy) { 304 this.strategy = strategy; 305 setParams = true; 306 } 307 } 308 } 309 310 /** 311 * Sets the compression level to the specified value. 312 * 313 * <p> If the compression level is changed, the next invocation 314 * of {@code deflate} will compress the input available so far 315 * with the old level (and may be flushed); the new level will 316 * take effect only after that invocation. 317 * 318 * @param level the new compression level (0-9) 319 * @exception IllegalArgumentException if the compression level is invalid 320 */ 321 public void setLevel(int level) { 322 if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) { 323 throw new IllegalArgumentException("invalid compression level"); 324 } 325 synchronized (zsRef) { 326 if (this.level != level) { 327 this.level = level; 328 setParams = true; 329 } 330 } 331 } 332 333 /** 334 * Returns true if the input data buffer is empty and setInput() 335 * should be called in order to provide more input. 336 * @return true if the input data buffer is empty and setInput() 337 * should be called in order to provide more input 338 */ 339 public boolean needsInput() { 340 synchronized (zsRef) { 341 return len <= 0; 342 } 343 } 344 345 /** 346 * When called, indicates that compression should end with the current 347 * contents of the input buffer. 348 */ 349 public void finish() { 350 synchronized (zsRef) { 351 finish = true; 352 } 353 } 354 355 /** 356 * Returns true if the end of the compressed data output stream has 357 * been reached. 358 * @return true if the end of the compressed data output stream has 359 * been reached 360 */ 361 public boolean finished() { 362 synchronized (zsRef) { 363 return finished; 364 } 365 } 366 367 /** 368 * Compresses the input data and fills specified buffer with compressed 369 * data. Returns actual number of bytes of compressed data. A return value 370 * of 0 indicates that {@link #needsInput() needsInput} should be called 371 * in order to determine if more input data is required. 372 * 373 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 374 * An invocation of this method of the form {@code deflater.deflate(b, off, len)} 375 * yields the same result as the invocation of 376 * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}. 377 * 378 * @param b the buffer for the compressed data 379 * @param off the start offset of the data 380 * @param len the maximum number of bytes of compressed data 381 * @return the actual number of bytes of compressed data written to the 382 * output buffer 383 */ 384 public int deflate(byte[] b, int off, int len) { 385 return deflate(b, off, len, NO_FLUSH); 386 } 387 388 /** 389 * Compresses the input data and fills specified buffer with compressed 390 * data. Returns actual number of bytes of compressed data. A return value 391 * of 0 indicates that {@link #needsInput() needsInput} should be called 392 * in order to determine if more input data is required. 393 * 394 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 395 * An invocation of this method of the form {@code deflater.deflate(b)} 396 * yields the same result as the invocation of 397 * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. 398 * 399 * @param b the buffer for the compressed data 400 * @return the actual number of bytes of compressed data written to the 401 * output buffer 402 */ 403 public int deflate(byte[] b) { 404 return deflate(b, 0, b.length, NO_FLUSH); 405 } 406 407 /** 408 * Compresses the input data and fills the specified buffer with compressed 409 * data. Returns actual number of bytes of data compressed. 410 * 411 * <p>Compression flush mode is one of the following three modes: 412 * 413 * <ul> 414 * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data 415 * to accumulate, before producing output, in order to achieve the best 416 * compression (should be used in normal use scenario). A return value 417 * of 0 in this flush mode indicates that {@link #needsInput()} should 418 * be called in order to determine if more input data is required. 419 * 420 * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed, 421 * to the specified output buffer, so that an inflater that works on 422 * compressed data can get all input data available so far (In particular 423 * the {@link #needsInput()} returns {@code true} after this invocation 424 * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} 425 * may degrade compression for some compression algorithms and so it 426 * should be used only when necessary. 427 * 428 * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with 429 * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater 430 * that works on the compressed output data can restart from this point 431 * if previous compressed data has been damaged or if random access is 432 * desired. Using {@link #FULL_FLUSH} too often can seriously degrade 433 * compression. 434 * </ul> 435 * 436 * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if 437 * the return value is {@code len}, the space available in output 438 * buffer {@code b}, this method should be invoked again with the same 439 * {@code flush} parameter and more output space. Make sure that 440 * {@code len} is greater than 6 to avoid flush marker (5 bytes) being 441 * repeatedly output to the output buffer every time this method is 442 * invoked. 443 * 444 * @param b the buffer for the compressed data 445 * @param off the start offset of the data 446 * @param len the maximum number of bytes of compressed data 447 * @param flush the compression flush mode 448 * @return the actual number of bytes of compressed data written to 449 * the output buffer 450 * 451 * @throws IllegalArgumentException if the flush mode is invalid 452 * @since 1.7 453 */ 454 public int deflate(byte[] b, int off, int len, int flush) { 455 if (b == null) { 456 throw new NullPointerException(); 457 } 458 if (off < 0 || len < 0 || off > b.length - len) { 459 throw new ArrayIndexOutOfBoundsException(); 460 } 461 synchronized (zsRef) { 462 ensureOpen(); 463 if (flush == NO_FLUSH || flush == SYNC_FLUSH || 464 flush == FULL_FLUSH) { 465 int thisLen = this.len; 466 int n = deflateBytes(zsRef.address(), b, off, len, flush); 467 bytesWritten += n; 468 bytesRead += (thisLen - this.len); 469 return n; 470 } 471 throw new IllegalArgumentException(); 472 } 473 } 474 475 /** 476 * Returns the ADLER-32 value of the uncompressed data. 477 * @return the ADLER-32 value of the uncompressed data 478 */ 479 public int getAdler() { 480 synchronized (zsRef) { 481 ensureOpen(); 482 return getAdler(zsRef.address()); 483 } 484 } 485 486 /** 487 * Returns the total number of uncompressed bytes input so far. 488 * 489 * <p>Since the number of bytes may be greater than 490 * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now 491 * the preferred means of obtaining this information.</p> 492 * 493 * @return the total number of uncompressed bytes input so far 494 */ 495 public int getTotalIn() { 496 return (int) getBytesRead(); 497 } 498 499 /** 500 * Returns the total number of uncompressed bytes input so far. 501 * 502 * @return the total (non-negative) number of uncompressed bytes input so far 503 * @since 1.5 504 */ 505 public long getBytesRead() { 506 synchronized (zsRef) { 507 ensureOpen(); 508 return bytesRead; 509 } 510 } 511 512 /** 513 * Returns the total number of compressed bytes output so far. 514 * 515 * <p>Since the number of bytes may be greater than 516 * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now 517 * the preferred means of obtaining this information.</p> 518 * 519 * @return the total number of compressed bytes output so far 520 */ 521 public int getTotalOut() { 522 return (int) getBytesWritten(); 523 } 524 525 /** 526 * Returns the total number of compressed bytes output so far. 527 * 528 * @return the total (non-negative) number of compressed bytes output so far 529 * @since 1.5 530 */ 531 public long getBytesWritten() { 532 synchronized (zsRef) { 533 ensureOpen(); 534 return bytesWritten; 535 } 536 } 537 538 /** 539 * Resets deflater so that a new set of input data can be processed. 540 * Keeps current compression level and strategy settings. 541 */ 542 public void reset() { 543 synchronized (zsRef) { 544 ensureOpen(); 545 reset(zsRef.address()); 546 finish = false; 547 finished = false; 548 off = len = 0; 549 bytesRead = bytesWritten = 0; 550 } 551 } 552 553 /** 554 * Closes the compressor and discards any unprocessed input. 555 * 556 * This method should be called when the compressor is no longer 557 * being used. Once this method is called, the behavior of the 558 * Deflater object is undefined. 559 */ 560 public void end() { 561 synchronized (zsRef) { 562 zsRef.clean(); 563 buf = null; 564 } 565 } 566 567 /** 568 * Closes the compressor when garbage is collected. 569 * 570 * @deprecated The {@code finalize} method has been deprecated and will be 571 * removed. It is implemented as a no-op. Subclasses that override 572 * {@code finalize} in order to perform cleanup should be modified to use 573 * alternative cleanup mechanisms and to remove the overriding {@code finalize} 574 * method. The recommended cleanup for compressor is to explicitly call 575 * {@code end} method when it is no longer in use. If the {@code end} is 576 * not invoked explicitly the resource of the compressor will be released 577 * when the instance becomes unreachable. 578 */ 579 @Deprecated(since="9", forRemoval=true) 580 protected void finalize() {} 581 582 private void ensureOpen() { 583 assert Thread.holdsLock(zsRef); 584 if (zsRef.address() == 0) 585 throw new NullPointerException("Deflater has been closed"); 586 } 587 588 private static native void initIDs(); 589 private static native long init(int level, int strategy, boolean nowrap); 590 private static native void setDictionary(long addr, byte[] b, int off, int len); 591 private native int deflateBytes(long addr, byte[] b, int off, int len, 592 int flush); 593 private static native int getAdler(long addr); 594 private static native void reset(long addr); 595 private static native void end(long addr); 596 597 /** 598 * A reference to the native zlib's z_stream structure. It also 599 * serves as the "cleaner" to clean up the native resource when 600 * the Deflater is ended, closed or cleaned. 601 */ 602 static class DeflaterZStreamRef implements Runnable { 603 604 private long address; 605 private final Cleanable cleanable; 606 607 private DeflaterZStreamRef(Deflater owner, long addr) { 608 this.cleanable = (owner != null) ? CleanerFactory.cleaner().register(owner, this) : null; 609 this.address = addr; 610 } 611 612 long address() { 613 return address; 614 } 615 616 void clean() { 617 cleanable.clean(); 618 } 619 620 public synchronized void run() { 621 long addr = address; 622 address = 0; 623 if (addr != 0) { 624 end(addr); 625 } 626 } 627 628 /* 629 * If {@code Deflater} has been subclassed and the {@code end} method is 630 * overridden, uses {@code finalizer} mechanism for resource cleanup. So 631 * {@code end} method can be called when the {@code Deflater} is unreachable. 632 * This mechanism will be removed when the {@code finalize} method is 633 * removed from {@code Deflater}. 634 */ 635 static DeflaterZStreamRef get(Deflater owner, long addr) { 636 Class<?> clz = owner.getClass(); 637 while (clz != Deflater.class) { 638 try { 639 clz.getDeclaredMethod("end"); 640 return new FinalizableZStreamRef(owner, addr); 641 } catch (NoSuchMethodException nsme) {} 642 clz = clz.getSuperclass(); 643 } 644 return new DeflaterZStreamRef(owner, addr); 645 } 646 647 private static class FinalizableZStreamRef extends DeflaterZStreamRef { 648 final Deflater owner; 649 650 FinalizableZStreamRef (Deflater owner, long addr) { 651 super(null, addr); 652 this.owner = owner; 653 } 654 655 @Override 656 void clean() { 657 run(); 658 } 659 660 @Override 661 @SuppressWarnings("deprecation") 662 protected void finalize() { 663 owner.end(); 664 } 665 } 666 } 667 }