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