[gjs/wip/carlosg/arrays-in-signals: 1/2] value: Introspect element-type in arrays
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/carlosg/arrays-in-signals: 1/2] value: Introspect element-type in arrays
- Date: Wed, 3 Mar 2021 13:20:07 +0000 (UTC)
commit 6914e06dc7d7b404df449b76ddd8af1a1029a347
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Feb 15 23:51:53 2021 +0100
value: Introspect element-type in arrays
Expose a helper function to convert array types from a
GValue in place of a GIArgument, and use it when converting
types for signal handlers.
This should handle all byte/ptr/regular arrays, and all
possible element-types contained inside.
Fixes: https://gitlab.gnome.org/GNOME/gjs/-/issues/377
gi/arg.cpp | 35 +++++++++++++++++++++++++++++++++++
gi/arg.h | 6 ++++++
gi/value.cpp | 28 +++++++++++++++++++++++++---
3 files changed, 66 insertions(+), 3 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index a1f393aa..60efca56 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -2160,6 +2160,41 @@ gjs_array_from_boxed_array (JSContext *context,
param_info, length, data);
}
+GJS_JSAPI_RETURN_CONVENTION
+bool
+gjs_array_from_g_value_array (JSContext *context,
+ JS::MutableHandleValue value_p,
+ GITypeInfo *param_info,
+ const GValue *gvalue)
+{
+ GArray *array;
+ GPtrArray *ptr_array;
+ gpointer data = NULL;
+ gsize length = 0;
+ GIArrayType array_type;
+ GType value_gtype = G_VALUE_TYPE (gvalue);
+
+ /* GByteArray is just a typedef for GArray internally */
+ if (g_type_is_a(value_gtype, G_TYPE_BYTE_ARRAY) ||
+ g_type_is_a(value_gtype, G_TYPE_ARRAY)) {
+ array_type = g_type_is_a(value_gtype, G_TYPE_BYTE_ARRAY) ?
+ GI_ARRAY_TYPE_BYTE_ARRAY : GI_ARRAY_TYPE_ARRAY;
+ array = (GArray*) g_value_get_boxed(gvalue);
+ data = array->data;
+ length = array->len;
+ } else if (g_type_is_a(value_gtype, G_TYPE_PTR_ARRAY)) {
+ array_type = GI_ARRAY_TYPE_PTR_ARRAY;
+ ptr_array = (GPtrArray*) g_value_get_boxed(gvalue);
+ data = ptr_array->pdata;
+ length = ptr_array->len;
+ } else {
+ g_assert_not_reached();
+ }
+
+ return gjs_array_from_carray_internal(context, value_p, array_type,
+ param_info, length, data);
+}
+
template <typename T>
GJS_JSAPI_RETURN_CONVENTION static bool fill_vector_from_zero_terminated_carray(
JSContext* cx, JS::RootedValueVector& elems, // NOLINT(runtime/references)
diff --git a/gi/arg.h b/gi/arg.h
index 90ea60fb..72a69c0a 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -123,4 +123,10 @@ bool gjs_array_to_strv (JSContext *context,
unsigned int length,
void **arr_p);
+GJS_JSAPI_RETURN_CONVENTION
+bool gjs_array_from_g_value_array (JSContext *context,
+ JS::MutableHandleValue value_p,
+ GITypeInfo *param_info,
+ const GValue *gvalue);
+
#endif // GI_ARG_H_
diff --git a/gi/value.cpp b/gi/value.cpp
index 26a679f3..b83276c4 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -11,6 +11,7 @@
#include <glib-object.h>
#include <glib.h>
+#include <js/Array.h>
#include <js/CharacterEncoding.h>
#include <js/Conversions.h>
#include <js/GCVector.h> // for RootedVector
@@ -840,10 +841,31 @@ gjs_value_from_g_value_internal(JSContext *context,
gjs_throw(context, "Failed to convert strv to array");
return false;
}
- } else if (g_type_is_a(gtype, G_TYPE_HASH_TABLE) ||
+ } else if (g_type_is_a(gtype, G_TYPE_PTR_ARRAY) ||
g_type_is_a(gtype, G_TYPE_ARRAY) ||
- g_type_is_a(gtype, G_TYPE_BYTE_ARRAY) ||
- g_type_is_a(gtype, G_TYPE_PTR_ARRAY)) {
+ g_type_is_a(gtype, G_TYPE_BYTE_ARRAY)) {
+
+ GISignalInfo *signal_info;
+ signal_info = get_signal_info_if_available(signal_query);
+ if (!signal_info) {
+ gjs_throw(context, "Unknown signal.");
+ return false;
+ }
+
+ /* Look for element-type */
+ GITypeInfo type_info;
+ GIArgInfo *arg_info = g_callable_info_get_arg(signal_info, arg_n - 1);
+ g_arg_info_load_type(arg_info, &type_info);
+ GITypeInfo *element_info = g_type_info_get_param_type (&type_info, 0);
+
+ if (!gjs_array_from_g_value_array(context,
+ value_p,
+ element_info,
+ gvalue)) {
+ gjs_throw(context, "Failed to convert array");
+ return false;
+ }
+ } else if (g_type_is_a(gtype, G_TYPE_HASH_TABLE)) {
gjs_throw(context,
"Unable to introspect element-type of container in GValue");
return false;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]