49 * compresser.setInput(input); 50 * compresser.finish(); 51 * int compressedDataLength = compresser.deflate(output); 52 * 53 * // Decompress the bytes 54 * Inflater decompresser = new Inflater(); 55 * decompresser.setInput(output, 0, compressedDataLength); 56 * byte[] result = new byte[100]; 57 * int resultLength = decompresser.inflate(result); 58 * decompresser.end(); 59 * 60 * // Decode the bytes into a String 61 * String outputString = new String(result, 0, resultLength, "UTF-8"); 62 * } catch(java.io.UnsupportedEncodingException ex) { 63 * // handle 64 * } catch (java.util.zip.DataFormatException ex) { 65 * // handle 66 * } 67 * </pre></blockquote> 68 * 69 * @see Deflater 70 * @author David Connelly 71 * @since 1.1 72 * 73 */ 74 public 75 class Inflater { 76 77 private final ZStreamRef zsRef; 78 private byte[] buf = defaultBuf; 79 private int off, len; 80 private boolean finished; 81 private boolean needDict; 82 private long bytesRead; 83 private long bytesWritten; 84 85 private static final byte[] defaultBuf = new byte[0]; 86 87 static { 88 ZipUtils.loadLibrary(); 89 initIDs(); 90 } 91 92 /** 93 * Creates a new decompressor. If the parameter 'nowrap' is true then 94 * the ZLIB header and checksum fields will not be used. This provides 95 * compatibility with the compression format used by both GZIP and PKZIP. 96 * <p> 97 * Note: When using the 'nowrap' option it is also necessary to provide 98 * an extra "dummy" byte as input. This is required by the ZLIB native 99 * library in order to support certain optimizations. 100 * 101 * @param nowrap if true then support GZIP compatible compression 102 */ 103 public Inflater(boolean nowrap) { 104 zsRef = new ZStreamRef(init(nowrap)); 105 } 106 107 /** 108 * Creates a new decompressor. 109 */ 110 public Inflater() { 111 this(false); 112 } 113 114 /** 115 * Sets input data for decompression. Should be called whenever 116 * needsInput() returns true indicating that more input data is 117 * required. 118 * @param b the input data bytes 119 * @param off the start offset of the input data 120 * @param len the length of the input data 121 * @see Inflater#needsInput 122 */ 123 public void setInput(byte[] b, int off, int len) { 124 if (b == null) { 344 } 345 } 346 347 /** 348 * Resets inflater so that a new set of input data can be processed. 349 */ 350 public void reset() { 351 synchronized (zsRef) { 352 ensureOpen(); 353 reset(zsRef.address()); 354 buf = defaultBuf; 355 finished = false; 356 needDict = false; 357 off = len = 0; 358 bytesRead = bytesWritten = 0; 359 } 360 } 361 362 /** 363 * Closes the decompressor and discards any unprocessed input. 364 * This method should be called when the decompressor is no longer 365 * being used, but will also be called automatically by the finalize() 366 * method. Once this method is called, the behavior of the Inflater 367 * object is undefined. 368 */ 369 public void end() { 370 synchronized (zsRef) { 371 long addr = zsRef.address(); 372 zsRef.clear(); 373 if (addr != 0) { 374 end(addr); 375 buf = null; 376 } 377 } 378 } 379 380 /** 381 * Closes the decompressor when garbage is collected. 382 * 383 * @deprecated The {@code finalize} method has been deprecated. 384 * Subclasses that override {@code finalize} in order to perform cleanup 385 * should be modified to use alternative cleanup mechanisms and 386 * to remove the overriding {@code finalize} method. 387 * When overriding the {@code finalize} method, its implementation must explicitly 388 * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. 389 * See the specification for {@link Object#finalize()} for further 390 * information about migration options. 391 */ 392 @Deprecated(since="9") 393 protected void finalize() { 394 end(); 395 } 396 397 private void ensureOpen () { 398 assert Thread.holdsLock(zsRef); 399 if (zsRef.address() == 0) 400 throw new NullPointerException("Inflater has been closed"); 401 } 402 403 boolean ended() { 404 synchronized (zsRef) { 405 return zsRef.address() == 0; 406 } 407 } 408 409 private static native void initIDs(); 410 private static native long init(boolean nowrap); 411 private static native void setDictionary(long addr, byte[] b, int off, 412 int len); 413 private native int inflateBytes(long addr, byte[] b, int off, int len) 414 throws DataFormatException; 415 private static native int getAdler(long addr); | 49 * compresser.setInput(input); 50 * compresser.finish(); 51 * int compressedDataLength = compresser.deflate(output); 52 * 53 * // Decompress the bytes 54 * Inflater decompresser = new Inflater(); 55 * decompresser.setInput(output, 0, compressedDataLength); 56 * byte[] result = new byte[100]; 57 * int resultLength = decompresser.inflate(result); 58 * decompresser.end(); 59 * 60 * // Decode the bytes into a String 61 * String outputString = new String(result, 0, resultLength, "UTF-8"); 62 * } catch(java.io.UnsupportedEncodingException ex) { 63 * // handle 64 * } catch (java.util.zip.DataFormatException ex) { 65 * // handle 66 * } 67 * </pre></blockquote> 68 * 69 * @apiNote 70 * To release resources used by this {@code Inflater}, the {@link #end()} method 71 * should be called explicitly. Subclasses are responsible for the cleanup of resources 72 * acquired by the subclass. Subclasses that override {@link #finalize()} in order 73 * to perform cleanup should be modified to use alternative cleanup mechanisms such 74 * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. 75 * 76 * @see Deflater 77 * @author David Connelly 78 * @since 1.1 79 * 80 */ 81 82 public class Inflater { 83 84 private final ZStreamRef zsRef; 85 private byte[] buf = defaultBuf; 86 private int off, len; 87 private boolean finished; 88 private boolean needDict; 89 private long bytesRead; 90 private long bytesWritten; 91 92 private static final byte[] defaultBuf = new byte[0]; 93 94 static { 95 ZipUtils.loadLibrary(); 96 initIDs(); 97 } 98 99 /** 100 * Creates a new decompressor. If the parameter 'nowrap' is true then 101 * the ZLIB header and checksum fields will not be used. This provides 102 * compatibility with the compression format used by both GZIP and PKZIP. 103 * <p> 104 * Note: When using the 'nowrap' option it is also necessary to provide 105 * an extra "dummy" byte as input. This is required by the ZLIB native 106 * library in order to support certain optimizations. 107 * 108 * @param nowrap if true then support GZIP compatible compression 109 */ 110 public Inflater(boolean nowrap) { 111 this.zsRef = ZStreamRef.get(this, () -> init(nowrap), Inflater::end); 112 } 113 114 /** 115 * Creates a new decompressor. 116 */ 117 public Inflater() { 118 this(false); 119 } 120 121 /** 122 * Sets input data for decompression. Should be called whenever 123 * needsInput() returns true indicating that more input data is 124 * required. 125 * @param b the input data bytes 126 * @param off the start offset of the input data 127 * @param len the length of the input data 128 * @see Inflater#needsInput 129 */ 130 public void setInput(byte[] b, int off, int len) { 131 if (b == null) { 351 } 352 } 353 354 /** 355 * Resets inflater so that a new set of input data can be processed. 356 */ 357 public void reset() { 358 synchronized (zsRef) { 359 ensureOpen(); 360 reset(zsRef.address()); 361 buf = defaultBuf; 362 finished = false; 363 needDict = false; 364 off = len = 0; 365 bytesRead = bytesWritten = 0; 366 } 367 } 368 369 /** 370 * Closes the decompressor and discards any unprocessed input. 371 * 372 * This method should be called when the decompressor is no longer 373 * being used. Once this method is called, the behavior of the 374 * Inflater object is undefined. 375 */ 376 public void end() { 377 synchronized (zsRef) { 378 zsRef.clean(); 379 buf = null; 380 } 381 } 382 383 /** 384 * Closes the decompressor when garbage is collected. 385 * 386 * @implSpec 387 * If this {@code Inflater} has been subclassed and the {@code end} method 388 * has been overridden, the {@code end} method will be called when the 389 * inflater is unreachable. 390 * 391 * @deprecated The {@code finalize} method has been deprecated and 392 * implemented as a no-op. Subclasses that override {@code finalize} 393 * in order to perform cleanup should be modified to use alternative 394 * cleanup mechanisms and remove the overriding {@code finalize} 395 * method. The recommended cleanup for compressor is to explicitly 396 * call {@code end} method when it is no longer in use. If the 397 * {@code end} is not invoked explicitly the resource of the compressor 398 * will be released when the instance becomes phantom-reachable, 399 */ 400 @Deprecated(since="9", forRemoval=true) 401 protected void finalize() {} 402 403 private void ensureOpen () { 404 assert Thread.holdsLock(zsRef); 405 if (zsRef.address() == 0) 406 throw new NullPointerException("Inflater has been closed"); 407 } 408 409 boolean ended() { 410 synchronized (zsRef) { 411 return zsRef.address() == 0; 412 } 413 } 414 415 private static native void initIDs(); 416 private static native long init(boolean nowrap); 417 private static native void setDictionary(long addr, byte[] b, int off, 418 int len); 419 private native int inflateBytes(long addr, byte[] b, int off, int len) 420 throws DataFormatException; 421 private static native int getAdler(long addr); |