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