extern "C" void Java_java_util_zip_Inflater_resetImpl(JNIEnv* env, jobject, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); int err = inflateReset(&stream->stream); if (err != Z_OK) { throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err, stream); } }
extern "C" jint Java_java_util_zip_Inflater_setFileInputImpl(JNIEnv* env, jobject, jobject javaFileDescriptor, jlong off, jint len, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); // We reuse the existing native buffer if it's large enough. // TODO: benchmark. if (stream->inCap < len) { stream->setInput(env, NULL, 0, len); } else { stream->stream.next_in = reinterpret_cast<Bytef*>(&stream->input[0]); stream->stream.avail_in = len; } // As an Android-specific optimization, we read directly onto the native heap. // The original code used Java to read onto the Java heap and then called setInput(byte[]). // TODO: benchmark. int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); int rc = TEMP_FAILURE_RETRY(lseek(fd, off, SEEK_SET)); if (rc == -1) { jniThrowIOException(env, errno); return 0; } jint totalByteCount = 0; Bytef* dst = reinterpret_cast<Bytef*>(&stream->input[0]); ssize_t byteCount; while ((byteCount = TEMP_FAILURE_RETRY(read(fd, dst, len))) > 0) { dst += byteCount; len -= byteCount; totalByteCount += byteCount; } if (byteCount == -1) { jniThrowIOException(env, errno); return 0; } return totalByteCount; }
extern "C" jint Java_java_util_zip_Inflater_inflateImpl(JNIEnv* env, jobject recv, jbyteArray buf, int off, int len, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); ScopedByteArrayRW out(env, buf); if (out.get() == NULL) { return -1; } stream->stream.next_out = reinterpret_cast<Bytef*>(out.get() + off); stream->stream.avail_out = len; Bytef* initialNextIn = stream->stream.next_in; Bytef* initialNextOut = stream->stream.next_out; int err = inflate(&stream->stream, Z_SYNC_FLUSH); switch (err) { case Z_OK: break; case Z_NEED_DICT: static jfieldID needsDictionary = env->GetFieldID(JniConstants::inflaterClass, "needsDictionary", "Z"); env->SetBooleanField(recv, needsDictionary, JNI_TRUE); break; case Z_STREAM_END: static jfieldID finished = env->GetFieldID(JniConstants::inflaterClass, "finished", "Z"); env->SetBooleanField(recv, finished, JNI_TRUE); break; case Z_STREAM_ERROR: return 0; default: throwExceptionForZlibError(env, "java/util/zip/DataFormatException", err, stream); return -1; } jint bytesRead = stream->stream.next_in - initialNextIn; jint bytesWritten = stream->stream.next_out - initialNextOut; static jfieldID inReadField = env->GetFieldID(JniConstants::inflaterClass, "inRead", "I"); jint inReadValue = env->GetIntField(recv, inReadField); inReadValue += bytesRead; env->SetIntField(recv, inReadField, inReadValue); return bytesWritten; }
extern "C" void Java_java_util_zip_Inflater_setInputImpl(JNIEnv* env, jobject, jbyteArray buf, jint off, jint len, jlong handle) { toNativeZipStream(handle)->setInput(env, buf, off, len); }
extern "C" jlong Java_java_util_zip_Inflater_getTotalInImpl(JNIEnv*, jobject, jlong handle) { return toNativeZipStream(handle)->stream.total_in; }
extern "C" void Java_java_util_zip_Inflater_endImpl(JNIEnv*, jobject, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); inflateEnd(&stream->stream); delete stream; }
extern "C" void Java_java_util_zip_Inflater_setDictionaryImpl(JNIEnv* env, jobject, jbyteArray dict, int off, int len, jlong handle) { toNativeZipStream(handle)->setDictionary(env, dict, off, len, true); }
static void Inflater_setInputImpl(JNIEnv* env, jobject, jbyteArray buf, jint off, jint len, jlong handle) { toNativeZipStream(handle)->setInput(env, buf, off, len); }
extern "C" jint Java_java_util_zip_Inflater_getAdlerImpl(JNIEnv*, jobject, jlong handle) { return toNativeZipStream(handle)->stream.adler; }
static jlong Inflater_getTotalInImpl(JNIEnv*, jobject, jlong handle) { return toNativeZipStream(handle)->stream.total_in; }
static void Inflater_resetImpl(JNIEnv* env, jobject, jlong handle) { int err = inflateReset(&toNativeZipStream(handle)->stream); if (err != Z_OK) { throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err); } }
static void Inflater_setDictionaryImpl(JNIEnv* env, jobject, jbyteArray dict, int off, int len, jlong handle) { toNativeZipStream(handle)->setDictionary(env, dict, off, len, true); }
static void Inflater_endImpl(JNIEnv*, jobject, jlong handle) { NativeZipStream* stream = toNativeZipStream(handle); inflateEnd(&stream->stream); delete stream; }
static jint Inflater_getAdlerImpl(JNIEnv*, jobject, jlong handle) { return toNativeZipStream(handle)->stream.adler; }