[gtk+/wip/baedert/gl: 21/25] css parser: Reuse one GString



commit 98f5d68ddd7c16fd49a9e7825dc6ac2f86516ef2
Author: Timm Bäder <mail baedert org>
Date:   Sun Dec 31 15:16:22 2017 +0100

    css parser: Reuse one GString
    
    Instead of creating a new one for every ident, name and string, just
    create one GString and reuse it. This means the GString we keep around
    will grow to the maximum size of any ident, name or string we parse,
    which is still not terribly large.

 gtk/gtkcssparser.c |   52 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 43 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c
index 852f9ef..acc554d 100644
--- a/gtk/gtkcssparser.c
+++ b/gtk/gtkcssparser.c
@@ -44,6 +44,9 @@ struct _GtkCssParser
 
   const char            *line_start;
   guint                  line;
+
+  /* Use this for parsing identifiers, names and strings. */
+  GString               *ident_str;
 };
 
 GtkCssParser *
@@ -68,6 +71,8 @@ _gtk_css_parser_new (const char            *data,
   parser->line_start = data;
   parser->line = 0;
 
+  parser->ident_str = NULL;
+
   return parser;
 }
 
@@ -79,6 +84,9 @@ _gtk_css_parser_free (GtkCssParser *parser)
   if (parser->file)
     g_object_unref (parser->file);
 
+  if (parser->ident_str)
+    g_string_free (parser->ident_str, TRUE);
+
   g_slice_free (GtkCssParser, parser);
 }
 
@@ -390,6 +398,21 @@ _gtk_css_parser_read_char (GtkCssParser *parser,
   return FALSE;
 }
 
+static char *
+_gtk_css_parser_get_ident (GtkCssParser *parser)
+{
+  char *result;
+  gsize len;
+
+  len = parser->ident_str->len;
+
+  result = g_new (char, len + 1);
+  memcpy (result, parser->ident_str->str, len + 1);
+  g_string_set_size (parser->ident_str, 0);
+
+  return result;
+}
+
 char *
 _gtk_css_parser_try_name (GtkCssParser *parser,
                           gboolean      skip_whitespace)
@@ -398,7 +421,10 @@ _gtk_css_parser_try_name (GtkCssParser *parser,
 
   g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
 
-  name = g_string_new (NULL);
+  if (parser->ident_str == NULL)
+    parser->ident_str = g_string_new (NULL);
+
+  name = parser->ident_str;
 
   while (_gtk_css_parser_read_char (parser, name, NMCHAR))
     ;
@@ -406,7 +432,7 @@ _gtk_css_parser_try_name (GtkCssParser *parser,
   if (skip_whitespace)
     _gtk_css_parser_skip_whitespace (parser);
 
-  return g_string_free (name, FALSE);
+  return _gtk_css_parser_get_ident (parser);
 }
 
 char *
@@ -420,7 +446,10 @@ _gtk_css_parser_try_ident (GtkCssParser *parser,
 
   start = parser->data;
   
-  ident = g_string_new (NULL);
+  if (parser->ident_str == NULL)
+    parser->ident_str = g_string_new (NULL);
+
+  ident = parser->ident_str;
 
   if (*parser->data == '-')
     {
@@ -431,7 +460,7 @@ _gtk_css_parser_try_ident (GtkCssParser *parser,
   if (!_gtk_css_parser_read_char (parser, ident, NMSTART))
     {
       parser->data = start;
-      g_string_free (ident, TRUE);
+      g_string_set_size (ident, 0);
       return NULL;
     }
 
@@ -441,7 +470,7 @@ _gtk_css_parser_try_ident (GtkCssParser *parser,
   if (skip_whitespace)
     _gtk_css_parser_skip_whitespace (parser);
 
-  return g_string_free (ident, FALSE);
+  return _gtk_css_parser_get_ident (parser);
 }
 
 gboolean
@@ -469,7 +498,12 @@ _gtk_css_parser_read_string (GtkCssParser *parser)
     }
   
   parser->data++;
-  str = g_string_new (NULL);
+
+  if (parser->ident_str == NULL)
+    parser->ident_str = g_string_new (NULL);
+
+  str = parser->ident_str;
+  g_assert (str->len == 0);
 
   while (TRUE)
     {
@@ -490,7 +524,7 @@ _gtk_css_parser_read_string (GtkCssParser *parser)
             {
               parser->data++;
               _gtk_css_parser_skip_whitespace (parser);
-              return g_string_free (str, FALSE);
+              return _gtk_css_parser_get_ident (parser);
             }
           
           g_string_append_c (str, *parser->data);
@@ -499,12 +533,12 @@ _gtk_css_parser_read_string (GtkCssParser *parser)
         case '\0':
           /* FIXME: position */
           _gtk_css_parser_error (parser, "Missing end quote in string.");
-          g_string_free (str, TRUE);
+          g_string_set_size (str, 0);
           return NULL;
         default:
           _gtk_css_parser_error (parser, 
                                  "Invalid character in string. Must be escaped.");
-          g_string_free (str, TRUE);
+          g_string_set_size (str, 0);
           return NULL;
         }
     }


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