< prev index next >

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

Print this page

        

*** 23,32 **** --- 23,37 ---- * questions. */ package java.util.zip; + import jdk.internal.ref.CleanerFactory; + + import java.lang.ref.Cleaner; + import java.lang.ref.Reference; + /** * This class provides support for general purpose compression using the * popular ZLIB compression library. The ZLIB compression library was * initially developed as part of the PNG graphics standard and is not * protected by patents. It is fully described in the specifications at
*** 65,82 **** * } catch (java.util.zip.DataFormatException ex) { * // handle * } * </pre></blockquote> * * @see Inflater * @author David Connelly * @since 1.1 */ public class Deflater { ! private final ZStreamRef zsRef; private byte[] buf = new byte[0]; private int off, len; private int level, strategy; private boolean setParams; private boolean finish, finished; --- 70,101 ---- * } catch (java.util.zip.DataFormatException ex) { * // handle * } * </pre></blockquote> * + * <p> + * @apiNote + * In earlier versions the {@link Object#finalize} method was overridden and + * specified to call the {@code end} method to close the {@code deflater} and + * release the resource when the instance becomes unreachable. + * The {@code finalize} method is no longer defined. The recommended cleanup + * for compressor is to explicitly call {@code end} method when it is no + * longer in use. + * + * @implNote + * The resource of the compressor will be released when the instance becomes + * phantom-reachable, if the {@code end} is not invoked explicitly. + * <p> + * * @see Inflater * @author David Connelly * @since 1.1 */ public class Deflater { ! private final Cleaner.LongCleanableResource zsRef; private byte[] buf = new byte[0]; private int off, len; private int level, strategy; private boolean setParams; private boolean finish, finished;
*** 167,177 **** * @param nowrap if true then use GZIP compatible compression */ public Deflater(int level, boolean nowrap) { this.level = level; this.strategy = DEFAULT_STRATEGY; ! this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); } /** * Creates a new compressor using the specified compression level. * Compressed data will be generated in ZLIB format. --- 186,200 ---- * @param nowrap if true then use GZIP compatible compression */ public Deflater(int level, boolean nowrap) { this.level = level; this.strategy = DEFAULT_STRATEGY; ! this.zsRef = CleanerFactory ! .cleaner() ! .createLongResource(this, ! () -> init(level, DEFAULT_STRATEGY, nowrap), ! Deflater::end); } /** * Creates a new compressor using the specified compression level. * Compressed data will be generated in ZLIB format.
*** 240,250 **** if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); ! setDictionary(zsRef.address(), b, off, len); } } /** * Sets preset dictionary for compression. A preset dictionary is used --- 263,274 ---- if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); ! setDictionary(zsRef.value(), b, off, len); ! Reference.reachabilityFence(this); } } /** * Sets preset dictionary for compression. A preset dictionary is used
*** 443,453 **** synchronized (zsRef) { ensureOpen(); if (flush == NO_FLUSH || flush == SYNC_FLUSH || flush == FULL_FLUSH) { int thisLen = this.len; ! int n = deflateBytes(zsRef.address(), b, off, len, flush); bytesWritten += n; bytesRead += (thisLen - this.len); return n; } throw new IllegalArgumentException(); --- 467,478 ---- synchronized (zsRef) { ensureOpen(); if (flush == NO_FLUSH || flush == SYNC_FLUSH || flush == FULL_FLUSH) { int thisLen = this.len; ! int n = deflateBytes(zsRef.value(), b, off, len, flush); ! Reference.reachabilityFence(this); bytesWritten += n; bytesRead += (thisLen - this.len); return n; } throw new IllegalArgumentException();
*** 459,469 **** * @return the ADLER-32 value of the uncompressed data */ public int getAdler() { synchronized (zsRef) { ensureOpen(); ! return getAdler(zsRef.address()); } } /** * Returns the total number of uncompressed bytes input so far. --- 484,496 ---- * @return the ADLER-32 value of the uncompressed data */ public int getAdler() { synchronized (zsRef) { ensureOpen(); ! int adler = getAdler(zsRef.value()); ! Reference.reachabilityFence(this); ! return adler; } } /** * Returns the total number of uncompressed bytes input so far.
*** 522,579 **** * Keeps current compression level and strategy settings. */ public void reset() { synchronized (zsRef) { ensureOpen(); ! reset(zsRef.address()); finish = false; finished = false; off = len = 0; bytesRead = bytesWritten = 0; } } /** * Closes the compressor and discards any unprocessed input. * This method should be called when the compressor is no longer ! * being used, but will also be called automatically by the ! * finalize() method. Once this method is called, the behavior ! * of the Deflater object is undefined. */ public void end() { synchronized (zsRef) { ! long addr = zsRef.address(); ! zsRef.clear(); ! if (addr != 0) { ! end(addr); buf = null; } } - } - - /** - * Closes the compressor when garbage is collected. - * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. - */ - @Deprecated(since="9") - protected void finalize() { - end(); - } private void ensureOpen() { assert Thread.holdsLock(zsRef); ! if (zsRef.address() == 0) throw new NullPointerException("Deflater has been closed"); } private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); private native int deflateBytes(long addr, byte[] b, int off, int len, --- 549,589 ---- * Keeps current compression level and strategy settings. */ public void reset() { synchronized (zsRef) { ensureOpen(); ! reset(zsRef.value()); ! Reference.reachabilityFence(this); finish = false; finished = false; off = len = 0; bytesRead = bytesWritten = 0; } } /** * Closes the compressor and discards any unprocessed input. + * * This method should be called when the compressor is no longer ! * being used. Once this method is called, the behavior of the ! * Deflater object is undefined. */ public void end() { synchronized (zsRef) { ! zsRef.clean(); buf = null; } } private void ensureOpen() { assert Thread.holdsLock(zsRef); ! try { ! zsRef.value(); ! } catch (IllegalStateException e) { throw new NullPointerException("Deflater has been closed"); } + } private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); private native int deflateBytes(long addr, byte[] b, int off, int len,
< prev index next >