diff options
author | Richard Hughes <richard@hughsie.com> | 2016-11-18 14:54:06 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2016-11-21 12:31:35 +0000 |
commit | 75db3a8f67404bd670433115e1d5a44536bd508e (patch) | |
tree | 4fe1a0e8a0c6f9909de177e6eb57b8197a88ced3 /libappstream-glib/as-yaml.c | |
parent | c21087431fa22214057e53c3a5ac032722f415e0 (diff) | |
download | appstream-glib-75db3a8f67404bd670433115e1d5a44536bd508e.tar.gz |
Add support for ONLY_NATIVE_LANGS when parsing yaml fileswip/hughsie/AsRefString
This saves ~20Mb of RSS on a typical desktop Debian install.
Diffstat (limited to 'libappstream-glib/as-yaml.c')
-rw-r--r-- | libappstream-glib/as-yaml.c | 86 |
1 files changed, 68 insertions, 18 deletions
diff --git a/libappstream-glib/as-yaml.c b/libappstream-glib/as-yaml.c index 76cab57..579695a 100644 --- a/libappstream-glib/as-yaml.c +++ b/libappstream-glib/as-yaml.c @@ -26,6 +26,7 @@ #endif #include "as-node.h" +#include "as-ref-string.h" #include "as-yaml.h" typedef enum { @@ -38,8 +39,8 @@ typedef enum { } AsYamlNodeKind; typedef struct { - gchar *key; - gchar *value; + AsRefString *key; + AsRefString *value; AsYamlNodeKind kind; } AsYamlNode; @@ -113,8 +114,10 @@ as_node_yaml_destroy_node_cb (AsNode *node, gpointer data) AsYamlNode *ym = node->data; if (ym == NULL) return FALSE; - g_free (ym->key); - g_free (ym->value); + if (ym->key != NULL) + as_ref_string_unref (ym->key); + if (ym->value != NULL) + as_ref_string_unref (ym->value); g_slice_free (AsYamlNode, ym); return FALSE; } @@ -197,7 +200,8 @@ as_yaml_node_new (AsYamlNodeKind kind, const gchar *id) AsYamlNode *ym; ym = g_slice_new0 (AsYamlNode); ym->kind = kind; - ym->key = g_strdup (id); + if (id != NULL) + ym->key = as_ref_string_ref (id); return ym; } @@ -315,8 +319,35 @@ as_yaml_parser_error_to_gerror (yaml_parser_t *parser, GError **error) return FALSE; } +typedef struct { + AsYamlFromFlags flags; + const gchar * const *locales; + yaml_parser_t *parser; +} AsYamlContext; + +static gboolean +as_yaml_node_valid (AsYamlContext *ctx, AsNode *parent, const gchar *key) +{ + const gchar *sections[] = { "Name", "Summary", "Description", NULL }; + AsYamlNode *ym = parent->data; + + /* if native filtering enabled */ + if ((ctx->flags & AS_YAML_FROM_FLAG_ONLY_NATIVE_LANGS) == 0) + return TRUE; + + /* filter by translatable sections */ + if (!g_strv_contains (sections, ym->key)) + return TRUE; + + /* non-native language */ + if (g_strv_contains (ctx->locales, key)) + return TRUE; + + return FALSE; +} + static gboolean -as_node_yaml_process_layer (yaml_parser_t *parser, AsNode *parent, GError **error) +as_node_yaml_process_layer (AsYamlContext *ctx, AsNode *parent, GError **error) { AsYamlNode *ym; AsNode *last_scalar = NULL; @@ -324,12 +355,14 @@ as_node_yaml_process_layer (yaml_parser_t *parser, AsNode *parent, GError **erro const gchar *tmp; gboolean valid = TRUE; yaml_event_t event; + AsRefString *map_str = as_ref_string_new_static ("{"); + AsRefString *seq_str = as_ref_string_new_static ("["); while (valid) { /* process event */ - if (!yaml_parser_parse (parser, &event)) - return as_yaml_parser_error_to_gerror (parser, error); + if (!yaml_parser_parse (ctx->parser, &event)) + return as_yaml_parser_error_to_gerror (ctx->parser, error); switch (event.type) { case YAML_SCALAR_EVENT: @@ -337,37 +370,43 @@ as_node_yaml_process_layer (yaml_parser_t *parser, AsNode *parent, GError **erro if (as_yaml_node_get_kind (parent) != AS_YAML_NODE_KIND_SEQ && last_scalar != NULL) { ym = last_scalar->data; - ym->value = g_strdup (tmp); + if (ym->key != NULL) + ym->value = as_ref_string_new_copy (tmp); ym->kind = AS_YAML_NODE_KIND_KEY_VALUE; last_scalar = NULL; } else { - ym = as_yaml_node_new (AS_YAML_NODE_KIND_KEY, tmp); + if (as_yaml_node_valid (ctx, parent, tmp)) { + g_autoptr(AsRefString) rstr = as_ref_string_new_copy (tmp); + ym = as_yaml_node_new (AS_YAML_NODE_KIND_KEY, rstr); + } else { + ym = as_yaml_node_new (AS_YAML_NODE_KIND_KEY, NULL); + } last_scalar = g_node_append_data (parent, ym); } break; case YAML_MAPPING_START_EVENT: if (last_scalar == NULL) { - ym = as_yaml_node_new (AS_YAML_NODE_KIND_MAP, "{"); + ym = as_yaml_node_new (AS_YAML_NODE_KIND_MAP, map_str); new = g_node_append_data (parent, ym); } else { ym = last_scalar->data; ym->kind = AS_YAML_NODE_KIND_MAP; new = last_scalar; } - if (!as_node_yaml_process_layer (parser, new, error)) + if (!as_node_yaml_process_layer (ctx, new, error)) return FALSE; last_scalar = NULL; break; case YAML_SEQUENCE_START_EVENT: if (last_scalar == NULL) { - ym = as_yaml_node_new (AS_YAML_NODE_KIND_SEQ, "["); + ym = as_yaml_node_new (AS_YAML_NODE_KIND_SEQ, seq_str); new = g_node_append_data (parent, ym); } else { ym = last_scalar->data; ym->kind = AS_YAML_NODE_KIND_SEQ; new = last_scalar; } - if (!as_node_yaml_process_layer (parser, new, error)) + if (!as_node_yaml_process_layer (ctx, new, error)) return FALSE; last_scalar = NULL; break; @@ -392,10 +431,14 @@ G_DEFINE_AUTO_CLEANUP_FREE_FUNC(AsYamlParser, yaml_parser_delete, NULL); #endif AsNode * -as_yaml_from_data (const gchar *data, gssize data_len, GError **error) +as_yaml_from_data (const gchar *data, + gssize data_len, + AsYamlFromFlags flags, + GError **error) { g_autoptr(AsYaml) node = NULL; #ifdef AS_BUILD_DEP11 + AsYamlContext ctx; yaml_parser_t parser; g_auto(AsYamlParser) parser_cleanup = NULL; @@ -409,7 +452,10 @@ as_yaml_from_data (const gchar *data, gssize data_len, GError **error) data_len = (gssize) strlen (data); yaml_parser_set_input_string (&parser, (guchar *) data, (gsize) data_len); node = g_node_new (NULL); - if (!as_node_yaml_process_layer (&parser, node, error)) + ctx.parser = &parser; + ctx.flags = flags; + ctx.locales = g_get_language_names (); + if (!as_node_yaml_process_layer (&ctx, node, error)) return NULL; #else g_set_error_literal (error, @@ -441,7 +487,7 @@ as_yaml_read_handler_cb (void *data, #endif AsNode * -as_yaml_from_file (GFile *file, GCancellable *cancellable, GError **error) +as_yaml_from_file (GFile *file, AsYamlFromFlags flags, GCancellable *cancellable, GError **error) { g_autoptr(AsYaml) node = NULL; #ifdef AS_BUILD_DEP11 @@ -453,6 +499,7 @@ as_yaml_from_file (GFile *file, GCancellable *cancellable, GError **error) g_autoptr(GFileInfo) info = NULL; g_autoptr(GInputStream) file_stream = NULL; g_autoptr(GInputStream) stream_data = NULL; + AsYamlContext ctx; /* what kind of file is this */ info = g_file_query_info (file, @@ -491,7 +538,10 @@ as_yaml_from_file (GFile *file, GCancellable *cancellable, GError **error) parser_cleanup = &parser; yaml_parser_set_input (&parser, as_yaml_read_handler_cb, stream_data); node = g_node_new (NULL); - if (!as_node_yaml_process_layer (&parser, node, error)) + ctx.parser = &parser; + ctx.flags = flags; + ctx.locales = g_get_language_names (); + if (!as_node_yaml_process_layer (&ctx, node, error)) return NULL; #else g_set_error_literal (error, |