Index: base/android/jni_map.cc |
diff --git a/base/android/jni_map.cc b/base/android/jni_map.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cda9a385d3798da6fd069ef060998ea42aa7ff4a |
--- /dev/null |
+++ b/base/android/jni_map.cc |
@@ -0,0 +1,104 @@ |
+// Copyright (c) 2013 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_map.h" |
+ |
+#include <map> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/jni_string.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/logging.h" |
+ |
+namespace base { |
+namespace android { |
+ |
+// Converts a std::map<std::string, string16> to a java HashMap<String,String>. |
nyquist
2013/02/20 07:33:09
Nit: insert space between Java generics types.
Yaron
2013/02/21 21:39:15
Done.
|
+ScopedJavaLocalRef<jobject> ConvertMapToJavaMap( |
+ JNIEnv* env, |
+ const std::map<std::string, string16>& cmap) { |
+ ScopedJavaLocalRef<jclass> map_clazz = GetClass(env, "java/util/HashMap"); |
bulach
2013/02/20 14:41:25
a kitten has died.... :D
any chance of generating
Yaron
2013/02/21 21:39:15
That seems suboptimal to me. I feel like what you'
|
+ jmethodID map_constructor = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, map_clazz.obj(), "<init>", "()V"); |
+ jmethodID map_put = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, map_clazz.obj(), "put", |
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); |
+ |
+ jobject jmap = env->NewObject(map_clazz.obj(), map_constructor); |
+ DCHECK(jmap); |
+ CheckException(env); |
+ |
+ for (std::map<std::string, string16>::const_iterator i = cmap.begin(); |
+ i != cmap.end(); i++) { |
+ ScopedJavaLocalRef<jstring> key = ConvertUTF8ToJavaString(env, i->first); |
+ ScopedJavaLocalRef<jstring> value = ConvertUTF16ToJavaString(env, |
+ i->second); |
+ // Assign the result to a ScopedJavaLocalRef so we don't leak the local ref. |
+ ScopedJavaLocalRef<jobject> result(env, |
+ env->CallObjectMethod(jmap, map_put, key.obj(), value.obj())); |
+ CheckException(env); |
+ } |
+ return ScopedJavaLocalRef<jobject>(env, jmap); |
+} |
+ |
+std::map<std::string, string16> ConvertJavaMapToMap(JNIEnv* env, |
+ jobject jmap) { |
+ std::map<std::string, string16> cmap; |
+ |
+ // Get a Set of all items. |
+ ScopedJavaLocalRef<jclass> map_clazz = GetClass(env, "java/util/HashMap"); |
+ jmethodID map_entryset = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, map_clazz.obj(), "entrySet", "()Ljava/util/Set;"); |
+ ScopedJavaLocalRef<jobject> jset(env, |
+ env->CallObjectMethod(jmap, map_entryset)); |
+ DCHECK(!jset.is_null()); |
+ CheckException(env); |
+ |
+ // Get an iterator for this set. |
+ ScopedJavaLocalRef<jclass> set_clazz = GetClass(env, "java/util/Set"); |
+ jmethodID set_iterator = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, set_clazz.obj(), "iterator", "()Ljava/util/Iterator;"); |
+ ScopedJavaLocalRef<jobject> iter(env, |
+ env->CallObjectMethod(jset.obj(), set_iterator)); |
+ DCHECK(!iter.is_null()); |
+ CheckException(env); |
+ |
+ // Loop over them. |
nyquist
2013/02/20 07:33:09
Nit: Technically you don't start looping yet, you'
Yaron
2013/02/21 21:39:15
Dropped most comments as with bindings, the readab
|
+ ScopedJavaLocalRef<jclass> iter_clazz = GetClass(env, "java/util/Iterator"); |
+ jmethodID iter_hasnext = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, iter_clazz.obj(), "hasNext", "()Z"); |
+ jmethodID iter_next = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, iter_clazz.obj(), "next", "()Ljava/lang/Object;"); |
+ |
+ ScopedJavaLocalRef<jclass> map_entry_clazz = |
+ GetClass(env, "java/util/Map$Entry"); |
+ jmethodID map_entry_getkey = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, map_entry_clazz.obj(), "getKey", "()Ljava/lang/Object;"); |
+ jmethodID map_entry_getvalue = MethodID::Get<MethodID::TYPE_INSTANCE>( |
+ env, map_entry_clazz.obj(), "getValue", "()Ljava/lang/Object;"); |
+ |
+ // Dump items into a std::map. |
+ while (env->CallBooleanMethod(iter.obj(), iter_hasnext)) { |
+ CheckException(env); |
+ ScopedJavaLocalRef<jobject> map_entry(env, |
+ env->CallObjectMethod(iter.obj(), iter_next)); |
+ DCHECK(env->IsInstanceOf(map_entry.obj(), map_entry_clazz.obj())); |
+ ScopedJavaLocalRef<jstring> jkey(env, |
+ static_cast<jstring>(env->CallObjectMethod(map_entry.obj(), |
+ map_entry_getkey))); |
+ ScopedJavaLocalRef<jstring> jvalue(env, |
+ static_cast<jstring>(env->CallObjectMethod(map_entry.obj(), |
+ map_entry_getvalue))); |
+ // For profiles, jvalue can be null if not found in the contacts database. |
nyquist
2013/02/20 07:33:09
Which contacts database? What does this have to do
Yaron
2013/02/21 21:39:15
dropped. Copied costant from the original implemen
|
+ if (!jkey.is_null() && !jvalue.is_null() && |
+ env->GetStringLength(jvalue.obj())) { |
+ cmap[ConvertJavaStringToUTF8(jkey)] = ConvertJavaStringToUTF16(jvalue); |
+ } |
+ } |
+ return cmap; |
+} |
+ |
+ |
+} // namespace android |
+} // namespace base |