< prev index next >

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;


  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  * <p>
  70  * @apiNote
  71  * In earlier versions the {@link Object#finalize} method was overridden and
  72  * specified to call the {@code end} method to close the {@code inflater} and
  73  * release the resource when the instance becomes unreachable.
  74  * The {@code finalize} method is no longer defined. The recommended cleanup
  75  * for decompressor is to explicitly call {@code end} method when it is no
  76  * longer in use.
  77  *
  78  * @implNote
  79  * The resource of the decompressor will be released when the instance becomes
  80  * phantom-reachable, if the {@code end} is not invoked explicitly.
  81  * <p>
  82  *
  83  * @see         Deflater
  84  * @author      David Connelly
  85  * @since 1.1
  86  *
  87  */
  88 public
  89 class Inflater {
  90 
  91     private final ZStreamRef zsRef;
  92     private byte[] buf = defaultBuf;
  93     private int off, len;
  94     private boolean finished;
  95     private boolean needDict;
  96     private long bytesRead;
  97     private long bytesWritten;
  98 
  99     private static final byte[] defaultBuf = new byte[0];
 100 
 101     static {
 102         ZipUtils.loadLibrary();
 103         initIDs();
 104     }
 105 
 106     /**
 107      * Creates a new decompressor. If the parameter 'nowrap' is true then
 108      * the ZLIB header and checksum fields will not be used. This provides
 109      * compatibility with the compression format used by both GZIP and PKZIP.
 110      * <p>
 111      * Note: When using the 'nowrap' option it is also necessary to provide
 112      * an extra "dummy" byte as input. This is required by the ZLIB native
 113      * library in order to support certain optimizations.
 114      *
 115      * @param nowrap if true then support GZIP compatible compression
 116      */
 117     public Inflater(boolean nowrap) {
 118         this.zsRef = new ZStreamRef(this, () -> init(nowrap), Inflater::end);
 119     }
 120 
 121     /**
 122      * Creates a new decompressor.
 123      */
 124     public Inflater() {
 125         this(false);
 126     }
 127 
 128     /**
 129      * Sets input data for decompression. Should be called whenever
 130      * needsInput() returns true indicating that more input data is
 131      * required.
 132      * @param b the input data bytes
 133      * @param off the start offset of the input data
 134      * @param len the length of the input data
 135      * @see Inflater#needsInput
 136      */
 137     public void setInput(byte[] b, int off, int len) {
 138         if (b == null) {


 358         }
 359     }
 360 
 361     /**
 362      * Resets inflater so that a new set of input data can be processed.
 363      */
 364     public void reset() {
 365         synchronized (zsRef) {
 366             ensureOpen();
 367             reset(zsRef.address());
 368             buf = defaultBuf;
 369             finished = false;
 370             needDict = false;
 371             off = len = 0;
 372             bytesRead = bytesWritten = 0;
 373         }
 374     }
 375 
 376     /**
 377      * Closes the decompressor and discards any unprocessed input.
 378      *
 379      * This method should be called when the decompressor is no longer
 380      * being used. Once this method is called, the behavior of the
 381      * Inflater object is undefined.

 382      */
 383     public void end() {
 384         synchronized (zsRef) {
 385             zsRef.clean();



 386             buf = null;
 387         }


















 388     }
 389 
 390     private void ensureOpen () {
 391         assert Thread.holdsLock(zsRef);
 392         if (zsRef.address() == 0)
 393             throw new NullPointerException("Inflater has been closed");
 394     }
 395 
 396     boolean ended() {
 397         synchronized (zsRef) {
 398             return zsRef.address() == 0;
 399         }
 400     }
 401 
 402     private static native void initIDs();
 403     private static native long init(boolean nowrap);
 404     private static native void setDictionary(long addr, byte[] b, int off,
 405                                              int len);
 406     private native int inflateBytes(long addr, byte[] b, int off, int len)
 407             throws DataFormatException;
< prev index next >