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