diff options
author | Milan Crha <mcrha@redhat.com> | 2017-11-27 15:53:00 +0000 |
---|---|---|
committer | Philip Withnall <withnall@endlessm.com> | 2017-11-27 19:03:48 +0000 |
commit | a9c5cbb9788f187470c44d1bc5231cdf249ac8e0 (patch) | |
tree | 195e2a015abd5f87ef672ec14d137fc85ae49e46 | |
parent | 83cce228f50227e3425ba734782c925cdf491fbb (diff) | |
download | libgdata-a9c5cbb9788f187470c44d1bc5231cdf249ac8e0.tar.gz |
core: Add a GDataParser flag for ignoring erroneous child elements
In some situations, it makes sense to ignore child elements if they fail
to parse properly, rather than propagating that error up to the parent.
See the following commit for an example of such a situation.
https://bugzilla.gnome.org/show_bug.cgi?id=790671
-rw-r--r-- | gdata/gdata-parser.c | 16 | ||||
-rw-r--r-- | gdata/gdata-parser.h | 4 |
2 files changed, 18 insertions, 2 deletions
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c index a43c2ecf..987cb17c 100644 --- a/gdata/gdata-parser.c +++ b/gdata/gdata-parser.c @@ -633,6 +633,9 @@ gdata_parser_object_from_element_setter (xmlNode *element, const gchar *element_ { GDataParsable *parsable, *parent_parsable; GDataParserSetterFunc setter; + GError *local_error = NULL; + + g_return_val_if_fail (!(options & P_REQUIRED) || !(options & P_IGNORE_ERROR), FALSE); /* We're lax on the types so that we don't have to do loads of casting when calling the function, which makes the parsing code more legible */ setter = (GDataParserSetterFunc) _setter; @@ -643,9 +646,20 @@ gdata_parser_object_from_element_setter (xmlNode *element, const gchar *element_ return FALSE; /* Get the object and check for instantiation failure */ - parsable = _gdata_parsable_new_from_xml_node (object_type, element->doc, element, NULL, error); + parsable = _gdata_parsable_new_from_xml_node (object_type, element->doc, element, NULL, &local_error); + g_assert ((parsable == NULL) == (local_error != NULL)); + if (options & P_REQUIRED && parsable == NULL) { /* The error has already been set by _gdata_parsable_new_from_xml_node() */ + g_propagate_error (error, g_steal_pointer (&local_error)); + *success = FALSE; + return TRUE; + } else if ((options & P_IGNORE_ERROR) && parsable == NULL) { + g_clear_error (&local_error); + *success = TRUE; + return TRUE; + } else if (local_error != NULL) { + g_propagate_error (error, g_steal_pointer (&local_error)); *success = FALSE; return TRUE; } diff --git a/gdata/gdata-parser.h b/gdata/gdata-parser.h index bc7a15a7..0eddf13b 100644 --- a/gdata/gdata-parser.h +++ b/gdata/gdata-parser.h @@ -57,6 +57,7 @@ gboolean gdata_parser_int64_from_iso8601 (const gchar *date, gint64 *_time); * this only applies to gdata_parser_string_from_element() * @P_DEFAULT: if the element content is %NULL or empty, return an empty value instead of erroring (this is mutually exclusive with %P_REQUIRED * and %P_NON_EMPTY) + * @P_IGNORE_ERROR: ignore any error when the parse fails; can be used to skip empty values (this is mutually exclusive with %P_REQUIRED) * * Parsing options to be passed in a bitwise fashion to gdata_parser_string_from_element() or gdata_parser_object_from_element(). * Their names aren't namespaced as they aren't public, and brevity is important, since they're used frequently in the parsing code. @@ -68,7 +69,8 @@ typedef enum { P_NO_DUPES = 1 << 0, P_REQUIRED = 1 << 1, P_NON_EMPTY = 1 << 2, - P_DEFAULT = 1 << 3 + P_DEFAULT = 1 << 3, + P_IGNORE_ERROR = 1 << 4 } GDataParserOptions; typedef void (*GDataParserSetterFunc) (GDataParsable *parent_parsable, GDataParsable *parsable); |