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