[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / base / android / jni_array.cc
blobbc922f883c2f8c296fbbfdd4a2590afc2fb11bc9
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/jni_string.h"
9 #include "base/logging.h"
11 namespace base {
12 namespace android {
13 namespace {
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.
18 template <typename JavaArrayType>
19 size_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));
26 } // namespace
28 ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
29 JNIEnv* env, const uint8* bytes, size_t len) {
30 jbyteArray byte_array = env->NewByteArray(len);
31 CheckException(env);
32 DCHECK(byte_array);
34 env->SetByteArrayRegion(
35 byte_array, 0, len, reinterpret_cast<const jbyte*>(bytes));
36 CheckException(env);
38 return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
41 ScopedJavaLocalRef<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);
47 env->SetIntArrayRegion(
48 int_array, 0, len, reinterpret_cast<const jint*>(ints));
49 CheckException(env);
51 return ScopedJavaLocalRef<jintArray>(env, int_array);
54 ScopedJavaLocalRef<jintArray> ToJavaIntArray(
55 JNIEnv* env, const std::vector<int>& ints) {
56 return ToJavaIntArray(env, ints.data(), ints.size());
59 ScopedJavaLocalRef<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);
65 env->SetLongArrayRegion(
66 long_array, 0, len, reinterpret_cast<const jlong*>(longs));
67 CheckException(env);
69 return ScopedJavaLocalRef<jlongArray>(env, long_array);
72 // Returns a new Java long array converted from the given int64 array.
73 BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
74 JNIEnv* env, const std::vector<int64>& longs) {
75 return ToJavaLongArray(env, longs.data(), longs.size());
78 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
79 JNIEnv* env, const std::vector<std::string>& v) {
80 ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
81 jobjectArray joa = env->NewObjectArray(v.size(),
82 byte_array_clazz.obj(), NULL);
83 CheckException(env);
85 for (size_t i = 0; i < v.size(); ++i) {
86 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(env,
87 reinterpret_cast<const uint8*>(v[i].data()), v[i].length());
88 env->SetObjectArrayElement(joa, i, byte_array.obj());
90 return ScopedJavaLocalRef<jobjectArray>(env, joa);
93 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
94 JNIEnv* env, const std::vector<std::string>& v) {
95 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
96 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
97 CheckException(env);
99 for (size_t i = 0; i < v.size(); ++i) {
100 ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
101 env->SetObjectArrayElement(joa, i, item.obj());
103 return ScopedJavaLocalRef<jobjectArray>(env, joa);
106 ScopedJavaLocalRef<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);
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());
116 return ScopedJavaLocalRef<jobjectArray>(env, joa);
119 void AppendJavaStringArrayToStringVector(JNIEnv* env,
120 jobjectArray array,
121 std::vector<string16>* out) {
122 DCHECK(out);
123 if (!array)
124 return;
125 size_t len = SafeGetArrayLength(env, array);
126 size_t back = out->size();
127 out->resize(back + len);
128 for (size_t i = 0; i < len; ++i) {
129 ScopedJavaLocalRef<jstring> str(env,
130 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
131 ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i]));
135 void AppendJavaStringArrayToStringVector(JNIEnv* env,
136 jobjectArray array,
137 std::vector<std::string>* out) {
138 DCHECK(out);
139 if (!array)
140 return;
141 size_t len = SafeGetArrayLength(env, array);
142 size_t back = out->size();
143 out->resize(back + len);
144 for (size_t i = 0; i < len; ++i) {
145 ScopedJavaLocalRef<jstring> str(env,
146 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
147 ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i]));
151 void AppendJavaByteArrayToByteVector(JNIEnv* env,
152 jbyteArray byte_array,
153 std::vector<uint8>* out) {
154 DCHECK(out);
155 if (!byte_array)
156 return;
157 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]));
166 void JavaByteArrayToByteVector(JNIEnv* env,
167 jbyteArray byte_array,
168 std::vector<uint8>* out) {
169 DCHECK(out);
170 DCHECK(byte_array);
171 out->clear();
172 AppendJavaByteArrayToByteVector(env, byte_array, out);
175 void JavaIntArrayToIntVector(JNIEnv* env,
176 jintArray int_array,
177 std::vector<int>* out) {
178 DCHECK(out);
179 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]);
188 void 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());
198 void JavaLongArrayToLongVector(JNIEnv* env,
199 jlongArray long_array,
200 std::vector<jlong>* out) {
201 DCHECK(out);
202 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]);
209 void JavaFloatArrayToFloatVector(JNIEnv* env,
210 jfloatArray float_array,
211 std::vector<float>* out) {
212 DCHECK(out);
213 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]);
220 void JavaArrayOfByteArrayToStringVector(
221 JNIEnv* env,
222 jobjectArray array,
223 std::vector<std::string>* out) {
224 DCHECK(out);
225 size_t len = SafeGetArrayLength(env, array);
226 out->resize(len);
227 for (size_t i = 0; i < len; ++i) {
228 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);
233 (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
234 env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
238 } // namespace android
239 } // namespace base