[gjs] Support null terminated C arrays of any type
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Support null terminated C arrays of any type
- Date: Fri, 13 May 2011 15:48:36 +0000 (UTC)
commit 23c687db514bcf4a22d250ecdcbf3c3847c109c6
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sun Nov 7 22:59:54 2010 +0100
Support null terminated C arrays of any type
Before, only string arrays (GStrv) were supported.
Now C arrays can be converted to JS arrays regardless of their
type.
https://bugzilla.gnome.org/show_bug.cgi?id=634253
gi/arg.c | 130 +++++++++++++++++++++++++++++++++++++++---
test/js/testGIMarshalling.js | 15 +++++
2 files changed, 137 insertions(+), 8 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index bceb4d4..ebebbf7 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -1698,6 +1698,100 @@ finally:
}
static JSBool
+gjs_array_from_zero_terminated_c_array (JSContext *context,
+ jsval *value_p,
+ GITypeInfo *param_info,
+ gpointer c_array)
+{
+ JSObject *obj;
+ jsval elem;
+ GArgument arg;
+ JSBool result;
+ GITypeTag element_type;
+ guint i;
+
+ element_type = g_type_info_get_tag(param_info);
+ element_type = replace_gtype(element_type);
+
+ obj = JS_NewArrayObject(context, 0, NULL);
+ if (obj == NULL)
+ return JS_FALSE;
+
+ *value_p = OBJECT_TO_JSVAL(obj);
+
+ elem = JSVAL_VOID;
+ JS_AddValueRoot(context, &elem);
+
+#define ITERATE(type) \
+ do { \
+ g##type *array = c_array; \
+ for (i = 0; array[i]; i++) { \
+ arg.v_##type = array[i]; \
+ if (!gjs_value_from_g_argument(context, &elem, param_info, &arg)) \
+ goto finally; \
+ if (!JS_DefineElement(context, obj, i, elem, NULL, NULL, \
+ JSPROP_ENUMERATE)) \
+ goto finally; \
+ } \
+ } while(0);
+
+ switch (element_type) {
+ case GI_TYPE_TAG_UINT8:
+ ITERATE(uint8);
+ break;
+ case GI_TYPE_TAG_INT8:
+ ITERATE(int8);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ ITERATE(uint16);
+ break;
+ case GI_TYPE_TAG_INT16:
+ ITERATE(int16);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ ITERATE(uint32);
+ break;
+ case GI_TYPE_TAG_INT32:
+ ITERATE(int32);
+ break;
+ case GI_TYPE_TAG_UINT64:
+ ITERATE(uint64);
+ break;
+ case GI_TYPE_TAG_INT64:
+ ITERATE(int64);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ ITERATE(float);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ ITERATE(double);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ ITERATE(pointer);
+ break;
+ default:
+ gjs_throw(context, "Unknown element-type %d", element_type);
+ goto finally;
+ }
+
+#undef ITERATE
+
+ result = JS_TRUE;
+
+finally:
+ JS_RemoveValueRoot(context, &elem);
+
+ return result;
+}
+
+
+static JSBool
gjs_object_from_g_hash (JSContext *context,
jsval *value_p,
GITypeInfo *key_param_info,
@@ -1998,14 +2092,10 @@ gjs_value_from_g_argument (JSContext *context,
param_tag = g_type_info_get_tag((GITypeInfo*) param_info);
- if (param_tag == GI_TYPE_TAG_UTF8) {
- result = gjs_array_from_strv(context,
- value_p,
- arg->v_pointer);
- } else {
- gjs_throw(context, "FIXME: Only supporting null-terminated arrays of strings");
- result = FALSE;
- }
+ result = gjs_array_from_zero_terminated_c_array(context,
+ value_p,
+ param_info,
+ arg->v_pointer);
g_base_info_unref((GIBaseInfo*) param_info);
@@ -2292,6 +2382,30 @@ gjs_g_arg_release_internal(JSContext *context,
g_free (arg->v_pointer);
break;
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GHASH:
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ g_assert (g_type_info_is_zero_terminated (type_info));
+ gpointer *array;
+ GArgument elem;
+
+ for (array = arg->v_pointer; *array; array++) {
+ elem.v_pointer = *array;
+ if (!gjs_g_arg_release_internal(context,
+ GI_TRANSFER_EVERYTHING,
+ param_info,
+ element_type,
+ &elem)) {
+ failed = JS_TRUE;
+ }
+ }
+ }
+ g_free (arg->v_pointer);
+ break;
+
default:
g_assert_not_reached ();
}
diff --git a/test/js/testGIMarshalling.js b/test/js/testGIMarshalling.js
index 5d74e95..467b105 100644
--- a/test/js/testGIMarshalling.js
+++ b/test/js/testGIMarshalling.js
@@ -5,6 +5,21 @@ const GIMarshallingTests = imports.gi.GIMarshallingTests;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
+function testCArray() {
+ var array;
+ array = GIMarshallingTests.array_zero_terminated_return();
+ assertEquals("0", array[0]);
+ assertEquals("1", array[1]);
+ assertEquals("2", array[2]);
+ assertEquals(3, array.length);
+
+ array = GIMarshallingTests.array_zero_terminated_return_struct();
+ assertEquals(3, array.length);
+ assertEquals(42, array[0].long_);
+ assertEquals(43, array[1].long_);
+ assertEquals(44, array[2].long_);
+}
+
function testGArray() {
var array;
// Tests disabled due to do g-i typelib compilation bug
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]