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.
4
5 #include "base/android/jni_array.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/logging.h"
10
11 namespace base {
12 namespace android {
13
ToJavaByteArray(JNIEnv * env,const uint8 * bytes,size_t len)14 ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
15 JNIEnv* env, const uint8* bytes, size_t len) {
16 jbyteArray byte_array = env->NewByteArray(len);
17 CheckException(env);
18 DCHECK(byte_array);
19
20 jbyte* elements = env->GetByteArrayElements(byte_array, NULL);
21 memcpy(elements, bytes, len);
22 env->ReleaseByteArrayElements(byte_array, elements, 0);
23 CheckException(env);
24
25 return ScopedJavaLocalRef<jbyteArray>(env, byte_array);
26 }
27
ToJavaIntArray(JNIEnv * env,const int * ints,size_t len)28 ScopedJavaLocalRef<jintArray> ToJavaIntArray(
29 JNIEnv* env, const int* ints, size_t len) {
30 jintArray int_array = env->NewIntArray(len);
31 CheckException(env);
32 DCHECK(int_array);
33
34 jint* elements = env->GetIntArrayElements(int_array, NULL);
35 memcpy(elements, ints, len * sizeof(*ints));
36 env->ReleaseIntArrayElements(int_array, elements, 0);
37 CheckException(env);
38
39 return ScopedJavaLocalRef<jintArray>(env, int_array);
40 }
41
ToJavaIntArray(JNIEnv * env,const std::vector<int> & ints)42 ScopedJavaLocalRef<jintArray> ToJavaIntArray(
43 JNIEnv* env, const std::vector<int>& ints) {
44 return ToJavaIntArray(env, ints.begin(), ints.size());
45 }
46
ToJavaLongArray(JNIEnv * env,const int64 * longs,size_t len)47 ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
48 JNIEnv* env, const int64* longs, size_t len) {
49 jlongArray long_array = env->NewLongArray(len);
50 CheckException(env);
51 DCHECK(long_array);
52
53 jlong* elements = env->GetLongArrayElements(long_array, NULL);
54 memcpy(elements, longs, len * sizeof(*longs));
55 env->ReleaseLongArrayElements(long_array, elements, 0);
56 CheckException(env);
57
58 return ScopedJavaLocalRef<jlongArray>(env, long_array);
59 }
60
61 // Returns a new Java long array converted from the given int64 array.
ToJavaLongArray(JNIEnv * env,const std::vector<int64> & longs)62 BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(
63 JNIEnv* env, const std::vector<int64>& longs) {
64 return ToJavaLongArray(env, longs.begin(), longs.size());
65 }
66
ToJavaArrayOfByteArray(JNIEnv * env,const std::vector<std::string> & v)67 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray(
68 JNIEnv* env, const std::vector<std::string>& v) {
69 ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B");
70 jobjectArray joa = env->NewObjectArray(v.size(),
71 byte_array_clazz.obj(), NULL);
72 CheckException(env);
73
74 for (size_t i = 0; i < v.size(); ++i) {
75 ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(env,
76 reinterpret_cast<const uint8*>(v[i].data()), v[i].length());
77 env->SetObjectArrayElement(joa, i, byte_array.obj());
78 }
79 return ScopedJavaLocalRef<jobjectArray>(env, joa);
80 }
81
ToJavaArrayOfStrings(JNIEnv * env,const std::vector<std::string> & v)82 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
83 JNIEnv* env, const std::vector<std::string>& v) {
84 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
85 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
86 CheckException(env);
87
88 for (size_t i = 0; i < v.size(); ++i) {
89 ScopedJavaLocalRef<jstring> item = ConvertUTF8ToJavaString(env, v[i]);
90 env->SetObjectArrayElement(joa, i, item.obj());
91 }
92 return ScopedJavaLocalRef<jobjectArray>(env, joa);
93 }
94
ToJavaArrayOfStrings(JNIEnv * env,const std::vector<string16> & v)95 ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings(
96 JNIEnv* env, const std::vector<string16>& v) {
97 ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String");
98 jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL);
99 CheckException(env);
100
101 for (size_t i = 0; i < v.size(); ++i) {
102 ScopedJavaLocalRef<jstring> item = ConvertUTF16ToJavaString(env, v[i]);
103 env->SetObjectArrayElement(joa, i, item.obj());
104 }
105 return ScopedJavaLocalRef<jobjectArray>(env, joa);
106 }
107
AppendJavaStringArrayToStringVector(JNIEnv * env,jobjectArray array,std::vector<string16> * out)108 void AppendJavaStringArrayToStringVector(JNIEnv* env,
109 jobjectArray array,
110 std::vector<string16>* out) {
111 DCHECK(out);
112 if (!array)
113 return;
114 jsize len = env->GetArrayLength(array);
115 size_t back = out->size();
116 out->resize(back + len);
117 for (jsize i = 0; i < len; ++i) {
118 ScopedJavaLocalRef<jstring> str(env,
119 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
120 ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i]));
121 }
122 }
123
AppendJavaStringArrayToStringVector(JNIEnv * env,jobjectArray array,std::vector<std::string> * out)124 void AppendJavaStringArrayToStringVector(JNIEnv* env,
125 jobjectArray array,
126 std::vector<std::string>* out) {
127 DCHECK(out);
128 if (!array)
129 return;
130 jsize len = env->GetArrayLength(array);
131 size_t back = out->size();
132 out->resize(back + len);
133 for (jsize i = 0; i < len; ++i) {
134 ScopedJavaLocalRef<jstring> str(env,
135 static_cast<jstring>(env->GetObjectArrayElement(array, i)));
136 ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i]));
137 }
138 }
139
AppendJavaByteArrayToByteVector(JNIEnv * env,jbyteArray byte_array,std::vector<uint8> * out)140 void AppendJavaByteArrayToByteVector(JNIEnv* env,
141 jbyteArray byte_array,
142 std::vector<uint8>* out) {
143 DCHECK(out);
144 if (!byte_array)
145 return;
146 jsize len = env->GetArrayLength(byte_array);
147 jbyte* bytes = env->GetByteArrayElements(byte_array, NULL);
148 out->insert(out->end(), bytes, bytes + len);
149 env->ReleaseByteArrayElements(byte_array, bytes, JNI_ABORT);
150 }
151
JavaByteArrayToByteVector(JNIEnv * env,jbyteArray byte_array,std::vector<uint8> * out)152 void JavaByteArrayToByteVector(JNIEnv* env,
153 jbyteArray byte_array,
154 std::vector<uint8>* out) {
155 DCHECK(out);
156 out->clear();
157 AppendJavaByteArrayToByteVector(env, byte_array, out);
158 }
159
JavaIntArrayToIntVector(JNIEnv * env,jintArray int_array,std::vector<int> * out)160 void JavaIntArrayToIntVector(JNIEnv* env,
161 jintArray int_array,
162 std::vector<int>* out) {
163 DCHECK(out);
164 out->clear();
165 jsize len = env->GetArrayLength(int_array);
166 jint* ints = env->GetIntArrayElements(int_array, NULL);
167 for (jsize i = 0; i < len; ++i) {
168 out->push_back(static_cast<int>(ints[i]));
169 }
170 env->ReleaseIntArrayElements(int_array, ints, JNI_ABORT);
171 }
172
JavaFloatArrayToFloatVector(JNIEnv * env,jfloatArray float_array,std::vector<float> * out)173 void JavaFloatArrayToFloatVector(JNIEnv* env,
174 jfloatArray float_array,
175 std::vector<float>* out) {
176 DCHECK(out);
177 out->clear();
178 jsize len = env->GetArrayLength(float_array);
179 jfloat* floats = env->GetFloatArrayElements(float_array, NULL);
180 for (jsize i = 0; i < len; ++i) {
181 out->push_back(static_cast<float>(floats[i]));
182 }
183 env->ReleaseFloatArrayElements(float_array, floats, JNI_ABORT);
184 }
185
JavaArrayOfByteArrayToStringVector(JNIEnv * env,jobjectArray array,std::vector<std::string> * out)186 void JavaArrayOfByteArrayToStringVector(
187 JNIEnv* env,
188 jobjectArray array,
189 std::vector<std::string>* out) {
190 DCHECK(out);
191 out->clear();
192 jsize len = env->GetArrayLength(array);
193 out->resize(len);
194 for (jsize i = 0; i < len; ++i) {
195 jbyteArray bytes_array = static_cast<jbyteArray>(
196 env->GetObjectArrayElement(array, i));
197 jsize bytes_len = env->GetArrayLength(bytes_array);
198 jbyte* bytes = env->GetByteArrayElements(bytes_array, NULL);
199 (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
200 env->ReleaseByteArrayElements(bytes_array, bytes, JNI_ABORT);
201 }
202 }
203
204 } // namespace android
205 } // namespace base
206