blob: 77d33d6ce5bd5f566bb899c9242f4d2d7d0668b2 [file] [log] [blame]
[email protected]fe0f1ab2012-02-09 21:02:271// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]396b67232011-08-11 11:23:522// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]61c86c62011-08-02 16:11:164
5#include "base/android/jni_array.h"
6
[email protected]61c86c62011-08-02 16:11:167#include "base/android/jni_android.h"
[email protected]f98d7b92011-09-09 10:17:358#include "base/android/jni_string.h"
[email protected]61c86c62011-08-02 16:11:169#include "base/logging.h"
10
11namespace base {
12namespace android {
jdduke54720d12015-01-10 01:55:2113namespace {
14
15// As |GetArrayLength| makes no guarantees about the returned value (e.g., it
16// may be -1 if |array| is not a valid Java array), provide a safe wrapper
17// that always returns a valid, non-negative size.
18template <typename JavaArrayType>
Torne (Richard Coles)3c22e8302018-10-12 18:34:2219size_t SafeGetArrayLength(JNIEnv* env, const JavaRef<JavaArrayType>& jarray) {
jdduke54720d12015-01-10 01:55:2120 DCHECK(jarray);
Torne (Richard Coles)3c22e8302018-10-12 18:34:2221 jsize length = env->GetArrayLength(jarray.obj());
jdduke54720d12015-01-10 01:55:2122 DCHECK_GE(length, 0) << "Invalid array length: " << length;
23 return static_cast<size_t>(std::max(0, length));
24}
25
26} // namespace
[email protected]61c86c62011-08-02 16:11:1627
scheib1be6fde2015-11-03 18:15:2528ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(JNIEnv* env,
29 const uint8_t* bytes,
30 size_t len) {
[email protected]61c86c62011-08-02 16:11:1631 jbyteArray byte_array = env->NewByteArray(len);
[email protected]f98d7b92011-09-09 10:17:3532 CheckException(env);
[email protected]a42d4632011-10-26 21:48:0033 DCHECK(byte_array);
[email protected]61c86c62011-08-02 16:11:1634
[email protected]c60c83e2014-01-16 06:42:0335 env->SetByteArrayRegion(
36 byte_array, 0, len, reinterpret_cast<const jbyte*>(bytes));
[email protected]61c86c62011-08-02 16:11:1637 CheckException(env);
38
[email protected]fe0f1ab2012-02-09 21:02:2739 return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
[email protected]61c86c62011-08-02 16:11:1640}
41
scheib1be6fde2015-11-03 18:15:2542ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
43 JNIEnv* env,
44 const std::vector<uint8_t>& bytes) {
45 return ToJavaByteArray(env, bytes.data(), bytes.size());
46}
47
Torne (Richard Coles)cd5fa3f2018-10-02 16:09:5748ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(JNIEnv* env,
49 const std::string& str) {
50 return ToJavaByteArray(env, reinterpret_cast<const uint8_t*>(str.data()),
51 str.size());
52}
53
vitaliiif5491922017-05-15 09:11:0754ScopedJavaLocalRef<jbooleanArray> ToJavaBooleanArray(JNIEnv* env,
55 const bool* bools,
56 size_t len) {
57 jbooleanArray boolean_array = env->NewBooleanArray(len);
58 CheckException(env);
59 DCHECK(boolean_array);
60
61 env->SetBooleanArrayRegion(boolean_array, 0, len,
62 reinterpret_cast<const jboolean*>(bools));
63 CheckException(env);
64
65 return ScopedJavaLocalRef<jbooleanArray>(env, boolean_array);
66}
67
[email protected]2fd6b7032013-09-11 00:20:2568ScopedJavaLocalRef<jintArray> ToJavaIntArray(
69 JNIEnv* env, const int* ints, size_t len) {
70 jintArray int_array = env->NewIntArray(len);
71 CheckException(env);
72 DCHECK(int_array);
73
[email protected]c60c83e2014-01-16 06:42:0374 env->SetIntArrayRegion(
75 int_array, 0, len, reinterpret_cast<const jint*>(ints));
[email protected]2fd6b7032013-09-11 00:20:2576 CheckException(env);
77
78 return ScopedJavaLocalRef<jintArray>(env, int_array);
79}
80
81ScopedJavaLocalRef<jintArray> ToJavaIntArray(
82 JNIEnv* env, const std::vector<int>& ints) {
jdduke9f355f212015-05-05 07:34:0583 return ToJavaIntArray(env, ints.data(), ints.size());
[email protected]2fd6b7032013-09-11 00:20:2584}
85
scheib1be6fde2015-11-03 18:15:2586ScopedJavaLocalRef<jlongArray> ToJavaLongArray(JNIEnv* env,
87 const int64_t* longs,
88 size_t len) {
[email protected]2a3a0592013-02-22 18:53:0489 jlongArray long_array = env->NewLongArray(len);
90 CheckException(env);
91 DCHECK(long_array);
92
[email protected]c60c83e2014-01-16 06:42:0393 env->SetLongArrayRegion(
94 long_array, 0, len, reinterpret_cast<const jlong*>(longs));
[email protected]2a3a0592013-02-22 18:53:0495 CheckException(env);
96
97 return ScopedJavaLocalRef<jlongArray>(env, long_array);
98}
99
scheib1be6fde2015-11-03 18:15:25100// Returns a new Java long array converted from the given int64_t array.
[email protected]2a3a0592013-02-22 18:53:04101BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
scheib1be6fde2015-11-03 18:15:25102 JNIEnv* env,
103 const std::vector<int64_t>& longs) {
jdduke9f355f212015-05-05 07:34:05104 return ToJavaLongArray(env, longs.data(), longs.size());
[email protected]2a3a0592013-02-22 18:53:04105}
106
kinabae07c4b72016-02-10 12:42:08107// Returns a new Java float array converted from the given C++ float array.
108BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray(
109 JNIEnv* env, const float* floats, size_t len) {
110 jfloatArray float_array = env->NewFloatArray(len);
111 CheckException(env);
112 DCHECK(float_array);
113
114 env->SetFloatArrayRegion(
115 float_array, 0, len, reinterpret_cast<const jfloat*>(floats));
116 CheckException(env);
117
118 return ScopedJavaLocalRef<jfloatArray>(env, float_array);
119}
120
121BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray(
122 JNIEnv* env,
123 const std::vector<float>& floats) {
124 return ToJavaFloatArray(env, floats.data(), floats.size());
125}
126
[email protected]fe0f1ab2012-02-09 21:02:27127ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
128 JNIEnv* env, const std::vector<std::string>& v) {
129 ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
[email protected]f98d7b92011-09-09 10:17:35130 jobjectArray joa = env->NewObjectArray(v.size(),
131 byte_array_clazz.obj(), NULL);
132 CheckException(env);
[email protected]61c86c62011-08-02 16:11:16133
[email protected]f98d7b92011-09-09 10:17:35134 for (size_t i = 0; i < v.size(); ++i) {
scheib1be6fde2015-11-03 18:15:25135 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(
136 env, reinterpret_cast<const uint8_t*>(v[i].data()), v[i].length());
[email protected]61c86c62011-08-02 16:11:16137 env->SetObjectArrayElement(joa, i, byte_array.obj());
138 }
[email protected]fe0f1ab2012-02-09 21:02:27139 return ScopedJavaLocalRef<jobjectArray>(env, joa);
[email protected]61c86c62011-08-02 16:11:16140}
141
[email protected]fe0f1ab2012-02-09 21:02:27142ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
143 JNIEnv* env, const std::vector<std::string>& v) {
144 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
[email protected]f98d7b92011-09-09 10:17:35145 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
146 CheckException(env);
147
148 for (size_t i = 0; i < v.size(); ++i) {
[email protected]fe0f1ab2012-02-09 21:02:27149 ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
[email protected]f98d7b92011-09-09 10:17:35150 env->SetObjectArrayElement(joa, i, item.obj());
151 }
[email protected]fe0f1ab2012-02-09 21:02:27152 return ScopedJavaLocalRef<jobjectArray>(env, joa);
153}
154
[email protected]80ec0c32012-04-24 23:55:20155ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
156 JNIEnv* env, const std::vector<string16>& v) {
157 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
158 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
159 CheckException(env);
160
161 for (size_t i = 0; i < v.size(); ++i) {
162 ScopedJavaLocalRef<jstring> item = ConvertUTF16ToJavaString(env, v[i]);
163 env->SetObjectArrayElement(joa, i, item.obj());
164 }
165 return ScopedJavaLocalRef<jobjectArray>(env, joa);
166}
167
168void AppendJavaStringArrayToStringVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22169 const JavaRef<jobjectArray>& array,
[email protected]80ec0c32012-04-24 23:55:20170 std::vector<string16>* out) {
171 DCHECK(out);
[email protected]b8452fa2012-06-15 01:41:41172 if (!array)
[email protected]80ec0c32012-04-24 23:55:20173 return;
jdduke54720d12015-01-10 01:55:21174 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17175 size_t back = out->size();
176 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21177 for (size_t i = 0; i < len; ++i) {
Torne (Richard Coles)3c22e8302018-10-12 18:34:22178 ScopedJavaLocalRef<jstring> str(
179 env, static_cast<jstring>(env->GetObjectArrayElement(array.obj(), i)));
vitaliiif5491922017-05-15 09:11:07180 ConvertJavaStringToUTF16(env, str.obj(), out->data() + back + i);
[email protected]80ec0c32012-04-24 23:55:20181 }
182}
183
[email protected]380a2ce2012-06-18 18:48:55184void AppendJavaStringArrayToStringVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22185 const JavaRef<jobjectArray>& array,
[email protected]380a2ce2012-06-18 18:48:55186 std::vector<std::string>* out) {
187 DCHECK(out);
188 if (!array)
189 return;
jdduke54720d12015-01-10 01:55:21190 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17191 size_t back = out->size();
192 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21193 for (size_t i = 0; i < len; ++i) {
Torne (Richard Coles)3c22e8302018-10-12 18:34:22194 ScopedJavaLocalRef<jstring> str(
195 env, static_cast<jstring>(env->GetObjectArrayElement(array.obj(), i)));
vitaliiif5491922017-05-15 09:11:07196 ConvertJavaStringToUTF8(env, str.obj(), out->data() + back + i);
[email protected]380a2ce2012-06-18 18:48:55197 }
198}
199
[email protected]fe0f1ab2012-02-09 21:02:27200void AppendJavaByteArrayToByteVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22201 const JavaRef<jbyteArray>& byte_array,
scheib1be6fde2015-11-03 18:15:25202 std::vector<uint8_t>* out) {
[email protected]fe0f1ab2012-02-09 21:02:27203 DCHECK(out);
204 if (!byte_array)
205 return;
jdduke54720d12015-01-10 01:55:21206 size_t len = SafeGetArrayLength(env, byte_array);
207 if (!len)
208 return;
209 size_t back = out->size();
210 out->resize(back + len);
Torne (Richard Coles)3c22e8302018-10-12 18:34:22211 env->GetByteArrayRegion(byte_array.obj(), 0, len,
vitaliiif5491922017-05-15 09:11:07212 reinterpret_cast<int8_t*>(out->data() + back));
[email protected]fe0f1ab2012-02-09 21:02:27213}
214
215void JavaByteArrayToByteVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22216 const JavaRef<jbyteArray>& byte_array,
scheib1be6fde2015-11-03 18:15:25217 std::vector<uint8_t>* out) {
[email protected]fe0f1ab2012-02-09 21:02:27218 DCHECK(out);
jdduke54720d12015-01-10 01:55:21219 DCHECK(byte_array);
[email protected]fe0f1ab2012-02-09 21:02:27220 out->clear();
221 AppendJavaByteArrayToByteVector(env, byte_array, out);
[email protected]f98d7b92011-09-09 10:17:35222}
223
Torne (Richard Coles)cd5fa3f2018-10-02 16:09:57224void JavaByteArrayToString(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22225 const JavaRef<jbyteArray>& byte_array,
Torne (Richard Coles)cd5fa3f2018-10-02 16:09:57226 std::string* out) {
227 DCHECK(out);
228 DCHECK(byte_array);
229
230 std::vector<uint8_t> byte_vector;
231 JavaByteArrayToByteVector(env, byte_array, &byte_vector);
232 out->assign(byte_vector.begin(), byte_vector.end());
233}
234
vitaliiif5491922017-05-15 09:11:07235void JavaBooleanArrayToBoolVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22236 const JavaRef<jbooleanArray>& boolean_array,
vitaliiif5491922017-05-15 09:11:07237 std::vector<bool>* out) {
238 DCHECK(out);
239 if (!boolean_array)
240 return;
241 size_t len = SafeGetArrayLength(env, boolean_array);
242 if (!len)
243 return;
244 out->resize(len);
245 // It is not possible to get bool* out of vector<bool>.
Torne (Richard Coles)3c22e8302018-10-12 18:34:22246 jboolean* values = env->GetBooleanArrayElements(boolean_array.obj(), nullptr);
vitaliiif5491922017-05-15 09:11:07247 for (size_t i = 0; i < len; ++i) {
248 out->at(i) = static_cast<bool>(values[i]);
249 }
250}
251
[email protected]30935362012-06-28 21:26:23252void JavaIntArrayToIntVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22253 const JavaRef<jintArray>& int_array,
[email protected]30935362012-06-28 21:26:23254 std::vector<int>* out) {
255 DCHECK(out);
jdduke54720d12015-01-10 01:55:21256 size_t len = SafeGetArrayLength(env, int_array);
257 out->resize(len);
258 if (!len)
259 return;
Torne (Richard Coles)3c22e8302018-10-12 18:34:22260 env->GetIntArrayRegion(int_array.obj(), 0, len, out->data());
[email protected]433461802013-05-22 21:32:27261}
262
fgorski59ab07f32015-08-26 21:06:36263void JavaLongArrayToInt64Vector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22264 const JavaRef<jlongArray>& long_array,
scheib1be6fde2015-11-03 18:15:25265 std::vector<int64_t>* out) {
fgorski59ab07f32015-08-26 21:06:36266 DCHECK(out);
267 std::vector<jlong> temp;
268 JavaLongArrayToLongVector(env, long_array, &temp);
269 out->resize(0);
270 out->insert(out->begin(), temp.begin(), temp.end());
271}
272
[email protected]1b9f6bf92014-07-18 22:50:46273void JavaLongArrayToLongVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22274 const JavaRef<jlongArray>& long_array,
jdduke54720d12015-01-10 01:55:21275 std::vector<jlong>* out) {
[email protected]1b9f6bf92014-07-18 22:50:46276 DCHECK(out);
jdduke54720d12015-01-10 01:55:21277 size_t len = SafeGetArrayLength(env, long_array);
278 out->resize(len);
279 if (!len)
280 return;
Torne (Richard Coles)3c22e8302018-10-12 18:34:22281 env->GetLongArrayRegion(long_array.obj(), 0, len, out->data());
[email protected]1b9f6bf92014-07-18 22:50:46282}
283
[email protected]433461802013-05-22 21:32:27284void JavaFloatArrayToFloatVector(JNIEnv* env,
Torne (Richard Coles)3c22e8302018-10-12 18:34:22285 const JavaRef<jfloatArray>& float_array,
[email protected]433461802013-05-22 21:32:27286 std::vector<float>* out) {
287 DCHECK(out);
jdduke54720d12015-01-10 01:55:21288 size_t len = SafeGetArrayLength(env, float_array);
289 out->resize(len);
290 if (!len)
291 return;
Torne (Richard Coles)3c22e8302018-10-12 18:34:22292 env->GetFloatArrayRegion(float_array.obj(), 0, len, out->data());
[email protected]30935362012-06-28 21:26:23293}
294
Torne (Richard Coles)3c22e8302018-10-12 18:34:22295void JavaArrayOfByteArrayToStringVector(JNIEnv* env,
296 const JavaRef<jobjectArray>& array,
297 std::vector<std::string>* out) {
[email protected]65d58352012-12-05 15:00:28298 DCHECK(out);
jdduke54720d12015-01-10 01:55:21299 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17300 out->resize(len);
jdduke54720d12015-01-10 01:55:21301 for (size_t i = 0; i < len; ++i) {
[email protected]db45c212014-05-06 17:40:20302 ScopedJavaLocalRef<jbyteArray> bytes_array(
Torne (Richard Coles)3c22e8302018-10-12 18:34:22303 env,
304 static_cast<jbyteArray>(env->GetObjectArrayElement(array.obj(), i)));
[email protected]db45c212014-05-06 17:40:20305 jsize bytes_len = env->GetArrayLength(bytes_array.obj());
twellingtonaf303ba2015-10-29 23:15:57306 jbyte* bytes = env->GetByteArrayElements(bytes_array.obj(), nullptr);
[email protected]df0d7142012-12-14 01:31:17307 (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
[email protected]db45c212014-05-06 17:40:20308 env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
[email protected]65d58352012-12-05 15:00:28309 }
310}
311
Torne (Richard Coles)3c22e8302018-10-12 18:34:22312void JavaArrayOfIntArrayToIntVector(JNIEnv* env,
313 const JavaRef<jobjectArray>& array,
314 std::vector<std::vector<int>>* out) {
twellingtonaf303ba2015-10-29 23:15:57315 DCHECK(out);
316 size_t len = SafeGetArrayLength(env, array);
317 out->resize(len);
318 for (size_t i = 0; i < len; ++i) {
319 ScopedJavaLocalRef<jintArray> int_array(
Torne (Richard Coles)3c22e8302018-10-12 18:34:22320 env,
321 static_cast<jintArray>(env->GetObjectArrayElement(array.obj(), i)));
322 JavaIntArrayToIntVector(env, int_array, &out->at(i));
twellingtonaf303ba2015-10-29 23:15:57323 }
324}
325
[email protected]61c86c62011-08-02 16:11:16326} // namespace android
327} // namespace base