[gjs] Add support for converting GHashTable return values/out parameters.
- From: Havoc Pennington <hp src gnome org>
- To: svn-commits-list gnome org
- Subject: [gjs] Add support for converting GHashTable return values/out parameters.
- Date: Wed, 13 May 2009 19:21:47 -0400 (EDT)
commit 4ed31d7d8b3f7d1a8e089d9704d0a3f68638bda5
Author: C. Scott Ananian <cscott litl com>
Date: Thu Apr 30 15:32:41 2009 -0400
Add support for converting GHashTable return values/out parameters.
---
gi/arg.c | 108 ++++++++++++++++++++++++++++++++++++++++
test/js/testEverythingBasic.js | 16 ++++++
2 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/gi/arg.c b/gi/arg.c
index 8418dab..4532707 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -969,6 +969,83 @@ gjs_array_from_g_list (JSContext *context,
return result;
}
+static JSBool
+gjs_object_from_g_hash (JSContext *context,
+ jsval *value_p,
+ GITypeInfo *key_param_info,
+ GITypeInfo *val_param_info,
+ GHashTable *hash)
+{
+ GHashTableIter iter;
+ JSObject *obj;
+ JSString *keystr;
+ char *keyutf8 = NULL;
+ jsval keyjs, valjs;
+ GArgument keyarg, valarg;
+ JSBool result;
+
+ // a NULL hash table becomes a null JS value
+ if (hash==NULL) {
+ *value_p = JSVAL_NULL;
+ return JS_TRUE;
+ }
+
+ obj = JS_NewObject(context, NULL, NULL, NULL);
+ if (obj == NULL)
+ return JS_FALSE;
+
+ *value_p = OBJECT_TO_JSVAL(obj);
+ JS_AddRoot(context, &obj);
+
+ keyjs = JSVAL_VOID;
+ JS_AddRoot(context, &keyjs);
+
+ valjs = JSVAL_VOID;
+ JS_AddRoot(context, &valjs);
+
+ keystr = NULL;
+ JS_AddRoot(context, &keystr);
+
+ result = JS_FALSE;
+
+ g_hash_table_iter_init(&iter, hash);
+ while (g_hash_table_iter_next
+ (&iter, &keyarg.v_pointer, &valarg.v_pointer)) {
+ if (!gjs_value_from_g_argument(context, &keyjs,
+ key_param_info, &keyarg))
+ goto out;
+
+ keystr = JS_ValueToString(context, keyjs);
+ if (!keystr)
+ goto out;
+
+ if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(keystr), &keyutf8))
+ goto out;
+
+ if (!gjs_value_from_g_argument(context, &valjs,
+ val_param_info, &valarg))
+ goto out;
+
+ if (!JS_DefineProperty(context, obj, keyutf8, valjs,
+ NULL, NULL, JSPROP_ENUMERATE))
+ goto out;
+
+ g_free(keyutf8);
+ keyutf8 = NULL;
+ }
+
+ result = JS_TRUE;
+
+ out:
+ if (keyutf8) g_free(keyutf8);
+ JS_RemoveRoot(context, &obj);
+ JS_RemoveRoot(context, &keyjs);
+ JS_RemoveRoot(context, &valjs);
+ JS_RemoveRoot(context, &keystr);
+
+ return result;
+}
+
JSBool
gjs_value_from_g_argument (JSContext *context,
jsval *value_p,
@@ -1193,6 +1270,29 @@ gjs_value_from_g_argument (JSContext *context,
}
break;
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_param_info, *val_param_info;
+ gboolean result;
+
+ key_param_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(key_param_info != NULL);
+ val_param_info = g_type_info_get_param_type(type_info, 1);
+ g_assert(val_param_info != NULL);
+
+ result = gjs_object_from_g_hash(context,
+ value_p,
+ key_param_info,
+ val_param_info,
+ arg->v_pointer);
+
+ g_base_info_unref((GIBaseInfo*) key_param_info);
+ g_base_info_unref((GIBaseInfo*) val_param_info);
+
+ return result;
+ }
+ break;
+
case GI_TYPE_TAG_INT:
case GI_TYPE_TAG_UINT:
case GI_TYPE_TAG_LONG:
@@ -1399,6 +1499,14 @@ gjs_g_arg_release_internal(JSContext *context,
g_slist_free(arg->v_pointer);
break;
+ case GI_TYPE_TAG_GHASH:
+ // Note that we depend on the GHashTable's destroy functions to
+ // match the transfer mode. If you don't want the keys and
+ // values freed, the GHashTable should have null key/value
+ // destroy functions. Otherwise everything is released together.
+ g_hash_table_destroy(arg->v_pointer);
+ break;
+
default:
gjs_debug(GJS_DEBUG_ERROR,
"Unhandled type %s releasing GArgument",
diff --git a/test/js/testEverythingBasic.js b/test/js/testEverythingBasic.js
index 5f69b2f..67c396a 100644
--- a/test/js/testEverythingBasic.js
+++ b/test/js/testEverythingBasic.js
@@ -227,6 +227,22 @@ function testArrayOut() {
// FIXME: test_array_int_full_out and test_array_int_none_out unimplemented
}
+/* GHash type */
+function testGHashOut() {
+ const HASH_STR = '({foo:"bar", baz:"bat", qux:"quux"})';
+ assertEquals(null, Everything.test_ghash_null_return());
+ assertEquals(HASH_STR, Everything.test_ghash_nothing_return().toSource());
+ assertEquals(HASH_STR, Everything.test_ghash_nothing_return2().toSource());
+ assertEquals(HASH_STR, Everything.test_ghash_container_return().toSource());
+ assertEquals(HASH_STR, Everything.test_ghash_everything_return().toSource());
+}
+
+function testNestedGHashOut() {
+ const HASH_STR = '({wibble:{foo:"bar", baz:"bat", qux:"quux"}})';
+ assertEquals(HASH_STR, Everything.test_ghash_nested_everything_return().toSource());
+ assertEquals(HASH_STR, Everything.test_ghash_nested_everything_return2().toSource());
+}
+
/* Enums */
function testEnumParam() {
let e = Everything.test_enum_param(Everything.TestEnum.VALUE1);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]