[libgdata] core: Add a GDataParser flag for ignoring erroneous child elements



commit a9c5cbb9788f187470c44d1bc5231cdf249ac8e0
Author: Milan Crha <mcrha redhat com>
Date:   Mon Nov 27 15:53:00 2017 +0000

    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

 gdata/gdata-parser.c |   16 +++++++++++++++-
 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 a43c2ec..987cb17 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 bc7a15a..0eddf13 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]