Finish off the new JNI implementation.
There are a handful of remaining TODOs, but this gives us complete coverage.
Change-Id: Ibee38e6a87a0fcfae769d991125b0551243c8eeb
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index 0964b62..ddc0408 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -279,7 +279,7 @@
env_->UnregisterNatives(jlobject);
}
-#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, scalar_type, expected_class_descriptor) \
+#define EXPECT_PRIMITIVE_ARRAY(new_fn, get_region_fn, set_region_fn, get_elements_fn, release_elements_fn, scalar_type, expected_class_descriptor) \
jsize size = 4; \
/* Allocate an array and check it has the right type and length. */ \
scalar_type ## Array a = env_->new_fn(size); \
@@ -317,31 +317,40 @@
EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "fixed copy not equal"; \
/* Copy back the whole array. */ \
env_->get_region_fn(a, 0, size, dst_buf); \
- EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"
+ EXPECT_TRUE(memcmp(src_buf, dst_buf, sizeof(src_buf)) == 0) << "full copy not equal"; \
+ /* GetPrimitiveArrayCritical */ \
+ void* v = env_->GetPrimitiveArrayCritical(a, NULL); \
+ EXPECT_TRUE(memcmp(src_buf, v, sizeof(src_buf)) == 0) << "GetPrimitiveArrayCritical not equal"; \
+ env_->ReleasePrimitiveArrayCritical(a, v, 0); \
+ /* GetXArrayElements */ \
+ scalar_type* xs = env_->get_elements_fn(a, NULL); \
+ EXPECT_TRUE(memcmp(src_buf, xs, sizeof(src_buf)) == 0) << # get_elements_fn " not equal"; \
+ env_->release_elements_fn(a, xs, 0); \
+ EXPECT_EQ(reinterpret_cast<uintptr_t>(v), reinterpret_cast<uintptr_t>(xs))
TEST_F(JniInternalTest, BooleanArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, jboolean, "[Z");
+ EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z");
}
TEST_F(JniInternalTest, ByteArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, jbyte, "[B");
+ EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B");
}
TEST_F(JniInternalTest, CharArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, jchar, "[C");
+ EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C");
}
TEST_F(JniInternalTest, DoubleArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, jdouble, "[D");
+ EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D");
}
TEST_F(JniInternalTest, FloatArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, jfloat, "[F");
+ EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F");
}
TEST_F(JniInternalTest, IntArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, jint, "[I");
+ EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, GetIntArrayElements, ReleaseIntArrayElements, jint, "[I");
}
TEST_F(JniInternalTest, LongArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, jlong, "[J");
+ EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J");
}
TEST_F(JniInternalTest, ShortArrays) {
- EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, jshort, "[S");
+ EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S");
}
TEST_F(JniInternalTest, NewObjectArray) {
@@ -365,6 +374,15 @@
EXPECT_TRUE(a != NULL);
EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
EXPECT_EQ(1, env_->GetArrayLength(a));
+ EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), NULL));
+
+ jstring s = env_->NewStringUTF("poop");
+ a = env_->NewObjectArray(2, element_class, s);
+ EXPECT_TRUE(a != NULL);
+ EXPECT_TRUE(env_->IsInstanceOf(a, array_class));
+ EXPECT_EQ(2, env_->GetArrayLength(a));
+ EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s));
+ EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s));
}
TEST_F(JniInternalTest, GetArrayLength) {
@@ -495,6 +513,71 @@
EXPECT_EQ('x', bytes[3]);
}
+TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) {
+ EXPECT_TRUE(env_->GetStringUTFChars(NULL, NULL) == NULL);
+
+ jstring s = env_->NewStringUTF("hello");
+ ASSERT_TRUE(s != NULL);
+
+ const char* utf = env_->GetStringUTFChars(s, NULL);
+ EXPECT_STREQ("hello", utf);
+ env_->ReleaseStringUTFChars(s, utf);
+
+ jboolean is_copy = JNI_FALSE;
+ utf = env_->GetStringUTFChars(s, &is_copy);
+ EXPECT_EQ(JNI_TRUE, is_copy);
+ EXPECT_STREQ("hello", utf);
+ env_->ReleaseStringUTFChars(s, utf);
+}
+
+TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) {
+ jstring s = env_->NewStringUTF("hello");
+ ASSERT_TRUE(s != NULL);
+
+ jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
+ const jchar* chars = env_->GetStringChars(s, NULL);
+ EXPECT_EQ(expected[0], chars[0]);
+ EXPECT_EQ(expected[1], chars[1]);
+ EXPECT_EQ(expected[2], chars[2]);
+ EXPECT_EQ(expected[3], chars[3]);
+ EXPECT_EQ(expected[4], chars[4]);
+ env_->ReleaseStringChars(s, chars);
+
+ jboolean is_copy = JNI_FALSE;
+ chars = env_->GetStringChars(s, &is_copy);
+ EXPECT_EQ(JNI_FALSE, is_copy);
+ EXPECT_EQ(expected[0], chars[0]);
+ EXPECT_EQ(expected[1], chars[1]);
+ EXPECT_EQ(expected[2], chars[2]);
+ EXPECT_EQ(expected[3], chars[3]);
+ EXPECT_EQ(expected[4], chars[4]);
+ env_->ReleaseStringChars(s, chars);
+}
+
+TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) {
+ jstring s = env_->NewStringUTF("hello");
+ ASSERT_TRUE(s != NULL);
+
+ jchar expected[] = { 'h', 'e', 'l', 'l', 'o' };
+ const jchar* chars = env_->GetStringCritical(s, NULL);
+ EXPECT_EQ(expected[0], chars[0]);
+ EXPECT_EQ(expected[1], chars[1]);
+ EXPECT_EQ(expected[2], chars[2]);
+ EXPECT_EQ(expected[3], chars[3]);
+ EXPECT_EQ(expected[4], chars[4]);
+ env_->ReleaseStringCritical(s, chars);
+
+ jboolean is_copy = JNI_FALSE;
+ chars = env_->GetStringCritical(s, &is_copy);
+ EXPECT_EQ(JNI_FALSE, is_copy);
+ EXPECT_EQ(expected[0], chars[0]);
+ EXPECT_EQ(expected[1], chars[1]);
+ EXPECT_EQ(expected[2], chars[2]);
+ EXPECT_EQ(expected[3], chars[3]);
+ EXPECT_EQ(expected[4], chars[4]);
+ env_->ReleaseStringCritical(s, chars);
+}
+
TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) {
jclass c = env_->FindClass("[Ljava/lang/Object;");
ASSERT_TRUE(c != NULL);