mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-20 23:58:54 +02:00
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:
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <girepository.h>
|
#include <girepository.h>
|
||||||
@@ -114,6 +116,47 @@ g_struct_info_get_field (GIStructInfo *info,
|
|||||||
g_struct_get_field_offset (info, n));
|
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:
|
* g_struct_info_get_n_methods:
|
||||||
* @info: a #GIStructInfo
|
* @info: a #GIStructInfo
|
||||||
|
@@ -48,6 +48,10 @@ GI_AVAILABLE_IN_ALL
|
|||||||
GIFieldInfo * g_struct_info_get_field (GIStructInfo *info,
|
GIFieldInfo * g_struct_info_get_field (GIStructInfo *info,
|
||||||
gint n);
|
gint n);
|
||||||
|
|
||||||
|
GI_AVAILABLE_IN_ALL
|
||||||
|
GIFieldInfo * g_struct_info_find_field (GIStructInfo *info,
|
||||||
|
const gchar *name);
|
||||||
|
|
||||||
GI_AVAILABLE_IN_ALL
|
GI_AVAILABLE_IN_ALL
|
||||||
gint g_struct_info_get_n_methods (GIStructInfo *info);
|
gint g_struct_info_get_n_methods (GIStructInfo *info);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user