soc.2012.android: 63a95e6b: Added a GHashTable wrapper
michael at soc.pidgin.im
michael at soc.pidgin.im
Mon May 28 11:36:47 EDT 2012
----------------------------------------------------------------------
Revision: 63a95e6b14caf6640ed95c06e144d41e87254adf
Parent: 79066781382574dc91de998f878a699616543c7f
Author: michael at soc.pidgin.im
Date: 05/28/12 10:37:54
Branch: im.pidgin.soc.2012.android
URL: http://d.pidgin.im/viewmtn/revision/info/63a95e6b14caf6640ed95c06e144d41e87254adf
Changelog:
Added a GHashTable wrapper
Changes against parent 79066781382574dc91de998f878a699616543c7f
added android/workspace/im.pidgin.libpurple/native/GHashTableReference.c
added android/workspace/im.pidgin.libpurple/native/helpers.c
added android/workspace/im.pidgin.libpurple/native/helpers.h
added android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTableReference.java
patched android/workspace/im.pidgin.libpurple/native/build.ant
patched android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTable.java
patched android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTableSet.java
-------------- next part --------------
============================================================
--- android/workspace/im.pidgin.libpurple/native/build.ant 2ea0eb20a128370fcb9ebe651fff7c0740fd3e2b
+++ android/workspace/im.pidgin.libpurple/native/build.ant 15c9020c6d45647c25cd3870e1ab2a5107011b03
@@ -49,8 +49,7 @@
<javah classdefinition="im.pidgin.libpurple.core.dns.DnsQueryFailedCallback" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.core.dns.DnsQueryResolvedCallback" to="${javah.out}" />
- <javah classdefinition="im.pidgin.libpurple.glib.GHashTable" to="${javah.out}" />
- <javah classdefinition="im.pidgin.libpurple.glib.GHashTableSet" to="${javah.out}" />
+ <javah classdefinition="im.pidgin.libpurple.glib.GHashTableReference" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.glib.GList" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.glib.GListIterator" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.glib.GSourceFunctionCall" to="${javah.out}" />
============================================================
--- android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTable.java 4caf1f1e4917aad17ca7312d84ca1a6b752a719c
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTable.java fa22407d3720e5f22ff0ef1cf036b065573e3b64
@@ -13,17 +13,23 @@ public class GHashTable<E> extends Abstr
* @param <E>
*/
public class GHashTable<E> extends AbstractMap<String, E> {
+
+ private final GHashTableReference<E> reference;
+ protected GHashTable(GHashTableReference<E> reference) {
+ this.reference = reference;
+ }
+
@Override
public Set<java.util.Map.Entry<String, E>> entrySet() {
- // TODO Auto-generated method stub
- return null;
+ return new GHashTableSet<E>(reference);
}
@Override
public E put(String key, E value) {
- // TODO Auto-generated method stub
- return super.get(key);
+ E old = reference.lookup(key);
+ reference.insert(key, value);
+ return old;
};
@Override
============================================================
--- android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTableSet.java f35ea287bd51a62aa5280f7fc8e1880de1f34e90
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTableSet.java 5aa68190d8291484bde798b16eae77dd565c8557
@@ -6,16 +6,20 @@ public class GHashTableSet<E> extends Ab
public class GHashTableSet<E> extends AbstractSet<Entry<String, E>> {
+ private final GHashTableReference<E> reference;
+
+ protected GHashTableSet(GHashTableReference<E> reference) {
+ this.reference = reference;
+ }
+
@Override
public Iterator<Entry<String, E>> iterator() {
- // TODO Auto-generated method stub
- return null;
+ return new GHashTableIterator<E>(reference);
}
@Override
public int size() {
- // TODO Auto-generated method stub
- return 0;
+ return reference.size();
}
}
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/GHashTableReference.c 338689a17d007f7e9ed4eede1ffea9953af71f5a
@@ -0,0 +1,147 @@
+#include <jni.h>
+
+#include "GHashTableReference.h"
+#include "helpers.h"
+#include <glib.h>
+
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: size_native
+ * Signature: ()I
+ */JNIEXPORT jint JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_size_1native(JNIEnv *env,
+ jobject javatable)
+{
+ GHashTable *table;
+
+ table = (GHashTable*) getNativePointer(env, javatable);
+ g_return_val_if_fail(table != NULL, 0);
+
+ return (jint) g_hash_table_size(table);
+}
+
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: insert_native
+ * Signature: (Ljava/lang/String;J)V
+ */JNIEXPORT void JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_insert_1native(JNIEnv *env,
+ jobject javatable, jstring key, jlong value)
+{
+ const char* keystring;
+ GHashTable *table;
+
+ table = (GHashTable*) getNativePointer(env, javatable);
+ g_return_if_fail(table != NULL);
+
+ keystring = (*env)->GetStringUTFChars(env, key, NULL);
+ g_return_if_fail(keystring != NULL);
+
+ if (value == 0) {
+ g_hash_table_remove(table, keystring);
+ } else {
+ g_hash_table_insert(table, (gpointer) keystring, longToP(value));
+ }
+
+ (*env)->ReleaseStringUTFChars(env, key, keystring);
+}
+
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: lookup_native
+ * Signature: (Ljava/lang/String;)J
+ */JNIEXPORT jlong JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_lookup_1native(JNIEnv *env,
+ jobject javatable, jstring key)
+{
+ const char* keystring;
+ GHashTable *table;
+
+ table = (GHashTable*) getNativePointer(env, javatable);
+ g_return_val_if_fail(table != NULL, 0);
+
+ keystring = (*env)->GetStringUTFChars(env, key, NULL);
+ g_return_val_if_fail(keystring != NULL, 0);
+
+ void *value = g_hash_table_lookup(table, keystring);
+
+ (*env)->ReleaseStringUTFChars(env, key, keystring);
+ return pToLong(value);
+}
+
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: getIterator_native
+ * Signature: ()J
+ */JNIEXPORT jlong JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_getIterator_1native(
+ JNIEnv *env, jobject javatable)
+{
+ GHashTable *table;
+ GHashTableIter* iter;
+
+ table = (GHashTable*) getNativePointer(env, javatable);
+ g_return_val_if_fail(table != NULL, 0);
+
+ iter = g_new(GHashTableIter, 1);
+ g_return_val_if_fail(iter != NULL, 0);
+
+ g_hash_table_iter_init(iter, table);
+
+ return pToLong(iter);
+}
+
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: freeIterator_native
+ * Signature: (J)V
+ */JNIEXPORT void JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_freeIterator_1native(
+ JNIEnv *env, jobject javatable, jlong it)
+{
+ GHashTableIter *iter;
+
+ iter = (GHashTableIter*) longToP(it);
+ free(iter);
+}
+/*
+ * Class: im_pidgin_libpurple_glib_GHashTableReference
+ * Method: next_native
+ * Signature: (J)Z
+ */JNIEXPORT jboolean JNICALL
+Java_im_pidgin_libpurple_glib_GHashTableReference_next_1native(JNIEnv *env,
+ jobject javatable, jlong it)
+{
+ GHashTableIter *iter;
+ static jfieldID keyFieldId = NULL;
+ static jfieldID valueFieldId = NULL;
+ jstring keyString;
+
+ if (valueFieldId == NULL) {
+ jclass cls = (*env)->GetObjectClass(env, javatable);
+ keyFieldId = (*env)->GetFieldID(env, cls, "iteratorKey",
+ "Ljava/lang/String;");
+ g_return_val_if_fail(keyFieldId != NULL, JNI_FALSE);
+ valueFieldId = (*env)->GetFieldID(env, cls, "iteratorValue", "J");
+ g_return_val_if_fail(valueFieldId != NULL, JNI_FALSE);
+ }
+
+ iter = (GHashTableIter*) longToP(it);
+
+ gpointer key;
+ gpointer value;
+
+ gboolean success = g_hash_table_iter_next(iter, &key, &value);
+
+ if (success) {
+ keyString =(*env)->NewStringUTF(env, (char*) key);
+ g_return_val_if_fail(keyString != NULL, JNI_FALSE);
+
+ (*env)->SetObjectField(env, javatable, keyFieldId, keyString);
+ (*env)->SetLongField(env, javatable, valueFieldId, pToLong(value));
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/helpers.c c1dc99a68d168d1466e477595ea135683a96bbd8
@@ -0,0 +1,56 @@
+/*
+ * helpers.h
+ *
+ * Some helper utilities that ease access to given elements.
+ *
+ * Contains methods to access peered objects, and initialize jni contexts.
+ *
+ * Created on: 28.05.2012
+ * Author: michaelz
+ */
+
+#include "helpers.h"
+
+gboolean setJavaObject(JavaObjectReference *ref, JNIEnv *env, jobject object) {
+ g_return_val_if_fail(env != NULL, FALSE);
+ g_return_val_if_fail(object != NULL, FALSE);
+
+ JavaVM *jvm;
+ jint success = (*env)->GetJavaVM(env, &jvm);
+ if (success != 0) {
+ return FALSE;
+ }
+
+ jclass localClass = (*env)->GetObjectClass(env, object);
+ if (localClass == NULL) {
+ return FALSE;
+ }
+
+ ref->class = (*env)->NewGlobalRef(env, localClass);
+ ref->handlerObject = object;
+ ref->jvm = jvm;
+ (*env)->DeleteLocalRef(env, localClass);
+
+ return TRUE;
+}
+
+/**
+ * Gets the peer field of an object of the peer class.
+ */
+void *getNativePointer(JNIEnv *env, jobject peered) {
+ static jfieldID peerField = NULL;
+
+ if (peerField == NULL) {
+ jclass class = (*env)->FindClass(env,
+ "im/pidgin/libpurple/peering/Peered");
+ if (class == NULL) {
+ return NULL;
+ }
+ (*env)->GetFieldID(env, class, "nativePointer", "J");
+ if (peerField == NULL) {
+ return NULL;
+ }
+ }
+
+ return longToP((*env)->GetLongField(env, peered, peerField));
+}
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/helpers.h da8cd3d604a44e4eb7258380b02a8bf8ef1cc1f8
@@ -0,0 +1,61 @@
+/*
+ * helpers.h
+ *
+ * Created on: 28.05.2012
+ * Author: michaelz
+ */
+
+#ifndef HELPERS_H_
+#define HELPERS_H_
+#include <glib.h>
+#include <jni.h>
+
+/**
+ * Converts a pointer to a java long
+ */
+#define pToLong(arg) ((jlong) ((intptr_t) (arg)))
+/**
+ * Converts a java long to a void*
+ */
+#define longToP(arg) ((void*) ((intptr_t) (arg)))
+
+/**
+ * To be removed when glib logging works.
+ */
+#include <android/log.h>
+#define DEBUG(...) __android_log_print(ANDROID_LOG_DEBUG, "char/jni", __VA_ARGS__);
+
+/**
+ * A definition of an object for callbacks.
+ */
+typedef struct {
+ jobject handlerObject;
+ JavaVM *jvm;
+ jclass class;
+} JavaObjectReference;
+
+#define JAVA_NULL_OBJECT_REF { NULL, NULL, NULL }
+
+/**
+ * Checks the jvm context, adds the *env-Variable that points to the java enviroment.
+ * If it fails, just logs the error and calls return.
+ */
+#define CALLBACK_START_VOID(context) CALLBACK_START(context, )
+
+/**
+ * Same as CALLBACK_START_VOID, but returns a value.
+ */
+#define CALLBACK_START(context, failval) \
+ JNIEnv *env; \
+ if (context.jvm == NULL || context.handlerObject == NULL || (*context.jvm)->GetEnv(context.jvm, (void**)&env, JNI_VERSION_1_2) == JNI_EDETACHED) {\
+ __android_log_print(ANDROID_LOG_DEBUG, "jni",\
+ "Error: No callback object registered or in wrong thread");\
+ return failval;\
+ }
+
+
+gboolean setJavaObject(JavaObjectReference *ref, JNIEnv *env, jobject object);
+
+void *getNativePointer(JNIEnv *env, jobject peered);
+
+#endif /* HELPERS_H_ */
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/glib/GHashTableReference.java ac930045bc8ff17c3e1e89a1ec8f0cb84e64a678
@@ -0,0 +1,83 @@
+package im.pidgin.libpurple.glib;
+
+import im.pidgin.libpurple.peering.PeerGenerator;
+import im.pidgin.libpurple.peering.Peered;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Map.Entry;
+
+public final class GHashTableReference<E> extends Peered {
+
+ private final PeerGenerator<E> peerGenerator;
+
+ protected GHashTableReference(long nativePointer, PeerGenerator<E> peerGenerator) {
+ super(nativePointer);
+ this.peerGenerator = peerGenerator;
+ }
+
+ public synchronized int size() {
+ ensureNotDestroyed();
+ return size_native();
+ }
+
+ private native int size_native();
+
+ public synchronized void insert(String key, E value) {
+ if (key == null || value == null) {
+ throw new NullPointerException();
+ }
+ ensureNotDestroyed();
+ insert_native(key, peerGenerator.getPeer(value));
+ }
+
+ private native void insert_native(String key, long value);
+
+ public synchronized E lookup(String key) {
+ if (key == null) {
+ throw new NullPointerException();
+ }
+ ensureNotDestroyed();
+ return peerGenerator.getPeer(lookup_native(key));
+ }
+
+ private native long lookup_native(String key);
+
+
+ public synchronized void remove(String key) {
+ ensureNotDestroyed();
+ insert_native(key, 0);
+ }
+
+
+ public synchronized long getIterator() {
+ ensureNotDestroyed();
+ return getIterator_native();
+ }
+
+
+ private native long getIterator_native();
+
+ public synchronized void freeIterator(long it) {
+ ensureNotDestroyed();
+ freeIterator_native(it);
+ }
+
+
+ private native void freeIterator_native(long it);
+
+ private String iteratorKey;
+ private long iteratorValue;
+
+ public synchronized Entry<String, E> next(long it) {
+ ensureNotDestroyed();
+ if (next_native(it)) {
+ return new SimpleImmutableEntry<String, E>(iteratorKey, peerGenerator.getPeer(iteratorValue));
+ } else {
+ return null;
+ }
+ }
+
+ private native boolean next_native(long it);
+
+
+}
More information about the Commits
mailing list