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