[libgdata] core: Add an internal parser for hexadecimal colours in JSON members



commit d7f93942811ba761cfb16430744a40e89a5bf5b6
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun May 3 16:21:30 2015 +0100

    core: Add an internal parser for hexadecimal colours in JSON members
    
    This will be used for v3 of the Calendar API.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=664353

 gdata/gdata-parser.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gdata/gdata-parser.h |    8 ++++
 2 files changed, 106 insertions(+), 0 deletions(-)
---
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index a659336..aba9eb2 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -29,6 +29,7 @@
 
 #include "gdata-parser.h"
 #include "gdata-service.h"
+#include "gdata-types.h"
 #include "gdata-private.h"
 
 static gchar *
@@ -1092,6 +1093,103 @@ gdata_parser_strv_from_json_member (JsonReader *reader,
        return TRUE;
 }
 
+/*
+ * gdata_parser_color_from_json_member:
+ * @reader: #JsonReader cursor object to read JSON node from
+ * @element_name: the name of the element to parse
+ * @options: a bitwise combination of parsing options from #GDataParserOptions,
+ *   or %P_NONE
+ * @output: (out caller-allocates): the return location for the parsed colour
+ *   value
+ * @success: the return location for a value which is %TRUE if the colour was
+ *   parsed successfully, %FALSE if an error was encountered, and undefined if
+ *   @element didn't match @element_name
+ * @error: a #GError, or %NULL
+ *
+ * Gets the colour value of @element if its name is @element_name, subject to
+ * various checks specified by @options. It expects the text content of
+ * @element to be an RGB colour in hexadecimal format, with an optional leading
+ * hash symbol (for example, `#RRGGBB` or `RRGGBB`).
+ *
+ * If @element doesn't match @element_name, %FALSE will be returned, @error
+ * will be unset and @success will be unset.
+ *
+ * If @element matches @element_name but one of the checks specified by
+ * @options fails, %TRUE will be returned, @error will be set to a
+ * %GDATA_SERVICE_ERROR_PROTOCOL_ERROR error and @success will be set to %FALSE.
+ *
+ * If @element matches @element_name and all of the checks specified by
+ * @options pass, %TRUE will be returned, @error will be unset and @success
+ * will be set to %TRUE.
+ *
+ * The reason for returning the success of the parsing in @success is so that
+ * calls to gdata_parser_color_from_json_member() can be chained together in a
+ * large "or" statement based on their return values, for the purposes of
+ * determining whether any of the calls matched a given @element. If any of the
+ * calls to gdata_parser_color_from_json_member() return %TRUE, the value of
+ * @success can be examined.
+ *
+ * Return value: %TRUE if @element matched @element_name, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_parser_color_from_json_member (JsonReader *reader,
+                                     const gchar *member_name,
+                                     GDataParserOptions options,
+                                     GDataColor *output,
+                                     gboolean *success,
+                                     GError **error)
+{
+       const gchar *text;
+       GDataColor colour;
+       const GError *child_error = NULL;
+
+       /* Check if there's such an element */
+       if (g_strcmp0 (json_reader_get_member_name (reader), member_name) != 0) {
+               return FALSE;
+       }
+
+       /* Check if the output colour has already been set. The JSON parser
+        * guarantees this can't happen. */
+       g_assert (!(options & P_NO_DUPES) ||
+                 (output->red == 0 && output->green == 0 && output->blue == 0));
+
+       /* Get the string and check it for NULLness. Check for errors first. */
+       text = json_reader_get_string_value (reader);
+       child_error = json_reader_get_error (reader);
+       if (child_error != NULL) {
+               *success = gdata_parser_error_from_json_error (reader, child_error, error);
+               return TRUE;
+       } else if (options & P_REQUIRED && (text == NULL || *text == '\0')) {
+               *success = gdata_parser_error_required_json_content_missing (reader, error);
+               return TRUE;
+       }
+
+       /* Attempt to parse the string as a hexadecimal colour. */
+       if (gdata_color_from_hexadecimal (text, &colour) == FALSE) {
+               /* Error */
+               g_set_error (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR,
+                            /* Translators: the first parameter is the name of an XML element (including the 
angle brackets
+                             * ("<" and ">"), and the second parameter is the erroneous value (which was not 
in hexadecimal
+                             * RGB format).
+                             *
+                             * For example:
+                             *  The content of a <entry/gCal:color> element ("00FG56") was not in 
hexadecimal RGB format. */
+                            _("The content of a %s element (\"%s\") was not in hexadecimal RGB format."),
+                            member_name, text);
+               *success = FALSE;
+
+               return TRUE;
+       }
+
+       /* Success! */
+       *output = colour;
+       *success = TRUE;
+
+       return TRUE;
+}
+
 void
 gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar *element_content, 
const gchar *post)
 {
diff --git a/gdata/gdata-parser.h b/gdata/gdata-parser.h
index 84e1079..bc7a15a 100644
--- a/gdata/gdata-parser.h
+++ b/gdata/gdata-parser.h
@@ -20,6 +20,7 @@
 #include <glib.h>
 
 #include "gdata-parsable.h"
+#include "gdata-types.h"
 
 #ifndef GDATA_PARSER_H
 #define GDATA_PARSER_H
@@ -105,6 +106,13 @@ gdata_parser_strv_from_json_member (JsonReader *reader,
                                     GDataParserOptions options,
                                     gchar ***output, gboolean *success,
                                     GError **error);
+gboolean
+gdata_parser_color_from_json_member (JsonReader *reader,
+                                     const gchar *member_name,
+                                     GDataParserOptions options,
+                                     GDataColor *output,
+                                     gboolean *success,
+                                     GError **error);
 
 void gdata_parser_string_append_escaped (GString *xml_string, const gchar *pre, const gchar 
*element_content, const gchar *post);
 gchar *gdata_parser_utf8_trim_whitespace (const gchar *s) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;


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