< prev index next >

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

Print this page

        

@@ -23,14 +23,19 @@
  * questions.
  */
 
 package java.util.zip;
 
+import jdk.internal.ref.CleanerFactory;
+
+import java.io.EOFException;
 import java.io.FilterInputStream;
-import java.io.InputStream;
 import java.io.IOException;
-import java.io.EOFException;
+import java.io.InputStream;
+import java.lang.ref.Cleaner;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 /**
  * This class implements a stream filter for uncompressing data in the
  * "deflate" compression format. It is also used as the basis for other
  * decompression filters, such as GZIPInputStream.

@@ -58,10 +63,13 @@
 
     private boolean closed = false;
     // this flag is set to true after EOF has reached
     private boolean reachEOF = false;
 
+    // in case this stream manages own Inflater, else null
+    private final Cleaner.CleanableResource<Inflater> infRes;
+
     /**
      * Check to make sure that this stream has not been closed
      */
     private void ensureOpen() throws IOException {
         if (closed) {

@@ -83,12 +91,13 @@
         if (in == null || inf == null) {
             throw new NullPointerException();
         } else if (size <= 0) {
             throw new IllegalArgumentException("buffer size <= 0");
         }
+        this.buf = new byte[size];
+        this.infRes = null; // uses specified/default decompressor
         this.inf = inf;
-        buf = new byte[size];
     }
 
     /**
      * Creates a new input stream with the specified decompressor and a
      * default buffer size.

@@ -108,10 +117,35 @@
     public InflaterInputStream(InputStream in) {
         this(in, new Inflater());
         usesDefaultInflater = true;
     }
 
+    /**
+     * Creates a new input stream with a decompressor allocated by inflaterAllocator
+     * and deallocated by inflaterDeallocator and buffer size.
+     * @param in the input stream
+     * @param inflaterAllocator the inflater allocator function
+     * @param inflaterDeallocator the inflater de-allocator function
+     * @param size the input buffer size
+     */
+    InflaterInputStream(InputStream in,
+                        Supplier<Inflater> inflaterAllocator,
+                        Consumer<Inflater> inflaterDeallocator,
+                        int size) {
+        super(in);
+        if (in == null) {
+            throw new NullPointerException();
+        } else if (size <= 0) {
+            throw new IllegalArgumentException("buffer size <= 0");
+        }
+        this.buf = new byte[size];
+        this.infRes = CleanerFactory
+            .cleaner()
+            .createResource(this, inflaterAllocator, inflaterDeallocator);
+        this.inf = infRes.value();
+    }
+
     private byte[] singleByteBuf = new byte[1];
 
     /**
      * Reads a byte of uncompressed data. This method will block until
      * enough input is available for decompression.

@@ -225,11 +259,13 @@
      * with the stream.
      * @exception IOException if an I/O error has occurred
      */
     public void close() throws IOException {
         if (!closed) {
-            if (usesDefaultInflater)
+            if (infRes != null)
+                infRes.clean();
+            else if (usesDefaultInflater)
                 inf.end();
             in.close();
             closed = true;
         }
     }
< prev index next >