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