summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2018-05-21 17:08:13 +0100
committerRichard Hughes <richard@hughsie.com>2018-05-21 17:15:10 +0100
commitf498bb9ca87eb6f30484dcbf57972c3673c07f59 (patch)
tree96997948664a7d6982d56e6d854e8d64955ece09
parent01682237f69740c4c2e0501ea3c87daeeaca0f33 (diff)
downloadappstream-glib-f498bb9ca87eb6f30484dcbf57972c3673c07f59.tar.gz
trivial: Store the locale as an interned string
-rw-r--r--libappstream-glib/as-app.c8
-rw-r--r--libappstream-glib/as-node-private.h2
-rw-r--r--libappstream-glib/as-node.c48
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;