1 /* 2 * Copyright (c) 1996, 2018, 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 java.lang.ref.Reference; 30 import java.nio.ByteBuffer; 31 import java.nio.ReadOnlyBufferException; 32 import java.util.Objects; 33 34 import jdk.internal.ref.CleanerFactory; 35 import sun.nio.ch.DirectBuffer; 36 37 /** 38 * This class provides support for general purpose compression using the 39 * popular ZLIB compression library. The ZLIB compression library was 40 * initially developed as part of the PNG graphics standard and is not 41 * protected by patents. It is fully described in the specifications at 42 * the <a href="package-summary.html#package.description">java.util.zip 43 * package description</a>. 44 * <p> 45 * This class deflates sequences of bytes into ZLIB compressed data format. 46 * The input byte sequence is provided in either byte array or byte buffer, 47 * via one of the {@code setInput()} methods. The output byte sequence is 48 * written to the output byte array or byte buffer passed to the 49 * {@code deflate()} methods. 50 * <p> 51 * The following code fragment demonstrates a trivial compression 52 * and decompression of a string using {@code Deflater} and 53 * {@code Inflater}. 54 * 55 * <blockquote><pre> 56 * try { 57 * // Encode a String into bytes 58 * String inputString = "blahblahblah"; 59 * byte[] input = inputString.getBytes("UTF-8"); 60 * 61 * // Compress the bytes 62 * byte[] output = new byte[100]; 63 * Deflater compresser = new Deflater(); 64 * compresser.setInput(input); 65 * compresser.finish(); 66 * int compressedDataLength = compresser.deflate(output); 67 * compresser.end(); 68 * 69 * // Decompress the bytes 70 * Inflater decompresser = new Inflater(); 71 * decompresser.setInput(output, 0, compressedDataLength); 72 * byte[] result = new byte[100]; 73 * int resultLength = decompresser.inflate(result); 74 * decompresser.end(); 75 * 76 * // Decode the bytes into a String 77 * String outputString = new String(result, 0, resultLength, "UTF-8"); 78 * } catch (java.io.UnsupportedEncodingException ex) { 79 * // handle 80 * } catch (java.util.zip.DataFormatException ex) { 81 * // handle 82 * } 83 * </pre></blockquote> 84 * 85 * @apiNote 86 * To release resources used by this {@code Deflater}, the {@link #end()} method 87 * should be called explicitly. Subclasses are responsible for the cleanup of resources 88 * acquired by the subclass. Subclasses that override {@link #finalize()} in order 89 * to perform cleanup should be modified to use alternative cleanup mechanisms such 90 * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. 91 * 92 * @implSpec 93 * If this {@code Deflater} has been subclassed and the {@code end} method has been 94 * overridden, the {@code end} method will be called by the finalization when the 95 * deflater is unreachable. But the subclasses should not depend on this specific 96 * implementation; the finalization is not reliable and the {@code finalize} method 97 * is deprecated to be removed. 98 * 99 * @see Inflater 100 * @author David Connelly 101 * @since 1.1 102 */ 103 104 public class Deflater { 105 106 private final DeflaterZStreamRef zsRef; 107 private ByteBuffer input = ZipUtils.defaultBuf; 108 private byte[] inputArray; 109 private int inputPos, inputLim; 110 private int level, strategy; 111 private boolean setParams; 112 private boolean finish, finished; 113 private long bytesRead; 114 private long bytesWritten; 115 116 /** 117 * Compression method for the deflate algorithm (the only one currently 118 * supported). 119 */ 120 public static final int DEFLATED = 8; 121 122 /** 123 * Compression level for no compression. 124 */ 125 public static final int NO_COMPRESSION = 0; 126 127 /** 128 * Compression level for fastest compression. 129 */ 130 public static final int BEST_SPEED = 1; 131 132 /** 133 * Compression level for best compression. 134 */ 135 public static final int BEST_COMPRESSION = 9; 136 137 /** 138 * Default compression level. 139 */ 140 public static final int DEFAULT_COMPRESSION = -1; 141 142 /** 143 * Compression strategy best used for data consisting mostly of small 144 * values with a somewhat random distribution. Forces more Huffman coding 145 * and less string matching. 146 */ 147 public static final int FILTERED = 1; 148 149 /** 150 * Compression strategy for Huffman coding only. 151 */ 152 public static final int HUFFMAN_ONLY = 2; 153 154 /** 155 * Default compression strategy. 156 */ 157 public static final int DEFAULT_STRATEGY = 0; 158 159 /** 160 * Compression flush mode used to achieve best compression result. 161 * 162 * @see Deflater#deflate(byte[], int, int, int) 163 * @since 1.7 164 */ 165 public static final int NO_FLUSH = 0; 166 167 /** 168 * Compression flush mode used to flush out all pending output; may 169 * degrade compression for some compression algorithms. 170 * 171 * @see Deflater#deflate(byte[], int, int, int) 172 * @since 1.7 173 */ 174 public static final int SYNC_FLUSH = 2; 175 176 /** 177 * Compression flush mode used to flush out all pending output and 178 * reset the deflater. Using this mode too often can seriously degrade 179 * compression. 180 * 181 * @see Deflater#deflate(byte[], int, int, int) 182 * @since 1.7 183 */ 184 public static final int FULL_FLUSH = 3; 185 186 /** 187 * Flush mode to use at the end of output. Can only be provided by the 188 * user by way of {@link #finish()}. 189 */ 190 private static final int FINISH = 4; 191 192 static { 193 ZipUtils.loadLibrary(); 194 } 195 196 /** 197 * Creates a new compressor using the specified compression level. 198 * If 'nowrap' is true then the ZLIB header and checksum fields will 199 * not be used in order to support the compression format used in 200 * both GZIP and PKZIP. 201 * @param level the compression level (0-9) 202 * @param nowrap if true then use GZIP compatible compression 203 */ 204 public Deflater(int level, boolean nowrap) { 205 this.level = level; 206 this.strategy = DEFAULT_STRATEGY; 207 this.zsRef = DeflaterZStreamRef.get(this, 208 init(level, DEFAULT_STRATEGY, nowrap)); 209 } 210 211 /** 212 * Creates a new compressor using the specified compression level. 213 * Compressed data will be generated in ZLIB format. 214 * @param level the compression level (0-9) 215 */ 216 public Deflater(int level) { 217 this(level, false); 218 } 219 220 /** 221 * Creates a new compressor with the default compression level. 222 * Compressed data will be generated in ZLIB format. 223 */ 224 public Deflater() { 225 this(DEFAULT_COMPRESSION, false); 226 } 227 228 /** 229 * Sets input data for compression. 230 * <p> 231 * One of the {@code setInput()} methods should be called whenever 232 * {@code needsInput()} returns true indicating that more input data 233 * is required. 234 * <p> 235 * @param input the input data bytes 236 * @param off the start offset of the data 237 * @param len the length of the data 238 * @see Deflater#needsInput 239 */ 240 public void setInput(byte[] input, int off, int len) { 241 if (off < 0 || len < 0 || off > input.length - len) { 242 throw new ArrayIndexOutOfBoundsException(); 243 } 244 synchronized (zsRef) { 245 this.input = null; 246 this.inputArray = input; 247 this.inputPos = off; 248 this.inputLim = off + len; 249 } 250 } 251 252 /** 253 * Sets input data for compression. 254 * <p> 255 * One of the {@code setInput()} methods should be called whenever 256 * {@code needsInput()} returns true indicating that more input data 257 * is required. 258 * <p> 259 * @param input the input data bytes 260 * @see Deflater#needsInput 261 */ 262 public void setInput(byte[] input) { 263 setInput(input, 0, input.length); 264 } 265 266 /** 267 * Sets input data for compression. 268 * <p> 269 * One of the {@code setInput()} methods should be called whenever 270 * {@code needsInput()} returns true indicating that more input data 271 * is required. 272 * <p> 273 * The given buffer's position will be advanced as deflate 274 * operations are performed, up to the buffer's limit. 275 * The input buffer may be modified (refilled) between deflate 276 * operations; doing so is equivalent to creating a new buffer 277 * and setting it with this method. 278 * <p> 279 * Modifying the input buffer's contents, position, or limit 280 * concurrently with an deflate operation will result in 281 * undefined behavior, which may include incorrect operation 282 * results or operation failure. 283 * 284 * @param input the input data bytes 285 * @see Deflater#needsInput 286 * @since 11 287 */ 288 public void setInput(ByteBuffer input) { 289 Objects.requireNonNull(input); 290 synchronized (zsRef) { 291 this.input = input; 292 this.inputArray = null; 293 } 294 } 295 296 /** 297 * Sets preset dictionary for compression. A preset dictionary is used 298 * when the history buffer can be predetermined. When the data is later 299 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 300 * in order to get the Adler-32 value of the dictionary required for 301 * decompression. 302 * @param dictionary the dictionary data bytes 303 * @param off the start offset of the data 304 * @param len the length of the data 305 * @see Inflater#inflate 306 * @see Inflater#getAdler 307 */ 308 public void setDictionary(byte[] dictionary, int off, int len) { 309 if (off < 0 || len < 0 || off > dictionary.length - len) { 310 throw new ArrayIndexOutOfBoundsException(); 311 } 312 synchronized (zsRef) { 313 ensureOpen(); 314 setDictionary(zsRef.address(), dictionary, off, len); 315 } 316 } 317 318 /** 319 * Sets preset dictionary for compression. A preset dictionary is used 320 * when the history buffer can be predetermined. When the data is later 321 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 322 * in order to get the Adler-32 value of the dictionary required for 323 * decompression. 324 * @param dictionary the dictionary data bytes 325 * @see Inflater#inflate 326 * @see Inflater#getAdler 327 */ 328 public void setDictionary(byte[] dictionary) { 329 setDictionary(dictionary, 0, dictionary.length); 330 } 331 332 /** 333 * Sets preset dictionary for compression. A preset dictionary is used 334 * when the history buffer can be predetermined. When the data is later 335 * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called 336 * in order to get the Adler-32 value of the dictionary required for 337 * decompression. 338 * <p> 339 * The bytes in given byte buffer will be fully consumed by this method. On 340 * return, its position will equal its limit. 341 * 342 * @param dictionary the dictionary data bytes 343 * @see Inflater#inflate 344 * @see Inflater#getAdler 345 */ 346 public void setDictionary(ByteBuffer dictionary) { 347 synchronized (zsRef) { 348 int position = dictionary.position(); 349 int remaining = Math.max(dictionary.limit() - position, 0); 350 ensureOpen(); 351 if (dictionary.isDirect()) { 352 long address = ((DirectBuffer) dictionary).address(); 353 try { 354 setDictionaryBuffer(zsRef.address(), address + position, remaining); 355 } finally { 356 Reference.reachabilityFence(dictionary); 357 } 358 } else { 359 byte[] array = ZipUtils.getBufferArray(dictionary); 360 int offset = ZipUtils.getBufferOffset(dictionary); 361 setDictionary(zsRef.address(), array, offset + position, remaining); 362 } 363 dictionary.position(position + remaining); 364 } 365 } 366 367 /** 368 * Sets the compression strategy to the specified value. 369 * 370 * <p> If the compression strategy is changed, the next invocation 371 * of {@code deflate} will compress the input available so far with 372 * the old strategy (and may be flushed); the new strategy will take 373 * effect only after that invocation. 374 * 375 * @param strategy the new compression strategy 376 * @exception IllegalArgumentException if the compression strategy is 377 * invalid 378 */ 379 public void setStrategy(int strategy) { 380 switch (strategy) { 381 case DEFAULT_STRATEGY: 382 case FILTERED: 383 case HUFFMAN_ONLY: 384 break; 385 default: 386 throw new IllegalArgumentException(); 387 } 388 synchronized (zsRef) { 389 if (this.strategy != strategy) { 390 this.strategy = strategy; 391 setParams = true; 392 } 393 } 394 } 395 396 /** 397 * Sets the compression level to the specified value. 398 * 399 * <p> If the compression level is changed, the next invocation 400 * of {@code deflate} will compress the input available so far 401 * with the old level (and may be flushed); the new level will 402 * take effect only after that invocation. 403 * 404 * @param level the new compression level (0-9) 405 * @exception IllegalArgumentException if the compression level is invalid 406 */ 407 public void setLevel(int level) { 408 if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) { 409 throw new IllegalArgumentException("invalid compression level"); 410 } 411 synchronized (zsRef) { 412 if (this.level != level) { 413 this.level = level; 414 setParams = true; 415 } 416 } 417 } 418 419 /** 420 * Returns true if no data remains in the input buffer. This can 421 * be used to determine if one of the {@code setInput()} methods should be 422 * called in order to provide more input. 423 * 424 * @return true if the input data buffer is empty and setInput() 425 * should be called in order to provide more input 426 */ 427 public boolean needsInput() { 428 synchronized (zsRef) { 429 ByteBuffer input = this.input; 430 return input == null ? inputLim == inputPos : ! input.hasRemaining(); 431 } 432 } 433 434 /** 435 * When called, indicates that compression should end with the current 436 * contents of the input buffer. 437 */ 438 public void finish() { 439 synchronized (zsRef) { 440 finish = true; 441 } 442 } 443 444 /** 445 * Returns true if the end of the compressed data output stream has 446 * been reached. 447 * @return true if the end of the compressed data output stream has 448 * been reached 449 */ 450 public boolean finished() { 451 synchronized (zsRef) { 452 return finished; 453 } 454 } 455 456 /** 457 * Compresses the input data and fills specified buffer with compressed 458 * data. Returns actual number of bytes of compressed data. A return value 459 * of 0 indicates that {@link #needsInput() needsInput} should be called 460 * in order to determine if more input data is required. 461 * 462 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 463 * An invocation of this method of the form {@code deflater.deflate(b, off, len)} 464 * yields the same result as the invocation of 465 * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}. 466 * 467 * @param output the buffer for the compressed data 468 * @param off the start offset of the data 469 * @param len the maximum number of bytes of compressed data 470 * @return the actual number of bytes of compressed data written to the 471 * output buffer 472 */ 473 public int deflate(byte[] output, int off, int len) { 474 return deflate(output, off, len, NO_FLUSH); 475 } 476 477 /** 478 * Compresses the input data and fills specified buffer with compressed 479 * data. Returns actual number of bytes of compressed data. A return value 480 * of 0 indicates that {@link #needsInput() needsInput} should be called 481 * in order to determine if more input data is required. 482 * 483 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 484 * An invocation of this method of the form {@code deflater.deflate(b)} 485 * yields the same result as the invocation of 486 * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. 487 * 488 * @param output the buffer for the compressed data 489 * @return the actual number of bytes of compressed data written to the 490 * output buffer 491 */ 492 public int deflate(byte[] output) { 493 return deflate(output, 0, output.length, NO_FLUSH); 494 } 495 496 /** 497 * Compresses the input data and fills specified buffer with compressed 498 * data. Returns actual number of bytes of compressed data. A return value 499 * of 0 indicates that {@link #needsInput() needsInput} should be called 500 * in order to determine if more input data is required. 501 * 502 * <p>This method uses {@link #NO_FLUSH} as its compression flush mode. 503 * An invocation of this method of the form {@code deflater.deflate(output)} 504 * yields the same result as the invocation of 505 * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. 506 * 507 * @param output the buffer for the compressed data 508 * @return the actual number of bytes of compressed data written to the 509 * output buffer 510 * @since 11 511 */ 512 public int deflate(ByteBuffer output) { 513 return deflate(output, NO_FLUSH); 514 } 515 516 /** 517 * Compresses the input data and fills the specified buffer with compressed 518 * data. Returns actual number of bytes of data compressed. 519 * 520 * <p>Compression flush mode is one of the following three modes: 521 * 522 * <ul> 523 * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data 524 * to accumulate, before producing output, in order to achieve the best 525 * compression (should be used in normal use scenario). A return value 526 * of 0 in this flush mode indicates that {@link #needsInput()} should 527 * be called in order to determine if more input data is required. 528 * 529 * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed, 530 * to the specified output buffer, so that an inflater that works on 531 * compressed data can get all input data available so far (In particular 532 * the {@link #needsInput()} returns {@code true} after this invocation 533 * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} 534 * may degrade compression for some compression algorithms and so it 535 * should be used only when necessary. 536 * 537 * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with 538 * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater 539 * that works on the compressed output data can restart from this point 540 * if previous compressed data has been damaged or if random access is 541 * desired. Using {@link #FULL_FLUSH} too often can seriously degrade 542 * compression. 543 * </ul> 544 * 545 * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if 546 * the return value is {@code len}, the space available in output 547 * buffer {@code b}, this method should be invoked again with the same 548 * {@code flush} parameter and more output space. Make sure that 549 * {@code len} is greater than 6 to avoid flush marker (5 bytes) being 550 * repeatedly output to the output buffer every time this method is 551 * invoked. 552 * 553 * <p>If the {@link #setInput(ByteBuffer)} method was called to provide a buffer 554 * for input, the input buffer's position will be advanced by the number of bytes 555 * consumed by this operation. 556 * 557 * @param output the buffer for the compressed data 558 * @param off the start offset of the data 559 * @param len the maximum number of bytes of compressed data 560 * @param flush the compression flush mode 561 * @return the actual number of bytes of compressed data written to 562 * the output buffer 563 * 564 * @throws IllegalArgumentException if the flush mode is invalid 565 * @since 1.7 566 */ 567 public int deflate(byte[] output, int off, int len, int flush) { 568 if (off < 0 || len < 0 || off > output.length - len) { 569 throw new ArrayIndexOutOfBoundsException(); 570 } 571 if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { 572 throw new IllegalArgumentException(); 573 } 574 synchronized (zsRef) { 575 ensureOpen(); 576 577 ByteBuffer input = this.input; 578 if (finish) { 579 // disregard given flush mode in this case 580 flush = FINISH; 581 } 582 int params; 583 if (setParams) { 584 // bit 0: true to set params 585 // bit 1-2: strategy (0, 1, or 2) 586 // bit 3-31: level (0..9 or -1) 587 params = 1 | strategy << 1 | level << 3; 588 } else { 589 params = 0; 590 } 591 int inputPos; 592 long result; 593 if (input == null) { 594 inputPos = this.inputPos; 595 result = deflateBytesBytes(zsRef.address(), 596 inputArray, inputPos, inputLim - inputPos, 597 output, off, len, 598 flush, params); 599 } else { 600 inputPos = input.position(); 601 int inputRem = Math.max(input.limit() - inputPos, 0); 602 if (input.isDirect()) { 603 try { 604 long inputAddress = ((DirectBuffer) input).address(); 605 result = deflateBufferBytes(zsRef.address(), 606 inputAddress + inputPos, inputRem, 607 output, off, len, 608 flush, params); 609 } finally { 610 Reference.reachabilityFence(input); 611 } 612 } else { 613 byte[] inputArray = ZipUtils.getBufferArray(input); 614 int inputOffset = ZipUtils.getBufferOffset(input); 615 result = deflateBytesBytes(zsRef.address(), 616 inputArray, inputOffset + inputPos, inputRem, 617 output, off, len, 618 flush, params); 619 } 620 } 621 int read = (int) (result & 0x7fff_ffffL); 622 int written = (int) (result >>> 31 & 0x7fff_ffffL); 623 if ((result >>> 62 & 1) != 0) { 624 finished = true; 625 } 626 if (params != 0 && (result >>> 63 & 1) == 0) { 627 setParams = false; 628 } 629 if (input != null) { 630 input.position(inputPos + read); 631 } else { 632 this.inputPos = inputPos + read; 633 } 634 bytesWritten += written; 635 bytesRead += read; 636 return written; 637 } 638 } 639 640 /** 641 * Compresses the input data and fills the specified buffer with compressed 642 * data. Returns actual number of bytes of data compressed. 643 * 644 * <p>Compression flush mode is one of the following three modes: 645 * 646 * <ul> 647 * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data 648 * to accumulate, before producing output, in order to achieve the best 649 * compression (should be used in normal use scenario). A return value 650 * of 0 in this flush mode indicates that {@link #needsInput()} should 651 * be called in order to determine if more input data is required. 652 * 653 * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed, 654 * to the specified output buffer, so that an inflater that works on 655 * compressed data can get all input data available so far (In particular 656 * the {@link #needsInput()} returns {@code true} after this invocation 657 * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} 658 * may degrade compression for some compression algorithms and so it 659 * should be used only when necessary. 660 * 661 * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with 662 * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater 663 * that works on the compressed output data can restart from this point 664 * if previous compressed data has been damaged or if random access is 665 * desired. Using {@link #FULL_FLUSH} too often can seriously degrade 666 * compression. 667 * </ul> 668 * 669 * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if 670 * the return value is equal to the {@linkplain ByteBuffer#remaining() remaining space} 671 * of the buffer, this method should be invoked again with the same 672 * {@code flush} parameter and more output space. Make sure that 673 * the buffer has at least 6 bytes of remaining space to avoid the 674 * flush marker (5 bytes) being repeatedly output to the output buffer 675 * every time this method is invoked. 676 * 677 * <p>On success, the position of the given {@code output} byte buffer will be 678 * advanced by as many bytes as were produced by the operation, which is equal 679 * to the number returned by this method. 680 * 681 * <p>If the {@link #setInput(ByteBuffer)} method was called to provide a buffer 682 * for input, the input buffer's position will be advanced by the number of bytes 683 * consumed by this operation. 684 * 685 * @param output the buffer for the compressed data 686 * @param flush the compression flush mode 687 * @return the actual number of bytes of compressed data written to 688 * the output buffer 689 * 690 * @throws IllegalArgumentException if the flush mode is invalid 691 * @since 11 692 */ 693 public int deflate(ByteBuffer output, int flush) { 694 if (output.isReadOnly()) { 695 throw new ReadOnlyBufferException(); 696 } 697 if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { 698 throw new IllegalArgumentException(); 699 } 700 synchronized (zsRef) { 701 ensureOpen(); 702 703 ByteBuffer input = this.input; 704 if (finish) { 705 // disregard given flush mode in this case 706 flush = FINISH; 707 } 708 int params; 709 if (setParams) { 710 // bit 0: true to set params 711 // bit 1-2: strategy (0, 1, or 2) 712 // bit 3-31: level (0..9 or -1) 713 params = 1 | strategy << 1 | level << 3; 714 } else { 715 params = 0; 716 } 717 int outputPos = output.position(); 718 int outputRem = Math.max(output.limit() - outputPos, 0); 719 int inputPos; 720 long result; 721 if (input == null) { 722 inputPos = this.inputPos; 723 if (output.isDirect()) { 724 long outputAddress = ((DirectBuffer) output).address(); 725 try { 726 result = deflateBytesBuffer(zsRef.address(), 727 inputArray, inputPos, inputLim - inputPos, 728 outputAddress + outputPos, outputRem, 729 flush, params); 730 } finally { 731 Reference.reachabilityFence(output); 732 } 733 } else { 734 byte[] outputArray = ZipUtils.getBufferArray(output); 735 int outputOffset = ZipUtils.getBufferOffset(output); 736 result = deflateBytesBytes(zsRef.address(), 737 inputArray, inputPos, inputLim - inputPos, 738 outputArray, outputOffset + outputPos, outputRem, 739 flush, params); 740 } 741 } else { 742 inputPos = input.position(); 743 int inputRem = Math.max(input.limit() - inputPos, 0); 744 if (input.isDirect()) { 745 long inputAddress = ((DirectBuffer) input).address(); 746 try { 747 if (output.isDirect()) { 748 long outputAddress = outputPos + ((DirectBuffer) output).address(); 749 try { 750 result = deflateBufferBuffer(zsRef.address(), 751 inputAddress + inputPos, inputRem, 752 outputAddress, outputRem, 753 flush, params); 754 } finally { 755 Reference.reachabilityFence(output); 756 } 757 } else { 758 byte[] outputArray = ZipUtils.getBufferArray(output); 759 int outputOffset = ZipUtils.getBufferOffset(output); 760 result = deflateBufferBytes(zsRef.address(), 761 inputAddress + inputPos, inputRem, 762 outputArray, outputOffset + outputPos, outputRem, 763 flush, params); 764 } 765 } finally { 766 Reference.reachabilityFence(input); 767 } 768 } else { 769 byte[] inputArray = ZipUtils.getBufferArray(input); 770 int inputOffset = ZipUtils.getBufferOffset(input); 771 if (output.isDirect()) { 772 long outputAddress = ((DirectBuffer) output).address(); 773 try { 774 result = deflateBytesBuffer(zsRef.address(), 775 inputArray, inputOffset + inputPos, inputRem, 776 outputAddress + outputPos, outputRem, 777 flush, params); 778 } finally { 779 Reference.reachabilityFence(output); 780 } 781 } else { 782 byte[] outputArray = ZipUtils.getBufferArray(output); 783 int outputOffset = ZipUtils.getBufferOffset(output); 784 result = deflateBytesBytes(zsRef.address(), 785 inputArray, inputOffset + inputPos, inputRem, 786 outputArray, outputOffset + outputPos, outputRem, 787 flush, params); 788 } 789 } 790 } 791 int read = (int) (result & 0x7fff_ffffL); 792 int written = (int) (result >>> 31 & 0x7fff_ffffL); 793 if ((result >>> 62 & 1) != 0) { 794 finished = true; 795 } 796 if (params != 0 && (result >>> 63 & 1) == 0) { 797 setParams = false; 798 } 799 if (input != null) { 800 input.position(inputPos + read); 801 } else { 802 this.inputPos = inputPos + read; 803 } 804 output.position(outputPos + written); 805 bytesWritten += written; 806 bytesRead += read; 807 return written; 808 } 809 } 810 811 /** 812 * Returns the ADLER-32 value of the uncompressed data. 813 * @return the ADLER-32 value of the uncompressed data 814 */ 815 public int getAdler() { 816 synchronized (zsRef) { 817 ensureOpen(); 818 return getAdler(zsRef.address()); 819 } 820 } 821 822 /** 823 * Returns the total number of uncompressed bytes input so far. 824 * 825 * <p>Since the number of bytes may be greater than 826 * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now 827 * the preferred means of obtaining this information.</p> 828 * 829 * @return the total number of uncompressed bytes input so far 830 */ 831 public int getTotalIn() { 832 return (int) getBytesRead(); 833 } 834 835 /** 836 * Returns the total number of uncompressed bytes input so far. 837 * 838 * @return the total (non-negative) number of uncompressed bytes input so far 839 * @since 1.5 840 */ 841 public long getBytesRead() { 842 synchronized (zsRef) { 843 ensureOpen(); 844 return bytesRead; 845 } 846 } 847 848 /** 849 * Returns the total number of compressed bytes output so far. 850 * 851 * <p>Since the number of bytes may be greater than 852 * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now 853 * the preferred means of obtaining this information.</p> 854 * 855 * @return the total number of compressed bytes output so far 856 */ 857 public int getTotalOut() { 858 return (int) getBytesWritten(); 859 } 860 861 /** 862 * Returns the total number of compressed bytes output so far. 863 * 864 * @return the total (non-negative) number of compressed bytes output so far 865 * @since 1.5 866 */ 867 public long getBytesWritten() { 868 synchronized (zsRef) { 869 ensureOpen(); 870 return bytesWritten; 871 } 872 } 873 874 /** 875 * Resets deflater so that a new set of input data can be processed. 876 * Keeps current compression level and strategy settings. 877 */ 878 public void reset() { 879 synchronized (zsRef) { 880 ensureOpen(); 881 reset(zsRef.address()); 882 finish = false; 883 finished = false; 884 input = ZipUtils.defaultBuf; 885 inputArray = null; 886 bytesRead = bytesWritten = 0; 887 } 888 } 889 890 /** 891 * Closes the compressor and discards any unprocessed input. 892 * 893 * This method should be called when the compressor is no longer 894 * being used. Once this method is called, the behavior of the 895 * Deflater object is undefined. 896 */ 897 public void end() { 898 synchronized (zsRef) { 899 zsRef.clean(); 900 input = ZipUtils.defaultBuf; 901 } 902 } 903 904 /** 905 * Closes the compressor when garbage is collected. 906 * 907 * @deprecated The {@code finalize} method has been deprecated and will be 908 * removed. It is implemented as a no-op. Subclasses that override 909 * {@code finalize} in order to perform cleanup should be modified to use 910 * alternative cleanup mechanisms and to remove the overriding {@code finalize} 911 * method. The recommended cleanup for compressor is to explicitly call 912 * {@code end} method when it is no longer in use. If the {@code end} is 913 * not invoked explicitly the resource of the compressor will be released 914 * when the instance becomes unreachable. 915 */ 916 @Deprecated(since="9", forRemoval=true) 917 protected void finalize() {} 918 919 private void ensureOpen() { 920 assert Thread.holdsLock(zsRef); 921 if (zsRef.address() == 0) 922 throw new NullPointerException("Deflater has been closed"); 923 } 924 925 private static native long init(int level, int strategy, boolean nowrap); 926 private static native void setDictionary(long addr, byte[] b, int off, 927 int len); 928 private static native void setDictionaryBuffer(long addr, long bufAddress, int len); 929 private native long deflateBytesBytes(long addr, 930 byte[] inputArray, int inputOff, int inputLen, 931 byte[] outputArray, int outputOff, int outputLen, 932 int flush, int params); 933 private native long deflateBytesBuffer(long addr, 934 byte[] inputArray, int inputOff, int inputLen, 935 long outputAddress, int outputLen, 936 int flush, int params); 937 private native long deflateBufferBytes(long addr, 938 long inputAddress, int inputLen, 939 byte[] outputArray, int outputOff, int outputLen, 940 int flush, int params); 941 private native long deflateBufferBuffer(long addr, 942 long inputAddress, int inputLen, 943 long outputAddress, int outputLen, 944 int flush, int params); 945 private static native int getAdler(long addr); 946 private static native void reset(long addr); 947 private static native void end(long addr); 948 949 /** 950 * A reference to the native zlib's z_stream structure. It also 951 * serves as the "cleaner" to clean up the native resource when 952 * the Deflater is ended, closed or cleaned. 953 */ 954 static class DeflaterZStreamRef implements Runnable { 955 956 private long address; 957 private final Cleanable cleanable; 958 959 private DeflaterZStreamRef(Deflater owner, long addr) { 960 this.cleanable = (owner != null) ? CleanerFactory.cleaner().register(owner, this) : null; 961 this.address = addr; 962 } 963 964 long address() { 965 return address; 966 } 967 968 void clean() { 969 cleanable.clean(); 970 } 971 972 public synchronized void run() { 973 long addr = address; 974 address = 0; 975 if (addr != 0) { 976 end(addr); 977 } 978 } 979 980 /* 981 * If {@code Deflater} has been subclassed and the {@code end} method is 982 * overridden, uses {@code finalizer} mechanism for resource cleanup. So 983 * {@code end} method can be called when the {@code Deflater} is unreachable. 984 * This mechanism will be removed when the {@code finalize} method is 985 * removed from {@code Deflater}. 986 */ 987 static DeflaterZStreamRef get(Deflater owner, long addr) { 988 Class<?> clz = owner.getClass(); 989 while (clz != Deflater.class) { 990 try { 991 clz.getDeclaredMethod("end"); 992 return new FinalizableZStreamRef(owner, addr); 993 } catch (NoSuchMethodException nsme) {} 994 clz = clz.getSuperclass(); 995 } 996 return new DeflaterZStreamRef(owner, addr); 997 } 998 999 private static class FinalizableZStreamRef extends DeflaterZStreamRef { 1000 final Deflater owner; 1001 1002 FinalizableZStreamRef (Deflater owner, long addr) { 1003 super(null, addr); 1004 this.owner = owner; 1005 } 1006 1007 @Override 1008 void clean() { 1009 run(); 1010 } 1011 1012 @Override 1013 @SuppressWarnings("deprecation") 1014 protected void finalize() { 1015 owner.end(); 1016 } 1017 } 1018 } 1019 }