mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 17:56:17 +01:00
typelib: Only malloc once during string iteration
Just more efficient.
This commit is contained in:
parent
33afebb2d7
commit
f84db0d30d
68
gitypelib.c
68
gitypelib.c
@ -223,20 +223,68 @@ g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *s;
|
||||||
|
const char *separator;
|
||||||
|
GString buf;
|
||||||
|
} StrSplitIter;
|
||||||
|
|
||||||
|
static void
|
||||||
|
strsplit_iter_init (StrSplitIter *iter,
|
||||||
|
const char *s,
|
||||||
|
const char *separator)
|
||||||
|
{
|
||||||
|
iter->s = s;
|
||||||
|
iter->separator = separator;
|
||||||
|
iter->buf.str = NULL;
|
||||||
|
iter->buf.len = 0;
|
||||||
|
iter->buf.allocated_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
strsplit_iter_next (StrSplitIter *iter,
|
||||||
|
char **out_val)
|
||||||
|
{
|
||||||
|
const char *s = iter->s;
|
||||||
|
const char *next;
|
||||||
|
gsize len;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return FALSE;
|
||||||
|
next = strstr (s, iter->separator);
|
||||||
|
iter->s = next;
|
||||||
|
if (next)
|
||||||
|
len = next - s;
|
||||||
|
else
|
||||||
|
len = strlen (s);
|
||||||
|
g_string_overwrite_len (&iter->buf, 0, s, (gssize)len);
|
||||||
|
*out_val = iter->buf.str;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
strsplit_iter_clear (StrSplitIter *iter)
|
||||||
|
{
|
||||||
|
g_free (iter->buf.str);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
g_typelib_matches_gtype_name_prefix (GITypelib *typelib,
|
g_typelib_matches_gtype_name_prefix (GITypelib *typelib,
|
||||||
const gchar *gtype_name)
|
const gchar *gtype_name)
|
||||||
{
|
{
|
||||||
Header *header = (Header *)typelib->data;
|
Header *header = (Header *)typelib->data;
|
||||||
const char *c_prefix;
|
const char *c_prefix;
|
||||||
gchar **prefixes;
|
gchar *prefix;
|
||||||
gchar **prefix;
|
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
StrSplitIter split_iter;
|
||||||
|
gsize gtype_name_len;
|
||||||
|
|
||||||
c_prefix = g_typelib_get_string (typelib, header->c_prefix);
|
c_prefix = g_typelib_get_string (typelib, header->c_prefix);
|
||||||
if (c_prefix == NULL)
|
if (c_prefix == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
gtype_name_len = strlen (gtype_name);
|
||||||
|
|
||||||
/* c_prefix is a comma separated string of supported prefixes
|
/* c_prefix is a comma separated string of supported prefixes
|
||||||
* in the typelib.
|
* in the typelib.
|
||||||
* We match the specified gtype_name if the gtype_name starts
|
* We match the specified gtype_name if the gtype_name starts
|
||||||
@ -244,20 +292,24 @@ g_typelib_matches_gtype_name_prefix (GITypelib *typelib,
|
|||||||
* For example, a typelib offering the 'Gdk' prefix does match
|
* For example, a typelib offering the 'Gdk' prefix does match
|
||||||
* GdkX11Cursor, however a typelib offering the 'G' prefix does not.
|
* GdkX11Cursor, however a typelib offering the 'G' prefix does not.
|
||||||
*/
|
*/
|
||||||
prefixes = g_strsplit (c_prefix, ",", 0);
|
strsplit_iter_init (&split_iter, c_prefix, ",");
|
||||||
for (prefix = prefixes; *prefix; prefix++)
|
while (strsplit_iter_next (&split_iter, &prefix))
|
||||||
{
|
{
|
||||||
size_t len = strlen (*prefix);
|
size_t len = strlen (prefix);
|
||||||
if (strncmp (*prefix, gtype_name, len))
|
|
||||||
|
if (gtype_name_len < len)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strlen (gtype_name) > len && g_ascii_isupper (gtype_name[len]))
|
if (strncmp (prefix, gtype_name, len) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (g_ascii_isupper (gtype_name[len]))
|
||||||
{
|
{
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_strfreev(prefixes);
|
strsplit_iter_clear (&split_iter);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user