blob: bc922f883c2f8c296fbbfdd4a2590afc2fb11bc9 [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
[email protected]fe0f1ab2012-02-09 21:02:2728ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
29 JNIEnv* env, const uint8* bytes, size_t len) {
[email protected]61c86c62011-08-02 16:11:1630 jbyteArray byte_array = env->NewByteArray(len);
[email protected]f98d7b92011-09-09 10:17:3531 CheckException(env);
[email protected]a42d4632011-10-26 21:48:0032 DCHECK(byte_array);
[email protected]61c86c62011-08-02 16:11:1633
[email protected]c60c83e2014-01-16 06:42:0334 env->SetByteArrayRegion(
35 byte_array, 0, len, reinterpret_cast<const jbyte*>(bytes));
[email protected]61c86c62011-08-02 16:11:1636 CheckException(env);
37
[email protected]fe0f1ab2012-02-09 21:02:2738 return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
[email protected]61c86c62011-08-02 16:11:1639}
40
[email protected]2fd6b7032013-09-11 00:20:2541ScopedJavaLocalRef<jintArray> ToJavaIntArray(
42 JNIEnv* env, const int* ints, size_t len) {
43 jintArray int_array = env->NewIntArray(len);
44 CheckException(env);
45 DCHECK(int_array);
46
[email protected]c60c83e2014-01-16 06:42:0347 env->SetIntArrayRegion(
48 int_array, 0, len, reinterpret_cast<const jint*>(ints));
[email protected]2fd6b7032013-09-11 00:20:2549 CheckException(env);
50
51 return ScopedJavaLocalRef<jintArray>(env, int_array);
52}
53
54ScopedJavaLocalRef<jintArray> ToJavaIntArray(
55 JNIEnv* env, const std::vector<int>& ints) {
jdduke9f355f212015-05-05 07:34:0556 return ToJavaIntArray(env, ints.data(), ints.size());
[email protected]2fd6b7032013-09-11 00:20:2557}
58
[email protected]2a3a0592013-02-22 18:53:0459ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
60 JNIEnv* env, const int64* longs, size_t len) {
61 jlongArray long_array = env->NewLongArray(len);
62 CheckException(env);
63 DCHECK(long_array);
64
[email protected]c60c83e2014-01-16 06:42:0365 env->SetLongArrayRegion(
66 long_array, 0, len, reinterpret_cast<const jlong*>(longs));
[email protected]2a3a0592013-02-22 18:53:0467 CheckException(env);
68
69 return ScopedJavaLocalRef<jlongArray>(env, long_array);
70}
71
72// Returns a new Java long array converted from the given int64 array.
73BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
74 JNIEnv* env, const std::vector<int64>& longs) {
jdduke9f355f212015-05-05 07:34:0575 return ToJavaLongArray(env, longs.data(), longs.size());
[email protected]2a3a0592013-02-22 18:53:0476}
77
[email protected]fe0f1ab2012-02-09 21:02:2778ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
79 JNIEnv* env, const std::vector<std::string>& v) {
80 ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
[email protected]f98d7b92011-09-09 10:17:3581 jobjectArray joa = env->NewObjectArray(v.size(),
82 byte_array_clazz.obj(), NULL);
83 CheckException(env);
[email protected]61c86c62011-08-02 16:11:1684
[email protected]f98d7b92011-09-09 10:17:3585 for (size_t i = 0; i < v.size(); ++i) {
[email protected]fe0f1ab2012-02-09 21:02:2786 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(env,
87 reinterpret_cast<const uint8*>(v[i].data()), v[i].length());
[email protected]61c86c62011-08-02 16:11:1688 env->SetObjectArrayElement(joa, i, byte_array.obj());
89 }
[email protected]fe0f1ab2012-02-09 21:02:2790 return ScopedJavaLocalRef<jobjectArray>(env, joa);
[email protected]61c86c62011-08-02 16:11:1691}
92
[email protected]fe0f1ab2012-02-09 21:02:2793ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
94 JNIEnv* env, const std::vector<std::string>& v) {
95 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
[email protected]f98d7b92011-09-09 10:17:3596 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
97 CheckException(env);
98
99 for (size_t i = 0; i < v.size(); ++i) {
[email protected]fe0f1ab2012-02-09 21:02:27100 ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
[email protected]f98d7b92011-09-09 10:17:35101 env->SetObjectArrayElement(joa, i, item.obj());
102 }
[email protected]fe0f1ab2012-02-09 21:02:27103 return ScopedJavaLocalRef<jobjectArray>(env, joa);
104}
105
[email protected]80ec0c32012-04-24 23:55:20106ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
107 JNIEnv* env, const std::vector<string16>& v) {
108 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
109 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
110 CheckException(env);
111
112 for (size_t i = 0; i < v.size(); ++i) {
113 ScopedJavaLocalRef<jstring> item = ConvertUTF16ToJavaString(env, v[i]);
114 env->SetObjectArrayElement(joa, i, item.obj());
115 }
116 return ScopedJavaLocalRef<jobjectArray>(env, joa);
117}
118
119void AppendJavaStringArrayToStringVector(JNIEnv* env,
[email protected]b8452fa2012-06-15 01:41:41120 jobjectArray array,
[email protected]80ec0c32012-04-24 23:55:20121 std::vector<string16>* out) {
122 DCHECK(out);
[email protected]b8452fa2012-06-15 01:41:41123 if (!array)
[email protected]80ec0c32012-04-24 23:55:20124 return;
jdduke54720d12015-01-10 01:55:21125 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17126 size_t back = out->size();
127 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21128 for (size_t i = 0; i < len; ++i) {
[email protected]80ec0c32012-04-24 23:55:20129 ScopedJavaLocalRef<jstring> str(env,
[email protected]b8452fa2012-06-15 01:41:41130 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
[email protected]df0d7142012-12-14 01:31:17131 ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i]));
[email protected]80ec0c32012-04-24 23:55:20132 }
133}
134
[email protected]380a2ce2012-06-18 18:48:55135void AppendJavaStringArrayToStringVector(JNIEnv* env,
136 jobjectArray array,
137 std::vector<std::string>* out) {
138 DCHECK(out);
139 if (!array)
140 return;
jdduke54720d12015-01-10 01:55:21141 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17142 size_t back = out->size();
143 out->resize(back + len);
jdduke54720d12015-01-10 01:55:21144 for (size_t i = 0; i < len; ++i) {
[email protected]380a2ce2012-06-18 18:48:55145 ScopedJavaLocalRef<jstring> str(env,
146 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
[email protected]df0d7142012-12-14 01:31:17147 ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i]));
[email protected]380a2ce2012-06-18 18:48:55148 }
149}
150
[email protected]fe0f1ab2012-02-09 21:02:27151void AppendJavaByteArrayToByteVector(JNIEnv* env,
152 jbyteArray byte_array,
153 std::vector<uint8>* out) {
154 DCHECK(out);
155 if (!byte_array)
156 return;
jdduke54720d12015-01-10 01:55:21157 size_t len = SafeGetArrayLength(env, byte_array);
158 if (!len)
159 return;
160 size_t back = out->size();
161 out->resize(back + len);
162 env->GetByteArrayRegion(byte_array, 0, len,
163 reinterpret_cast<int8*>(&(*out)[back]));
[email protected]fe0f1ab2012-02-09 21:02:27164}
165
166void JavaByteArrayToByteVector(JNIEnv* env,
167 jbyteArray byte_array,
168 std::vector<uint8>* out) {
169 DCHECK(out);
jdduke54720d12015-01-10 01:55:21170 DCHECK(byte_array);
[email protected]fe0f1ab2012-02-09 21:02:27171 out->clear();
172 AppendJavaByteArrayToByteVector(env, byte_array, out);
[email protected]f98d7b92011-09-09 10:17:35173}
174
[email protected]30935362012-06-28 21:26:23175void JavaIntArrayToIntVector(JNIEnv* env,
[email protected]433461802013-05-22 21:32:27176 jintArray int_array,
[email protected]30935362012-06-28 21:26:23177 std::vector<int>* out) {
178 DCHECK(out);
jdduke54720d12015-01-10 01:55:21179 size_t len = SafeGetArrayLength(env, int_array);
180 out->resize(len);
181 if (!len)
182 return;
183 // TODO(jdduke): Use |out->data()| for pointer access after switch to libc++,
184 // both here and in the other conversion routines. See crbug.com/427718.
185 env->GetIntArrayRegion(int_array, 0, len, &(*out)[0]);
[email protected]433461802013-05-22 21:32:27186}
187
fgorski59ab07f32015-08-26 21:06:36188void JavaLongArrayToInt64Vector(JNIEnv* env,
189 jlongArray long_array,
190 std::vector<int64>* out) {
191 DCHECK(out);
192 std::vector<jlong> temp;
193 JavaLongArrayToLongVector(env, long_array, &temp);
194 out->resize(0);
195 out->insert(out->begin(), temp.begin(), temp.end());
196}
197
[email protected]1b9f6bf92014-07-18 22:50:46198void JavaLongArrayToLongVector(JNIEnv* env,
199 jlongArray long_array,
jdduke54720d12015-01-10 01:55:21200 std::vector<jlong>* out) {
[email protected]1b9f6bf92014-07-18 22:50:46201 DCHECK(out);
jdduke54720d12015-01-10 01:55:21202 size_t len = SafeGetArrayLength(env, long_array);
203 out->resize(len);
204 if (!len)
205 return;
206 env->GetLongArrayRegion(long_array, 0, len, &(*out)[0]);
[email protected]1b9f6bf92014-07-18 22:50:46207}
208
[email protected]433461802013-05-22 21:32:27209void JavaFloatArrayToFloatVector(JNIEnv* env,
210 jfloatArray float_array,
211 std::vector<float>* out) {
212 DCHECK(out);
jdduke54720d12015-01-10 01:55:21213 size_t len = SafeGetArrayLength(env, float_array);
214 out->resize(len);
215 if (!len)
216 return;
217 env->GetFloatArrayRegion(float_array, 0, len, &(*out)[0]);
[email protected]30935362012-06-28 21:26:23218}
219
[email protected]65d58352012-12-05 15:00:28220void JavaArrayOfByteArrayToStringVector(
221 JNIEnv* env,
222 jobjectArray array,
223 std::vector<std::string>* out) {
224 DCHECK(out);
jdduke54720d12015-01-10 01:55:21225 size_t len = SafeGetArrayLength(env, array);
[email protected]df0d7142012-12-14 01:31:17226 out->resize(len);
jdduke54720d12015-01-10 01:55:21227 for (size_t i = 0; i < len; ++i) {
[email protected]db45c212014-05-06 17:40:20228 ScopedJavaLocalRef<jbyteArray> bytes_array(
229 env, static_cast<jbyteArray>(
230 env->GetObjectArrayElement(array, i)));
231 jsize bytes_len = env->GetArrayLength(bytes_array.obj());
232 jbyte* bytes = env->GetByteArrayElements(bytes_array.obj(), NULL);
[email protected]df0d7142012-12-14 01:31:17233 (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
[email protected]db45c212014-05-06 17:40:20234 env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
[email protected]65d58352012-12-05 15:00:28235 }
236}
237
[email protected]61c86c62011-08-02 16:11:16238} // namespace android
239} // namespace base