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