src/java.base/share/classes/java/util/zip/Deflater.java
changeset 48337 0ee20aad71c4
parent 48238 9f225d4387e2
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 compression using the
    32  * This class provides support for general purpose compression 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  * @since 1.1
    89  * @since 1.1
    87  */
    90  */
    88 
    91 
    89 public class Deflater {
    92 public class Deflater {
    90 
    93 
    91     private final ZStreamRef zsRef;
    94     private final DeflaterZStreamRef zsRef;
    92     private byte[] buf = new byte[0];
    95     private byte[] buf = new byte[0];
    93     private int off, len;
    96     private int off, len;
    94     private int level, strategy;
    97     private int level, strategy;
    95     private boolean setParams;
    98     private boolean setParams;
    96     private boolean finish, finished;
    99     private boolean finish, finished;
   181      * @param nowrap if true then use GZIP compatible compression
   184      * @param nowrap if true then use GZIP compatible compression
   182      */
   185      */
   183     public Deflater(int level, boolean nowrap) {
   186     public Deflater(int level, boolean nowrap) {
   184         this.level = level;
   187         this.level = level;
   185         this.strategy = DEFAULT_STRATEGY;
   188         this.strategy = DEFAULT_STRATEGY;
   186         this.zsRef = ZStreamRef.get(this,
   189         this.zsRef = DeflaterZStreamRef.get(this,
   187                 () -> init(level, DEFAULT_STRATEGY, nowrap),
   190                                     init(level, DEFAULT_STRATEGY, nowrap));
   188                 Deflater::end);
       
   189     }
   191     }
   190 
   192 
   191     /**
   193     /**
   192      * Creates a new compressor using the specified compression level.
   194      * Creates a new compressor using the specified compression level.
   193      * Compressed data will be generated in ZLIB format.
   195      * Compressed data will be generated in ZLIB format.
   589     private native int deflateBytes(long addr, byte[] b, int off, int len,
   591     private native int deflateBytes(long addr, byte[] b, int off, int len,
   590                                     int flush);
   592                                     int flush);
   591     private static native int getAdler(long addr);
   593     private static native int getAdler(long addr);
   592     private static native void reset(long addr);
   594     private static native void reset(long addr);
   593     private static native void end(long addr);
   595     private static native void end(long addr);
       
   596 
       
   597     /**
       
   598      * A reference to the native zlib's z_stream structure. It also
       
   599      * serves as the "cleaner" to clean up the native resource when
       
   600      * the Deflater is ended, closed or cleaned.
       
   601      */
       
   602     static class DeflaterZStreamRef implements Runnable {
       
   603 
       
   604         private long address;
       
   605         private final Cleanable cleanable;
       
   606 
       
   607         private DeflaterZStreamRef(Deflater owner, long addr) {
       
   608             this.cleanable = (owner != null) ? CleanerFactory.cleaner().register(owner, this) : null;
       
   609             this.address = addr;
       
   610         }
       
   611 
       
   612         long address() {
       
   613             return address;
       
   614         }
       
   615 
       
   616         void clean() {
       
   617             cleanable.clean();
       
   618         }
       
   619 
       
   620         public synchronized void run() {
       
   621             long addr = address;
       
   622             address = 0;
       
   623             if (addr != 0) {
       
   624                 end(addr);
       
   625             }
       
   626         }
       
   627 
       
   628         /*
       
   629          * If {@code Deflater} has been subclassed and the {@code end} method is
       
   630          * overridden, uses {@code finalizer} mechanism for resource cleanup. So
       
   631          * {@code end} method can be called when the {@code Deflater} is unreachable.
       
   632          * This mechanism will be removed when the {@code finalize} method is
       
   633          * removed from {@code Deflater}.
       
   634          */
       
   635         static DeflaterZStreamRef get(Deflater owner, long addr) {
       
   636             Class<?> clz = owner.getClass();
       
   637             while (clz != Deflater.class) {
       
   638                 try {
       
   639                     clz.getDeclaredMethod("end");
       
   640                     return new FinalizableZStreamRef(owner, addr);
       
   641                 } catch (NoSuchMethodException nsme) {}
       
   642                 clz = clz.getSuperclass();
       
   643             }
       
   644             return new DeflaterZStreamRef(owner, addr);
       
   645         }
       
   646 
       
   647         private static class FinalizableZStreamRef extends DeflaterZStreamRef {
       
   648             final Deflater owner;
       
   649 
       
   650             FinalizableZStreamRef (Deflater owner, long addr) {
       
   651                 super(null, addr);
       
   652                 this.owner = owner;
       
   653             }
       
   654 
       
   655             @Override
       
   656             void clean() {
       
   657                 run();
       
   658             }
       
   659 
       
   660             @Override
       
   661             @SuppressWarnings("deprecation")
       
   662             protected void finalize() {
       
   663                 owner.end();
       
   664             }
       
   665         }
       
   666     }
   594 }
   667 }