Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: base/android/jni_array.cc

Issue 851503003: Update from https://crrev.com/311076 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/android/jni_array.h ('k') | base/android/jni_array_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/android/jni_array.cc
diff --git a/base/android/jni_array.cc b/base/android/jni_array.cc
index 3c064138381d580a12a77062d3d90a5abd21ac32..a1573543d09fe75fb7037b9559a56d7df05d4aae 100644
--- a/base/android/jni_array.cc
+++ b/base/android/jni_array.cc
@@ -10,6 +10,20 @@
namespace base {
namespace android {
+namespace {
+
+// As |GetArrayLength| makes no guarantees about the returned value (e.g., it
+// may be -1 if |array| is not a valid Java array), provide a safe wrapper
+// that always returns a valid, non-negative size.
+template <typename JavaArrayType>
+size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) {
+ DCHECK(jarray);
+ jsize length = env->GetArrayLength(jarray);
+ DCHECK_GE(length, 0) << "Invalid array length: " << length;
+ return static_cast<size_t>(std::max(0, length));
+}
+
+} // namespace
ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
JNIEnv* env, const uint8* bytes, size_t len) {
@@ -108,10 +122,10 @@ void AppendJavaStringArrayToStringVector(JNIEnv* env,
DCHECK(out);
if (!array)
return;
- jsize len = env->GetArrayLength(array);
+ size_t len = SafeGetArrayLength(env, array);
size_t back = out->size();
out->resize(back + len);
- for (jsize i = 0; i < len; ++i) {
+ for (size_t i = 0; i < len; ++i) {
ScopedJavaLocalRef<jstring> str(env,
static_cast<jstring>(env->GetObjectArrayElement(array, i)));
ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i]));
@@ -124,10 +138,10 @@ void AppendJavaStringArrayToStringVector(JNIEnv* env,
DCHECK(out);
if (!array)
return;
- jsize len = env->GetArrayLength(array);
+ size_t len = SafeGetArrayLength(env, array);
size_t back = out->size();
out->resize(back + len);
- for (jsize i = 0; i < len; ++i) {
+ for (size_t i = 0; i < len; ++i) {
ScopedJavaLocalRef<jstring> str(env,
static_cast<jstring>(env->GetObjectArrayElement(array, i)));
ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i]));
@@ -140,16 +154,20 @@ void AppendJavaByteArrayToByteVector(JNIEnv* env,
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);
+ size_t len = SafeGetArrayLength(env, byte_array);
+ if (!len)
+ return;
+ size_t back = out->size();
+ out->resize(back + len);
+ env->GetByteArrayRegion(byte_array, 0, len,
+ reinterpret_cast<int8*>(&(*out)[back]));
}
void JavaByteArrayToByteVector(JNIEnv* env,
jbyteArray byte_array,
std::vector<uint8>* out) {
DCHECK(out);
+ DCHECK(byte_array);
out->clear();
AppendJavaByteArrayToByteVector(env, byte_array, out);
}
@@ -158,39 +176,35 @@ void JavaIntArrayToIntVector(JNIEnv* env,
jintArray int_array,
std::vector<int>* 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<int>(ints[i]));
- }
- env->ReleaseIntArrayElements(int_array, ints, JNI_ABORT);
+ size_t len = SafeGetArrayLength(env, int_array);
+ out->resize(len);
+ if (!len)
+ return;
+ // TODO(jdduke): Use |out->data()| for pointer access after switch to libc++,
+ // both here and in the other conversion routines. See crbug.com/427718.
+ env->GetIntArrayRegion(int_array, 0, len, &(*out)[0]);
}
void JavaLongArrayToLongVector(JNIEnv* env,
jlongArray long_array,
- std::vector<long>* out) {
+ std::vector<jlong>* out) {
DCHECK(out);
- out->clear();
- jsize len = env->GetArrayLength(long_array);
- jlong* longs = env->GetLongArrayElements(long_array, NULL);
- for (jsize i = 0; i < len; ++i) {
- out->push_back(static_cast<long>(longs[i]));
- }
- env->ReleaseLongArrayElements(long_array, longs, JNI_ABORT);
+ size_t len = SafeGetArrayLength(env, long_array);
+ out->resize(len);
+ if (!len)
+ return;
+ env->GetLongArrayRegion(long_array, 0, len, &(*out)[0]);
}
void JavaFloatArrayToFloatVector(JNIEnv* env,
jfloatArray float_array,
std::vector<float>* 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<float>(floats[i]));
- }
- env->ReleaseFloatArrayElements(float_array, floats, JNI_ABORT);
+ size_t len = SafeGetArrayLength(env, float_array);
+ out->resize(len);
+ if (!len)
+ return;
+ env->GetFloatArrayRegion(float_array, 0, len, &(*out)[0]);
}
void JavaArrayOfByteArrayToStringVector(
@@ -198,10 +212,9 @@ void JavaArrayOfByteArrayToStringVector(
jobjectArray array,
std::vector<std::string>* out) {
DCHECK(out);
- out->clear();
- jsize len = env->GetArrayLength(array);
+ size_t len = SafeGetArrayLength(env, array);
out->resize(len);
- for (jsize i = 0; i < len; ++i) {
+ for (size_t i = 0; i < len; ++i) {
ScopedJavaLocalRef<jbyteArray> bytes_array(
env, static_cast<jbyteArray>(
env->GetObjectArrayElement(array, i)));
« no previous file with comments | « base/android/jni_array.h ('k') | base/android/jni_array_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698