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