diff options
author | Garrett Regier <garrett.regier@riftio.com> | 2015-06-03 04:59:11 -0700 |
---|---|---|
committer | Garrett Regier <garrett.regier@riftio.com> | 2015-06-21 13:01:25 -0700 |
commit | cf6ea68018b94529aeb02aaa8b430c8d061e55c1 (patch) | |
tree | b0850de8d9d62557d1613e1cac46c828bb6e6a3d /girepository/gistructinfo.c | |
parent | ec91f9d11b40de198b2faf8a80b49dbd71107750 (diff) | |
download | gobject-introspection-cf6ea68018b94529aeb02aaa8b430c8d061e55c1.tar.gz |
girepository: Add g_struct_info_find_field()
Add find_field utility function for finding a field info by name.
Beyond convenience, this should be faster than manually using
the get_n_fields and get_field functions because get_field does
an additional iteration for each field to calculate offsets O(n^2).
Thus find_field combines the offset and comparison
computations into a single loop O(n).
Based on a patch by Simon Feltman.
Diffstat (limited to 'girepository/gistructinfo.c')
-rw-r--r-- | girepository/gistructinfo.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/girepository/gistructinfo.c b/girepository/gistructinfo.c index 0fbaec84..bd777463 100644 --- a/girepository/gistructinfo.c +++ b/girepository/gistructinfo.c @@ -22,6 +22,8 @@ #include "config.h" +#include <string.h> + #include <glib.h> #include <girepository.h> @@ -115,6 +117,47 @@ g_struct_info_get_field (GIStructInfo *info, } /** + * g_struct_info_find_field: + * @info: a #GIStructInfo + * @name: a field name + * + * Obtain the type information for field named @name. + * + * Returns: (transfer full): the #GIFieldInfo or %NULL if not found, + * free it with g_base_info_unref() when done. + */ +GIFieldInfo * +g_struct_info_find_field (GIStructInfo *info, + const gchar *name) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; + guint32 offset = rinfo->offset + header->struct_blob_size; + gint i; + + for (i = 0; i < blob->n_fields; i++) + { + FieldBlob *field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[field_blob->name]; + + if (strcmp (name, fname) == 0) + { + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, + (GIBaseInfo* )info, + rinfo->typelib, + offset); + } + + offset += header->field_blob_size; + if (field_blob->has_embedded_type) + offset += header->callback_blob_size; + } + + return NULL; +} + +/** * g_struct_info_get_n_methods: * @info: a #GIStructInfo * |