< prev index next >

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

Print this page
rev 48331 : 8193507: [REDO] Startup regression due to JDK-8185582
Reviewed-by: alanb, rriggs
Contributed-by: xueming.shen@oracle.com, claes.redestad@oracle.com


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.zip;
  27 



  28 /**
  29  * This class provides support for general purpose compression using the
  30  * popular ZLIB compression library. The ZLIB compression library was
  31  * initially developed as part of the PNG graphics standard and is not
  32  * protected by patents. It is fully described in the specifications at
  33  * the <a href="package-summary.html#package.description">java.util.zip
  34  * package description</a>.
  35  *
  36  * <p>The following code fragment demonstrates a trivial compression
  37  * and decompression of a string using {@code Deflater} and
  38  * {@code Inflater}.
  39  *
  40  * <blockquote><pre>
  41  * try {
  42  *     // Encode a String into bytes
  43  *     String inputString = "blahblahblah";
  44  *     byte[] input = inputString.getBytes("UTF-8");
  45  *
  46  *     // Compress the bytes
  47  *     byte[] output = new byte[100];


  71  * To release resources used by this {@code Deflater}, the {@link #end()} method
  72  * should be called explicitly. Subclasses are responsible for the cleanup of resources
  73  * acquired by the subclass. Subclasses that override {@link #finalize()} in order
  74  * to perform cleanup should be modified to use alternative cleanup mechanisms such
  75  * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
  76  *
  77  * @implSpec
  78  * If this {@code Deflater} has been subclassed and the {@code end} method has been
  79  * overridden, the {@code end} method will be called by the finalization when the
  80  * deflater is unreachable. But the subclasses should not depend on this specific
  81  * implementation; the finalization is not reliable and the {@code finalize} method
  82  * is deprecated to be removed.
  83  *
  84  * @see         Inflater
  85  * @author      David Connelly
  86  * @since 1.1
  87  */
  88 
  89 public class Deflater {
  90 
  91     private final ZStreamRef zsRef;
  92     private byte[] buf = new byte[0];
  93     private int off, len;
  94     private int level, strategy;
  95     private boolean setParams;
  96     private boolean finish, finished;
  97     private long bytesRead;
  98     private long bytesWritten;
  99 
 100     /**
 101      * Compression method for the deflate algorithm (the only one currently
 102      * supported).
 103      */
 104     public static final int DEFLATED = 8;
 105 
 106     /**
 107      * Compression level for no compression.
 108      */
 109     public static final int NO_COMPRESSION = 0;
 110 
 111     /**


 166      * @since 1.7
 167      */
 168     public static final int FULL_FLUSH = 3;
 169 
 170     static {
 171         ZipUtils.loadLibrary();
 172         initIDs();
 173     }
 174 
 175     /**
 176      * Creates a new compressor using the specified compression level.
 177      * If 'nowrap' is true then the ZLIB header and checksum fields will
 178      * not be used in order to support the compression format used in
 179      * both GZIP and PKZIP.
 180      * @param level the compression level (0-9)
 181      * @param nowrap if true then use GZIP compatible compression
 182      */
 183     public Deflater(int level, boolean nowrap) {
 184         this.level = level;
 185         this.strategy = DEFAULT_STRATEGY;
 186         this.zsRef = ZStreamRef.get(this,
 187                 () -> init(level, DEFAULT_STRATEGY, nowrap),
 188                 Deflater::end);
 189     }
 190 
 191     /**
 192      * Creates a new compressor using the specified compression level.
 193      * Compressed data will be generated in ZLIB format.
 194      * @param level the compression level (0-9)
 195      */
 196     public Deflater(int level) {
 197         this(level, false);
 198     }
 199 
 200     /**
 201      * Creates a new compressor with the default compression level.
 202      * Compressed data will be generated in ZLIB format.
 203      */
 204     public Deflater() {
 205         this(DEFAULT_COMPRESSION, false);
 206     }
 207 
 208     /**


 574      *     not invoked explicitly the resource of the compressor will be released
 575      *     when the instance becomes unreachable.
 576      */
 577     @Deprecated(since="9", forRemoval=true)
 578     protected void finalize() {}
 579 
 580     private void ensureOpen() {
 581         assert Thread.holdsLock(zsRef);
 582         if (zsRef.address() == 0)
 583             throw new NullPointerException("Deflater has been closed");
 584     }
 585 
 586     private static native void initIDs();
 587     private static native long init(int level, int strategy, boolean nowrap);
 588     private static native void setDictionary(long addr, byte[] b, int off, int len);
 589     private native int deflateBytes(long addr, byte[] b, int off, int len,
 590                                     int flush);
 591     private static native int getAdler(long addr);
 592     private static native void reset(long addr);
 593     private static native void end(long addr);







































































 594 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.util.zip;
  27 
  28 import java.lang.ref.Cleaner.Cleanable;
  29 import jdk.internal.ref.CleanerFactory;
  30 
  31 /**
  32  * This class provides support for general purpose compression using the
  33  * popular ZLIB compression library. The ZLIB compression library was
  34  * initially developed as part of the PNG graphics standard and is not
  35  * protected by patents. It is fully described in the specifications at
  36  * the <a href="package-summary.html#package.description">java.util.zip
  37  * package description</a>.
  38  *
  39  * <p>The following code fragment demonstrates a trivial compression
  40  * and decompression of a string using {@code Deflater} and
  41  * {@code Inflater}.
  42  *
  43  * <blockquote><pre>
  44  * try {
  45  *     // Encode a String into bytes
  46  *     String inputString = "blahblahblah";
  47  *     byte[] input = inputString.getBytes("UTF-8");
  48  *
  49  *     // Compress the bytes
  50  *     byte[] output = new byte[100];


  74  * To release resources used by this {@code Deflater}, the {@link #end()} method
  75  * should be called explicitly. Subclasses are responsible for the cleanup of resources
  76  * acquired by the subclass. Subclasses that override {@link #finalize()} in order
  77  * to perform cleanup should be modified to use alternative cleanup mechanisms such
  78  * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
  79  *
  80  * @implSpec
  81  * If this {@code Deflater} has been subclassed and the {@code end} method has been
  82  * overridden, the {@code end} method will be called by the finalization when the
  83  * deflater is unreachable. But the subclasses should not depend on this specific
  84  * implementation; the finalization is not reliable and the {@code finalize} method
  85  * is deprecated to be removed.
  86  *
  87  * @see         Inflater
  88  * @author      David Connelly
  89  * @since 1.1
  90  */
  91 
  92 public class Deflater {
  93 
  94     private final DeflaterZStreamRef zsRef;
  95     private byte[] buf = new byte[0];
  96     private int off, len;
  97     private int level, strategy;
  98     private boolean setParams;
  99     private boolean finish, finished;
 100     private long bytesRead;
 101     private long bytesWritten;
 102 
 103     /**
 104      * Compression method for the deflate algorithm (the only one currently
 105      * supported).
 106      */
 107     public static final int DEFLATED = 8;
 108 
 109     /**
 110      * Compression level for no compression.
 111      */
 112     public static final int NO_COMPRESSION = 0;
 113 
 114     /**


 169      * @since 1.7
 170      */
 171     public static final int FULL_FLUSH = 3;
 172 
 173     static {
 174         ZipUtils.loadLibrary();
 175         initIDs();
 176     }
 177 
 178     /**
 179      * Creates a new compressor using the specified compression level.
 180      * If 'nowrap' is true then the ZLIB header and checksum fields will
 181      * not be used in order to support the compression format used in
 182      * both GZIP and PKZIP.
 183      * @param level the compression level (0-9)
 184      * @param nowrap if true then use GZIP compatible compression
 185      */
 186     public Deflater(int level, boolean nowrap) {
 187         this.level = level;
 188         this.strategy = DEFAULT_STRATEGY;
 189         this.zsRef = DeflaterZStreamRef.get(this,
 190                                     init(level, DEFAULT_STRATEGY, nowrap));

 191     }
 192 
 193     /**
 194      * Creates a new compressor using the specified compression level.
 195      * Compressed data will be generated in ZLIB format.
 196      * @param level the compression level (0-9)
 197      */
 198     public Deflater(int level) {
 199         this(level, false);
 200     }
 201 
 202     /**
 203      * Creates a new compressor with the default compression level.
 204      * Compressed data will be generated in ZLIB format.
 205      */
 206     public Deflater() {
 207         this(DEFAULT_COMPRESSION, false);
 208     }
 209 
 210     /**


 576      *     not invoked explicitly the resource of the compressor will be released
 577      *     when the instance becomes unreachable.
 578      */
 579     @Deprecated(since="9", forRemoval=true)
 580     protected void finalize() {}
 581 
 582     private void ensureOpen() {
 583         assert Thread.holdsLock(zsRef);
 584         if (zsRef.address() == 0)
 585             throw new NullPointerException("Deflater has been closed");
 586     }
 587 
 588     private static native void initIDs();
 589     private static native long init(int level, int strategy, boolean nowrap);
 590     private static native void setDictionary(long addr, byte[] b, int off, int len);
 591     private native int deflateBytes(long addr, byte[] b, int off, int len,
 592                                     int flush);
 593     private static native int getAdler(long addr);
 594     private static native void reset(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     }
 667 }
< prev index next >