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