代码拉取完成,页面将自动刷新
Subject: [PATCH] [Huawei]support KAE-zip
---
jdk/make/CompileLaunchers.gmk | 34 ++++---
jdk/make/lib/CoreLibraries.gmk | 71 ++++++++++++++
jdk/make/mapfiles/libzip/mapfile-vers | 3 +
.../share/classes/java/util/zip/Deflater.java | 10 +-
.../java/util/zip/GZIPInputStream.java | 14 +++
.../java/util/zip/GZIPOutputStream.java | 20 ++++
.../share/classes/java/util/zip/Inflater.java | 14 ++-
.../java/util/zip/InflaterOutputStream.java | 24 ++---
jdk/src/share/lib/security/java.policy | 2 +
jdk/src/share/native/java/util/zip/Deflater.c | 37 +++++++
jdk/src/share/native/java/util/zip/Inflater.c | 98 +++++++++++++++++++
.../java/util/zip/DeflateIn_InflateOut.java | 74 +++++++++++++-
12 files changed, 367 insertions(+), 34 deletions(-)
diff --git a/jdk/make/CompileLaunchers.gmk b/jdk/make/CompileLaunchers.gmk
index de1ea9f4b..513e2ee1b 100644
--- a/jdk/make/CompileLaunchers.gmk
+++ b/jdk/make/CompileLaunchers.gmk
@@ -474,17 +474,29 @@ ifeq ($(USE_EXTERNAL_LIBZ), true)
UNPACKEXE_ZIPOBJS := -lz
else
UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
- UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \
- $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX)
-
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX)
+ else
+ UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libz/zcrc32$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/deflate$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/trees$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/zadler32$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/compress$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/zutil$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/inflate$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/infback$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/inftrees$(OBJ_SUFFIX) \
+ $(JDK_OUTPUTDIR)/objs/libz/inffast$(OBJ_SUFFIX)
+ endif
endif
UNPACKEXE_LANG := C
diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk
index d1cd1d3de..1af991693 100644
--- a/jdk/make/lib/CoreLibraries.gmk
+++ b/jdk/make/lib/CoreLibraries.gmk
@@ -261,11 +261,76 @@ $(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM)
##########################################################################################
+ifneq ($(USE_EXTERNAL_LIBZ), true)
+ ifneq ($(OPENJDK_TARGET_OS), windows)
+ BUILD_LIBZ_EXCLUDES :=
+
+ ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ ZLIB_CPPFLAGS += -DHAVE_UNISTD_H
+ endif
+
+ BUILD_LIBZ_REORDER :=
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
+ ifneq ($(OPENJDK_TARGET_CPU), x86_64)
+ BUILD_LIBZ_REORDER := $(JDK_TOPDIR)/make/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU)
+ endif
+ endif
+
+ ifeq ($(LIBZ_CAN_USE_MMAP), true)
+ BUILD_LIBZ_MMAP := -DUSE_MMAP
+ endif
+
+ $(eval $(call SetupNativeCompilation,BUILD_LIBZ, \
+ LIBRARY := z, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ LANG := C, \
+ OPTIMIZATION := LOW, \
+ SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib, \
+ EXCLUDES := $(LIBZ_EXCLUDES), \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(ZLIB_CPPFLAGS) \
+ -I$(JDK_TOPDIR)/src/share/native/java/io \
+ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io, \
+ CFLAGS_posix := $(BUILD_LIBZ_MMAP) -UDEBUG, \
+ MAPFILE := , \
+ REORDER := $(BUILD_LIBZ_REORDER), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN) \
+ $(EXPORT_Z_FUNCS), \
+ LDFLAGS_windows := jvm.lib \
+ $(WIN_JAVA_LIB), \
+ LDFLAGS_SUFFIX_linux := , \
+ LDFLAGS_SUFFIX_solaris := , \
+ LDFLAGS_SUFFIX_aix := ,\
+ LDFLAGS_SUFFIX_macosx := , \
+ VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
+ RC_FLAGS := $(RC_FLAGS) \
+ -D "JDK_FNAME=z.dll" \
+ -D "JDK_INTERNAL_NAME=z" \
+ -D "JDK_FTYPE=0x2L", \
+ OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libz, \
+ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+
+
+ $(BUILD_LIBZ): $(BUILD_LIBJAVA)
+
+ BUILD_LIBRARIES += $(BUILD_LIBZ)
+ endif
+endif
+
+##########################################################################################
+
BUILD_LIBZIP_EXCLUDES :=
ifeq ($(USE_EXTERNAL_LIBZ), true)
+ BUILD_LIBZIP_SRC :=
LIBZ := -lz
LIBZIP_EXCLUDES += zlib
else
+ ifneq ($(OPENJDK_TARGET_OS), windows)
+ BUILD_LIBZIP_SRC := Adler32.c CRC32.c Deflater.c Inflater.c zip_util.c ZipFile.c
+ LIBZ := -lz
+ endif
ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
ifeq ($(OPENJDK_TARGET_OS), macosx)
ZLIB_CPPFLAGS += -DHAVE_UNISTD_H
@@ -289,6 +354,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
LANG := C, \
OPTIMIZATION := LOW, \
SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \
+ INCLUDE_FILES := $(BUILD_LIBZIP_SRC), \
EXCLUDES := $(LIBZIP_EXCLUDES), \
CFLAGS := $(CFLAGS_JDKLIB) \
$(ZLIB_CPPFLAGS) \
@@ -315,9 +381,14 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libzip, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+ifneq ($(USE_EXTERNAL_LIBZ), true)
+ LIBZ :=
+endif
$(BUILD_LIBZIP): $(BUILD_LIBJAVA)
+$(BUILD_LIBZIP): $(BUILD_LIBZ)
+
BUILD_LIBRARIES += $(BUILD_LIBZIP)
##########################################################################################
diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers
index 5d33990c3..5c6d27d0d 100644
--- a/jdk/make/mapfiles/libzip/mapfile-vers
+++ b/jdk/make/mapfiles/libzip/mapfile-vers
@@ -38,13 +38,16 @@ 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_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_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 bffa397d9..a4ea40cf8 100644
--- a/jdk/src/share/classes/java/util/zip/Deflater.java
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java
@@ -81,6 +81,7 @@ 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
@@ -168,7 +169,13 @@ class Deflater {
public Deflater(int level, boolean nowrap) {
this.level = level;
this.strategy = DEFAULT_STRATEGY;
- this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
+ 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));
}
/**
@@ -571,6 +578,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 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 0d57e8ab3..7fb753729 100644
--- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
+++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
@@ -54,6 +54,11 @@ class GZIPInputStream extends InflaterInputStream {
private boolean closed = false;
+ /*
+ * GZIP use KAE.
+ */
+ private boolean gzipUseKae = false;
+
/**
* Check to make sure that this stream has not been closed
*/
@@ -76,6 +81,12 @@ class GZIPInputStream extends InflaterInputStream {
public GZIPInputStream(InputStream in, int size) throws IOException {
super(in, 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;
readHeader(in);
}
@@ -209,6 +220,9 @@ 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;
+
InputStream in = this.in;
int n = inf.getRemaining();
if (n > 0) {
diff --git a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
index 1c3f8592e..0f0be98bb 100644
--- a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
@@ -52,6 +52,11 @@ class GZIPOutputStream extends DeflaterOutputStream {
*/
private final static int TRAILER_SIZE = 8;
+ /*
+ * GZIP use KAE.
+ */
+ private boolean gzipUseKae = false;
+
/**
* Creates a new output stream with the specified buffer size.
*
@@ -91,6 +96,12 @@ class GZIPOutputStream extends DeflaterOutputStream {
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;
writeHeader();
crc.reset();
}
@@ -160,6 +171,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) {
+ out.write(buf, 0, len);
+ return;
+ }
writeTrailer(buf, len);
len = len + TRAILER_SIZE;
out.write(buf, 0, len);
@@ -168,6 +184,10 @@ 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
byte[] trailer = new byte[TRAILER_SIZE];
diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java
index c1eefe122..42e90f525 100644
--- a/jdk/src/share/classes/java/util/zip/Inflater.java
+++ b/jdk/src/share/classes/java/util/zip/Inflater.java
@@ -80,6 +80,7 @@ class Inflater {
private boolean needDict;
private long bytesRead;
private long bytesWritten;
+ private boolean inflaterUseKae;
private static final byte[] defaultBuf = new byte[0];
@@ -100,7 +101,11 @@ class Inflater {
* @param nowrap if true then support GZIP compatible compression
*/
public Inflater(boolean nowrap) {
- zsRef = new ZStreamRef(init(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));
}
/**
@@ -256,7 +261,9 @@ class Inflater {
synchronized (zsRef) {
ensureOpen();
int thisLen = this.len;
- int n = inflateBytes(zsRef.address(), b, off, len);
+ int n = this.inflaterUseKae ?
+ inflateBytesKAE(zsRef.address(), b, off, len) :
+ inflateBytes(zsRef.address(), b, off, len);
bytesWritten += n;
bytesRead += (thisLen - this.len);
return n;
@@ -397,10 +404,13 @@ class Inflater {
private native static void initIDs();
private native static long init(boolean nowrap);
+ private native static long initKae();
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/InflaterOutputStream.java b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
index 02900c741..62c6bb153 100644
--- a/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
+++ b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, 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
@@ -236,16 +236,9 @@ public class InflaterOutputStream extends FilterOutputStream {
// Fill the decompressor buffer with output data
if (inf.needsInput()) {
- int part;
-
- if (len < 1) {
- break;
- }
-
- part = (len < 512 ? len : 512);
- inf.setInput(b, off, part);
- off += part;
- len -= part;
+ inf.setInput(b, off, len);
+ // Only use input buffer once.
+ len = 0;
}
// Decompress and write blocks of output data
@@ -256,13 +249,14 @@ public class InflaterOutputStream extends FilterOutputStream {
}
} while (n > 0);
- // Check the decompressor
- if (inf.finished()) {
- break;
- }
+ // Check for missing dictionary first
if (inf.needsDictionary()) {
throw new ZipException("ZLIB dictionary missing");
}
+ // Check the decompressor
+ if (inf.finished() || (len == 0) /* no more input */ ) {
+ break;
+ }
}
} catch (DataFormatException ex) {
// Improperly formatted compressed (ZIP) data
diff --git a/jdk/src/share/lib/security/java.policy b/jdk/src/share/lib/security/java.policy
index 8b6289720..baec2ea15 100644
--- a/jdk/src/share/lib/security/java.policy
+++ b/jdk/src/share/lib/security/java.policy
@@ -48,5 +48,7 @@ grant {
permission java.util.PropertyPermission "java.vm.name", "read";
permission java.util.PropertyPermission "sun.security.pkcs11.disableKeyExtraction", "read";
+
+ permission java.util.PropertyPermission "GZIP_USE_KAE", "read";
};
diff --git a/jdk/src/share/native/java/util/zip/Deflater.c b/jdk/src/share/native/java/util/zip/Deflater.c
index c1bd34667..1b048e4f5 100644
--- a/jdk/src/share/native/java/util/zip/Deflater.c
+++ b/jdk/src/share/native/java/util/zip/Deflater.c
@@ -37,6 +37,7 @@
#include "java_util_zip_Deflater.h"
#define DEF_MEM_LEVEL 8
+#define KAE_DEFLATER_WindowBit 31
static jfieldID levelID;
static jfieldID strategyID;
@@ -104,6 +105,42 @@ 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)
+{
+ z_stream *strm = calloc(1, sizeof(z_stream));
+
+ if (strm == 0) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ } else {
+ const char *msg;
+ int ret = deflateInit2(strm, level, Z_DEFLATED, KAE_DEFLATER_WindowBit, DEF_MEM_LEVEL, strategy);
+ switch (ret) {
+ case Z_OK:
+ return ptr_to_jlong(strm);
+ case Z_MEM_ERROR:
+ free(strm);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ case Z_STREAM_ERROR:
+ free(strm);
+ JNU_ThrowIllegalArgumentException(env, 0);
+ return jlong_zero;
+ default:
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ "unknown error initializing zlib library");
+ free(strm);
+ JNU_ThrowInternalError(env, msg);
+ return jlong_zero;
+ }
+ }
+}
+
JNIEXPORT void JNICALL
Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
jarray b, jint off, jint len)
diff --git a/jdk/src/share/native/java/util/zip/Inflater.c b/jdk/src/share/native/java/util/zip/Inflater.c
index 79bcdd5b6..fca207215 100644
--- a/jdk/src/share/native/java/util/zip/Inflater.c
+++ b/jdk/src/share/native/java/util/zip/Inflater.c
@@ -41,6 +41,7 @@
#define ThrowDataFormatException(env, msg) \
JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
+#define KAE_INFLATER_WindowBit 31
static jfieldID needDictID;
static jfieldID finishedID;
@@ -94,6 +95,39 @@ 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)
+{
+ z_stream *strm = calloc(1, sizeof(z_stream));
+
+ if (strm == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ } else {
+ const char *msg;
+ int ret = inflateInit2(strm, KAE_INFLATER_WindowBit);
+ switch (ret) {
+ case Z_OK:
+ return ptr_to_jlong(strm);
+ case Z_MEM_ERROR:
+ free(strm);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return jlong_zero;
+ default:
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ (ret == Z_STREAM_ERROR) ?
+ "inflateInit2 returned Z_STREAM_ERROR" :
+ "unknown error initializing zlib library");
+ free(strm);
+ JNU_ThrowInternalError(env, msg);
+ return jlong_zero;
+ }
+ }
+}
+
JNIEXPORT void JNICALL
Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
jarray b, jint off, jint len)
@@ -181,6 +215,70 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
}
}
+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);
+ (*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_getAdler(JNIEnv *env, jclass cls, jlong addr)
{
diff --git a/jdk/test/java/util/zip/DeflateIn_InflateOut.java b/jdk/test/java/util/zip/DeflateIn_InflateOut.java
index dd69a7773..048d8e34c 100644
--- a/jdk/test/java/util/zip/DeflateIn_InflateOut.java
+++ b/jdk/test/java/util/zip/DeflateIn_InflateOut.java
@@ -41,14 +41,31 @@ public class DeflateIn_InflateOut {
private static ByteArrayOutputStream baos;
private static InflaterOutputStream ios;
- private static void reset() {
+ private static Inflater reset(byte[] dict) {
new Random(new Date().getTime()).nextBytes(data);
bais = new ByteArrayInputStream(data);
- dis = new DeflaterInputStream(bais);
+ if (dict == null) {
+ dis = new DeflaterInputStream(bais);
+ } else {
+ Deflater def = new Deflater();
+ def.setDictionary(dict);
+ dis = new DeflaterInputStream(bais, def);
+ }
baos = new ByteArrayOutputStream();
- ios = new InflaterOutputStream(baos);
+ if (dict == null) {
+ ios = new InflaterOutputStream(baos);
+ return null;
+ } else {
+ Inflater inf = new Inflater();
+ ios = new InflaterOutputStream(baos, inf);
+ return inf;
+ }
+ }
+
+ private static void reset() {
+ reset(null);
}
/** Check byte arrays read/write. */
@@ -216,6 +233,44 @@ public class DeflateIn_InflateOut {
check(numNotSkipped + numSkipBytes == numReadable);
}
+ /** Check "needsDictionary()". */
+ private static void NeedsDictionary() throws Throwable {
+ byte[] dict = {1, 2, 3, 4};
+ Adler32 adler32 = new Adler32();
+ adler32.update(dict);
+ long checksum = adler32.getValue();
+ byte[] buf = new byte[512];
+
+ Inflater inf = reset(dict);
+ check(dis.available() == 1);
+ boolean dictSet = false;
+ for (;;) {
+ int len = dis.read(buf, 0, buf.length);
+ if (len < 0) {
+ break;
+ } else {
+ try {
+ ios.write(buf, 0, len);
+ if (dictSet == false) {
+ check(false, "Must throw ZipException without dictionary");
+ return;
+ }
+ } catch (ZipException ze) {
+ check(dictSet == false, "Dictonary must be set only once");
+ check(checksum == inf.getAdler(), "Incorrect dictionary");
+ inf.setDictionary(dict);
+ // After setting the dictionary, we have to flush the
+ // InflaterOutputStream now in order to consume all the
+ // pending input data from the last, failed call to "write()".
+ ios.flush();
+ dictSet = true;
+ }
+ }
+ }
+ check(dis.available() == 0);
+ ios.close();
+ check(Arrays.equals(data, baos.toByteArray()));
+ }
public static void realMain(String[] args) throws Throwable {
ArrayReadWrite();
@@ -227,15 +282,24 @@ public class DeflateIn_InflateOut {
ByteReadByteWrite();
SkipBytes();
+
+ NeedsDictionary();
}
//--------------------- Infrastructure ---------------------------
static volatile int passed = 0, failed = 0;
static void pass() {passed++;}
- static void fail() {failed++; Thread.dumpStack();}
- static void fail(String msg) {System.out.println(msg); fail();}
+ static void fail() { fail(null); }
+ static void fail(String msg) {
+ failed++;
+ if (msg != null) {
+ System.err.println(msg);
+ }
+ Thread.dumpStack();
+ }
static void unexpected(Throwable t) {failed++; t.printStackTrace();}
static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
static void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass();
else fail(x + " not equal to " + y);}
--
2.23.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。