diff options
author | Richard Hughes <richard@hughsie.com> | 2014-04-08 12:30:08 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2014-04-08 12:31:20 +0100 |
commit | 365dade7b7d14fdb1d0ef358a1d6a6ff27a492e2 (patch) | |
tree | 78b98e4c1715c173676616317f963153ac93667f | |
parent | d491d8809183d5930e6ae87ce32859f60a5712bf (diff) | |
download | appstream-glib-365dade7b7d14fdb1d0ef358a1d6a6ff27a492e2.tar.gz |
Load AppStream files assuming literal text strings
AppStream is a 'destination' format, so we don't want to try to parse the text
data and reassemble strings and strip leading whitespace. However, as AsNode is
used by AppData too (a source format) we just need to add a new flag to make
this configurable.
-rw-r--r-- | libappstream-glib/as-node.c | 60 | ||||
-rw-r--r-- | libappstream-glib/as-node.h | 2 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 9 | ||||
-rw-r--r-- | libappstream-glib/as-store.c | 4 |
4 files changed, 46 insertions, 29 deletions
diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c index 2a531f1..c8d6a6e 100644 --- a/libappstream-glib/as-node.c +++ b/libappstream-glib/as-node.c @@ -370,6 +370,11 @@ as_node_to_xml_string (GString *xml, } } +typedef struct { + GNode *current; + AsNodeFromXmlFlags flags; +} AsNodeToXmlHelper; + /** * as_node_to_xml: * @node: a #GNode. @@ -398,13 +403,13 @@ as_node_to_xml (const GNode *node, AsNodeToXmlFlags flags) **/ static void as_node_start_element_cb (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) { - GNode **current = (GNode **) user_data; + AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data; AsNodeData *data; guint i; @@ -418,7 +423,7 @@ as_node_start_element_cb (GMarkupParseContext *context, } /* add the node to the DOM */ - *current = g_node_append_data (*current, data); + helper->current = g_node_append_data (helper->current, data); } /** @@ -426,12 +431,12 @@ as_node_start_element_cb (GMarkupParseContext *context, **/ static void as_node_end_element_cb (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) + const gchar *element_name, + gpointer user_data, + GError **error) { - GNode **current = (GNode **) user_data; - (*current) = (*current)->parent; + AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data; + helper->current = helper->current->parent; } /** @@ -444,7 +449,7 @@ as_node_text_cb (GMarkupParseContext *context, gpointer user_data, GError **error) { - GNode **current = (GNode **) user_data; + AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data; AsNodeData *data; guint i; gchar **split; @@ -462,10 +467,11 @@ as_node_text_cb (GMarkupParseContext *context, return; /* save cdata */ - data = (*current)->data; + data = helper->current->data; /* create as it's now required */ - if (g_strstr_len (text, text_len, "\n") == NULL) { + if ((helper->flags & AS_NODE_FROM_XML_FLAG_LITERAL_TEXT) > 0 || + g_strstr_len (text, text_len, "\n") == NULL) { data->cdata = g_strndup (text, text_len); /* split up into lines and add each with spaces stripped */ @@ -475,8 +481,10 @@ as_node_text_cb (GMarkupParseContext *context, split = g_strsplit (text, "\n", -1); for (i = 0; split[i] != NULL; i++) { g_strstrip (split[i]); - if (split[i][0] == '\0') + if (split[i][0] == '\0') { + g_string_append (tmp, "\n\n"); continue; + } g_string_append_printf (tmp, "%s ", split[i]); } @@ -507,10 +515,10 @@ as_node_from_xml (const gchar *data, AsNodeFromXmlFlags flags, GError **error) { + AsNodeToXmlHelper helper; GError *error_local = NULL; GMarkupParseContext *ctx; GNode *root; - GNode *current; gboolean ret; const GMarkupParser parser = { as_node_start_element_cb, @@ -521,10 +529,12 @@ as_node_from_xml (const gchar *data, g_return_val_if_fail (data != NULL, FALSE); - current = root = g_node_new (NULL); + root = g_node_new (NULL); + helper.flags = flags; + helper.current = root; ctx = g_markup_parse_context_new (&parser, G_MARKUP_PREFIX_ERROR_POSITION, - ¤t, + &helper, NULL); ret = g_markup_parse_context_parse (ctx, data, @@ -542,7 +552,7 @@ as_node_from_xml (const gchar *data, } /* more opening than closing */ - if (root != current) { + if (root != helper.current) { g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, @@ -575,13 +585,13 @@ as_node_from_file (GFile *file, GCancellable *cancellable, GError **error) { + AsNodeToXmlHelper helper; GConverter *conv = NULL; GError *error_local = NULL; GFileInfo *info = NULL; GInputStream *file_stream = NULL; GInputStream *stream_data = NULL; GMarkupParseContext *ctx = NULL; - GNode *current; GNode *root = NULL; const gchar *content_type = NULL; gboolean ret = TRUE; @@ -625,10 +635,12 @@ as_node_from_file (GFile *file, } /* parse */ - current = root = g_node_new (NULL); + root = g_node_new (NULL); + helper.flags = flags; + helper.current = root; ctx = g_markup_parse_context_new (&parser, G_MARKUP_PREFIX_ERROR_POSITION, - ¤t, + &helper, NULL); data = g_malloc (chunk_size); @@ -659,7 +671,7 @@ as_node_from_file (GFile *file, } /* more opening than closing */ - if (root != current) { + if (root != helper.current) { g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, diff --git a/libappstream-glib/as-node.h b/libappstream-glib/as-node.h index b72fa7a..1800bcf 100644 --- a/libappstream-glib/as-node.h +++ b/libappstream-glib/as-node.h @@ -55,11 +55,13 @@ typedef enum { /** * AsNodeFromXmlFlags: * @AS_NODE_FROM_XML_FLAG_NONE: No extra flags to use + * @AS_NODE_FROM_XML_FLAG_LITERAL_TEXT: Treat the text as an exact string * * The flags for converting from XML. **/ typedef enum { AS_NODE_FROM_XML_FLAG_NONE = 0, /* Since: 0.1.0 */ + AS_NODE_FROM_XML_FLAG_LITERAL_TEXT = 1, /* Since: 0.1.3 */ /*< private >*/ AS_NODE_FROM_XML_FLAG_LAST } AsNodeFromXmlFlags; diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index d260d54..a0ca242 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -402,13 +402,15 @@ ch_test_app_no_markup_func (void) const gchar *src = "<application>" "<id type=\"desktop\">org.gnome.Software.desktop</id>" - "<description>Software</description>" + "<description>Software is awesome:\n\n * Bada\n * Boom!</description>" "</application>"; app = as_app_new (); /* to object */ - root = as_node_from_xml (src, -1, 0, &error); + root = as_node_from_xml (src, -1, + AS_NODE_FROM_XML_FLAG_LITERAL_TEXT, + &error); g_assert_no_error (error); g_assert (root != NULL); n = as_node_find (root, "application"); @@ -419,7 +421,8 @@ ch_test_app_no_markup_func (void) /* verify */ g_assert_cmpstr (as_app_get_id_full (app), ==, "org.gnome.Software.desktop"); - g_assert_cmpstr (as_app_get_description (app, "C"), ==, "Software"); + g_assert_cmpstr (as_app_get_description (app, "C"), ==, + "Software is awesome:\n\n * Bada\n * Boom!"); as_node_unref (root); /* back to node */ diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index cb27757..ac4faf5 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -407,7 +407,7 @@ as_store_from_file (AsStore *store, g_return_val_if_fail (AS_IS_STORE (store), FALSE); root = as_node_from_file (file, - AS_NODE_FROM_XML_FLAG_NONE, + AS_NODE_FROM_XML_FLAG_LITERAL_TEXT, cancellable, &error_local); if (root == NULL) { @@ -461,7 +461,7 @@ as_store_from_xml (AsStore *store, g_return_val_if_fail (AS_IS_STORE (store), FALSE); root = as_node_from_xml (data, data_len, - AS_NODE_FROM_XML_FLAG_NONE, + AS_NODE_FROM_XML_FLAG_LITERAL_TEXT, &error_local); if (root == NULL) { ret = FALSE; |