// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/android/jni_array.h" #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/logging.h" namespace base { namespace android { ScopedJavaLocalRef ToJavaByteArray( JNIEnv* env, const uint8* bytes, size_t len) { jbyteArray byte_array = env->NewByteArray(len); CheckException(env); DCHECK(byte_array); jbyte* elements = env->GetByteArrayElements(byte_array, NULL); memcpy(elements, bytes, len); env->ReleaseByteArrayElements(byte_array, elements, 0); CheckException(env); return ScopedJavaLocalRef(env, byte_array); } ScopedJavaLocalRef ToJavaIntArray( JNIEnv* env, const int* ints, size_t len) { jintArray int_array = env->NewIntArray(len); CheckException(env); DCHECK(int_array); jint* elements = env->GetIntArrayElements(int_array, NULL); memcpy(elements, ints, len * sizeof(*ints)); env->ReleaseIntArrayElements(int_array, elements, 0); CheckException(env); return ScopedJavaLocalRef(env, int_array); } ScopedJavaLocalRef ToJavaIntArray( JNIEnv* env, const std::vector& ints) { return ToJavaIntArray(env, ints.begin(), ints.size()); } ScopedJavaLocalRef ToJavaLongArray( JNIEnv* env, const int64* longs, size_t len) { jlongArray long_array = env->NewLongArray(len); CheckException(env); DCHECK(long_array); jlong* elements = env->GetLongArrayElements(long_array, NULL); memcpy(elements, longs, len * sizeof(*longs)); env->ReleaseLongArrayElements(long_array, elements, 0); CheckException(env); return ScopedJavaLocalRef(env, long_array); } // Returns a new Java long array converted from the given int64 array. BASE_EXPORT ScopedJavaLocalRef ToJavaLongArray( JNIEnv* env, const std::vector& longs) { return ToJavaLongArray(env, longs.begin(), longs.size()); } ScopedJavaLocalRef ToJavaArrayOfByteArray( JNIEnv* env, const std::vector& v) { ScopedJavaLocalRef byte_array_clazz = GetClass(env, "[B"); jobjectArray joa = env->NewObjectArray(v.size(), byte_array_clazz.obj(), NULL); CheckException(env); for (size_t i = 0; i < v.size(); ++i) { ScopedJavaLocalRef byte_array = ToJavaByteArray(env, reinterpret_cast(v[i].data()), v[i].length()); env->SetObjectArrayElement(joa, i, byte_array.obj()); } return ScopedJavaLocalRef(env, joa); } ScopedJavaLocalRef ToJavaArrayOfStrings( JNIEnv* env, const std::vector& v) { ScopedJavaLocalRef string_clazz = GetClass(env, "java/lang/String"); jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL); CheckException(env); for (size_t i = 0; i < v.size(); ++i) { ScopedJavaLocalRef item = ConvertUTF8ToJavaString(env, v[i]); env->SetObjectArrayElement(joa, i, item.obj()); } return ScopedJavaLocalRef(env, joa); } ScopedJavaLocalRef ToJavaArrayOfStrings( JNIEnv* env, const std::vector& v) { ScopedJavaLocalRef string_clazz = GetClass(env, "java/lang/String"); jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL); CheckException(env); for (size_t i = 0; i < v.size(); ++i) { ScopedJavaLocalRef item = ConvertUTF16ToJavaString(env, v[i]); env->SetObjectArrayElement(joa, i, item.obj()); } return ScopedJavaLocalRef(env, joa); } void AppendJavaStringArrayToStringVector(JNIEnv* env, jobjectArray array, std::vector* out) { DCHECK(out); if (!array) return; jsize len = env->GetArrayLength(array); size_t back = out->size(); out->resize(back + len); for (jsize i = 0; i < len; ++i) { ScopedJavaLocalRef str(env, static_cast(env->GetObjectArrayElement(array, i))); ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i])); } } void AppendJavaStringArrayToStringVector(JNIEnv* env, jobjectArray array, std::vector* out) { DCHECK(out); if (!array) return; jsize len = env->GetArrayLength(array); size_t back = out->size(); out->resize(back + len); for (jsize i = 0; i < len; ++i) { ScopedJavaLocalRef str(env, static_cast(env->GetObjectArrayElement(array, i))); ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i])); } } void AppendJavaByteArrayToByteVector(JNIEnv* env, jbyteArray byte_array, std::vector* out) { DCHECK(out); if (!byte_array) return; jsize len = env->GetArrayLength(byte_array); jbyte* bytes = env->GetByteArrayElements(byte_array, NULL); out->insert(out->end(), bytes, bytes + len); env->ReleaseByteArrayElements(byte_array, bytes, JNI_ABORT); } void JavaByteArrayToByteVector(JNIEnv* env, jbyteArray byte_array, std::vector* out) { DCHECK(out); out->clear(); AppendJavaByteArrayToByteVector(env, byte_array, out); } void JavaIntArrayToIntVector(JNIEnv* env, jintArray int_array, std::vector* out) { DCHECK(out); out->clear(); jsize len = env->GetArrayLength(int_array); jint* ints = env->GetIntArrayElements(int_array, NULL); for (jsize i = 0; i < len; ++i) { out->push_back(static_cast(ints[i])); } env->ReleaseIntArrayElements(int_array, ints, JNI_ABORT); } void JavaFloatArrayToFloatVector(JNIEnv* env, jfloatArray float_array, std::vector* out) { DCHECK(out); out->clear(); jsize len = env->GetArrayLength(float_array); jfloat* floats = env->GetFloatArrayElements(float_array, NULL); for (jsize i = 0; i < len; ++i) { out->push_back(static_cast(floats[i])); } env->ReleaseFloatArrayElements(float_array, floats, JNI_ABORT); } void JavaArrayOfByteArrayToStringVector( JNIEnv* env, jobjectArray array, std::vector* out) { DCHECK(out); out->clear(); jsize len = env->GetArrayLength(array); out->resize(len); for (jsize i = 0; i < len; ++i) { jbyteArray bytes_array = static_cast( env->GetObjectArrayElement(array, i)); jsize bytes_len = env->GetArrayLength(bytes_array); jbyte* bytes = env->GetByteArrayElements(bytes_array, NULL); (*out)[i].assign(reinterpret_cast(bytes), bytes_len); env->ReleaseByteArrayElements(bytes_array, bytes, JNI_ABORT); } } } // namespace android } // namespace base