From 9ef700b16138f22dfa91b68dd2d7e25794ea2dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 31 Dec 2017 15:16:22 +0100 Subject: [PATCH] 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 file changed, 43 insertions(+), 9 deletions(-) diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c index 852f9ef091..acc554d797 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; } }