[perl-Glib-Object-Introspection] Support more struct types when writing fields
- From: Torsten SchÃnfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection] Support more struct types when writing fields
- Date: Sat, 11 Aug 2012 18:30:38 +0000 (UTC)
commit d2abe8c2717e6b4cbafaf81cc50e029ca528cb13
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date: Sat Aug 11 20:27:57 2012 +0200
Support more struct types when writing fields
Specifically, boxed pointers and raw struct pointers.
NEWS | 5 +++
gperl-i11n-field.c | 79 +++++++++++++++++++++++++++++++++++++--------------
2 files changed, 62 insertions(+), 22 deletions(-)
---
diff --git a/NEWS b/NEWS
index 9343399..0c57526 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Overview of changes in Glib::Object::Introspection 0.012
+========================================================
+
+* Support more struct types when writing fields.
+
Overview of changes in Glib::Object::Introspection 0.011
========================================================
diff --git a/gperl-i11n-field.c b/gperl-i11n-field.c
index e5880e4..f991dbb 100644
--- a/gperl-i11n-field.c
+++ b/gperl-i11n-field.c
@@ -92,37 +92,72 @@ get_field (GIFieldInfo *field_info, gpointer mem, GITransfer transfer)
}
static void
-set_field (GIFieldInfo *field_info, gpointer mem, GITransfer transfer, SV *value)
+set_field (GIFieldInfo *field_info, gpointer mem, GITransfer transfer, SV *sv)
{
GITypeInfo *field_type;
GIBaseInfo *interface_info;
+ GITypeTag tag;
+ GIInfoType info_type;
GIArgument arg;
field_type = g_field_info_get_type (field_info);
+ tag = g_type_info_get_tag (field_type);
interface_info = g_type_info_get_interface (field_type);
+ info_type = interface_info
+ ? g_base_info_get_type (interface_info)
+ : GI_INFO_TYPE_INVALID;
- /* FIXME: No GIArgInfo and no
- * GPerlI11nInvocationInfo here. What if the
- * struct contains an object pointer, or a
- * callback field? And is it OK to always
- * allow undef? */
-
- /* This case is not handled by g_field_info_set_field. */
- if (!g_type_info_is_pointer (field_type) &&
- g_type_info_get_tag (field_type) == GI_TYPE_TAG_INTERFACE &&
- g_base_info_get_type (interface_info) == GI_INFO_TYPE_STRUCT)
+ /* Structs are not handled by g_field_info_set_field. */
+ if (tag == GI_TYPE_TAG_INTERFACE &&
+ info_type == GI_INFO_TYPE_STRUCT)
{
- gsize offset;
- gssize size;
- /* Enforce GI_TRANSFER_NOTHING since we will copy into the
- * memory that has already been allocated inside 'mem' */
- sv_to_arg (value, &arg, NULL, field_type,
- GI_TRANSFER_NOTHING, TRUE, NULL);
- offset = g_field_info_get_offset (field_info);
- size = g_struct_info_get_size (interface_info);
- g_memmove (mem + offset, arg.v_pointer, size);
- } else {
- sv_to_arg (value, &arg, NULL, field_type,
+ /* FIXME: No GIArgInfo and no GPerlI11nInvocationInfo here.
+ * What if the struct contains an object pointer, or a callback
+ * field? */
+ gsize offset = g_field_info_get_offset (field_info);
+ if (!g_type_info_is_pointer (field_type)) { /* By value */
+ gssize size;
+ /* Enforce GI_TRANSFER_NOTHING since we will copy into
+ * the memory that has already been allocated inside
+ * 'mem' */
+ arg.v_pointer = sv_to_struct (GI_TRANSFER_NOTHING,
+ interface_info,
+ info_type,
+ sv);
+ size = g_struct_info_get_size (interface_info);
+ g_memmove (mem + offset, arg.v_pointer, size);
+ } else { /* Pointer */
+ GType gtype = get_gtype (interface_info);
+ if (g_type_is_a (gtype, G_TYPE_BOXED)) {
+ gpointer old = G_STRUCT_MEMBER (gpointer, mem, offset);
+ /* GI_TRANSFER_NOTHING because we handle the
+ * memory ourselves here. */
+ sv_to_interface (NULL, field_type, GI_TRANSFER_NOTHING,
+ TRUE, sv, &arg, NULL);
+ if (arg.v_pointer != old) {
+ if (old)
+ g_boxed_free (gtype, old);
+ G_STRUCT_MEMBER (gpointer, mem, offset) =
+ arg.v_pointer
+ ? g_boxed_copy (gtype, arg.v_pointer)
+ : NULL;
+ }
+ } else {
+ g_assert (gtype == G_TYPE_INVALID || gtype == G_TYPE_NONE);
+ /* We have no way to know how to manage the
+ * memory here, so we just stuff the pointer in
+ * directly. */
+ G_STRUCT_MEMBER (gpointer, mem, offset) =
+ sv_to_struct (GI_TRANSFER_NOTHING,
+ interface_info,
+ info_type,
+ sv);
+ }
+ }
+ }
+
+ else {
+ sv_to_arg (sv, &arg, NULL, field_type,
transfer, TRUE, NULL);
if (!g_field_info_set_field (field_info, mem, &arg))
ccroak ("Could not set field '%s'",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]