# HG changeset patch # User alanb # Date 1286530624 -3600 # Node ID 9f5bfecff075312789b482524fc4bd963228b2e9 # Parent c4afb73bfc6bb8fd22ab608f5d549ee3f50103cd# Parent 415649ab5519efc9ffe6236452225cb54a475083 Merge diff -r c4afb73bfc6b -r 9f5bfecff075 jdk/src/share/native/java/util/zip/Inflater.c --- a/jdk/src/share/native/java/util/zip/Inflater.c Fri Oct 08 10:36:17 2010 +0100 +++ b/jdk/src/share/native/java/util/zip/Inflater.c Fri Oct 08 10:37:04 2010 +0100 @@ -116,13 +116,27 @@ 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 = MIN(this_len, len + 20); + jint consumed; - in_buf = (jbyte *) malloc(this_len); + in_buf = (jbyte *) malloc(in_len); if (in_buf == 0) { JNU_ThrowOutOfMemoryError(env, 0); return 0; } - (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf); + (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf); out_buf = (jbyte *) malloc(len); if (out_buf == 0) { @@ -133,7 +147,7 @@ strm->next_in = (Bytef *) in_buf; strm->next_out = (Bytef *) out_buf; - strm->avail_in = this_len; + strm->avail_in = in_len; strm->avail_out = len; ret = inflate(strm, Z_PARTIAL_FLUSH); @@ -148,16 +162,16 @@ (*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); + 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! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); + 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;