blob: 52b1679bbd24de5ca301912a17f02705f5549418 [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>
19size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) {
20 DCHECK(jarray);
21 jsize length = env->GetArrayLength(jarray);
22 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
vitaliiif5491922017-05-15 09:11:0748ScopedJavaLocalRef<jbooleanArray> ToJavaBooleanArray(JNIEnv* env,
49 const bool* bools,
50 size_t len) {
51 jbooleanArray boolean_array = env->NewBooleanArray(len);
52 CheckException(env);
53 DCHECK(boolean_array);
54
55 env->SetBooleanArrayRegion(boolean_array, 0, len,
56 reinterpret_cast<const jboolean*>(bools));
57 CheckException(env);
58
59 return ScopedJavaLocalRef<jbooleanArray>(env, boolean_array);
60}
61
[email protected]2fd6b7032013-09-11 00:20:2562ScopedJavaLocalRef<jintArray> ToJavaIntArray(
63 JNIEnv* env, const int* ints, size_t len) {
64 jintArray int_array = env->NewIntArray(len);
65 CheckException(env);
66 DCHECK(int_array);
67
[email protected]c60c83e2014-01-16 06:42:0368 env->SetIntArrayRegion(
69 int_array, 0, len, reinterpret_cast<const jint*>(ints));
[email protected]2fd6b7032013-09-11 00:20:2570 CheckException(env);
71
72 return ScopedJavaLocalRef<jintArray>(env, int_array);
73}
74
75ScopedJavaLocalRef<jintArray> ToJavaIntArray(
76 JNIEnv* env, const std::vector<int>& ints) {
jdduke9f355f212015-05-05 07:34:0577 return ToJavaIntArray(env, ints.data(), ints.size());
[email protected]2fd6b7032013-09-11 00:20:2578}
79
scheib1be6fde2015-11-03 18:15:2580ScopedJavaLocalRef<jlongArray> ToJavaLongArray(JNIEnv* env,
81 const int64_t* longs,
82 size_t len) {
[email protected]2a3a0592013-02-22 18:53:0483 jlongArray long_array = env->NewLongArray(len);
84 CheckException(env);
85 DCHECK(long_array);
86
[email protected]c60c83e2014-01-16 06:42:0387 env->SetLongArrayRegion(
88 long_array, 0, len, reinterpret_cast<const jlong*>(longs));
[email protected]2a3a0592013-02-22 18:53:0489 CheckException(env);
90
91 return ScopedJavaLocalRef<jlongArray>(env, long_array);
92}
93
scheib1be6fde2015-11-03 18:15:2594// Returns a new Java long array converted from the given int64_t array.
[email protected]2a3a0592013-02-22 18:53:0495BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
scheib1be6fde2015-11-03 18:15:2596 JNIEnv* env,
97 const std::vector<int64_t>& longs) {
jdduke9f355f212015-05-05 07:34:0598 return ToJavaLongArray(env, longs.data(), longs.size());
[email protected]2a3a0592013-02-22 18:53:0499}
100
kinabae07c4b72016-02-10 12:42:08101// Returns a new Java float array converted from the given C++ float array.
102BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray(
103 JNIEnv* env, const float* floats, size_t len) {
104 jfloatArray float_array = env->NewFloatArray(len);
105 CheckException(env);
106 DCHECK(float_array);
107
108 env->SetFloatArrayRegion(
109 float_array, 0, len, reinterpret_cast<const jfloat*>(floats));
110 CheckException(env);
111
112 return ScopedJavaLocalRef<jfloatArray>(env, float_array);
113}
114
115BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray(
116 JNIEnv* env,
117 const std::vector<float>& floats) {
118 return ToJavaFloatArray(env, floats.data(), floats.size());
119}
120
[email protected]fe0f1ab2012-02-09 21:02:27121ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
122 JNIEnv* env, const std::vector<std::string>& v) {
123 ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
[email protected]f98d7b92011-09-09 10:17:35124 jobjectArray joa = env->NewObjectArray(v.size(),
125 byte_array_clazz.obj(), NULL);
126 CheckException(env);
[email protected]61c86c62011-08-02 16:11:16127
[email protected]f98d7b92011-09-09 10:17:35128 for (size_t i = 0; i < v.size(); ++i) {
scheib1be6fde2015-11-03 18:15:25129 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(
130 env, reinterpret_cast<const uint8_t*>(v[i].data()), v[i].length());
[email protected]61c86c62011-08-02 16:11:16131 env->SetObjectArrayElement(joa, i, byte_array.obj());
132 }
[email protected]fe0f1ab2012-02-09 21:02:27133 return ScopedJavaLocalRef<jobjectArray>(env, joa);
[email protected]61c86c62011-08-02 16:11:16134}
135
[email protected]fe0f1ab2012-02-09 21:02:27136ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
137 JNIEnv* env, const std::vector<std::string>& v) {
138 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
[email protected]f98d7b92011-09-09 10:17:35139 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
140 CheckException(env);
141
142 for (size_t i = 0; i < v.size(); ++i) {
[email protected]fe0f1ab2012-02-09 21:02:27143 ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
[email protected]f98d7b92011-09-09 10:17:35144 env->SetObjectArrayElement(joa, i, item.obj());
145 }
[email protected]fe0f1ab2012-02-09 21:02:27146 return ScopedJavaLocalRef<jobjectArray>(env, joa);
147}
148
[email protected]80ec0c32012-04-24 23:55:20149ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
150 JNIEnv* env, const std::vector<string16>& v) {
151 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
152 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
153 CheckException(env);
154
155 for (size_t i = 0; i < v.size(); ++i) {
156 ScopedJavaLocalRef<jstring> item = ConvertUTF16ToJavaString(env, v[i]);
157 env->SetObjectArrayElement(joa, i, item.obj());
158 }
159 return ScopedJavaLocalRef<jobjectArray>(env, joa);
160}
161
162void AppendJavaStringArrayToStringVector(JNIEnv* env,
[email protected]b8452fa2012-06-15 01:41:41163 jobjectArray array,
[email protected]80ec0c32012-04-24 23:55:20164 std::vector<string16>* out) {
165 DCHECK(out);
[email protected]b8452fa2012-06-15 01:41:41166 if (!array)
[email protected]80ec0c32012-04-24 23:55:20167 return;
jdduke54720d12015-01-10 01:55:21168 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17169 size_t back = out->size();
170 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21171 for (size_t i = 0; i < len; ++i) {
[email protected]80ec0c32012-04-24 23:55:20172 ScopedJavaLocalRef<jstring> str(env,
[email protected]b8452fa2012-06-15 01:41:41173 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
vitaliiif5491922017-05-15 09:11:07174 ConvertJavaStringToUTF16(env, str.obj(), out->data() + back + i);
[email protected]80ec0c32012-04-24 23:55:20175 }
176}
177
[email protected]380a2ce2012-06-18 18:48:55178void AppendJavaStringArrayToStringVector(JNIEnv* env,
179 jobjectArray array,
180 std::vector<std::string>* out) {
181 DCHECK(out);
182 if (!array)
183 return;
jdduke54720d12015-01-10 01:55:21184 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17185 size_t back = out->size();
186 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21187 for (size_t i = 0; i < len; ++i) {
[email protected]380a2ce2012-06-18 18:48:55188 ScopedJavaLocalRef<jstring> str(env,
189 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
vitaliiif5491922017-05-15 09:11:07190 ConvertJavaStringToUTF8(env, str.obj(), out->data() + back + i);
[email protected]380a2ce2012-06-18 18:48:55191 }
192}
193
[email protected]fe0f1ab2012-02-09 21:02:27194void AppendJavaByteArrayToByteVector(JNIEnv* env,
195 jbyteArray byte_array,
scheib1be6fde2015-11-03 18:15:25196 std::vector<uint8_t>* out) {
[email protected]fe0f1ab2012-02-09 21:02:27197 DCHECK(out);
198 if (!byte_array)
199 return;
jdduke54720d12015-01-10 01:55:21200 size_t len = SafeGetArrayLength(env, byte_array);
201 if (!len)
202 return;
203 size_t back = out->size();
204 out->resize(back + len);
205 env->GetByteArrayRegion(byte_array, 0, len,
vitaliiif5491922017-05-15 09:11:07206 reinterpret_cast<int8_t*>(out->data() + back));
[email protected]fe0f1ab2012-02-09 21:02:27207}
208
209void JavaByteArrayToByteVector(JNIEnv* env,
210 jbyteArray byte_array,
scheib1be6fde2015-11-03 18:15:25211 std::vector<uint8_t>* out) {
[email protected]fe0f1ab2012-02-09 21:02:27212 DCHECK(out);
jdduke54720d12015-01-10 01:55:21213 DCHECK(byte_array);
[email protected]fe0f1ab2012-02-09 21:02:27214 out->clear();
215 AppendJavaByteArrayToByteVector(env, byte_array, out);
[email protected]f98d7b92011-09-09 10:17:35216}
217
vitaliiif5491922017-05-15 09:11:07218void JavaBooleanArrayToBoolVector(JNIEnv* env,
219 jbooleanArray boolean_array,
220 std::vector<bool>* out) {
221 DCHECK(out);
222 if (!boolean_array)
223 return;
224 size_t len = SafeGetArrayLength(env, boolean_array);
225 if (!len)
226 return;
227 out->resize(len);
228 // It is not possible to get bool* out of vector<bool>.
229 jboolean* values = env->GetBooleanArrayElements(boolean_array, nullptr);
230 for (size_t i = 0; i < len; ++i) {
231 out->at(i) = static_cast<bool>(values[i]);
232 }
233}
234
[email protected]30935362012-06-28 21:26:23235void JavaIntArrayToIntVector(JNIEnv* env,
[email protected]433461802013-05-22 21:32:27236 jintArray int_array,
[email protected]30935362012-06-28 21:26:23237 std::vector<int>* out) {
238 DCHECK(out);
jdduke54720d12015-01-10 01:55:21239 size_t len = SafeGetArrayLength(env, int_array);
240 out->resize(len);
241 if (!len)
242 return;
vitaliiif5491922017-05-15 09:11:07243 env->GetIntArrayRegion(int_array, 0, len, out->data());
[email protected]433461802013-05-22 21:32:27244}
245
fgorski59ab07f32015-08-26 21:06:36246void JavaLongArrayToInt64Vector(JNIEnv* env,
247 jlongArray long_array,
scheib1be6fde2015-11-03 18:15:25248 std::vector<int64_t>* out) {
fgorski59ab07f32015-08-26 21:06:36249 DCHECK(out);
250 std::vector<jlong> temp;
251 JavaLongArrayToLongVector(env, long_array, &temp);
252 out->resize(0);
253 out->insert(out->begin(), temp.begin(), temp.end());
254}
255
[email protected]1b9f6bf92014-07-18 22:50:46256void JavaLongArrayToLongVector(JNIEnv* env,
257 jlongArray long_array,
jdduke54720d12015-01-10 01:55:21258 std::vector<jlong>* out) {
[email protected]1b9f6bf92014-07-18 22:50:46259 DCHECK(out);
jdduke54720d12015-01-10 01:55:21260 size_t len = SafeGetArrayLength(env, long_array);
261 out->resize(len);
262 if (!len)
263 return;
vitaliiif5491922017-05-15 09:11:07264 env->GetLongArrayRegion(long_array, 0, len, out->data());
[email protected]1b9f6bf92014-07-18 22:50:46265}
266
[email protected]433461802013-05-22 21:32:27267void JavaFloatArrayToFloatVector(JNIEnv* env,
268 jfloatArray float_array,
269 std::vector<float>* out) {
270 DCHECK(out);
jdduke54720d12015-01-10 01:55:21271 size_t len = SafeGetArrayLength(env, float_array);
272 out->resize(len);
273 if (!len)
274 return;
vitaliiif5491922017-05-15 09:11:07275 env->GetFloatArrayRegion(float_array, 0, len, out->data());
[email protected]30935362012-06-28 21:26:23276}
277
[email protected]65d58352012-12-05 15:00:28278void JavaArrayOfByteArrayToStringVector(
279 JNIEnv* env,
280 jobjectArray array,
281 std::vector<std::string>* out) {
282 DCHECK(out);
jdduke54720d12015-01-10 01:55:21283 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17284 out->resize(len);
jdduke54720d12015-01-10 01:55:21285 for (size_t i = 0; i < len; ++i) {
[email protected]db45c212014-05-06 17:40:20286 ScopedJavaLocalRef<jbyteArray> bytes_array(
287 env, static_cast<jbyteArray>(
288 env->GetObjectArrayElement(array, i)));
289 jsize bytes_len = env->GetArrayLength(bytes_array.obj());
twellingtonaf303ba2015-10-29 23:15:57290 jbyte* bytes = env->GetByteArrayElements(bytes_array.obj(), nullptr);
[email protected]df0d7142012-12-14 01:31:17291 (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
[email protected]db45c212014-05-06 17:40:20292 env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
[email protected]65d58352012-12-05 15:00:28293 }
294}
295
twellingtonaf303ba2015-10-29 23:15:57296void JavaArrayOfIntArrayToIntVector(
297 JNIEnv* env,
298 jobjectArray array,
299 std::vector<std::vector<int>>* out) {
300 DCHECK(out);
301 size_t len = SafeGetArrayLength(env, array);
302 out->resize(len);
303 for (size_t i = 0; i < len; ++i) {
304 ScopedJavaLocalRef<jintArray> int_array(
305 env, static_cast<jintArray>(env->GetObjectArrayElement(array, i)));
vitaliiif5491922017-05-15 09:11:07306 JavaIntArrayToIntVector(env, int_array.obj(), &out->at(i));
twellingtonaf303ba2015-10-29 23:15:57307 }
308}
309
[email protected]61c86c62011-08-02 16:11:16310} // namespace android
311} // namespace base