[libgdata] core: Add gdata_parser_int64_from_element() to parse long numbers



commit 72464c86e970f205ae6bad765f65839cc9da46dd
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sat Apr 14 11:26:40 2012 +0100

    core: Add gdata_parser_int64_from_element() to parse long numbers
    
    In comparison to the old version, this handles normal integers rather than
    dates.
    
    This also ports some uses of g_ascii_strtoll() in GDataPicasaWebUser to the
    new API.

 gdata/gdata-parser.c                            |   77 +++++++++++++++++++++++
 gdata/gdata-parser.h                            |    2 +
 gdata/services/picasaweb/gdata-picasaweb-user.c |   14 +---
 3 files changed, 82 insertions(+), 11 deletions(-)
---
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index 8710c65..57388bf 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -18,6 +18,7 @@
  */
 
 #include <config.h>
+#include <errno.h>
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <sys/time.h>
@@ -458,6 +459,82 @@ gdata_parser_int64_time_from_element (xmlNode *element, const gchar *element_nam
 }
 
 /*
+ * gdata_parser_int64_from_element:
+ * @element: the element to check against
+ * @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 integer value
+ * @default_output: default value for the property, used with %P_NO_DUPES to detect duplicates
+ * @success: the return location for a value which is %TRUE if the integer 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 integer 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 integer in base 10 format.
+ *
+ * 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_int64_from_element() 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_int64_from_element() return %TRUE, the value of @success can be examined.
+ *
+ * Return value: %TRUE if @element matched @element_name, %FALSE otherwise
+ *
+ * Since: 0.13.0
+ */
+gboolean
+gdata_parser_int64_from_element (xmlNode *element, const gchar *element_name, GDataParserOptions options,
+                                 gint64 *output, gint64 default_output, gboolean *success, GError **error)
+{
+	xmlChar *text;
+	gchar *end_ptr;
+	gint64 val;
+
+	/* Check it's the right element */
+	if (xmlStrcmp (element->name, (xmlChar*) element_name) != 0) {
+		return FALSE;
+	}
+
+	/* Check if the output value has already been set */
+	if (options & P_NO_DUPES && *output != default_output) {
+		*success = gdata_parser_error_duplicate_element (element, error);
+		return TRUE;
+	}
+
+	/* Get the string and check it for NULLness */
+	text = xmlNodeListGetString (element->doc, element->children, TRUE);
+	if (options & P_REQUIRED && (text == NULL || *text == '\0')) {
+		xmlFree (text);
+		*success = gdata_parser_error_required_content_missing (element, error);
+		return TRUE;
+	}
+
+	/* Attempt to parse the string as a 64-bit integer */
+	errno = 0;
+	val = g_ascii_strtoll ((const gchar*) text, &end_ptr, 10);
+
+	if (errno != 0 || end_ptr == (gchar*) text) {
+		*success = gdata_parser_error_unknown_content (element, (gchar*) text, error);
+		xmlFree (text);
+		return TRUE;
+	}
+
+	*output = val;
+
+	/* Success! */
+	xmlFree (text);
+	*success = TRUE;
+
+	return TRUE;
+}
+
+/*
  * gdata_parser_object_from_element_setter:
  * @element: the element to check against
  * @element_name: the name of the element to parse
diff --git a/gdata/gdata-parser.h b/gdata/gdata-parser.h
index 0d9e90c..d37b18f 100644
--- a/gdata/gdata-parser.h
+++ b/gdata/gdata-parser.h
@@ -73,6 +73,8 @@ gboolean gdata_parser_string_from_element (xmlNode *element, const gchar *elemen
                                            gchar **output, gboolean *success, GError **error);
 gboolean gdata_parser_int64_time_from_element (xmlNode *element, const gchar *element_name, GDataParserOptions options,
                                                gint64 *output, gboolean *success, GError **error);
+gboolean gdata_parser_int64_from_element (xmlNode *element, const gchar *element_name, GDataParserOptions options,
+                                          gint64 *output, gint64 default_output, gboolean *success, GError **error);
 gboolean gdata_parser_object_from_element_setter (xmlNode *element, const gchar *element_name, GDataParserOptions options, GType object_type,
                                                   gpointer /* GDataParserSetterFunc */ _setter, gpointer /* GDataParsable * */ _parent_parsable,
                                                   gboolean *success, GError **error);
diff --git a/gdata/services/picasaweb/gdata-picasaweb-user.c b/gdata/services/picasaweb/gdata-picasaweb-user.c
index e02e8c4..4c91633 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-user.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-user.c
@@ -234,18 +234,10 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 
 	if (gdata_parser_string_from_element (node, "user", P_REQUIRED | P_NON_EMPTY, &(self->priv->user), &success, error) == TRUE ||
 	    gdata_parser_string_from_element (node, "nickname", P_REQUIRED | P_NON_EMPTY, &(self->priv->nickname), &success, error) == TRUE ||
-	    gdata_parser_string_from_element (node, "thumbnail", P_REQUIRED | P_NON_EMPTY, &(self->priv->thumbnail_uri), &success, error) == TRUE) {
+	    gdata_parser_string_from_element (node, "thumbnail", P_REQUIRED | P_NON_EMPTY, &(self->priv->thumbnail_uri), &success, error) == TRUE ||
+	    gdata_parser_int64_from_element (node, "quotacurrent", P_REQUIRED | P_NO_DUPES, &(self->priv->quota_current), -1, &success, error) == TRUE ||
+	    gdata_parser_int64_from_element (node, "quotalimit", P_REQUIRED | P_NO_DUPES, &(self->priv->quota_limit), -1, &success, error) == TRUE) {
 		return success;
-	} else if (xmlStrcmp (node->name, (xmlChar*) "quotacurrent") == 0) {
-		/* gphoto:quota-current */
-		xmlChar *quota_current = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->quota_current = g_ascii_strtoll ((const gchar*) quota_current, NULL, 10);
-		xmlFree (quota_current);
-	} else if (xmlStrcmp (node->name, (xmlChar*) "quotalimit") == 0) {
-		/* gphoto:quota-limit */
-		xmlChar *quota_limit = xmlNodeListGetString (doc, node->children, TRUE);
-		self->priv->quota_limit = g_ascii_strtoll ((const gchar*) quota_limit, NULL, 10);
-		xmlFree (quota_limit);
 	} else if (xmlStrcmp (node->name, (xmlChar*) "maxPhotosPerAlbum") == 0) {
 		/* gphoto:max-photos-per-album */
 		xmlChar *max_photos_per_album = xmlNodeListGetString (doc, node->children, TRUE);



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