summaryrefslogtreecommitdiff
path: root/girepository/ginfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/ginfo.c')
-rw-r--r--girepository/ginfo.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index eef3cd6e..1f14cb6f 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -134,6 +134,7 @@ struct _GIArgInfo
struct _GITypeInfo
{
GIBaseInfo base;
+ gboolean is_embedded;
};
struct _GIUnionInfo
@@ -154,7 +155,10 @@ g_info_new_full (GIInfoType type,
g_return_val_if_fail (container != NULL || repository != NULL, NULL);
- info = g_new0 (GIBaseInfo, 1);
+ if (type == GI_INFO_TYPE_TYPE)
+ info = (GIBaseInfo *)g_new0 (GITypeInfo, 1);
+ else
+ info = g_new0 (GIBaseInfo, 1);
info->ref_count = 1;
info->type = type;
@@ -643,9 +647,13 @@ g_type_info_new (GIBaseInfo *container,
guint32 offset)
{
SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
+ GITypeInfo *type_info;
- return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib,
+ type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib,
(type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
+ type_info->is_embedded = FALSE;
+
+ return type_info;
}
/**
@@ -876,7 +884,9 @@ g_type_info_get_tag (GITypeInfo *info)
GIBaseInfo *base = (GIBaseInfo *)info;
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
- if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
+ if (info->is_embedded)
+ return GI_TYPE_TAG_INTERFACE;
+ else if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
return type->flags.tag;
else
{
@@ -920,7 +930,11 @@ g_type_info_get_interface (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-
+
+ if (info->is_embedded)
+ return (GIBaseInfo *) g_info_new (type->offset, base, base->typelib,
+ base->offset);
+
if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
{
InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
@@ -1100,8 +1114,21 @@ GITypeInfo *
g_field_info_get_type (GIFieldInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
-
- return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type));
+ Header *header = (Header *)base->typelib->data;
+ FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
+ GITypeInfo *type_info;
+
+ if (blob->has_embedded_type)
+ {
+ type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE,
+ (GIBaseInfo*)info, base->typelib,
+ base->offset + header->field_blob_size);
+ type_info->is_embedded = TRUE;
+ }
+ else
+ return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type));
+
+ return type_info;
}
/* GIRegisteredTypeInfo functions */
@@ -1161,16 +1188,35 @@ g_struct_info_get_n_fields (GIStructInfo *info)
return blob->n_fields;
}
+static gint32
+g_struct_get_field_offset (GIStructInfo *info,
+ gint n)
+{
+ GIBaseInfo *base = (GIBaseInfo *)info;
+ Header *header = (Header *)base->typelib->data;
+ guint32 offset = base->offset + header->struct_blob_size;
+ gint i;
+ FieldBlob *field_blob;
+
+ for (i = 0; i < n; i++)
+ {
+ field_blob = (FieldBlob *)&base->typelib->data[offset];
+ offset += header->field_blob_size;
+ if (field_blob->has_embedded_type)
+ offset += header->callback_blob_size;
+ }
+
+ return offset;
+}
+
GIFieldInfo *
g_struct_info_get_field (GIStructInfo *info,
gint n)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- Header *header = (Header *)base->typelib->data;
return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib,
- base->offset + header->struct_blob_size +
- n * header->field_blob_size);
+ g_struct_get_field_offset (info, n));
}
gint
@@ -1191,8 +1237,7 @@ g_struct_info_get_method (GIStructInfo *info,
Header *header = (Header *)base->typelib->data;
gint offset;
- offset = base->offset + header->struct_blob_size
- + blob->n_fields * header->field_blob_size
+ offset = g_struct_get_field_offset (info, blob->n_fields)
+ n * header->function_blob_size;
return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base,
base->typelib, offset);