src/java.base/share/classes/java/util/zip/Inflater.java

Print this page




  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);