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