summaryrefslogtreecommitdiff
path: root/girepository
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2013-04-07 13:18:29 -0400
committerColin Walters <walters@verbum.org>2013-04-08 11:22:39 -0400
commitd5f26ced508bd1f91e769329b46ee1989fd4134a (patch)
tree49d0eb3942ea2e2667e14cbf939ef478076761fe /girepository
parent99a7287bb152dc4df299255f42b04ab1766ca6a6 (diff)
downloadgobject-introspection-d5f26ced508bd1f91e769329b46ee1989fd4134a.tar.gz
typelib: Only malloc once during string iteration
Just more efficient.
Diffstat (limited to 'girepository')
-rw-r--r--girepository/gitypelib.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/girepository/gitypelib.c b/girepository/gitypelib.c
index 2512e524..10bb98e0 100644
--- a/girepository/gitypelib.c
+++ b/girepository/gitypelib.c
@@ -223,20 +223,68 @@ g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib,
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
g_typelib_matches_gtype_name_prefix (GITypelib *typelib,
const gchar *gtype_name)
{
Header *header = (Header *)typelib->data;
const char *c_prefix;
- gchar **prefixes;
- gchar **prefix;
+ gchar *prefix;
gboolean ret = FALSE;
+ StrSplitIter split_iter;
+ gsize gtype_name_len;
c_prefix = g_typelib_get_string (typelib, header->c_prefix);
if (c_prefix == NULL)
return FALSE;
+ gtype_name_len = strlen (gtype_name);
+
/* c_prefix is a comma separated string of supported prefixes
* in the typelib.
* 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
* GdkX11Cursor, however a typelib offering the 'G' prefix does not.
*/
- prefixes = g_strsplit (c_prefix, ",", 0);
- for (prefix = prefixes; *prefix; prefix++)
+ strsplit_iter_init (&split_iter, c_prefix, ",");
+ while (strsplit_iter_next (&split_iter, &prefix))
{
- size_t len = strlen (*prefix);
- if (strncmp (*prefix, gtype_name, len))
+ size_t len = strlen (prefix);
+
+ if (gtype_name_len < len)
+ continue;
+
+ if (strncmp (prefix, gtype_name, len) != 0)
continue;
- if (strlen (gtype_name) > len && g_ascii_isupper (gtype_name[len]))
+ if (g_ascii_isupper (gtype_name[len]))
{
ret = TRUE;
break;
}
}
- g_strfreev(prefixes);
+ strsplit_iter_clear (&split_iter);
return ret;
}