src/java.base/share/classes/java/util/zip/Inflater.java
changeset 48337 0ee20aad71c4
parent 48330 e8230b52a8f4
child 49834 99644c75eaed
equal deleted inserted replaced
48336:267be02c1137 48337:0ee20aad71c4
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.util.zip;
    26 package java.util.zip;
       
    27 
       
    28 import java.lang.ref.Cleaner.Cleanable;
       
    29 import jdk.internal.ref.CleanerFactory;
    27 
    30 
    28 /**
    31 /**
    29  * This class provides support for general purpose decompression using the
    32  * This class provides support for general purpose decompression using the
    30  * popular ZLIB compression library. The ZLIB compression library was
    33  * popular ZLIB compression library. The ZLIB compression library was
    31  * initially developed as part of the PNG graphics standard and is not
    34  * initially developed as part of the PNG graphics standard and is not
    86  *
    89  *
    87  */
    90  */
    88 
    91 
    89 public class Inflater {
    92 public class Inflater {
    90 
    93 
    91     private final ZStreamRef zsRef;
    94     private final InflaterZStreamRef zsRef;
    92     private byte[] buf = defaultBuf;
    95     private byte[] buf = defaultBuf;
    93     private int off, len;
    96     private int off, len;
    94     private boolean finished;
    97     private boolean finished;
    95     private boolean needDict;
    98     private boolean needDict;
    96     private long bytesRead;
    99     private long bytesRead;
   113      * library in order to support certain optimizations.
   116      * library in order to support certain optimizations.
   114      *
   117      *
   115      * @param nowrap if true then support GZIP compatible compression
   118      * @param nowrap if true then support GZIP compatible compression
   116      */
   119      */
   117     public Inflater(boolean nowrap) {
   120     public Inflater(boolean nowrap) {
   118         this.zsRef = ZStreamRef.get(this, () -> init(nowrap), Inflater::end);
   121         this.zsRef = InflaterZStreamRef.get(this, init(nowrap));
   119     }
   122     }
   120 
   123 
   121     /**
   124     /**
   122      * Creates a new decompressor.
   125      * Creates a new decompressor.
   123      */
   126      */
   426     private native int inflateBytes(long addr, byte[] b, int off, int len)
   429     private native int inflateBytes(long addr, byte[] b, int off, int len)
   427             throws DataFormatException;
   430             throws DataFormatException;
   428     private static native int getAdler(long addr);
   431     private static native int getAdler(long addr);
   429     private static native void reset(long addr);
   432     private static native void reset(long addr);
   430     private static native void end(long addr);
   433     private static native void end(long addr);
       
   434 
       
   435     /**
       
   436      * A reference to the native zlib's z_stream structure. It also
       
   437      * serves as the "cleaner" to clean up the native resource when
       
   438      * the Inflater is ended, closed or cleaned.
       
   439      */
       
   440     static class InflaterZStreamRef implements Runnable {
       
   441 
       
   442         private long address;
       
   443         private final Cleanable cleanable;
       
   444 
       
   445         private InflaterZStreamRef(Inflater owner, long addr) {
       
   446             this.cleanable = (owner != null) ? CleanerFactory.cleaner().register(owner, this) : null;
       
   447             this.address = addr;
       
   448         }
       
   449 
       
   450         long address() {
       
   451             return address;
       
   452         }
       
   453 
       
   454         void clean() {
       
   455             cleanable.clean();
       
   456         }
       
   457 
       
   458         public synchronized void run() {
       
   459             long addr = address;
       
   460             address = 0;
       
   461             if (addr != 0) {
       
   462                 end(addr);
       
   463             }
       
   464         }
       
   465 
       
   466         /*
       
   467          * If {@code Inflater} has been subclassed and the {@code end} method is
       
   468          * overridden, uses {@code finalizer} mechanism for resource cleanup. So
       
   469          * {@code end} method can be called when the {@code Inflater} is unreachable.
       
   470          * This mechanism will be removed when the {@code finalize} method is
       
   471          * removed from {@code Inflater}.
       
   472          */
       
   473         static InflaterZStreamRef get(Inflater owner, long addr) {
       
   474             Class<?> clz = owner.getClass();
       
   475             while (clz != Inflater.class) {
       
   476                 try {
       
   477                     clz.getDeclaredMethod("end");
       
   478                     return new FinalizableZStreamRef(owner, addr);
       
   479                 } catch (NoSuchMethodException nsme) {}
       
   480                 clz = clz.getSuperclass();
       
   481             }
       
   482             return new InflaterZStreamRef(owner, addr);
       
   483         }
       
   484 
       
   485         private static class FinalizableZStreamRef extends InflaterZStreamRef {
       
   486             final Inflater owner;
       
   487 
       
   488             FinalizableZStreamRef(Inflater owner, long addr) {
       
   489                 super(null, addr);
       
   490                 this.owner = owner;
       
   491             }
       
   492 
       
   493             @Override
       
   494             void clean() {
       
   495                 run();
       
   496             }
       
   497 
       
   498             @Override
       
   499             @SuppressWarnings("deprecation")
       
   500             protected void finalize() {
       
   501                 owner.end();
       
   502             }
       
   503         }
       
   504     }
   431 }
   505 }