diff options
author | Richard Hughes <richard@hughsie.com> | 2018-05-21 17:08:13 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2018-05-21 17:15:10 +0100 |
commit | f498bb9ca87eb6f30484dcbf57972c3673c07f59 (patch) | |
tree | 96997948664a7d6982d56e6d854e8d64955ece09 | |
parent | 01682237f69740c4c2e0501ea3c87daeeaca0f33 (diff) | |
download | appstream-glib-f498bb9ca87eb6f30484dcbf57972c3673c07f59.tar.gz |
trivial: Store the locale as an interned string
-rw-r--r-- | libappstream-glib/as-app.c | 8 | ||||
-rw-r--r-- | libappstream-glib/as-node-private.h | 2 | ||||
-rw-r--r-- | libappstream-glib/as-node.c | 48 |
3 files changed, 45 insertions, 13 deletions
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index b59984d..7a8ee26 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -4928,7 +4928,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, guint32 flags, /* <name> */ case AS_TAG_NAME: - xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + xml_lang = as_node_fix_locale_full (n, as_node_get_attribute (n, "xml:lang")); if (xml_lang == NULL) break; str = as_node_get_data_as_refstr (n); @@ -4941,7 +4941,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, guint32 flags, /* <summary> */ case AS_TAG_SUMMARY: - xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + xml_lang = as_node_fix_locale_full (n, as_node_get_attribute (n, "xml:lang")); if (xml_lang == NULL) break; str = as_node_get_data_as_refstr (n); @@ -4954,7 +4954,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, guint32 flags, /* <developer_name> */ case AS_TAG_DEVELOPER_NAME: - xml_lang = as_node_fix_locale (as_node_get_attribute (n, "xml:lang")); + xml_lang = as_node_fix_locale_full (n, as_node_get_attribute (n, "xml:lang")); if (xml_lang == NULL) break; str = as_node_get_data_as_refstr (n); @@ -5069,7 +5069,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, guint32 flags, tmp = as_node_get_data (c); if (tmp == NULL) continue; - xml_lang2 = as_node_fix_locale (as_node_get_attribute (c, "xml:lang")); + xml_lang2 = as_node_fix_locale_full (n, as_node_get_attribute (c, "xml:lang")); if (xml_lang2 == NULL) continue; if (g_strstr_len (tmp, -1, ",") != NULL) diff --git a/libappstream-glib/as-node-private.h b/libappstream-glib/as-node-private.h index e89bd0a..c223889 100644 --- a/libappstream-glib/as-node-private.h +++ b/libappstream-glib/as-node-private.h @@ -61,6 +61,8 @@ void as_node_context_set_media_base_url (AsNodeContext *ctx, AsRefString *as_node_reflow_text (const gchar *text, gssize text_len); AsRefString *as_node_fix_locale (const gchar *locale); +AsRefString *as_node_fix_locale_full (const GNode *node, + const gchar *locale); AsRefString *as_node_get_data_as_refstr (const AsNode *node); AsRefString *as_node_get_attribute_as_refstr (const AsNode *node, diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c index 87c11a8..2c1ebfb 100644 --- a/libappstream-glib/as-node.c +++ b/libappstream-glib/as-node.c @@ -45,6 +45,7 @@ typedef struct { GHashTable *intern_attr; /* key=value of AsRefString */ GHashTable *intern_name; /* key=value of AsRefString */ + GHashTable *intern_lang; /* key=value of AsRefString */ } AsNodeRoot; typedef struct @@ -99,6 +100,10 @@ as_node_new (void) g_str_equal, (GDestroyNotify) as_ref_string_unref, NULL); + data->root->intern_lang = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) as_ref_string_unref, + NULL); return g_node_new (data); } @@ -108,13 +113,14 @@ as_node_attr_free (AsNodeAttr *attr) g_slice_free (AsNodeAttr, attr); } +/* transfer: none */ static AsRefString * as_node_intern (GHashTable *hash, const gchar *key) { AsRefString *rstr = g_hash_table_lookup (hash, key); if (rstr == NULL) { rstr = as_ref_string_new (key); - g_hash_table_insert (hash, rstr, rstr); + g_hash_table_add (hash, rstr); } return rstr; } @@ -170,6 +176,7 @@ as_node_destroy_node_cb (AsNode *node, gpointer user_data) if (data->is_root_node) { g_hash_table_unref (data->root->intern_attr); g_hash_table_unref (data->root->intern_name); + g_hash_table_unref (data->root->intern_lang); g_free (data->root); } else { if (!data->is_cdata_const && data->cdata != NULL) @@ -1989,6 +1996,33 @@ as_node_get_localized_unwrap_type_ul (const AsNode *node, } /** + * as_node_fix_locale_full: (skip) + * @node: A #AsNode + * @locale: The locale + * + * Fixes and filters incorrect locale strings using the root node to intern the + * locale. + * + * Returns: (transfer full): a newly allocated string + * + * Since: 0.7.9 + **/ +AsRefString * +as_node_fix_locale_full (const GNode *node, const gchar *locale) +{ + GNode *root = g_node_get_root ((GNode *) node); + AsNodeRoot *root_data = ((AsNodeData *)root->data)->root; + + if (locale == NULL) + return as_ref_string_new_static ("C"); + if (g_strcmp0 (locale, "xx") == 0) + return NULL; + if (g_strcmp0 (locale, "x-test") == 0) + return NULL; + return as_ref_string_ref (as_node_intern (root_data->intern_lang, locale)); +} + +/** * as_node_fix_locale: (skip) * @locale: The locale * @@ -2001,17 +2035,13 @@ as_node_get_localized_unwrap_type_ul (const AsNode *node, AsRefString * as_node_fix_locale (const gchar *locale) { - AsRefString *tmp; - if (locale == NULL) return as_ref_string_new_static ("C"); if (g_strcmp0 (locale, "xx") == 0) return NULL; if (g_strcmp0 (locale, "x-test") == 0) return NULL; - tmp = as_ref_string_new (locale); - g_strdelimit (tmp, "-", '_'); // FIXME: might be evil - return tmp; + return as_ref_string_new (locale); } /** @@ -2097,14 +2127,14 @@ as_node_get_localized_unwrap (const AsNode *node, GError **error) (GDestroyNotify) as_ref_string_unref); keys = g_hash_table_get_keys (hash); for (l = keys; l != NULL; l = l->next) { - gchar *locale_fixed; + g_autoptr(AsRefString) locale_fixed = NULL; xml_lang = l->data; - locale_fixed = as_node_fix_locale (xml_lang); + locale_fixed = as_node_fix_locale_full (node, xml_lang); if (locale_fixed == NULL) continue; str = g_hash_table_lookup (hash, xml_lang); g_hash_table_insert (results, - locale_fixed, + as_ref_string_ref (locale_fixed), as_ref_string_new (str->str)); } return results; |