[perl-Glib-Object-Introspection] Convert unboxed structs to Perl hashes
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection] Convert unboxed structs to Perl hashes
- Date: Mon, 19 Apr 2010 20:48:36 +0000 (UTC)
commit 049a5e6f1ad89a432e5906a54ef9115ac8c9ec00
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Mon Apr 19 22:47:59 2010 +0200
Convert unboxed structs to Perl hashes
When we encounter a record type that doesn't have a boxed type
associated with it, use the introspection data to create a Perl hash.
GObjectIntrospection.xs | 73 ++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 69 insertions(+), 4 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index adfcf15..751e722 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -64,6 +64,10 @@ static void attach_callback_data (GPerlI11nCallbackInfo *info, SV *data);
static void invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata);
static void release_callback (gpointer data);
+static SV * arg_to_sv (const GArgument * arg,
+ GITypeInfo * info,
+ GITransfer transfer);
+
/* ------------------------------------------------------------------------- */
/* Caller owns return value */
@@ -215,6 +219,61 @@ handle_void_arg (GIArgInfo * arg_info,
/* ------------------------------------------------------------------------- */
+static SV *
+struct_to_sv (GIBaseInfo* info,
+ GIInfoType info_type,
+ gpointer pointer,
+ gboolean own)
+{
+ HV *hv;
+
+ hv = newHV ();
+
+ switch (info_type) {
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ {
+ gint i, n_fields =
+ g_struct_info_get_n_fields ((GIStructInfo *) info);
+ for (i = 0; i < n_fields; i++) {
+ GIFieldInfo *field_info;
+ GArgument value;
+ field_info =
+ g_struct_info_get_field ((GIStructInfo *) info, i);
+ if (g_field_info_get_field (field_info, pointer, &value)) {
+ /* FIXME: Is it right to use
+ * GI_TRANSFER_NOTHING here? */
+ SV *sv;
+ const gchar *name;
+ sv = arg_to_sv (
+ &value,
+ g_field_info_get_type (field_info),
+ GI_TRANSFER_NOTHING);
+ name = g_base_info_get_name (
+ (GIBaseInfo *) field_info);
+ gperl_hv_take_sv (hv, name, strlen (name), sv);
+ }
+ g_base_info_unref ((GIBaseInfo *) field_info);
+ }
+ break;
+ }
+
+ case GI_INFO_TYPE_UNION:
+ /* FIXME */
+
+ default:
+ croak ("%s: unhandled info type %d", G_STRFUNC, info_type);
+ }
+
+ if (own) {
+ /* FIXME: Is it correct to just call g_free here? What if the
+ * thing was allocated via GSlice? */
+ g_free (pointer);
+ }
+
+ return newRV_noinc ((SV *) hv);
+}
+
static gpointer
sv_to_pointer (GIArgInfo * arg_info,
GITypeInfo * type_info,
@@ -249,7 +308,8 @@ sv_to_pointer (GIArgInfo * arg_info,
croak ("Could not find GType for boxed/struct/union type %s::%s",
g_base_info_get_namespace (interface),
g_base_info_get_name (interface));
- dwarn (" struct gtype %s (%d)\n",
+ /* FIXME: handle G_TYPE_NONE */
+ dwarn (" struct type: %s (%d)\n",
g_type_name (type), type);
pointer = gperl_get_boxed_check (sv, type);
break;
@@ -314,12 +374,17 @@ pointer_to_sv (GITypeInfo* info, gpointer pointer, gboolean own)
case GI_INFO_TYPE_BOXED:
{
GType type = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) interface);
- if (!type)
+ if (!type) {
croak ("Could not find GType for boxed/struct/union type %s::%s",
g_base_info_get_namespace (interface),
g_base_info_get_name (interface));
- dwarn (" boxed type: %d (%s)\n", type, g_type_name (type));
- sv = gperl_new_boxed (pointer, type, own);
+ } else if (type == G_TYPE_NONE) {
+ sv = struct_to_sv (interface, info_type, pointer, own);
+ } else {
+ dwarn (" struct type: %d (%s)\n",
+ type, g_type_name (type));
+ sv = gperl_new_boxed (pointer, type, own);
+ }
break;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]