< 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 >