149 lines
4.4 KiB
C++
149 lines
4.4 KiB
C++
|
// 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/scoped_java_ref.h"
|
||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||
|
|
||
|
namespace base {
|
||
|
namespace android {
|
||
|
|
||
|
TEST(JniArray, BasicConversions) {
|
||
|
const uint8 kBytes[] = { 0, 1, 2, 3 };
|
||
|
const size_t kLen = arraysize(kBytes);
|
||
|
JNIEnv* env = AttachCurrentThread();
|
||
|
ScopedJavaLocalRef<jbyteArray> bytes = ToJavaByteArray(env, kBytes, kLen);
|
||
|
ASSERT_TRUE(bytes.obj());
|
||
|
|
||
|
std::vector<uint8> vec(5);
|
||
|
JavaByteArrayToByteVector(env, bytes.obj(), &vec);
|
||
|
EXPECT_EQ(4U, vec.size());
|
||
|
EXPECT_EQ(std::vector<uint8>(kBytes, kBytes + kLen), vec);
|
||
|
|
||
|
AppendJavaByteArrayToByteVector(env, bytes.obj(), &vec);
|
||
|
EXPECT_EQ(8U, vec.size());
|
||
|
}
|
||
|
|
||
|
void CheckLongConversion(
|
||
|
JNIEnv* env,
|
||
|
const int64* long_array,
|
||
|
const size_t len,
|
||
|
const ScopedJavaLocalRef<jlongArray>& longs) {
|
||
|
ASSERT_TRUE(longs.obj());
|
||
|
|
||
|
jsize java_array_len = env->GetArrayLength(longs.obj());
|
||
|
ASSERT_EQ(static_cast<jsize>(len), java_array_len);
|
||
|
|
||
|
jlong value;
|
||
|
for (size_t i = 0; i < len; ++i) {
|
||
|
env->GetLongArrayRegion(longs.obj(), i, 1, &value);
|
||
|
ASSERT_EQ(long_array[i], value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TEST(JniArray, LongConversions) {
|
||
|
const int64 kLongs[] = { 0, 1, -1, kint64min, kint64max};
|
||
|
const size_t kLen = arraysize(kLongs);
|
||
|
|
||
|
JNIEnv* env = AttachCurrentThread();
|
||
|
CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, kLongs, kLen));
|
||
|
|
||
|
const std::vector<int64> vec(kLongs, kLongs + kLen);
|
||
|
CheckLongConversion(env, kLongs, kLen, ToJavaLongArray(env, vec));
|
||
|
}
|
||
|
|
||
|
TEST(JniArray, JavaIntArrayToIntVector) {
|
||
|
const int kInts[] = {0, 1, -1};
|
||
|
const size_t kLen = arraysize(kInts);
|
||
|
|
||
|
JNIEnv* env = AttachCurrentThread();
|
||
|
ScopedJavaLocalRef<jintArray> jints(env, env->NewIntArray(kLen));
|
||
|
ASSERT_TRUE(jints.obj());
|
||
|
|
||
|
for (size_t i = 0; i < kLen; ++i) {
|
||
|
jint j = static_cast<jint>(kInts[i]);
|
||
|
env->SetIntArrayRegion(jints.obj(), i, 1, &j);
|
||
|
ASSERT_FALSE(HasException(env));
|
||
|
}
|
||
|
|
||
|
std::vector<int> ints;
|
||
|
JavaIntArrayToIntVector(env, jints.obj(), &ints);
|
||
|
|
||
|
ASSERT_EQ(static_cast<jsize>(ints.size()), env->GetArrayLength(jints.obj()));
|
||
|
|
||
|
jint value;
|
||
|
for (size_t i = 0; i < kLen; ++i) {
|
||
|
env->GetIntArrayRegion(jints.obj(), i, 1, &value);
|
||
|
ASSERT_EQ(ints[i], value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TEST(JniArray, JavaFloatArrayToFloatVector) {
|
||
|
const float kFloats[] = {0.0, 0.5, -0.5};
|
||
|
const size_t kLen = arraysize(kFloats);
|
||
|
|
||
|
JNIEnv* env = AttachCurrentThread();
|
||
|
ScopedJavaLocalRef<jfloatArray> jfloats(env, env->NewFloatArray(kLen));
|
||
|
ASSERT_TRUE(jfloats.obj());
|
||
|
|
||
|
for (size_t i = 0; i < kLen; ++i) {
|
||
|
jfloat j = static_cast<jfloat>(kFloats[i]);
|
||
|
env->SetFloatArrayRegion(jfloats.obj(), i, 1, &j);
|
||
|
ASSERT_FALSE(HasException(env));
|
||
|
}
|
||
|
|
||
|
std::vector<float> floats;
|
||
|
JavaFloatArrayToFloatVector(env, jfloats.obj(), &floats);
|
||
|
|
||
|
ASSERT_EQ(static_cast<jsize>(floats.size()),
|
||
|
env->GetArrayLength(jfloats.obj()));
|
||
|
|
||
|
jfloat value;
|
||
|
for (size_t i = 0; i < kLen; ++i) {
|
||
|
env->GetFloatArrayRegion(jfloats.obj(), i, 1, &value);
|
||
|
ASSERT_EQ(floats[i], value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TEST(JniArray, JavaArrayOfByteArrayToStringVector) {
|
||
|
const int kMaxItems = 50;
|
||
|
JNIEnv* env = AttachCurrentThread();
|
||
|
|
||
|
// Create a byte[][] object.
|
||
|
ScopedJavaLocalRef<jclass> byte_array_clazz(env, env->FindClass("[B"));
|
||
|
ASSERT_TRUE(byte_array_clazz.obj());
|
||
|
|
||
|
ScopedJavaLocalRef<jobjectArray> array(
|
||
|
env, env->NewObjectArray(kMaxItems, byte_array_clazz.obj(), NULL));
|
||
|
ASSERT_TRUE(array.obj());
|
||
|
|
||
|
// Create kMaxItems byte buffers.
|
||
|
char text[16];
|
||
|
for (int i = 0; i < kMaxItems; ++i) {
|
||
|
snprintf(text, sizeof text, "%d", i);
|
||
|
ScopedJavaLocalRef<jbyteArray> byte_array = ToJavaByteArray(
|
||
|
env, reinterpret_cast<uint8*>(text),
|
||
|
static_cast<size_t>(strlen(text)));
|
||
|
ASSERT_TRUE(byte_array.obj());
|
||
|
|
||
|
env->SetObjectArrayElement(array.obj(), i, byte_array.obj());
|
||
|
ASSERT_FALSE(HasException(env));
|
||
|
}
|
||
|
|
||
|
// Convert to std::vector<std::string>, check the content.
|
||
|
std::vector<std::string> vec;
|
||
|
JavaArrayOfByteArrayToStringVector(env, array.obj(), &vec);
|
||
|
|
||
|
EXPECT_EQ(static_cast<size_t>(kMaxItems), vec.size());
|
||
|
for (int i = 0; i < kMaxItems; ++i) {
|
||
|
snprintf(text, sizeof text, "%d", i);
|
||
|
EXPECT_STREQ(text, vec[i].c_str());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // namespace android
|
||
|
} // namespace base
|