Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/girepository/ginfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/ginfo.c')
-rw-r--r--girepository/ginfo.c143
1 files changed, 105 insertions, 38 deletions
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index 1c34ee2..fcc5f09 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -1,6 +1,7 @@
/* GObject introspection: Repository implementation
*
* Copyright (C) 2005 Matthias Clasen
+ * Copyright (C) 2008,2009 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -402,65 +403,131 @@ g_base_info_is_deprecated (GIBaseInfo *info)
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.
+ *
+ * Return value: 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_annotation (const void *av,
- const void *bv)
+cmp_attribute (const void *av,
+ const void *bv)
{
- const AnnotationBlob *a = av;
- const AnnotationBlob *b = bv;
+ const AttributeBlob *a = av;
+ const AttributeBlob *b = bv;
- if (b->offset < a->offset)
+ if (a->offset < b->offset)
return -1;
-
- if (b->offset > a->offset)
+ else if (a->offset == b->offset)
+ return 0;
+ else
return 1;
-
- return 0;
}
-const gchar *
-g_base_info_get_annotation (GIBaseInfo *info,
- const gchar *name)
+static AttributeBlob *
+find_first_attribute (GIBaseInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
Header *header = (Header *)base->typelib->data;
- AnnotationBlob blob, *first, *after, *res, *next;
- const gchar *rname;
+ AttributeBlob blob, *first, *res, *previous;
blob.offset = base->offset;
- first = (AnnotationBlob *) &base->typelib->data[header->annotations];
- after = (AnnotationBlob *) &base->typelib->data[header->annotations +
- header->n_annotations * header->annotation_blob_size];
+ first = (AttributeBlob *) &base->typelib->data[header->attributes];
+
+ res = bsearch (&blob, first, header->n_attributes,
+ header->attribute_blob_size, cmp_attribute);
- res = bsearch (&blob, first, header->n_annotations,
- header->annotation_blob_size, cmp_annotation);
-
if (res == NULL)
return NULL;
- next = res;
- do
+ previous = res - 1;
+ while (previous >= first && previous->offset == base->offset)
{
- res = next;
- next = res -= header->annotation_blob_size;
+ res = previous;
+ previous = res - 1;
}
- while (next >= first && next->offset == base->offset);
-
- next = res;
- do
- {
- res = next;
-
- rname = g_typelib_get_string (base->typelib, res->name);
- if (strcmp (name, rname) == 0)
- return g_typelib_get_string (base->typelib, res->value);
- next = res += header->annotation_blob_size;
- }
- while (next < after && next->offset == base->offset);
+ return res;
+}
- return NULL;
+/**
+ * g_base_info_iterate_attributes:
+ * @info: A #GIBaseInfo
+ * @iter: 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>
+ *
+ * Return value: %TRUE if there are more attributes, %FALSE otherwise
+ */
+gboolean
+g_base_info_iterate_attributes (GIBaseInfo *info,
+ GIAttributeIter *iter,
+ gchar **name,
+ gchar **value)
+{
+ GIBaseInfo *base = (GIBaseInfo *)info;
+ Header *header = (Header *)base->typelib->data;
+ AttributeBlob *next, *after;
+
+ after = (AttributeBlob *) &base->typelib->data[header->attributes +
+ header->n_attributes * header->attribute_blob_size];
+
+ if (iter->data != NULL)
+ next = (AttributeBlob *) iter->data;
+ else
+ next = find_first_attribute (info);
+
+ if (next == NULL || next->offset != base->offset || next >= after)
+ return FALSE;
+
+ *name = (gchar*) g_typelib_get_string (base->typelib, next->name);
+ *value = (gchar*) g_typelib_get_string (base->typelib, next->value);
+ iter->data = next + 1;
+
+ return TRUE;
}
GIBaseInfo *