summaryrefslogtreecommitdiff
path: root/girepository/ginfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/ginfo.c')
-rw-r--r--girepository/ginfo.c642
1 files changed, 21 insertions, 621 deletions
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index 198bf6e0..70482a5a 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -27,607 +27,7 @@
#include "gtypelib.h"
#include "ginfo.h"
-
-typedef struct _GIRealInfo GIRealInfo;
-
-/*
- * We just use one structure for all of the info object
- * types; in general, we should be reading data directly
- * from the typelib, and not having computed data in
- * per-type structures.
- */
-struct _GIRealInfo
-{
- /* Keep this part in sync with GIUnresolvedInfo below */
- gint32 type;
- gint32 ref_count;
- GIRepository *repository;
- GIBaseInfo *container;
-
- /* Resolved specific */
-
- GTypelib *typelib;
- guint32 offset;
-
- guint32 type_is_embedded : 1; /* Used by GITypeInfo */
- guint32 reserved : 31;
-
- gpointer reserved2[4];
-};
-
-struct _GIUnresolvedInfo
-{
- /* Keep this part in sync with GIBaseInfo above */
- gint32 type;
- gint32 ref_count;
- GIRepository *repository;
- GIBaseInfo *container;
-
- /* Unresolved specific */
-
- const gchar *name;
- const gchar *namespace;
-};
-
-#define INVALID_REFCOUNT 0x7FFFFFFF
-
-static void
-g_info_init (GIRealInfo *info,
- GIInfoType type,
- GIRepository *repository,
- GIBaseInfo *container,
- GTypelib *typelib,
- guint32 offset)
-{
- memset (info, 0, sizeof (GIRealInfo));
-
- /* Invalid refcount used to flag stack-allocated infos */
- info->ref_count = INVALID_REFCOUNT;
- info->type = type;
-
- info->typelib = typelib;
- info->offset = offset;
-
- if (container)
- info->container = container;
-
- g_assert (G_IS_IREPOSITORY (repository));
- info->repository = repository;
-}
-
-/* info creation */
-GIBaseInfo *
-g_info_new_full (GIInfoType type,
- GIRepository *repository,
- GIBaseInfo *container,
- GTypelib *typelib,
- guint32 offset)
-{
- GIRealInfo *info;
-
- g_return_val_if_fail (container != NULL || repository != NULL, NULL);
-
- info = g_slice_new (GIRealInfo);
-
- g_info_init (info, type, repository, container, typelib, offset);
- info->ref_count = 1;
-
- if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT)
- g_base_info_ref (info->container);
-
- g_object_ref (info->repository);
-
- return (GIBaseInfo*)info;
-}
-
-GIBaseInfo *
-g_info_new (GIInfoType type,
- GIBaseInfo *container,
- GTypelib *typelib,
- guint32 offset)
-{
- return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset);
-}
-
-static GIBaseInfo *
-g_info_from_entry (GIRepository *repository,
- GTypelib *typelib,
- guint16 index)
-{
- GIBaseInfo *result;
- DirEntry *entry = g_typelib_get_dir_entry (typelib, index);
-
- if (entry->local)
- result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset);
- else
- {
- const gchar *namespace = g_typelib_get_string (typelib, entry->offset);
- const gchar *name = g_typelib_get_string (typelib, entry->name);
-
- result = g_irepository_find_by_name (repository, namespace, name);
- if (result == NULL)
- {
- GIUnresolvedInfo *unresolved;
-
- unresolved = g_slice_new0 (GIUnresolvedInfo);
-
- unresolved->type = GI_INFO_TYPE_UNRESOLVED;
- unresolved->ref_count = 1;
- unresolved->repository = g_object_ref (repository);
- unresolved->container = NULL;
- unresolved->name = name;
- unresolved->namespace = namespace;
-
- return (GIBaseInfo *)unresolved;
- }
- return (GIBaseInfo *)result;
- }
-
- return (GIBaseInfo *)result;
-}
-
-/* GIBaseInfo functions */
-
-/**
- * SECTION:gibaseinfo
- * @Short_description: Base struct for all GTypelib structs
- * @Title: GIBaseInfo
- *
- * GIBaseInfo is the common base struct of all other *Info structs
- * accessible through the #GIRepository API.
- * All other structs can be casted to a #GIBaseInfo, for instance:
- * <example>
- * <title>Casting a #GIFunctionInfo to #GIBaseInfo</title>
- * <programlisting>
- * GIFunctionInfo *function_info = ...;
- * GIBaseInfo *info = (GIBaseInfo*)function_info;
- * </programlisting>
- * </example>
- * Most #GIRepository APIs returning a #GIBaseInfo is actually creating a new struct, in other
- * words, g_base_info_unref() has to be called when done accessing the data.
- * GIBaseInfos are normally accessed by calling either
- * g_irepository_find_by_name(), g_irepository_find_by_gtype() or g_irepository_get_info().
- *
- * <example>
- * <title>Getting the Button of the Gtk typelib</title>
- * <programlisting>
- * GIBaseInfo *button_info = g_irepository_find_by_name(NULL, "Gtk", "Button");
- * ... use button_info ...
- * g_base_info_unref(button_info);
- * </programlisting>
- * </example>
- *
- */
-
-/**
- * g_base_info_ref:
- * @info: a #GIBaseInfo
- *
- * Increases the reference count of @info.
- *
- * Returns: the same @info.
- */
-GIBaseInfo *
-g_base_info_ref (GIBaseInfo *info)
-{
- GIRealInfo *rinfo = (GIRealInfo*)info;
-
- g_assert (rinfo->ref_count != INVALID_REFCOUNT);
- ((GIRealInfo*)info)->ref_count++;
-
- return info;
-}
-
-/**
- * g_base_info_unref:
- * @info: a #GIBaseInfo
- *
- * Decreases the reference count of @info. When its reference count
- * drops to 0, the info is freed.
- */
-void
-g_base_info_unref (GIBaseInfo *info)
-{
- GIRealInfo *rinfo = (GIRealInfo*)info;
-
- g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT);
- rinfo->ref_count--;
-
- if (!rinfo->ref_count)
- {
- if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT)
- g_base_info_unref (rinfo->container);
-
- if (rinfo->repository)
- g_object_unref (rinfo->repository);
-
- g_slice_free (GIRealInfo, rinfo);
- }
-}
-
-/**
- * g_base_info_get_type:
- * @info: a #GIBaseInfo
- *
- * Obtain the info type of the GIBaseInfo.
- *
- * Returns: the info type of @info
- */
-GIInfoType
-g_base_info_get_type (GIBaseInfo *info)
-{
-
- return ((GIRealInfo*)info)->type;
-}
-
-/**
- * g_base_info_get_name:
- * @info: a #GIBaseInfo
- *
- * Obtain the name of the @info. What the name represents depends on
- * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is
- * the name of the function.
- *
- * Returns: the name of @info or %NULL if it lacks a name.
- */
-const gchar *
-g_base_info_get_name (GIBaseInfo *info)
-{
- GIRealInfo *rinfo = (GIRealInfo*)info;
- g_assert (rinfo->ref_count > 0);
- switch (rinfo->type)
- {
- case GI_INFO_TYPE_FUNCTION:
- case GI_INFO_TYPE_CALLBACK:
- case GI_INFO_TYPE_STRUCT:
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_ENUM:
- case GI_INFO_TYPE_FLAGS:
- case GI_INFO_TYPE_OBJECT:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_CONSTANT:
- case GI_INFO_TYPE_ERROR_DOMAIN:
- case GI_INFO_TYPE_UNION:
- {
- CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_VALUE:
- {
- ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_SIGNAL:
- {
- SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_PROPERTY:
- {
- PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_VFUNC:
- {
- VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_FIELD:
- {
- FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
-
- case GI_INFO_TYPE_ARG:
- {
- ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return g_typelib_get_string (rinfo->typelib, blob->name);
- }
- break;
- case GI_INFO_TYPE_UNRESOLVED:
- {
- GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
-
- return unresolved->name;
- }
- break;
- case GI_INFO_TYPE_TYPE:
- default: ;
- g_assert_not_reached ();
- /* unnamed */
- }
-
- return NULL;
-}
-
-/**
- * g_base_info_get_namespace:
- * @info: a #GIBaseInfo
- *
- * Obtain the namespace of @info.
- *
- * Returns: the namespace
- */
-const gchar *
-g_base_info_get_namespace (GIBaseInfo *info)
-{
- GIRealInfo *rinfo = (GIRealInfo*) info;
- Header *header = (Header *)rinfo->typelib->data;
-
- g_assert (rinfo->ref_count > 0);
-
- if (rinfo->type == GI_INFO_TYPE_UNRESOLVED)
- {
- GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
-
- return unresolved->namespace;
- }
-
- return g_typelib_get_string (rinfo->typelib, header->namespace);
-}
-
-/**
- * g_base_info_is_deprecated:
- * @info: a #GIBaseInfo
- *
- * Obtain whether the @info is represents a metadata which is
- * deprecated or not.
- *
- * Returns: %TRUE if deprecated
- */
-gboolean
-g_base_info_is_deprecated (GIBaseInfo *info)
-{
- GIRealInfo *rinfo = (GIRealInfo*) info;
- switch (rinfo->type)
- {
- case GI_INFO_TYPE_FUNCTION:
- case GI_INFO_TYPE_CALLBACK:
- case GI_INFO_TYPE_STRUCT:
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_ENUM:
- case GI_INFO_TYPE_FLAGS:
- case GI_INFO_TYPE_OBJECT:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_CONSTANT:
- case GI_INFO_TYPE_ERROR_DOMAIN:
- {
- CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return blob->deprecated;
- }
- break;
-
- case GI_INFO_TYPE_VALUE:
- {
- ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return blob->deprecated;
- }
- break;
-
- case GI_INFO_TYPE_SIGNAL:
- {
- SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return blob->deprecated;
- }
- break;
-
- case GI_INFO_TYPE_PROPERTY:
- {
- PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
-
- return blob->deprecated;
- }
- break;
-
- case GI_INFO_TYPE_VFUNC:
- case GI_INFO_TYPE_FIELD:
- case GI_INFO_TYPE_ARG:
- case GI_INFO_TYPE_TYPE:
- default: ;
- /* no deprecation flag for these */
- }
-
- return FALSE;
-}
-
-/**
- * g_base_info_get_attribute:
- * @info: a #GIBaseInfo
- * @name: a freeform string naming an attribute
- *
- * Retrieve an arbitrary attribute associated with this node.
- *
- * Returns: The value of the attribute, or %NULL if no such attribute exists
- */
-const gchar *
-g_base_info_get_attribute (GIBaseInfo *info,
- const gchar *name)
-{
- GIAttributeIter iter = { 0, };
- gchar *curname, *curvalue;
- while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue))
- {
- if (strcmp (name, curname) == 0)
- return (const gchar*) curvalue;
- }
-
- return NULL;
-}
-
-static int
-cmp_attribute (const void *av,
- const void *bv)
-{
- const AttributeBlob *a = av;
- const AttributeBlob *b = bv;
-
- if (a->offset < b->offset)
- return -1;
- else if (a->offset == b->offset)
- return 0;
- else
- return 1;
-}
-
-static AttributeBlob *
-find_first_attribute (GIRealInfo *rinfo)
-{
- Header *header = (Header *)rinfo->typelib->data;
- AttributeBlob blob, *first, *res, *previous;
-
- blob.offset = rinfo->offset;
-
- first = (AttributeBlob *) &rinfo->typelib->data[header->attributes];
-
- res = bsearch (&blob, first, header->n_attributes,
- header->attribute_blob_size, cmp_attribute);
-
- if (res == NULL)
- return NULL;
-
- previous = res - 1;
- while (previous >= first && previous->offset == rinfo->offset)
- {
- res = previous;
- previous = res - 1;
- }
-
- return res;
-}
-
-/**
- * g_base_info_iterate_attributes:
- * @info: a #GIBaseInfo
- * @iterator: a #GIAttributeIter structure, must be initialized; see below
- * @name: (out) (transfer none): Returned name, must not be freed
- * @value: (out) (transfer none): Returned name, must not be freed
- *
- * Iterate over all attributes associated with this node. The iterator
- * structure is typically stack allocated, and must have its first
- * member initialized to %NULL.
- *
- * Both the @name and @value should be treated as constants
- * and must not be freed.
- *
- * <example>
- * <title>Iterating over attributes</title>
- * <programlisting>
- * void
- * print_attributes (GIBaseInfo *info)
- * {
- * GIAttributeIter iter = { 0, };
- * char *name;
- * char *value;
- * while (g_base_info_iterate_attributes (info, &iter, &name, &value))
- * {
- * g_print ("attribute name: %s value: %s", name, value);
- * }
- * }
- * </programlisting>
- * </example>
- *
- * Returns: %TRUE if there are more attributes
- */
-gboolean
-g_base_info_iterate_attributes (GIBaseInfo *info,
- GIAttributeIter *iterator,
- gchar **name,
- gchar **value)
-{
- GIRealInfo *rinfo = (GIRealInfo *)info;
- Header *header = (Header *)rinfo->typelib->data;
- AttributeBlob *next, *after;
-
- after = (AttributeBlob *) &rinfo->typelib->data[header->attributes +
- header->n_attributes * header->attribute_blob_size];
-
- if (iterator->data != NULL)
- next = (AttributeBlob *) iterator->data;
- else
- next = find_first_attribute (rinfo);
-
- if (next == NULL || next->offset != rinfo->offset || next >= after)
- return FALSE;
-
- *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name);
- *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value);
- iterator->data = next + 1;
-
- return TRUE;
-}
-
-/**
- * g_base_info_get_container:
- * @info: a #GIBaseInfo
- *
- * Obtain the container of the @info. The container is the parent
- * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an
- * #GIObjectInfo or #GIInterfaceInfo.
- *
- * Returns: (transfer none): the container
- */
-GIBaseInfo *
-g_base_info_get_container (GIBaseInfo *info)
-{
- return ((GIRealInfo*)info)->container;
-}
-
-/**
- * g_base_info_get_typelib:
- * @info: a #GIBaseInfo
- *
- * Obtain the typelib this @info belongs to
- *
- * Returns: (transfer none): the typelib.
- */
-GTypelib *
-g_base_info_get_typelib (GIBaseInfo *info)
-{
- return ((GIRealInfo*)info)->typelib;
-}
-
-/**
- * g_base_info_equal:
- * @info1: a #GIBaseInfo
- * @info2: a #GIBaseInfo
- *
- * Compare two #GIBaseInfo.
- *
- * Using pointer comparison is not practical since many functions return
- * different instances of #GIBaseInfo that refers to the same part of the
- * TypeLib; use this function instead to do #GIBaseInfo comparisons.
- *
- * Returns: %TRUE if and only if @info1 equals @info2.
- */
-gboolean
-g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2)
-{
- /* Compare the TypeLib pointers, which are mmapped. */
- GIRealInfo *rinfo1 = (GIRealInfo*)info1;
- GIRealInfo *rinfo2 = (GIRealInfo*)info2;
- return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset;
-}
+#include "girepository-private.h"
/* GIFunctionInfo functions */
@@ -832,8 +232,8 @@ g_type_info_init (GIBaseInfo *info,
GIRealInfo *rinfo = (GIRealInfo*)container;
SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
- g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib,
- (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
+ _g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib,
+ (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
}
/**
@@ -1015,8 +415,8 @@ g_callable_info_load_arg (GICallableInfo *info,
offset = signature_offset (info);
header = (Header *)rinfo->typelib->data;
- g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
- offset + header->signature_blob_size + n * header->arg_blob_size);
+ _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
+ offset + header->signature_blob_size + n * header->arg_blob_size);
}
/* GIArgInfo function */
@@ -1466,7 +866,7 @@ g_type_info_get_interface (GITypeInfo *info)
InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
if (blob->tag == GI_TYPE_TAG_INTERFACE)
- return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
+ return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
}
}
@@ -1663,9 +1063,9 @@ g_type_info_get_error_domain (GITypeInfo *info,
ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
if (blob->tag == GI_TYPE_TAG_ERROR)
- return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib,
- blob->domains[n]);
+ return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib,
+ blob->domains[n]);
}
return NULL;
@@ -1729,8 +1129,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info)
blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
- return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->error_codes);
+ return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->error_codes);
}
@@ -2125,8 +1525,8 @@ g_object_info_get_parent (GIObjectInfo *info)
ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
if (blob->parent)
- return (GIObjectInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->parent);
+ return (GIObjectInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->parent);
else
return NULL;
}
@@ -2173,8 +1573,8 @@ g_object_info_get_interface (GIObjectInfo *info,
GIRealInfo *rinfo = (GIRealInfo *)info;
ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
- return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->interfaces[n]);
+ return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->interfaces[n]);
}
gint
@@ -2441,8 +1841,8 @@ g_object_info_get_class_struct (GIObjectInfo *info)
ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
if (blob->gtype_struct)
- return (GIStructInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->gtype_struct);
+ return (GIStructInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->gtype_struct);
else
return NULL;
}
@@ -2464,8 +1864,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info,
GIRealInfo *rinfo = (GIRealInfo *)info;
InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
- return g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->prerequisites[n]);
+ return _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->prerequisites[n]);
}
@@ -2670,8 +2070,8 @@ g_interface_info_get_iface_struct (GIInterfaceInfo *info)
InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
if (blob->gtype_struct)
- return (GIStructInfo *) g_info_from_entry (rinfo->repository,
- rinfo->typelib, blob->gtype_struct);
+ return (GIStructInfo *) _g_info_from_entry (rinfo->repository,
+ rinfo->typelib, blob->gtype_struct);
else
return NULL;
}