[gobject-introspection] typelib: Only malloc once during string iteration



commit d5f26ced508bd1f91e769329b46ee1989fd4134a
Author: Colin Walters <walters verbum org>
Date:   Sun Apr 7 13:18:29 2013 -0400

    typelib: Only malloc once during string iteration
    
    Just more efficient.

 girepository/gitypelib.c |   68 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 60 insertions(+), 8 deletions(-)
---
diff --git a/girepository/gitypelib.c b/girepository/gitypelib.c
index 2512e52..10bb98e 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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]