692 lines
26 KiB
Diff
692 lines
26 KiB
Diff
---
|
|
jdk/make/mapfiles/libzip/mapfile-vers | 5 +-
|
|
.../share/classes/java/util/zip/Deflater.java | 36 +++++--
|
|
.../java/util/zip/GZIPInputStream.java | 73 +++++++++++---
|
|
.../java/util/zip/GZIPOutputStream.java | 44 +++++----
|
|
.../share/classes/java/util/zip/Inflater.java | 37 +++++---
|
|
.../java/util/zip/InflaterInputStream.java | 25 +++++
|
|
jdk/src/share/lib/security/java.policy | 2 +
|
|
jdk/src/share/native/java/util/zip/Deflater.c | 9 +-
|
|
jdk/src/share/native/java/util/zip/Inflater.c | 73 +-------------
|
|
.../java/util/zip/GZIP/TestAvailable.java | 94 +++++++++++++++++++
|
|
10 files changed, 272 insertions(+), 126 deletions(-)
|
|
create mode 100644 jdk/test/java/util/zip/GZIP/TestAvailable.java
|
|
|
|
diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers
|
|
index 5c6d27d0d..79ef59e5f 100644
|
|
--- a/jdk/make/mapfiles/libzip/mapfile-vers
|
|
+++ b/jdk/make/mapfiles/libzip/mapfile-vers
|
|
@@ -38,16 +38,15 @@ SUNWprivate_1.1 {
|
|
Java_java_util_zip_Deflater_end;
|
|
Java_java_util_zip_Deflater_getAdler;
|
|
Java_java_util_zip_Deflater_init;
|
|
- Java_java_util_zip_Deflater_initKae;
|
|
+ Java_java_util_zip_Deflater_initKAE;
|
|
Java_java_util_zip_Deflater_initIDs;
|
|
Java_java_util_zip_Deflater_reset;
|
|
Java_java_util_zip_Deflater_setDictionary;
|
|
Java_java_util_zip_Inflater_end;
|
|
Java_java_util_zip_Inflater_getAdler;
|
|
Java_java_util_zip_Inflater_inflateBytes;
|
|
- Java_java_util_zip_Inflater_inflateBytesKAE;
|
|
Java_java_util_zip_Inflater_init;
|
|
- Java_java_util_zip_Inflater_initKae;
|
|
+ Java_java_util_zip_Inflater_initKAE;
|
|
Java_java_util_zip_Inflater_initIDs;
|
|
Java_java_util_zip_Inflater_reset;
|
|
Java_java_util_zip_Inflater_setDictionary;
|
|
diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
index a4ea40cf8..509808349 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
@@ -81,7 +81,6 @@ class Deflater {
|
|
private boolean finish, finished;
|
|
private long bytesRead;
|
|
private long bytesWritten;
|
|
- private boolean defalterUseKae;
|
|
|
|
/**
|
|
* Compression method for the deflate algorithm (the only one currently
|
|
@@ -169,13 +168,20 @@ class Deflater {
|
|
public Deflater(int level, boolean nowrap) {
|
|
this.level = level;
|
|
this.strategy = DEFAULT_STRATEGY;
|
|
- if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
- ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
- this.defalterUseKae = true;
|
|
- }
|
|
- this.zsRef = defalterUseKae ?
|
|
- new ZStreamRef(initKae(level, DEFAULT_STRATEGY)) :
|
|
- new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
|
|
+ this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Creates a new compressor using the specified compression level
|
|
+ * and windowBits.
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ * @param level the compression level (0-9)
|
|
+ * @param windowBits compression format (-15~31)
|
|
+ */
|
|
+ public Deflater(int level, int windowBits) {
|
|
+ this.level = level;
|
|
+ this.strategy = DEFAULT_STRATEGY;
|
|
+ this.zsRef = new ZStreamRef(initKAE(level, DEFAULT_STRATEGY, windowBits));
|
|
}
|
|
|
|
/**
|
|
@@ -535,6 +541,18 @@ class Deflater {
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
+ * Resets deflater so that a new set of input data can be processed.
|
|
+ * Java fields are not initialized.
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ */
|
|
+ public void resetKAE() {
|
|
+ synchronized (zsRef) {
|
|
+ ensureOpen();
|
|
+ reset(zsRef.address());
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* Closes the compressor and discards any unprocessed input.
|
|
* This method should be called when the compressor is no longer
|
|
@@ -578,7 +596,7 @@ class Deflater {
|
|
|
|
private static native void initIDs();
|
|
private native static long init(int level, int strategy, boolean nowrap);
|
|
- private native static long initKae(int level, int strategy);
|
|
+ private native static long initKAE(int level, int strategy, int windowBits);
|
|
private native static void setDictionary(long addr, byte[] b, int off, int len);
|
|
private native int deflateBytes(long addr, byte[] b, int off, int len,
|
|
int flush);
|
|
diff --git a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
index 7fb753729..10d044caf 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
@@ -54,10 +54,22 @@ class GZIPInputStream extends InflaterInputStream {
|
|
|
|
private boolean closed = false;
|
|
|
|
- /*
|
|
- * GZIP use KAE.
|
|
+ /**
|
|
+ * The field is mainly used to support the KAE-zip feature.
|
|
*/
|
|
- private boolean gzipUseKae = false;
|
|
+ private static boolean GZIP_USE_KAE = false;
|
|
+
|
|
+ private static int WINDOWBITS = 31;
|
|
+
|
|
+ private static int FLUSHKAE = 2;
|
|
+
|
|
+ static {
|
|
+ if ("aarch64".equals(System.getProperty("os.arch"))) {
|
|
+ GZIP_USE_KAE = Boolean.parseBoolean(System.getProperty("GZIP_USE_KAE", "false"));
|
|
+ WINDOWBITS = Integer.parseInt(System.getProperty("WINDOWBITS", "31"));
|
|
+ FLUSHKAE = Integer.parseInt(System.getProperty("FLUSHKAE", "2"));
|
|
+ }
|
|
+ }
|
|
|
|
/**
|
|
* Check to make sure that this stream has not been closed
|
|
@@ -79,14 +91,13 @@ class GZIPInputStream extends InflaterInputStream {
|
|
* @exception IllegalArgumentException if {@code size <= 0}
|
|
*/
|
|
public GZIPInputStream(InputStream in, int size) throws IOException {
|
|
- super(in, new Inflater(true), size);
|
|
+ super(in, GZIP_USE_KAE ? new Inflater(WINDOWBITS, FLUSHKAE) : new Inflater(true), size);
|
|
usesDefaultInflater = true;
|
|
- if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
- ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
- gzipUseKae = true;
|
|
- }
|
|
- // file header will be readed by kae zlib when use kae
|
|
- if (gzipUseKae) return;
|
|
+
|
|
+ // When GZIP_USE_KAE is true, the header of the file is readed
|
|
+ // through the native zlib library, not in java code.
|
|
+ if (GZIP_USE_KAE) return;
|
|
+
|
|
readHeader(in);
|
|
}
|
|
|
|
@@ -127,13 +138,16 @@ class GZIPInputStream extends InflaterInputStream {
|
|
}
|
|
int n = super.read(buf, off, len);
|
|
if (n == -1) {
|
|
- if (readTrailer())
|
|
+ if (GZIP_USE_KAE ? readTrailerKAE() : readTrailer())
|
|
eos = true;
|
|
else
|
|
return this.read(buf, off, len);
|
|
} else {
|
|
crc.update(buf, off, n);
|
|
}
|
|
+ if (GZIP_USE_KAE && inf.finished()) {
|
|
+ if (readTrailerKAE()) eos = true;
|
|
+ }
|
|
return n;
|
|
}
|
|
|
|
@@ -220,9 +234,7 @@ class GZIPInputStream extends InflaterInputStream {
|
|
* data set)
|
|
*/
|
|
private boolean readTrailer() throws IOException {
|
|
- // file trailer will be readed by kae zlib when use kae
|
|
- if (gzipUseKae) return true;
|
|
-
|
|
+ if (GZIP_USE_KAE) return true;
|
|
InputStream in = this.in;
|
|
int n = inf.getRemaining();
|
|
if (n > 0) {
|
|
@@ -251,6 +263,39 @@ class GZIPInputStream extends InflaterInputStream {
|
|
return false;
|
|
}
|
|
|
|
+ /*
|
|
+ * Reads GZIP member trailer and returns true if the eos
|
|
+ * reached, false if there are more (concatenated gzip
|
|
+ * data set)
|
|
+ *
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ */
|
|
+ private boolean readTrailerKAE() throws IOException {
|
|
+ InputStream in = this.in;
|
|
+ int n = inf.getRemaining();
|
|
+ if (n > 0) {
|
|
+ in = new SequenceInputStream(
|
|
+ new ByteArrayInputStream(buf, len - n, n),
|
|
+ new FilterInputStream(in) {
|
|
+ public void close() throws IOException {}
|
|
+ });
|
|
+ }
|
|
+ // If there are more bytes available in "in" or the leftover in the "inf" is > 18 bytes:
|
|
+ // next.header.min(10) + next.trailer(8), try concatenated case
|
|
+
|
|
+ if (n > 18) {
|
|
+ inf.reset();
|
|
+ inf.setInput(buf, len - n, n);
|
|
+ } else {
|
|
+ try {
|
|
+ fillKAE(n);
|
|
+ } catch (IOException e) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
/*
|
|
* Reads unsigned integer in Intel byte order.
|
|
*/
|
|
diff --git a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
index 0f0be98bb..8eae40739 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
@@ -52,10 +52,19 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
*/
|
|
private final static int TRAILER_SIZE = 8;
|
|
|
|
- /*
|
|
- * GZIP use KAE.
|
|
+ /**
|
|
+ * The field is mainly used to support the KAE-zip feature.
|
|
*/
|
|
- private boolean gzipUseKae = false;
|
|
+ private static boolean GZIP_USE_KAE = false;
|
|
+
|
|
+ private static int WINDOWBITS = 31;
|
|
+
|
|
+ static {
|
|
+ if ("aarch64".equals(System.getProperty("os.arch"))) {
|
|
+ GZIP_USE_KAE = Boolean.parseBoolean(System.getProperty("GZIP_USE_KAE", "false"));
|
|
+ WINDOWBITS = Integer.parseInt(System.getProperty("WINDOWBITS", "31"));
|
|
+ }
|
|
+ }
|
|
|
|
/**
|
|
* Creates a new output stream with the specified buffer size.
|
|
@@ -92,16 +101,15 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
public GZIPOutputStream(OutputStream out, int size, boolean syncFlush)
|
|
throws IOException
|
|
{
|
|
- super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true),
|
|
+ super(out, GZIP_USE_KAE ? new Deflater(Deflater.DEFAULT_COMPRESSION, WINDOWBITS) :
|
|
+ new Deflater(Deflater.DEFAULT_COMPRESSION, true),
|
|
size,
|
|
syncFlush);
|
|
usesDefaultDeflater = true;
|
|
- if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
- ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
- gzipUseKae = true;
|
|
- }
|
|
- // file header will be writed by kae zlib when use kae
|
|
- if (gzipUseKae) return;
|
|
+
|
|
+ // When GZIP_USE_KAE is true, the header of the file is written
|
|
+ // through the native zlib library, not in java code.
|
|
+ if (GZIP_USE_KAE) return;
|
|
writeHeader();
|
|
crc.reset();
|
|
}
|
|
@@ -171,9 +179,11 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
int len = def.deflate(buf, 0, buf.length);
|
|
if (def.finished() && len <= buf.length - TRAILER_SIZE) {
|
|
// last deflater buffer. Fit trailer at the end
|
|
- // file trailer will be writed by kae zlib when use kae
|
|
- if (gzipUseKae) {
|
|
+ // When GZIP_USE_KAE is true, the trailer of the file is written
|
|
+ // through the native zlib library, not in java code.
|
|
+ if (GZIP_USE_KAE) {
|
|
out.write(buf, 0, len);
|
|
+ def.resetKAE();
|
|
return;
|
|
}
|
|
writeTrailer(buf, len);
|
|
@@ -184,12 +194,14 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
if (len > 0)
|
|
out.write(buf, 0, len);
|
|
}
|
|
- // file trailer will be writed by kae zlib when use kae
|
|
- if (gzipUseKae) {
|
|
- return;
|
|
- }
|
|
// if we can't fit the trailer at the end of the last
|
|
// deflater buffer, we write it separately
|
|
+ // When GZIP_USE_KAE is true, the trailer of the file is written
|
|
+ // through the native zlib library, not in java code.
|
|
+ if (GZIP_USE_KAE) {
|
|
+ def.resetKAE();
|
|
+ return;
|
|
+ }
|
|
byte[] trailer = new byte[TRAILER_SIZE];
|
|
writeTrailer(trailer, 0);
|
|
out.write(trailer);
|
|
diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
index 42e90f525..d1074cd8d 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
@@ -80,7 +80,6 @@ class Inflater {
|
|
private boolean needDict;
|
|
private long bytesRead;
|
|
private long bytesWritten;
|
|
- private boolean inflaterUseKae;
|
|
|
|
private static final byte[] defaultBuf = new byte[0];
|
|
|
|
@@ -101,11 +100,18 @@ class Inflater {
|
|
* @param nowrap if true then support GZIP compatible compression
|
|
*/
|
|
public Inflater(boolean nowrap) {
|
|
- if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
- ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
- inflaterUseKae = true;
|
|
- }
|
|
- zsRef = inflaterUseKae ? new ZStreamRef(initKae()): new ZStreamRef(init(nowrap));
|
|
+ zsRef = new ZStreamRef(init(nowrap));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Creates a new decompressor.
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ *
|
|
+ * @param windowBits compression format (-15~31)
|
|
+ * @param flushKAE inflate flush type (0~6)
|
|
+ */
|
|
+ public Inflater(int windowBits, int flushKAE) {
|
|
+ this.zsRef = new ZStreamRef(initKAE(windowBits, flushKAE));
|
|
}
|
|
|
|
/**
|
|
@@ -261,9 +267,7 @@ class Inflater {
|
|
synchronized (zsRef) {
|
|
ensureOpen();
|
|
int thisLen = this.len;
|
|
- int n = this.inflaterUseKae ?
|
|
- inflateBytesKAE(zsRef.address(), b, off, len) :
|
|
- inflateBytes(zsRef.address(), b, off, len);
|
|
+ int n = inflateBytes(zsRef.address(), b, off, len);
|
|
bytesWritten += n;
|
|
bytesRead += (thisLen - this.len);
|
|
return n;
|
|
@@ -365,6 +369,17 @@ class Inflater {
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
+ * Resets inflater so that a new set of input data can be processed.
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ */
|
|
+ public void resetKAE() {
|
|
+ synchronized (zsRef) {
|
|
+ ensureOpen();
|
|
+ reset(zsRef.address());
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* Closes the decompressor and discards any unprocessed input.
|
|
* This method should be called when the decompressor is no longer
|
|
@@ -404,13 +419,11 @@ class Inflater {
|
|
|
|
private native static void initIDs();
|
|
private native static long init(boolean nowrap);
|
|
- private native static long initKae();
|
|
+ private native static long initKAE(int windowBits, int flushKAE);
|
|
private native static void setDictionary(long addr, byte[] b, int off,
|
|
int len);
|
|
private native int inflateBytes(long addr, byte[] b, int off, int len)
|
|
throws DataFormatException;
|
|
- private native int inflateBytesKAE(long addr, byte[] b, int off, int len)
|
|
- throws DataFormatException;
|
|
private native static int getAdler(long addr);
|
|
private native static void reset(long addr);
|
|
private native static void end(long addr);
|
|
diff --git a/jdk/src/share/classes/java/util/zip/InflaterInputStream.java b/jdk/src/share/classes/java/util/zip/InflaterInputStream.java
|
|
index 163f619c1..b0ac7dd26 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/InflaterInputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/InflaterInputStream.java
|
|
@@ -179,6 +179,10 @@ class InflaterInputStream extends FilterInputStream {
|
|
ensureOpen();
|
|
if (reachEOF) {
|
|
return 0;
|
|
+ } else if (inf.finished()) {
|
|
+ // the end of the compressed data stream has been reached
|
|
+ reachEOF = true;
|
|
+ return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
@@ -242,6 +246,27 @@ class InflaterInputStream extends FilterInputStream {
|
|
inf.setInput(buf, 0, len);
|
|
}
|
|
|
|
+ /**
|
|
+ * Fills input buffer with more data to decompress.
|
|
+ * This method is mainly used to support the KAE-zip feature.
|
|
+ * @param n Maximum Read Bytes
|
|
+ * @throws IOException if an I/O error has occurred
|
|
+ */
|
|
+ protected void fillKAE(int n) throws IOException {
|
|
+ ensureOpen();
|
|
+ byte[] buftmp = new byte[buf.length];
|
|
+ if (n != 0) {
|
|
+ System.arraycopy(buf, buf.length - n, buftmp, 0, n);
|
|
+ }
|
|
+ int kaelen = in.read(buftmp, n, buf.length - n);
|
|
+ if (kaelen == -1) {
|
|
+ throw new EOFException("Unexpected end of ZLIB input stream");
|
|
+ }
|
|
+ System.arraycopy(buftmp, 0, buf, buf.length - n - kaelen, n + kaelen);
|
|
+ inf.reset();
|
|
+ inf.setInput(buf, buf.length - n - kaelen, n + kaelen);
|
|
+ }
|
|
+
|
|
/**
|
|
* Tests if this input stream supports the <code>mark</code> and
|
|
* <code>reset</code> methods. The <code>markSupported</code>
|
|
diff --git a/jdk/src/share/lib/security/java.policy b/jdk/src/share/lib/security/java.policy
|
|
index baec2ea15..284e3e334 100644
|
|
--- a/jdk/src/share/lib/security/java.policy
|
|
+++ b/jdk/src/share/lib/security/java.policy
|
|
@@ -50,5 +50,7 @@ grant {
|
|
permission java.util.PropertyPermission "sun.security.pkcs11.disableKeyExtraction", "read";
|
|
|
|
permission java.util.PropertyPermission "GZIP_USE_KAE", "read";
|
|
+ permission java.util.PropertyPermission "WINDOWBITS", "read";
|
|
+ permission java.util.PropertyPermission "FLUSHKAE", "read";
|
|
};
|
|
|
|
diff --git a/jdk/src/share/native/java/util/zip/Deflater.c b/jdk/src/share/native/java/util/zip/Deflater.c
|
|
index 1b048e4f5..b26eb1392 100644
|
|
--- a/jdk/src/share/native/java/util/zip/Deflater.c
|
|
+++ b/jdk/src/share/native/java/util/zip/Deflater.c
|
|
@@ -37,7 +37,6 @@
|
|
#include "java_util_zip_Deflater.h"
|
|
|
|
#define DEF_MEM_LEVEL 8
|
|
-#define KAE_DEFLATER_WindowBit 31
|
|
|
|
static jfieldID levelID;
|
|
static jfieldID strategyID;
|
|
@@ -106,8 +105,8 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
-Java_java_util_zip_Deflater_initKae(JNIEnv *env, jclass cls, jint level,
|
|
- jint strategy)
|
|
+Java_java_util_zip_Deflater_initKAE(JNIEnv *env, jclass cls, jint level,
|
|
+ jint strategy, jint windowBits)
|
|
{
|
|
z_stream *strm = calloc(1, sizeof(z_stream));
|
|
|
|
@@ -116,7 +115,9 @@ Java_java_util_zip_Deflater_initKae(JNIEnv *env, jclass cls, jint level,
|
|
return jlong_zero;
|
|
} else {
|
|
const char *msg;
|
|
- int ret = deflateInit2(strm, level, Z_DEFLATED, KAE_DEFLATER_WindowBit, DEF_MEM_LEVEL, strategy);
|
|
+ int ret = deflateInit2(strm, level, Z_DEFLATED,
|
|
+ windowBits,
|
|
+ DEF_MEM_LEVEL, strategy);
|
|
switch (ret) {
|
|
case Z_OK:
|
|
return ptr_to_jlong(strm);
|
|
diff --git a/jdk/src/share/native/java/util/zip/Inflater.c b/jdk/src/share/native/java/util/zip/Inflater.c
|
|
index fca207215..8317267ff 100644
|
|
--- a/jdk/src/share/native/java/util/zip/Inflater.c
|
|
+++ b/jdk/src/share/native/java/util/zip/Inflater.c
|
|
@@ -41,11 +41,11 @@
|
|
|
|
#define ThrowDataFormatException(env, msg) \
|
|
JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
|
|
-#define KAE_INFLATER_WindowBit 31
|
|
|
|
static jfieldID needDictID;
|
|
static jfieldID finishedID;
|
|
static jfieldID bufID, offID, lenID;
|
|
+static jint inflaterFlushType = Z_PARTIAL_FLUSH;
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
|
|
@@ -96,16 +96,17 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap)
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
-Java_java_util_zip_Inflater_initKae(JNIEnv *env, jclass cls)
|
|
+Java_java_util_zip_Inflater_initKAE(JNIEnv *env, jclass cls, jint windowBits, jint flushKAE)
|
|
{
|
|
z_stream *strm = calloc(1, sizeof(z_stream));
|
|
+ inflaterFlushType = flushKAE;
|
|
|
|
if (strm == NULL) {
|
|
JNU_ThrowOutOfMemoryError(env, 0);
|
|
return jlong_zero;
|
|
} else {
|
|
const char *msg;
|
|
- int ret = inflateInit2(strm, KAE_INFLATER_WindowBit);
|
|
+ int ret = inflateInit2(strm, windowBits);
|
|
switch (ret) {
|
|
case Z_OK:
|
|
return ptr_to_jlong(strm);
|
|
@@ -181,71 +182,7 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
|
|
strm->next_out = (Bytef *) (out_buf + off);
|
|
strm->avail_in = this_len;
|
|
strm->avail_out = len;
|
|
- ret = inflate(strm, Z_PARTIAL_FLUSH);
|
|
- (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
|
|
- (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
|
|
-
|
|
- switch (ret) {
|
|
- case Z_STREAM_END:
|
|
- (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
|
|
- /* fall through */
|
|
- case Z_OK:
|
|
- this_off += this_len - strm->avail_in;
|
|
- (*env)->SetIntField(env, this, offID, this_off);
|
|
- (*env)->SetIntField(env, this, lenID, strm->avail_in);
|
|
- return (jint) (len - strm->avail_out);
|
|
- case Z_NEED_DICT:
|
|
- (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
|
|
- /* Might have consumed some input here! */
|
|
- this_off += this_len - strm->avail_in;
|
|
- (*env)->SetIntField(env, this, offID, this_off);
|
|
- (*env)->SetIntField(env, this, lenID, strm->avail_in);
|
|
- return 0;
|
|
- case Z_BUF_ERROR:
|
|
- return 0;
|
|
- case Z_DATA_ERROR:
|
|
- ThrowDataFormatException(env, strm->msg);
|
|
- return 0;
|
|
- case Z_MEM_ERROR:
|
|
- JNU_ThrowOutOfMemoryError(env, 0);
|
|
- return 0;
|
|
- default:
|
|
- JNU_ThrowInternalError(env, strm->msg);
|
|
- return 0;
|
|
- }
|
|
-}
|
|
-
|
|
-JNIEXPORT jint JNICALL
|
|
-Java_java_util_zip_Inflater_inflateBytesKAE(JNIEnv *env, jobject this, jlong addr,
|
|
- jarray b, jint off, jint len)
|
|
-{
|
|
- z_stream *strm = jlong_to_ptr(addr);
|
|
- jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
|
|
- jint this_off = (*env)->GetIntField(env, this, offID);
|
|
- jint this_len = (*env)->GetIntField(env, this, lenID);
|
|
-
|
|
- jbyte *in_buf;
|
|
- jbyte *out_buf;
|
|
- int ret;
|
|
-
|
|
- in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
|
|
- if (in_buf == NULL) {
|
|
- if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
|
|
- JNU_ThrowOutOfMemoryError(env, 0);
|
|
- return 0;
|
|
- }
|
|
- out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
|
|
- if (out_buf == NULL) {
|
|
- (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
|
|
- if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
|
|
- JNU_ThrowOutOfMemoryError(env, 0);
|
|
- return 0;
|
|
- }
|
|
- strm->next_in = (Bytef *) (in_buf + this_off);
|
|
- strm->next_out = (Bytef *) (out_buf + off);
|
|
- strm->avail_in = this_len;
|
|
- strm->avail_out = len;
|
|
- ret = inflate(strm, Z_SYNC_FLUSH);
|
|
+ ret = inflate(strm, inflaterFlushType);
|
|
(*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
|
|
(*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
|
|
|
|
diff --git a/jdk/test/java/util/zip/GZIP/TestAvailable.java b/jdk/test/java/util/zip/GZIP/TestAvailable.java
|
|
new file mode 100644
|
|
index 000000000..3dc9b3445
|
|
--- /dev/null
|
|
+++ b/jdk/test/java/util/zip/GZIP/TestAvailable.java
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
|
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
+ *
|
|
+ * This code is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License version 2 only, as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * version 2 for more details (a copy is included in the LICENSE file that
|
|
+ * accompanied this code).
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License version
|
|
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
|
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+ *
|
|
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
+ * or visit www.oracle.com if you need additional information or have any
|
|
+ * questions.
|
|
+ */
|
|
+
|
|
+/* @test
|
|
+ * @library /lib/testlibrary/
|
|
+ * @build jdk.testlibrary.*
|
|
+ * @run main TestAvailable
|
|
+ * @bug 7031075
|
|
+ * @summary Make sure that available() method behaves as expected.
|
|
+ * @key randomness
|
|
+ */
|
|
+
|
|
+import java.io.*;
|
|
+import java.util.Random;
|
|
+import java.util.zip.*;
|
|
+import jdk.testlibrary.RandomFactory;
|
|
+
|
|
+public class TestAvailable {
|
|
+
|
|
+ public static void main(String args[]) throws Throwable {
|
|
+ Random r = RandomFactory.getRandom();
|
|
+ for (int n = 0; n < 10; n++) {
|
|
+ byte[] src = new byte[r.nextInt(100)];
|
|
+ r.nextBytes(src);
|
|
+
|
|
+ // test InflaterInputStream
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
+ try (DeflaterOutputStream dos = new DeflaterOutputStream(baos)) {
|
|
+ dos.write(src);
|
|
+ }
|
|
+ try (InflaterInputStream iis = new InflaterInputStream(
|
|
+ new ByteArrayInputStream(baos.toByteArray()))) {
|
|
+ test(iis, src);
|
|
+ }
|
|
+
|
|
+ // test GZIPInputStream
|
|
+ baos = new ByteArrayOutputStream();
|
|
+ try (GZIPOutputStream dos = new GZIPOutputStream(baos)) {
|
|
+ dos.write(src);
|
|
+ }
|
|
+ try (GZIPInputStream gis = new GZIPInputStream(
|
|
+ new ByteArrayInputStream(baos.toByteArray()))) {
|
|
+ test(gis, src);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void test(InputStream is, byte[] expected) throws IOException {
|
|
+ int cnt = 0;
|
|
+ do {
|
|
+ int available = is.available();
|
|
+ if (available > 0) {
|
|
+ int b = is.read();
|
|
+ if (b == -1) {
|
|
+ throw new RuntimeException("available() > 0, read() == -1 : failed!");
|
|
+ }
|
|
+ if (expected[cnt++] != (byte)b) {
|
|
+ throw new RuntimeException("read() : failed!");
|
|
+ }
|
|
+ } else if (available == 0) {
|
|
+ if (is.read() != -1) {
|
|
+ throw new RuntimeException("available() == 0, read() != -1 : failed!");
|
|
+ }
|
|
+ break;
|
|
+ } else {
|
|
+ throw new RuntimeException("available() < 0 : failed!");
|
|
+ }
|
|
+ } while (true);
|
|
+ if (cnt != expected.length) {
|
|
+ throw new RuntimeException("read : failed!");
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|
|
\ No newline at end of file
|
|
--
|
|
2.19.1
|
|
|