1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/android/jni_array.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/scoped_java_ref.h"
9 #include "testing/gtest/include/gtest/gtest.h"
14 TEST(JniArray
, BasicConversions
) {
15 const uint8 kBytes
[] = { 0, 1, 2, 3 };
16 const size_t kLen
= arraysize(kBytes
);
17 JNIEnv
* env
= AttachCurrentThread();
18 ScopedJavaLocalRef
<jbyteArray
> bytes
= ToJavaByteArray(env
, kBytes
, kLen
);
19 ASSERT_TRUE(bytes
.obj());
21 std::vector
<uint8
> vec(5);
22 JavaByteArrayToByteVector(env
, bytes
.obj(), &vec
);
23 EXPECT_EQ(4U, vec
.size());
24 std::vector
<uint8
> expected_vec(kBytes
, kBytes
+ kLen
);
25 EXPECT_EQ(expected_vec
, vec
);
27 AppendJavaByteArrayToByteVector(env
, bytes
.obj(), &vec
);
28 EXPECT_EQ(8U, vec
.size());
29 expected_vec
.insert(expected_vec
.end(), kBytes
, kBytes
+ kLen
);
30 EXPECT_EQ(expected_vec
, vec
);
33 void CheckIntConversion(
37 const ScopedJavaLocalRef
<jintArray
>& ints
) {
38 ASSERT_TRUE(ints
.obj());
40 jsize java_array_len
= env
->GetArrayLength(ints
.obj());
41 ASSERT_EQ(static_cast<jsize
>(len
), java_array_len
);
44 for (size_t i
= 0; i
< len
; ++i
) {
45 env
->GetIntArrayRegion(ints
.obj(), i
, 1, &value
);
46 ASSERT_EQ(int_array
[i
], value
);
50 TEST(JniArray
, IntConversions
) {
51 const int kInts
[] = { 0, 1, -1, kint32min
, kint32max
};
52 const size_t kLen
= arraysize(kInts
);
54 JNIEnv
* env
= AttachCurrentThread();
55 CheckIntConversion(env
, kInts
, kLen
, ToJavaIntArray(env
, kInts
, kLen
));
57 const std::vector
<int> vec(kInts
, kInts
+ kLen
);
58 CheckIntConversion(env
, kInts
, kLen
, ToJavaIntArray(env
, vec
));
61 void CheckLongConversion(
63 const int64
* long_array
,
65 const ScopedJavaLocalRef
<jlongArray
>& longs
) {
66 ASSERT_TRUE(longs
.obj());
68 jsize java_array_len
= env
->GetArrayLength(longs
.obj());
69 ASSERT_EQ(static_cast<jsize
>(len
), java_array_len
);
72 for (size_t i
= 0; i
< len
; ++i
) {
73 env
->GetLongArrayRegion(longs
.obj(), i
, 1, &value
);
74 ASSERT_EQ(long_array
[i
], value
);
78 TEST(JniArray
, LongConversions
) {
79 const int64 kLongs
[] = { 0, 1, -1, kint64min
, kint64max
};
80 const size_t kLen
= arraysize(kLongs
);
82 JNIEnv
* env
= AttachCurrentThread();
83 CheckLongConversion(env
, kLongs
, kLen
, ToJavaLongArray(env
, kLongs
, kLen
));
85 const std::vector
<int64
> vec(kLongs
, kLongs
+ kLen
);
86 CheckLongConversion(env
, kLongs
, kLen
, ToJavaLongArray(env
, vec
));
89 TEST(JniArray
, JavaIntArrayToIntVector
) {
90 const int kInts
[] = {0, 1, -1};
91 const size_t kLen
= arraysize(kInts
);
93 JNIEnv
* env
= AttachCurrentThread();
94 ScopedJavaLocalRef
<jintArray
> jints(env
, env
->NewIntArray(kLen
));
95 ASSERT_TRUE(jints
.obj());
97 for (size_t i
= 0; i
< kLen
; ++i
) {
98 jint j
= static_cast<jint
>(kInts
[i
]);
99 env
->SetIntArrayRegion(jints
.obj(), i
, 1, &j
);
100 ASSERT_FALSE(HasException(env
));
103 std::vector
<int> ints
;
104 JavaIntArrayToIntVector(env
, jints
.obj(), &ints
);
106 ASSERT_EQ(static_cast<jsize
>(ints
.size()), env
->GetArrayLength(jints
.obj()));
109 for (size_t i
= 0; i
< kLen
; ++i
) {
110 env
->GetIntArrayRegion(jints
.obj(), i
, 1, &value
);
111 ASSERT_EQ(ints
[i
], value
);
115 TEST(JniArray
, JavaLongArrayToInt64Vector
) {
116 const int64 kInt64s
[] = {0LL, 1LL, -1LL};
117 const size_t kLen
= arraysize(kInt64s
);
119 JNIEnv
* env
= AttachCurrentThread();
120 ScopedJavaLocalRef
<jlongArray
> jlongs(env
, env
->NewLongArray(kLen
));
121 ASSERT_TRUE(jlongs
.obj());
123 for (size_t i
= 0; i
< kLen
; ++i
) {
124 jlong j
= static_cast<jlong
>(kInt64s
[i
]);
125 env
->SetLongArrayRegion(jlongs
.obj(), i
, 1, &j
);
126 ASSERT_FALSE(HasException(env
));
129 std::vector
<int64
> int64s
;
130 JavaLongArrayToInt64Vector(env
, jlongs
.obj(), &int64s
);
132 ASSERT_EQ(static_cast<jsize
>(int64s
.size()),
133 env
->GetArrayLength(jlongs
.obj()));
136 for (size_t i
= 0; i
< kLen
; ++i
) {
137 env
->GetLongArrayRegion(jlongs
.obj(), i
, 1, &value
);
138 ASSERT_EQ(int64s
[i
], value
);
139 ASSERT_EQ(kInt64s
[i
], int64s
[i
]);
143 TEST(JniArray
, JavaLongArrayToLongVector
) {
144 const int64 kInt64s
[] = {0LL, 1LL, -1LL};
145 const size_t kLen
= arraysize(kInt64s
);
147 JNIEnv
* env
= AttachCurrentThread();
148 ScopedJavaLocalRef
<jlongArray
> jlongs(env
, env
->NewLongArray(kLen
));
149 ASSERT_TRUE(jlongs
.obj());
151 for (size_t i
= 0; i
< kLen
; ++i
) {
152 jlong j
= static_cast<jlong
>(kInt64s
[i
]);
153 env
->SetLongArrayRegion(jlongs
.obj(), i
, 1, &j
);
154 ASSERT_FALSE(HasException(env
));
157 std::vector
<jlong
> jlongs_vector
;
158 JavaLongArrayToLongVector(env
, jlongs
.obj(), &jlongs_vector
);
160 ASSERT_EQ(static_cast<jsize
>(jlongs_vector
.size()),
161 env
->GetArrayLength(jlongs
.obj()));
164 for (size_t i
= 0; i
< kLen
; ++i
) {
165 env
->GetLongArrayRegion(jlongs
.obj(), i
, 1, &value
);
166 ASSERT_EQ(jlongs_vector
[i
], value
);
170 TEST(JniArray
, JavaFloatArrayToFloatVector
) {
171 const float kFloats
[] = {0.0, 0.5, -0.5};
172 const size_t kLen
= arraysize(kFloats
);
174 JNIEnv
* env
= AttachCurrentThread();
175 ScopedJavaLocalRef
<jfloatArray
> jfloats(env
, env
->NewFloatArray(kLen
));
176 ASSERT_TRUE(jfloats
.obj());
178 for (size_t i
= 0; i
< kLen
; ++i
) {
179 jfloat j
= static_cast<jfloat
>(kFloats
[i
]);
180 env
->SetFloatArrayRegion(jfloats
.obj(), i
, 1, &j
);
181 ASSERT_FALSE(HasException(env
));
184 std::vector
<float> floats
;
185 JavaFloatArrayToFloatVector(env
, jfloats
.obj(), &floats
);
187 ASSERT_EQ(static_cast<jsize
>(floats
.size()),
188 env
->GetArrayLength(jfloats
.obj()));
191 for (size_t i
= 0; i
< kLen
; ++i
) {
192 env
->GetFloatArrayRegion(jfloats
.obj(), i
, 1, &value
);
193 ASSERT_EQ(floats
[i
], value
);
197 TEST(JniArray
, JavaArrayOfByteArrayToStringVector
) {
198 const int kMaxItems
= 50;
199 JNIEnv
* env
= AttachCurrentThread();
201 // Create a byte[][] object.
202 ScopedJavaLocalRef
<jclass
> byte_array_clazz(env
, env
->FindClass("[B"));
203 ASSERT_TRUE(byte_array_clazz
.obj());
205 ScopedJavaLocalRef
<jobjectArray
> array(
206 env
, env
->NewObjectArray(kMaxItems
, byte_array_clazz
.obj(), NULL
));
207 ASSERT_TRUE(array
.obj());
209 // Create kMaxItems byte buffers.
211 for (int i
= 0; i
< kMaxItems
; ++i
) {
212 snprintf(text
, sizeof text
, "%d", i
);
213 ScopedJavaLocalRef
<jbyteArray
> byte_array
= ToJavaByteArray(
214 env
, reinterpret_cast<uint8
*>(text
),
215 static_cast<size_t>(strlen(text
)));
216 ASSERT_TRUE(byte_array
.obj());
218 env
->SetObjectArrayElement(array
.obj(), i
, byte_array
.obj());
219 ASSERT_FALSE(HasException(env
));
222 // Convert to std::vector<std::string>, check the content.
223 std::vector
<std::string
> vec
;
224 JavaArrayOfByteArrayToStringVector(env
, array
.obj(), &vec
);
226 EXPECT_EQ(static_cast<size_t>(kMaxItems
), vec
.size());
227 for (int i
= 0; i
< kMaxItems
; ++i
) {
228 snprintf(text
, sizeof text
, "%d", i
);
229 EXPECT_STREQ(text
, vec
[i
].c_str());
233 } // namespace android