src/share/native/java/util/zip/Inflater.c
Print this page
*** 36,47 ****
#include "jvm.h"
#include "jni_util.h"
#include "zlib.h"
#include "java_util_zip_Inflater.h"
- #define MIN2(x, y) ((x) < (y) ? (x) : (y))
-
#define ThrowDataFormatException(env, msg) \
JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
static jfieldID needDictID;
static jfieldID finishedID;
--- 36,45 ----
*** 109,183 ****
JNIEXPORT jint JNICALL
Java_java_util_zip_Inflater_inflateBytes(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;
! /*
! * Avoid excess copying.
! * zlib stream usually has a few bytes of overhead for header info
! * (depends on the underlying data)
! *
! * (a) 5 bytes per 16KB
! * (b) 6 bytes for entire stream
! * (c) 4 bytes for gzip header
! * (d) 2 bytes for crc
! *
! * Use 20 bytes as the "safe cutoff" number.
! */
! jint in_len = MIN2(this_len, len + 20);
! jint consumed;
!
! in_buf = (jbyte *) malloc(in_len);
! if (in_buf == 0) {
! if (in_len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
! (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf);
!
! out_buf = (jbyte *) malloc(len);
! if (out_buf == 0) {
! free(in_buf);
if (len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
!
! strm->next_in = (Bytef *) in_buf;
! strm->next_out = (Bytef *) out_buf;
! strm->avail_in = in_len;
strm->avail_out = len;
ret = inflate(strm, Z_PARTIAL_FLUSH);
!
! if (ret == Z_STREAM_END || ret == Z_OK) {
! (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
! }
! free(out_buf);
! free(in_buf);
switch (ret) {
case Z_STREAM_END:
(*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
/* fall through */
case Z_OK:
! consumed = in_len - strm->avail_in;
! (*env)->SetIntField(env, this, offID, this_off + consumed);
! (*env)->SetIntField(env, this, lenID, this_len - consumed);
return len - strm->avail_out;
case Z_NEED_DICT:
(*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
/* Might have consumed some input here! */
! consumed = in_len - strm->avail_in;
! (*env)->SetIntField(env, this, offID, this_off + consumed);
! (*env)->SetIntField(env, this, lenID, this_len - consumed);
return 0;
case Z_BUF_ERROR:
return 0;
case Z_DATA_ERROR:
ThrowDataFormatException(env, strm->msg);
--- 107,160 ----
JNIEXPORT jint JNICALL
Java_java_util_zip_Inflater_inflateBytes(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)
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)
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_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 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);