1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.util.zip; 19 20 import dalvik.system.CloseGuard; 21 import java.util.Arrays; 22 import libcore.util.EmptyArray; 23 24 /** 25 * This class compresses data using the <i>DEFLATE</i> algorithm (see <a 26 * href="http://www.gzip.org/algorithm.txt">specification</a>). 27 * 28 * <p>It is usually more convenient to use {@link DeflaterOutputStream}. 29 * 30 * <p>To compress an in-memory {@code byte[]} to another in-memory {@code byte[]} manually: 31 * <pre> 32 * byte[] originalBytes = ... 33 * 34 * Deflater deflater = new Deflater(); 35 * deflater.setInput(originalBytes); 36 * deflater.finish(); 37 * 38 * ByteArrayOutputStream baos = new ByteArrayOutputStream(); 39 * byte[] buf = new byte[8192]; 40 * while (!deflater.finished()) { 41 * int byteCount = deflater.deflate(buf); 42 * baos.write(buf, 0, byteCount); 43 * } 44 * deflater.end(); 45 * 46 * byte[] compressedBytes = baos.toByteArray(); 47 * </pre> 48 * <p>In situations where you don't have all the input in one array (or have so much 49 * input that you want to feed it to the deflater in chunks), it's possible to call 50 * {@link #setInput setInput} repeatedly, but you're much better off using 51 * {@link DeflaterOutputStream} to handle all this for you. {@link DeflaterOutputStream} also helps 52 * minimize memory requirements — the sample code above is very expensive. 53 * 54 * <a name="compression_level"><h3>Compression levels</h3></a> 55 * <p>A compression level must be {@link #DEFAULT_COMPRESSION} to compromise between speed and 56 * compression (currently equivalent to level 6), or between 0 ({@link #NO_COMPRESSION}, where 57 * the input is simply copied) and 9 ({@link #BEST_COMPRESSION}). Level 1 ({@link #BEST_SPEED}) 58 * performs some compression, but with minimal speed overhead. 59 */ 60 public class Deflater { 61 62 /** 63 * This <a href="#compression_level">compression level</a> gives the best compression, 64 * but takes the most time. 65 */ 66 public static final int BEST_COMPRESSION = 9; 67 68 /** 69 * This <a href="#compression_level">compression level</a> gives minimal compression, 70 * but takes the least time (of any level that actually performs compression; 71 * see {@link #NO_COMPRESSION}). 72 */ 73 public static final int BEST_SPEED = 1; 74 75 /** 76 * This <a href="#compression_level">compression level</a> does no compression. 77 * It is even faster than {@link #BEST_SPEED}. 78 */ 79 public static final int NO_COMPRESSION = 0; 80 81 /** 82 * The default <a href="#compression_level">compression level</a>. 83 * This is a trade-off between speed and compression, currently equivalent to level 6. 84 */ 85 public static final int DEFAULT_COMPRESSION = -1; 86 87 /** 88 * The default compression strategy. 89 */ 90 public static final int DEFAULT_STRATEGY = 0; 91 92 /** 93 * The default compression method. 94 */ 95 public static final int DEFLATED = 8; 96 97 /** 98 * A compression strategy. 99 */ 100 public static final int FILTERED = 1; 101 102 /** 103 * A compression strategy. 104 */ 105 public static final int HUFFMAN_ONLY = 2; 106 107 /** 108 * Use buffering for best compression. 109 * @since 1.7 110 */ 111 public static final int NO_FLUSH = 0; 112 113 /** 114 * Flush buffers so recipients can immediately decode the data sent thus 115 * far. This mode may degrade compression. 116 * @since 1.7 117 */ 118 public static final int SYNC_FLUSH = 2; 119 120 /** 121 * Flush buffers so recipients can immediately decode the data sent thus 122 * far. The compression state is also reset to permit random access and 123 * recovery for clients who have discarded or damaged their own copy. This 124 * mode may degrade compression. 125 * @since 1.7 126 */ 127 public static final int FULL_FLUSH = 3; 128 129 /** 130 * Flush buffers and mark the end of the data stream. 131 */ 132 private static final int FINISH = 4; 133 134 /** 135 * The ugly name flushParm is for RI compatibility, should code need to access this 136 * field via reflection if it's not able to use public API to choose what 137 * kind of flushing it gets. 138 */ 139 private int flushParm = NO_FLUSH; 140 141 private boolean finished; 142 143 private int compressLevel = DEFAULT_COMPRESSION; 144 145 private int strategy = DEFAULT_STRATEGY; 146 147 private long streamHandle = -1; 148 149 private byte[] inputBuffer; 150 151 private int inRead; 152 153 private int inLength; 154 155 private final CloseGuard guard = CloseGuard.get(); 156 157 /** 158 * Constructs a new {@code Deflater} instance using the 159 * default <a href="#compression_level">compression level</a>. 160 * The compression strategy can be specified with {@link #setStrategy}. A 161 * header is added to the output by default; use {@link 162 * #Deflater(int, boolean)} if you need to omit the header. 163 */ 164 public Deflater() { 165 this(DEFAULT_COMPRESSION, false); 166 } 167 168 /** 169 * Constructs a new {@code Deflater} instance with the 170 * given <a href="#compression_level">compression level</a>. 171 * The compression strategy can be specified with {@link #setStrategy}. 172 * A header is added to the output by default; use 173 * {@link #Deflater(int, boolean)} if you need to omit the header. 174 */ 175 public Deflater(int level) { 176 this(level, false); 177 } 178 179 /** 180 * Constructs a new {@code Deflater} instance with the 181 * given <a href="#compression_level">compression level</a>. 182 * If {@code noHeader} is true, no ZLIB header is added to the 183 * output. In a zip file, every entry (compressed file) comes with such a 184 * header. The strategy can be specified using {@link #setStrategy}. 185 */ 186 public Deflater(int level, boolean noHeader) { 187 if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION) { 188 throw new IllegalArgumentException("Bad level: " + level); 189 } 190 compressLevel = level; 191 streamHandle = createStream(compressLevel, strategy, noHeader); 192 guard.open("end"); 193 } 194 195 /** 196 * Deflates the data (previously passed to {@link #setInput setInput}) into the 197 * supplied buffer. 198 * 199 * @return number of bytes of compressed data written to {@code buf}. 200 */ 201 public int deflate(byte[] buf) { 202 return deflate(buf, 0, buf.length); 203 } 204 205 /** 206 * Deflates data (previously passed to {@link #setInput setInput}) into a specific 207 * region within the supplied buffer. 208 * 209 * @return the number of bytes of compressed data written to {@code buf}. 210 */ 211 public synchronized int deflate(byte[] buf, int offset, int byteCount) { 212 return deflateImpl(buf, offset, byteCount, flushParm); 213 } 214 215 /** 216 * Deflates data (previously passed to {@link #setInput setInput}) into a specific 217 * region within the supplied buffer, optionally flushing the input buffer. 218 * 219 * @param flush one of {@link #NO_FLUSH}, {@link #SYNC_FLUSH} or {@link #FULL_FLUSH}. 220 * @return the number of compressed bytes written to {@code buf}. If this 221 * equals {@code byteCount}, the number of bytes of input to be flushed 222 * may have exceeded the output buffer's capacity. In this case, 223 * finishing a flush will require the output buffer to be drained 224 * and additional calls to {@link #deflate} to be made. 225 * @throws IllegalArgumentException if {@code flush} is invalid. 226 * @since 1.7 227 */ 228 public synchronized int deflate(byte[] buf, int offset, int byteCount, int flush) { 229 if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { 230 throw new IllegalArgumentException("Bad flush value: " + flush); 231 } 232 return deflateImpl(buf, offset, byteCount, flush); 233 } 234 235 private synchronized int deflateImpl(byte[] buf, int offset, int byteCount, int flush) { 236 checkOpen(); 237 Arrays.checkOffsetAndCount(buf.length, offset, byteCount); 238 if (inputBuffer == null) { 239 setInput(EmptyArray.BYTE); 240 } 241 return deflateImpl(buf, offset, byteCount, streamHandle, flush); 242 } 243 244 private native int deflateImpl(byte[] buf, int offset, int byteCount, long handle, int flushParm); 245 246 /** 247 * Frees all resources held onto by this deflating algorithm. Any unused 248 * input or output is discarded. This method should be called explicitly in 249 * order to free native resources as soon as possible. After {@code end()} is 250 * called, other methods will typically throw {@code IllegalStateException}. 251 */ 252 public synchronized void end() { 253 guard.close(); 254 endImpl(); 255 } 256 257 private void endImpl() { 258 if (streamHandle != -1) { 259 endImpl(streamHandle); 260 inputBuffer = null; 261 streamHandle = -1; 262 } 263 } 264 265 private native void endImpl(long handle); 266 267 @Override protected void finalize() { 268 try { 269 if (guard != null) { 270 guard.warnIfOpen(); 271 } 272 synchronized (this) { 273 end(); // to allow overriding classes to clean up 274 endImpl(); // in case those classes don't call super.end() 275 } 276 } finally { 277 try { 278 super.finalize(); 279 } catch (Throwable t) { 280 throw new AssertionError(t); 281 } 282 } 283 } 284 285 /** 286 * Indicates to the {@code Deflater} that all uncompressed input has been provided 287 * to it. 288 * 289 * @see #finished 290 */ 291 public synchronized void finish() { 292 flushParm = FINISH; 293 } 294 295 /** 296 * Returns true if {@link #finish finish} has been called and all 297 * data provided by {@link #setInput setInput} has been 298 * successfully compressed and consumed by {@link #deflate deflate}. 299 */ 300 public synchronized boolean finished() { 301 return finished; 302 } 303 304 /** 305 * Returns the {@link Adler32} checksum of the uncompressed data read so far. 306 */ 307 public synchronized int getAdler() { 308 checkOpen(); 309 return getAdlerImpl(streamHandle); 310 } 311 312 private native int getAdlerImpl(long handle); 313 314 /** 315 * Returns the total number of bytes of input read by this {@code Deflater}. This 316 * method is limited to 32 bits; use {@link #getBytesRead} instead. 317 */ 318 public synchronized int getTotalIn() { 319 checkOpen(); 320 return (int) getTotalInImpl(streamHandle); 321 } 322 323 private native long getTotalInImpl(long handle); 324 325 /** 326 * Returns the total number of bytes written to the output buffer by this {@code 327 * Deflater}. The method is limited to 32 bits; use {@link #getBytesWritten} instead. 328 */ 329 public synchronized int getTotalOut() { 330 checkOpen(); 331 return (int) getTotalOutImpl(streamHandle); 332 } 333 334 private native long getTotalOutImpl(long handle); 335 336 /** 337 * Returns true if {@link #setInput setInput} must be called before deflation can continue. 338 * If all uncompressed data has been provided to the {@code Deflater}, 339 * {@link #finish} must be called to ensure the compressed data is output. 340 */ 341 public synchronized boolean needsInput() { 342 if (inputBuffer == null) { 343 return true; 344 } 345 return inRead == inLength; 346 } 347 348 /** 349 * Resets the {@code Deflater} to accept new input without affecting any 350 * previously made settings for the compression strategy or level. This 351 * operation <i>must</i> be called after {@link #finished} returns 352 * true if the {@code Deflater} is to be reused. 353 */ 354 public synchronized void reset() { 355 checkOpen(); 356 flushParm = NO_FLUSH; 357 finished = false; 358 resetImpl(streamHandle); 359 inputBuffer = null; 360 } 361 362 private native void resetImpl(long handle); 363 364 /** 365 * Sets the dictionary to be used for compression by this {@code Deflater}. 366 * This method can only be called if this {@code Deflater} supports the writing 367 * of ZLIB headers. This is the default, but can be overridden 368 * using {@link #Deflater(int, boolean)}. 369 */ 370 public void setDictionary(byte[] dictionary) { 371 setDictionary(dictionary, 0, dictionary.length); 372 } 373 374 /** 375 * Sets the dictionary to be used for compression by this {@code Deflater}. 376 * This method can only be called if this {@code Deflater} supports the writing 377 * of ZLIB headers. This is the default, but can be overridden 378 * using {@link #Deflater(int, boolean)}. 379 */ 380 public synchronized void setDictionary(byte[] buf, int offset, int byteCount) { 381 checkOpen(); 382 Arrays.checkOffsetAndCount(buf.length, offset, byteCount); 383 setDictionaryImpl(buf, offset, byteCount, streamHandle); 384 } 385 386 private native void setDictionaryImpl(byte[] buf, int offset, int byteCount, long handle); 387 388 /** 389 * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes 390 * for later compression. 391 */ 392 public void setInput(byte[] buf) { 393 setInput(buf, 0, buf.length); 394 } 395 396 /** 397 * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes 398 * for later compression. 399 */ 400 public synchronized void setInput(byte[] buf, int offset, int byteCount) { 401 checkOpen(); 402 Arrays.checkOffsetAndCount(buf.length, offset, byteCount); 403 inLength = byteCount; 404 inRead = 0; 405 if (inputBuffer == null) { 406 setLevelsImpl(compressLevel, strategy, streamHandle); 407 } 408 inputBuffer = buf; 409 setInputImpl(buf, offset, byteCount, streamHandle); 410 } 411 412 private native void setLevelsImpl(int level, int strategy, long handle); 413 414 private native void setInputImpl(byte[] buf, int offset, int byteCount, long handle); 415 416 /** 417 * Sets the given <a href="#compression_level">compression level</a> 418 * to be used when compressing data. This value must be set 419 * prior to calling {@link #setInput setInput}. 420 * @exception IllegalArgumentException 421 * If the compression level is invalid. 422 */ 423 public synchronized void setLevel(int level) { 424 if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION) { 425 throw new IllegalArgumentException("Bad level: " + level); 426 } 427 if (inputBuffer != null) { 428 throw new IllegalStateException("setLevel cannot be called after setInput"); 429 } 430 compressLevel = level; 431 } 432 433 /** 434 * Sets the compression strategy to be used. The strategy must be one of 435 * FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY. This value must be set prior 436 * to calling {@link #setInput setInput}. 437 * 438 * @exception IllegalArgumentException 439 * If the strategy specified is not one of FILTERED, 440 * HUFFMAN_ONLY or DEFAULT_STRATEGY. 441 */ 442 public synchronized void setStrategy(int strategy) { 443 if (strategy < DEFAULT_STRATEGY || strategy > HUFFMAN_ONLY) { 444 throw new IllegalArgumentException("Bad strategy: " + strategy); 445 } 446 if (inputBuffer != null) { 447 throw new IllegalStateException("setStrategy cannot be called after setInput"); 448 } 449 this.strategy = strategy; 450 } 451 452 /** 453 * Returns the total number of bytes read by the {@code Deflater}. This 454 * method is the same as {@link #getTotalIn} except that it returns a 455 * {@code long} value instead of an integer. 456 */ 457 public synchronized long getBytesRead() { 458 checkOpen(); 459 return getTotalInImpl(streamHandle); 460 } 461 462 /** 463 * Returns a the total number of bytes written by this {@code Deflater}. This 464 * method is the same as {@code getTotalOut} except it returns a 465 * {@code long} value instead of an integer. 466 */ 467 public synchronized long getBytesWritten() { 468 checkOpen(); 469 return getTotalOutImpl(streamHandle); 470 } 471 472 private native long createStream(int level, int strategy1, boolean noHeader1); 473 474 private void checkOpen() { 475 if (streamHandle == -1) { 476 throw new IllegalStateException("attempt to use Deflater after calling end"); 477 } 478 } 479 } 480