1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/android/jni_array.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include <limits>
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #include "base/android/jni_android.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/android/scoped_java_ref.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
15*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker namespace base {
18*635a8641SAndroid Build Coastguard Worker namespace android {
19*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,BasicConversions)20*635a8641SAndroid Build Coastguard Worker TEST(JniArray, BasicConversions) {
21*635a8641SAndroid Build Coastguard Worker const uint8_t kBytes[] = {0, 1, 2, 3};
22*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kBytes);
23*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
24*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
25*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(bytes.obj());
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker std::vector<uint8_t> inputVector(kBytes, kBytes + kLen);
28*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jbyteArray> bytesFromVector =
29*635a8641SAndroid Build Coastguard Worker ToJavaByteArray(env, inputVector);
30*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(bytesFromVector.obj());
31*635a8641SAndroid Build Coastguard Worker
32*635a8641SAndroid Build Coastguard Worker std::vector<uint8_t> vectorFromBytes(5);
33*635a8641SAndroid Build Coastguard Worker std::vector<uint8_t> vectorFromVector(5);
34*635a8641SAndroid Build Coastguard Worker JavaByteArrayToByteVector(env, bytes.obj(), &vectorFromBytes);
35*635a8641SAndroid Build Coastguard Worker JavaByteArrayToByteVector(env, bytesFromVector.obj(), &vectorFromVector);
36*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(4U, vectorFromBytes.size());
37*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(4U, vectorFromVector.size());
38*635a8641SAndroid Build Coastguard Worker std::vector<uint8_t> expected_vec(kBytes, kBytes + kLen);
39*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_vec, vectorFromBytes);
40*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_vec, vectorFromVector);
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard Worker AppendJavaByteArrayToByteVector(env, bytes.obj(), &vectorFromBytes);
43*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(8U, vectorFromBytes.size());
44*635a8641SAndroid Build Coastguard Worker expected_vec.insert(expected_vec.end(), kBytes, kBytes + kLen);
45*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_vec, vectorFromBytes);
46*635a8641SAndroid Build Coastguard Worker }
47*635a8641SAndroid Build Coastguard Worker
CheckBoolConversion(JNIEnv * env,const bool * bool_array,const size_t len,const ScopedJavaLocalRef<jbooleanArray> & booleans)48*635a8641SAndroid Build Coastguard Worker void CheckBoolConversion(JNIEnv* env,
49*635a8641SAndroid Build Coastguard Worker const bool* bool_array,
50*635a8641SAndroid Build Coastguard Worker const size_t len,
51*635a8641SAndroid Build Coastguard Worker const ScopedJavaLocalRef<jbooleanArray>& booleans) {
52*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(booleans.obj());
53*635a8641SAndroid Build Coastguard Worker
54*635a8641SAndroid Build Coastguard Worker jsize java_array_len = env->GetArrayLength(booleans.obj());
55*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(len), java_array_len);
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker jboolean value;
58*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
59*635a8641SAndroid Build Coastguard Worker env->GetBooleanArrayRegion(booleans.obj(), i, 1, &value);
60*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(bool_array[i], value);
61*635a8641SAndroid Build Coastguard Worker }
62*635a8641SAndroid Build Coastguard Worker }
63*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,BoolConversions)64*635a8641SAndroid Build Coastguard Worker TEST(JniArray, BoolConversions) {
65*635a8641SAndroid Build Coastguard Worker const bool kBools[] = {false, true, false};
66*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kBools);
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
69*635a8641SAndroid Build Coastguard Worker CheckBoolConversion(env, kBools, kLen, ToJavaBooleanArray(env, kBools, kLen));
70*635a8641SAndroid Build Coastguard Worker }
71*635a8641SAndroid Build Coastguard Worker
CheckIntConversion(JNIEnv * env,const int * int_array,const size_t len,const ScopedJavaLocalRef<jintArray> & ints)72*635a8641SAndroid Build Coastguard Worker void CheckIntConversion(
73*635a8641SAndroid Build Coastguard Worker JNIEnv* env,
74*635a8641SAndroid Build Coastguard Worker const int* int_array,
75*635a8641SAndroid Build Coastguard Worker const size_t len,
76*635a8641SAndroid Build Coastguard Worker const ScopedJavaLocalRef<jintArray>& ints) {
77*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ints.obj());
78*635a8641SAndroid Build Coastguard Worker
79*635a8641SAndroid Build Coastguard Worker jsize java_array_len = env->GetArrayLength(ints.obj());
80*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(len), java_array_len);
81*635a8641SAndroid Build Coastguard Worker
82*635a8641SAndroid Build Coastguard Worker jint value;
83*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
84*635a8641SAndroid Build Coastguard Worker env->GetIntArrayRegion(ints.obj(), i, 1, &value);
85*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(int_array[i], value);
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker }
88*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,IntConversions)89*635a8641SAndroid Build Coastguard Worker TEST(JniArray, IntConversions) {
90*635a8641SAndroid Build Coastguard Worker const int kInts[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
91*635a8641SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::max()};
92*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kInts);
93*635a8641SAndroid Build Coastguard Worker
94*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
95*635a8641SAndroid Build Coastguard Worker CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, kInts, kLen));
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker const std::vector<int> vec(kInts, kInts + kLen);
98*635a8641SAndroid Build Coastguard Worker CheckIntConversion(env, kInts, kLen, ToJavaIntArray(env, vec));
99*635a8641SAndroid Build Coastguard Worker }
100*635a8641SAndroid Build Coastguard Worker
CheckLongConversion(JNIEnv * env,const int64_t * long_array,const size_t len,const ScopedJavaLocalRef<jlongArray> & longs)101*635a8641SAndroid Build Coastguard Worker void CheckLongConversion(JNIEnv* env,
102*635a8641SAndroid Build Coastguard Worker const int64_t* long_array,
103*635a8641SAndroid Build Coastguard Worker const size_t len,
104*635a8641SAndroid Build Coastguard Worker const ScopedJavaLocalRef<jlongArray>& longs) {
105*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(longs.obj());
106*635a8641SAndroid Build Coastguard Worker
107*635a8641SAndroid Build Coastguard Worker jsize java_array_len = env->GetArrayLength(longs.obj());
108*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(len), java_array_len);
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker jlong value;
111*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
112*635a8641SAndroid Build Coastguard Worker env->GetLongArrayRegion(longs.obj(), i, 1, &value);
113*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(long_array[i], value);
114*635a8641SAndroid Build Coastguard Worker }
115*635a8641SAndroid Build Coastguard Worker }
116*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,LongConversions)117*635a8641SAndroid Build Coastguard Worker TEST(JniArray, LongConversions) {
118*635a8641SAndroid Build Coastguard Worker const int64_t kLongs[] = {0, 1, -1, std::numeric_limits<int64_t>::min(),
119*635a8641SAndroid Build Coastguard Worker std::numeric_limits<int64_t>::max()};
120*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kLongs);
121*635a8641SAndroid Build Coastguard Worker
122*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
123*635a8641SAndroid Build Coastguard Worker CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
124*635a8641SAndroid Build Coastguard Worker
125*635a8641SAndroid Build Coastguard Worker const std::vector<int64_t> vec(kLongs, kLongs + kLen);
126*635a8641SAndroid Build Coastguard Worker CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
127*635a8641SAndroid Build Coastguard Worker }
128*635a8641SAndroid Build Coastguard Worker
CheckIntArrayConversion(JNIEnv * env,ScopedJavaLocalRef<jintArray> jints,std::vector<int> int_vector,const size_t len)129*635a8641SAndroid Build Coastguard Worker void CheckIntArrayConversion(JNIEnv* env,
130*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> jints,
131*635a8641SAndroid Build Coastguard Worker std::vector<int> int_vector,
132*635a8641SAndroid Build Coastguard Worker const size_t len) {
133*635a8641SAndroid Build Coastguard Worker jint value;
134*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
135*635a8641SAndroid Build Coastguard Worker env->GetIntArrayRegion(jints.obj(), i, 1, &value);
136*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(int_vector[i], value);
137*635a8641SAndroid Build Coastguard Worker }
138*635a8641SAndroid Build Coastguard Worker }
139*635a8641SAndroid Build Coastguard Worker
CheckBoolArrayConversion(JNIEnv * env,ScopedJavaLocalRef<jbooleanArray> jbooleans,std::vector<bool> bool_vector,const size_t len)140*635a8641SAndroid Build Coastguard Worker void CheckBoolArrayConversion(JNIEnv* env,
141*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jbooleanArray> jbooleans,
142*635a8641SAndroid Build Coastguard Worker std::vector<bool> bool_vector,
143*635a8641SAndroid Build Coastguard Worker const size_t len) {
144*635a8641SAndroid Build Coastguard Worker jboolean value;
145*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
146*635a8641SAndroid Build Coastguard Worker env->GetBooleanArrayRegion(jbooleans.obj(), i, 1, &value);
147*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(bool_vector[i], value);
148*635a8641SAndroid Build Coastguard Worker }
149*635a8641SAndroid Build Coastguard Worker }
150*635a8641SAndroid Build Coastguard Worker
CheckFloatConversion(JNIEnv * env,const float * float_array,const size_t len,const ScopedJavaLocalRef<jfloatArray> & floats)151*635a8641SAndroid Build Coastguard Worker void CheckFloatConversion(
152*635a8641SAndroid Build Coastguard Worker JNIEnv* env,
153*635a8641SAndroid Build Coastguard Worker const float* float_array,
154*635a8641SAndroid Build Coastguard Worker const size_t len,
155*635a8641SAndroid Build Coastguard Worker const ScopedJavaLocalRef<jfloatArray>& floats) {
156*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(floats.obj());
157*635a8641SAndroid Build Coastguard Worker
158*635a8641SAndroid Build Coastguard Worker jsize java_array_len = env->GetArrayLength(floats.obj());
159*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(len), java_array_len);
160*635a8641SAndroid Build Coastguard Worker
161*635a8641SAndroid Build Coastguard Worker jfloat value;
162*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < len; ++i) {
163*635a8641SAndroid Build Coastguard Worker env->GetFloatArrayRegion(floats.obj(), i, 1, &value);
164*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(float_array[i], value);
165*635a8641SAndroid Build Coastguard Worker }
166*635a8641SAndroid Build Coastguard Worker }
167*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,FloatConversions)168*635a8641SAndroid Build Coastguard Worker TEST(JniArray, FloatConversions) {
169*635a8641SAndroid Build Coastguard Worker const float kFloats[] = { 0.0f, 1.0f, -10.0f};
170*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kFloats);
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
173*635a8641SAndroid Build Coastguard Worker CheckFloatConversion(env, kFloats, kLen,
174*635a8641SAndroid Build Coastguard Worker ToJavaFloatArray(env, kFloats, kLen));
175*635a8641SAndroid Build Coastguard Worker
176*635a8641SAndroid Build Coastguard Worker const std::vector<float> vec(kFloats, kFloats + kLen);
177*635a8641SAndroid Build Coastguard Worker CheckFloatConversion(env, kFloats, kLen, ToJavaFloatArray(env, vec));
178*635a8641SAndroid Build Coastguard Worker }
179*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaBooleanArrayToBoolVector)180*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaBooleanArrayToBoolVector) {
181*635a8641SAndroid Build Coastguard Worker const bool kBools[] = {false, true, false};
182*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kBools);
183*635a8641SAndroid Build Coastguard Worker
184*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
185*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jbooleanArray> jbooleans(env, env->NewBooleanArray(kLen));
186*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(jbooleans.obj());
187*635a8641SAndroid Build Coastguard Worker
188*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
189*635a8641SAndroid Build Coastguard Worker jboolean j = static_cast<jboolean>(kBools[i]);
190*635a8641SAndroid Build Coastguard Worker env->SetBooleanArrayRegion(jbooleans.obj(), i, 1, &j);
191*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
192*635a8641SAndroid Build Coastguard Worker }
193*635a8641SAndroid Build Coastguard Worker
194*635a8641SAndroid Build Coastguard Worker std::vector<bool> bools;
195*635a8641SAndroid Build Coastguard Worker JavaBooleanArrayToBoolVector(env, jbooleans.obj(), &bools);
196*635a8641SAndroid Build Coastguard Worker
197*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(bools.size()),
198*635a8641SAndroid Build Coastguard Worker env->GetArrayLength(jbooleans.obj()));
199*635a8641SAndroid Build Coastguard Worker
200*635a8641SAndroid Build Coastguard Worker CheckBoolArrayConversion(env, jbooleans, bools, kLen);
201*635a8641SAndroid Build Coastguard Worker }
202*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaIntArrayToIntVector)203*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaIntArrayToIntVector) {
204*635a8641SAndroid Build Coastguard Worker const int kInts[] = {0, 1, -1};
205*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kInts);
206*635a8641SAndroid Build Coastguard Worker
207*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
208*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
209*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(jints.obj());
210*635a8641SAndroid Build Coastguard Worker
211*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
212*635a8641SAndroid Build Coastguard Worker jint j = static_cast<jint>(kInts[i]);
213*635a8641SAndroid Build Coastguard Worker env->SetIntArrayRegion(jints.obj(), i, 1, &j);
214*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
215*635a8641SAndroid Build Coastguard Worker }
216*635a8641SAndroid Build Coastguard Worker
217*635a8641SAndroid Build Coastguard Worker std::vector<int> ints;
218*635a8641SAndroid Build Coastguard Worker JavaIntArrayToIntVector(env, jints.obj(), &ints);
219*635a8641SAndroid Build Coastguard Worker
220*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
221*635a8641SAndroid Build Coastguard Worker
222*635a8641SAndroid Build Coastguard Worker CheckIntArrayConversion(env, jints, ints, kLen);
223*635a8641SAndroid Build Coastguard Worker }
224*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaLongArrayToInt64Vector)225*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaLongArrayToInt64Vector) {
226*635a8641SAndroid Build Coastguard Worker const int64_t kInt64s[] = {0LL, 1LL, -1LL};
227*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kInt64s);
228*635a8641SAndroid Build Coastguard Worker
229*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
230*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
231*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(jlongs.obj());
232*635a8641SAndroid Build Coastguard Worker
233*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
234*635a8641SAndroid Build Coastguard Worker jlong j = static_cast<jlong>(kInt64s[i]);
235*635a8641SAndroid Build Coastguard Worker env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
236*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
237*635a8641SAndroid Build Coastguard Worker }
238*635a8641SAndroid Build Coastguard Worker
239*635a8641SAndroid Build Coastguard Worker std::vector<int64_t> int64s;
240*635a8641SAndroid Build Coastguard Worker JavaLongArrayToInt64Vector(env, jlongs.obj(), &int64s);
241*635a8641SAndroid Build Coastguard Worker
242*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(int64s.size()),
243*635a8641SAndroid Build Coastguard Worker env->GetArrayLength(jlongs.obj()));
244*635a8641SAndroid Build Coastguard Worker
245*635a8641SAndroid Build Coastguard Worker jlong value;
246*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
247*635a8641SAndroid Build Coastguard Worker env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
248*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(int64s[i], value);
249*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(kInt64s[i], int64s[i]);
250*635a8641SAndroid Build Coastguard Worker }
251*635a8641SAndroid Build Coastguard Worker }
252*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaLongArrayToLongVector)253*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaLongArrayToLongVector) {
254*635a8641SAndroid Build Coastguard Worker const int64_t kInt64s[] = {0LL, 1LL, -1LL};
255*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kInt64s);
256*635a8641SAndroid Build Coastguard Worker
257*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
258*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jlongArray> jlongs(env, env->NewLongArray(kLen));
259*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(jlongs.obj());
260*635a8641SAndroid Build Coastguard Worker
261*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
262*635a8641SAndroid Build Coastguard Worker jlong j = static_cast<jlong>(kInt64s[i]);
263*635a8641SAndroid Build Coastguard Worker env->SetLongArrayRegion(jlongs.obj(), i, 1, &j);
264*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
265*635a8641SAndroid Build Coastguard Worker }
266*635a8641SAndroid Build Coastguard Worker
267*635a8641SAndroid Build Coastguard Worker std::vector<jlong> jlongs_vector;
268*635a8641SAndroid Build Coastguard Worker JavaLongArrayToLongVector(env, jlongs.obj(), &jlongs_vector);
269*635a8641SAndroid Build Coastguard Worker
270*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(jlongs_vector.size()),
271*635a8641SAndroid Build Coastguard Worker env->GetArrayLength(jlongs.obj()));
272*635a8641SAndroid Build Coastguard Worker
273*635a8641SAndroid Build Coastguard Worker jlong value;
274*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
275*635a8641SAndroid Build Coastguard Worker env->GetLongArrayRegion(jlongs.obj(), i, 1, &value);
276*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(jlongs_vector[i], value);
277*635a8641SAndroid Build Coastguard Worker }
278*635a8641SAndroid Build Coastguard Worker }
279*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaFloatArrayToFloatVector)280*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaFloatArrayToFloatVector) {
281*635a8641SAndroid Build Coastguard Worker const float kFloats[] = {0.0, 0.5, -0.5};
282*635a8641SAndroid Build Coastguard Worker const size_t kLen = arraysize(kFloats);
283*635a8641SAndroid Build Coastguard Worker
284*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
285*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
286*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(jfloats.obj());
287*635a8641SAndroid Build Coastguard Worker
288*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
289*635a8641SAndroid Build Coastguard Worker jfloat j = static_cast<jfloat>(kFloats[i]);
290*635a8641SAndroid Build Coastguard Worker env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
291*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
292*635a8641SAndroid Build Coastguard Worker }
293*635a8641SAndroid Build Coastguard Worker
294*635a8641SAndroid Build Coastguard Worker std::vector<float> floats;
295*635a8641SAndroid Build Coastguard Worker JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats);
296*635a8641SAndroid Build Coastguard Worker
297*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<jsize>(floats.size()),
298*635a8641SAndroid Build Coastguard Worker env->GetArrayLength(jfloats.obj()));
299*635a8641SAndroid Build Coastguard Worker
300*635a8641SAndroid Build Coastguard Worker jfloat value;
301*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kLen; ++i) {
302*635a8641SAndroid Build Coastguard Worker env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
303*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(floats[i], value);
304*635a8641SAndroid Build Coastguard Worker }
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaArrayOfByteArrayToStringVector)307*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
308*635a8641SAndroid Build Coastguard Worker const int kMaxItems = 50;
309*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
310*635a8641SAndroid Build Coastguard Worker
311*635a8641SAndroid Build Coastguard Worker // Create a byte[][] object.
312*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
313*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(byte_array_clazz.obj());
314*635a8641SAndroid Build Coastguard Worker
315*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobjectArray> array(
316*635a8641SAndroid Build Coastguard Worker env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
317*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(array.obj());
318*635a8641SAndroid Build Coastguard Worker
319*635a8641SAndroid Build Coastguard Worker // Create kMaxItems byte buffers.
320*635a8641SAndroid Build Coastguard Worker char text[16];
321*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < kMaxItems; ++i) {
322*635a8641SAndroid Build Coastguard Worker snprintf(text, sizeof text, "%d", i);
323*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jbyteArray> byte_array =
324*635a8641SAndroid Build Coastguard Worker ToJavaByteArray(env, reinterpret_cast<uint8_t*>(text),
325*635a8641SAndroid Build Coastguard Worker static_cast<size_t>(strlen(text)));
326*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(byte_array.obj());
327*635a8641SAndroid Build Coastguard Worker
328*635a8641SAndroid Build Coastguard Worker env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
329*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(HasException(env));
330*635a8641SAndroid Build Coastguard Worker }
331*635a8641SAndroid Build Coastguard Worker
332*635a8641SAndroid Build Coastguard Worker // Convert to std::vector<std::string>, check the content.
333*635a8641SAndroid Build Coastguard Worker std::vector<std::string> vec;
334*635a8641SAndroid Build Coastguard Worker JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec);
335*635a8641SAndroid Build Coastguard Worker
336*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
337*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < kMaxItems; ++i) {
338*635a8641SAndroid Build Coastguard Worker snprintf(text, sizeof text, "%d", i);
339*635a8641SAndroid Build Coastguard Worker EXPECT_STREQ(text, vec[i].c_str());
340*635a8641SAndroid Build Coastguard Worker }
341*635a8641SAndroid Build Coastguard Worker }
342*635a8641SAndroid Build Coastguard Worker
TEST(JniArray,JavaArrayOfIntArrayToIntVector)343*635a8641SAndroid Build Coastguard Worker TEST(JniArray, JavaArrayOfIntArrayToIntVector) {
344*635a8641SAndroid Build Coastguard Worker const size_t kNumItems = 4;
345*635a8641SAndroid Build Coastguard Worker JNIEnv* env = AttachCurrentThread();
346*635a8641SAndroid Build Coastguard Worker
347*635a8641SAndroid Build Coastguard Worker // Create an int[][] object.
348*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jclass> int_array_clazz(env, env->FindClass("[I"));
349*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(int_array_clazz.obj());
350*635a8641SAndroid Build Coastguard Worker
351*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jobjectArray> array(
352*635a8641SAndroid Build Coastguard Worker env, env->NewObjectArray(kNumItems, int_array_clazz.obj(), nullptr));
353*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(array.obj());
354*635a8641SAndroid Build Coastguard Worker
355*635a8641SAndroid Build Coastguard Worker // Populate int[][] object.
356*635a8641SAndroid Build Coastguard Worker const int kInts0[] = {0, 1, -1, std::numeric_limits<int32_t>::min(),
357*635a8641SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::max()};
358*635a8641SAndroid Build Coastguard Worker const size_t kLen0 = arraysize(kInts0);
359*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> int_array0 = ToJavaIntArray(env, kInts0, kLen0);
360*635a8641SAndroid Build Coastguard Worker env->SetObjectArrayElement(array.obj(), 0, int_array0.obj());
361*635a8641SAndroid Build Coastguard Worker
362*635a8641SAndroid Build Coastguard Worker const int kInts1[] = {3, 4, 5};
363*635a8641SAndroid Build Coastguard Worker const size_t kLen1 = arraysize(kInts1);
364*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> int_array1 = ToJavaIntArray(env, kInts1, kLen1);
365*635a8641SAndroid Build Coastguard Worker env->SetObjectArrayElement(array.obj(), 1, int_array1.obj());
366*635a8641SAndroid Build Coastguard Worker
367*635a8641SAndroid Build Coastguard Worker const int kInts2[] = {};
368*635a8641SAndroid Build Coastguard Worker const size_t kLen2 = 0;
369*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> int_array2 = ToJavaIntArray(env, kInts2, kLen2);
370*635a8641SAndroid Build Coastguard Worker env->SetObjectArrayElement(array.obj(), 2, int_array2.obj());
371*635a8641SAndroid Build Coastguard Worker
372*635a8641SAndroid Build Coastguard Worker const int kInts3[] = {16};
373*635a8641SAndroid Build Coastguard Worker const size_t kLen3 = arraysize(kInts3);
374*635a8641SAndroid Build Coastguard Worker ScopedJavaLocalRef<jintArray> int_array3 = ToJavaIntArray(env, kInts3, kLen3);
375*635a8641SAndroid Build Coastguard Worker env->SetObjectArrayElement(array.obj(), 3, int_array3.obj());
376*635a8641SAndroid Build Coastguard Worker
377*635a8641SAndroid Build Coastguard Worker // Convert to std::vector<std::vector<int>>, check the content.
378*635a8641SAndroid Build Coastguard Worker std::vector<std::vector<int>> out;
379*635a8641SAndroid Build Coastguard Worker JavaArrayOfIntArrayToIntVector(env, array.obj(), &out);
380*635a8641SAndroid Build Coastguard Worker
381*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kNumItems, out.size());
382*635a8641SAndroid Build Coastguard Worker CheckIntArrayConversion(env, int_array0, out[0], kLen0);
383*635a8641SAndroid Build Coastguard Worker CheckIntArrayConversion(env, int_array1, out[1], kLen1);
384*635a8641SAndroid Build Coastguard Worker CheckIntArrayConversion(env, int_array2, out[2], kLen2);
385*635a8641SAndroid Build Coastguard Worker CheckIntArrayConversion(env, int_array3, out[3], kLen3);
386*635a8641SAndroid Build Coastguard Worker }
387*635a8641SAndroid Build Coastguard Worker
388*635a8641SAndroid Build Coastguard Worker } // namespace android
389*635a8641SAndroid Build Coastguard Worker } // namespace base
390