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.
This commit is contained in:
Garrett Regier 2015-06-03 04:59:11 -07:00
parent 355fcd387d
commit 6eaa308869
2 changed files with 47 additions and 0 deletions

View File

@ -22,6 +22,8 @@
#include "config.h"
#include <string.h>
#include <glib.h>
#include <girepository.h>
@ -114,6 +116,47 @@ g_struct_info_get_field (GIStructInfo *info,
g_struct_get_field_offset (info, n));
}
/**
* 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

View File

@ -48,6 +48,10 @@ GI_AVAILABLE_IN_ALL
GIFieldInfo * g_struct_info_get_field (GIStructInfo *info,
gint n);
GI_AVAILABLE_IN_ALL
GIFieldInfo * g_struct_info_find_field (GIStructInfo *info,
const gchar *name);
GI_AVAILABLE_IN_ALL
gint g_struct_info_get_n_methods (GIStructInfo *info);