< prev index next >

src/java.base/share/classes/java/util/zip/Inflater.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 decompression 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\u20AC\u20AC";
  44  *     byte[] input = inputString.getBytes("UTF-8");
  45  *
  46  *     // Compress the bytes
  47  *     byte[] output = new byte[100];


  71  * should be called explicitly. Subclasses are responsible for the cleanup of resources
  72  * acquired by the subclass. Subclasses that override {@link #finalize()} in order
  73  * to perform cleanup should be modified to use alternative cleanup mechanisms such
  74  * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
  75  *
  76  * @implSpec
  77  * If this {@code Inflater} has been subclassed and the {@code end} method has been
  78  * overridden, the {@code end} method will be called by the finalization when the
  79  * inflater is unreachable. But the subclasses should not depend on this specific
  80  * implementation; the finalization is not reliable and the {@code finalize} method
  81  * is deprecated to be removed.
  82  *
  83  * @see         Deflater
  84  * @author      David Connelly
  85  * @since 1.1
  86  *
  87  */
  88 
  89 public 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 = ZStreamRef.get(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) {


 411         assert Thread.holdsLock(zsRef);
 412         if (zsRef.address() == 0)
 413             throw new NullPointerException("Inflater has been closed");
 414     }
 415 
 416     boolean ended() {
 417         synchronized (zsRef) {
 418             return zsRef.address() == 0;
 419         }
 420     }
 421 
 422     private static native void initIDs();
 423     private static native long init(boolean nowrap);
 424     private static native void setDictionary(long addr, byte[] b, int off,
 425                                              int len);
 426     private native int inflateBytes(long addr, byte[] b, int off, int len)
 427             throws DataFormatException;
 428     private static native int getAdler(long addr);
 429     private static native void reset(long addr);
 430     private static native void end(long addr);







































































 431 }


   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 decompression 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\u20AC\u20AC";
  47  *     byte[] input = inputString.getBytes("UTF-8");
  48  *
  49  *     // Compress the bytes
  50  *     byte[] output = new byte[100];


  74  * should be called explicitly. Subclasses are responsible for the cleanup of resources
  75  * acquired by the subclass. Subclasses that override {@link #finalize()} in order
  76  * to perform cleanup should be modified to use alternative cleanup mechanisms such
  77  * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
  78  *
  79  * @implSpec
  80  * If this {@code Inflater} has been subclassed and the {@code end} method has been
  81  * overridden, the {@code end} method will be called by the finalization when the
  82  * inflater is unreachable. But the subclasses should not depend on this specific
  83  * implementation; the finalization is not reliable and the {@code finalize} method
  84  * is deprecated to be removed.
  85  *
  86  * @see         Deflater
  87  * @author      David Connelly
  88  * @since 1.1
  89  *
  90  */
  91 
  92 public class Inflater {
  93 
  94     private final InflaterZStreamRef zsRef;
  95     private byte[] buf = defaultBuf;
  96     private int off, len;
  97     private boolean finished;
  98     private boolean needDict;
  99     private long bytesRead;
 100     private long bytesWritten;
 101 
 102     private static final byte[] defaultBuf = new byte[0];
 103 
 104     static {
 105         ZipUtils.loadLibrary();
 106         initIDs();
 107     }
 108 
 109     /**
 110      * Creates a new decompressor. If the parameter 'nowrap' is true then
 111      * the ZLIB header and checksum fields will not be used. This provides
 112      * compatibility with the compression format used by both GZIP and PKZIP.
 113      * <p>
 114      * Note: When using the 'nowrap' option it is also necessary to provide
 115      * an extra "dummy" byte as input. This is required by the ZLIB native
 116      * library in order to support certain optimizations.
 117      *
 118      * @param nowrap if true then support GZIP compatible compression
 119      */
 120     public Inflater(boolean nowrap) {
 121         this.zsRef = InflaterZStreamRef.get(this, init(nowrap));
 122     }
 123 
 124     /**
 125      * Creates a new decompressor.
 126      */
 127     public Inflater() {
 128         this(false);
 129     }
 130 
 131     /**
 132      * Sets input data for decompression. Should be called whenever
 133      * needsInput() returns true indicating that more input data is
 134      * required.
 135      * @param b the input data bytes
 136      * @param off the start offset of the input data
 137      * @param len the length of the input data
 138      * @see Inflater#needsInput
 139      */
 140     public void setInput(byte[] b, int off, int len) {
 141         if (b == null) {


 414         assert Thread.holdsLock(zsRef);
 415         if (zsRef.address() == 0)
 416             throw new NullPointerException("Inflater has been closed");
 417     }
 418 
 419     boolean ended() {
 420         synchronized (zsRef) {
 421             return zsRef.address() == 0;
 422         }
 423     }
 424 
 425     private static native void initIDs();
 426     private static native long init(boolean nowrap);
 427     private static native void setDictionary(long addr, byte[] b, int off,
 428                                              int len);
 429     private native int inflateBytes(long addr, byte[] b, int off, int len)
 430             throws DataFormatException;
 431     private static native int getAdler(long addr);
 432     private static native void reset(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     }
 505 }
< prev index next >