[libgdata] [core] Move all element string content parsing into one function
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] [core] Move all element string content parsing into one function
- Date: Thu, 25 Mar 2010 00:35:49 +0000 (UTC)
commit 39c746ad78870a34dceec15a1775a6df3e3476d4
Author: Philip Withnall <philip tecnocode co uk>
Date: Tue Mar 23 00:19:47 2010 +0000
[core] Move all element string content parsing into one function
gdata/atom/gdata-author.c | 30 ++---------
gdata/exif/gdata-exif-tags.c | 17 ++----
gdata/gd/gdata-gd-im-address.c | 10 ++--
gdata/gd/gdata-gd-name.c | 36 +++++--------
gdata/gd/gdata-gd-organization.c | 32 +++---------
gdata/gd/gdata-gd-postal-address.c | 44 +++++++--------
gdata/gdata-feed.c | 39 +++-----------
gdata/gdata-parser.c | 63 ++++++++++++++++++++++
gdata/gdata-parser.h | 21 +++++++
gdata/media/gdata-media-content.c | 2 +-
gdata/media/gdata-media-group.c | 14 ++---
gdata/services/picasaweb/gdata-picasaweb-album.c | 23 ++------
gdata/services/picasaweb/gdata-picasaweb-file.c | 28 +++-------
gdata/services/picasaweb/gdata-picasaweb-user.c | 39 +++-----------
gdata/services/youtube/gdata-youtube-group.c | 10 +---
15 files changed, 177 insertions(+), 231 deletions(-)
---
diff --git a/gdata/atom/gdata-author.c b/gdata/atom/gdata-author.c
index d214e25..a6378cd 100644
--- a/gdata/atom/gdata-author.c
+++ b/gdata/atom/gdata-author.c
@@ -190,33 +190,13 @@ gdata_author_set_property (GObject *object, guint property_id, const GValue *val
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataAuthorPrivate *priv = GDATA_AUTHOR (parsable)->priv;
- if (xmlStrcmp (node->name, (xmlChar*) "name") == 0) {
- /* atom:name */
- xmlChar *name;
-
- if (priv->name != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- name = xmlNodeListGetString (doc, node->children, TRUE);
- if (name == NULL || *name == '\0') {
- xmlFree (name);
- return gdata_parser_error_required_content_missing (node, error);
- }
- priv->name = (gchar*) name;
- } else if (xmlStrcmp (node->name, (xmlChar*) "uri") == 0) {
- /* atom:uri */
- if (priv->uri != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- priv->uri = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "email") == 0) {
- /* atom:email */
- if (priv->email_address != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- priv->email_address = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ if (gdata_parser_string_from_element (node, "name", P_NO_DUPES | P_REQUIRED | P_NON_EMPTY, &(priv->name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "uri", P_NO_DUPES | P_REQUIRED | P_NON_EMPTY, &(priv->uri), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "email", P_NO_DUPES | P_REQUIRED | P_NON_EMPTY, &(priv->email_address), &success, error) == TRUE) {
+ return success;
} else if (GDATA_PARSABLE_CLASS (gdata_author_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
/* Error! */
return FALSE;
diff --git a/gdata/exif/gdata-exif-tags.c b/gdata/exif/gdata-exif-tags.c
index 6db0d58..03f094d 100644
--- a/gdata/exif/gdata-exif-tags.c
+++ b/gdata/exif/gdata-exif-tags.c
@@ -106,6 +106,7 @@ gdata_exif_tags_finalize (GObject *object)
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataExifTags *self = GDATA_EXIF_TAGS (parsable);
if (xmlStrcmp (node->name, (xmlChar*) "distance") == 0 ) {
@@ -118,14 +119,10 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
xmlChar *fstop = xmlNodeListGetString (doc, node->children, TRUE);
self->priv->fstop = g_ascii_strtod ((gchar*) fstop, NULL);
xmlFree (fstop);
- } else if (xmlStrcmp (node->name, (xmlChar*) "make") == 0) {
- /* exif:make */
- g_free (self->priv->make);
- self->priv->make = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "model") == 0) {
- /* exif:model */
- g_free (self->priv->model);
- self->priv->model = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ } else if (gdata_parser_string_from_element (node, "make", P_NONE, &(self->priv->make), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "model", P_NONE, &(self->priv->model), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "imageUniqueID", P_NONE, &(self->priv->image_unique_id), &success, error) == TRUE) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "exposure") == 0) {
/* exif:exposure */
xmlChar *exposure = xmlNodeListGetString (doc, node->children, TRUE);
@@ -159,10 +156,6 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
self->priv->_time.tv_sec = (glong) (milliseconds / 1000);
self->priv->_time.tv_usec = (glong) ((milliseconds % 1000) * 1000);
- } else if (xmlStrcmp (node->name, (xmlChar*) "imageUniqueID") == 0) {
- /* exif:imageUniqueID */
- g_free (self->priv->image_unique_id);
- self->priv->image_unique_id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (GDATA_PARSABLE_CLASS (gdata_exif_tags_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
/* Error! */
return FALSE;
diff --git a/gdata/gd/gdata-gd-im-address.c b/gdata/gd/gdata-gd-im-address.c
index 69d828a..09856fc 100644
--- a/gdata/gd/gdata-gd-im-address.c
+++ b/gdata/gd/gdata-gd-im-address.c
@@ -240,7 +240,7 @@ gdata_gd_im_address_set_property (GObject *object, guint property_id, const GVal
static gboolean
pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error)
{
- xmlChar *address, *protocol, *rel;
+ xmlChar *address, *rel;
gboolean primary_bool;
GDataGDIMAddressPrivate *priv = GDATA_GD_IM_ADDRESS (parsable)->priv;
@@ -249,18 +249,20 @@ pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointe
return FALSE;
address = xmlGetProp (root_node, (xmlChar*) "address");
- if (address == NULL || *address == '\0')
+ if (address == NULL || *address == '\0') {
+ xmlFree (address);
return gdata_parser_error_required_property_missing (root_node, "address", error);
+ }
rel = xmlGetProp (root_node, (xmlChar*) "rel");
if (rel != NULL && *rel == '\0') {
xmlFree (address);
+ xmlFree (rel);
return gdata_parser_error_required_property_missing (root_node, "rel", error);
}
- protocol = xmlGetProp (root_node, (xmlChar*) "protocol");
priv->address = (gchar*) address;
- priv->protocol = (gchar*) protocol;
+ priv->protocol = (gchar*) xmlGetProp (root_node, (xmlChar*) "protocol");
priv->relation_type = (gchar*) rel;
priv->label = (gchar*) xmlGetProp (root_node, (xmlChar*) "label");
priv->is_primary = primary_bool;
diff --git a/gdata/gd/gdata-gd-name.c b/gdata/gd/gdata-gd-name.c
index 9079f35..4facd1d 100644
--- a/gdata/gd/gdata-gd-name.c
+++ b/gdata/gd/gdata-gd-name.c
@@ -274,29 +274,19 @@ gdata_gd_name_set_property (GObject *object, guint property_id, const GValue *va
}
}
-#define PARSE_STRING_ELEMENT(E,F) \
- if (xmlStrcmp (node->name, (xmlChar*) (E)) == 0) { \
- /* gd:##E */ \
- if (priv->F != NULL) \
- return gdata_parser_error_duplicate_element (node, error); \
- priv->F = (gchar*) xmlNodeListGetString (doc, node->children, TRUE); \
- }
-
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataGDNamePrivate *priv = GDATA_GD_NAME (parsable)->priv;
- PARSE_STRING_ELEMENT ("givenName", given_name)
- else PARSE_STRING_ELEMENT ("additionalName", additional_name)
- else PARSE_STRING_ELEMENT ("familyName", family_name)
- else PARSE_STRING_ELEMENT ("namePrefix", prefix)
- else PARSE_STRING_ELEMENT ("nameSuffix", suffix)
- else if (xmlStrcmp (node->name, (xmlChar*) "fullName") == 0) {
- /* gd:fullName */
- if (priv->full_name != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->full_name = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ if (gdata_parser_string_from_element (node, "givenName", P_NO_DUPES, &(priv->given_name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "additionalName", P_NO_DUPES, &(priv->additional_name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "familyName", P_NO_DUPES, &(priv->family_name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "namePrefix", P_NO_DUPES, &(priv->prefix), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "nameSuffix", P_NO_DUPES, &(priv->suffix), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "fullName", P_NO_DUPES, &(priv->full_name), &success, error) == TRUE) {
+ return success;
} else if (GDATA_PARSABLE_CLASS (gdata_gd_name_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
/* Error! */
return FALSE;
@@ -305,21 +295,23 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
return TRUE;
}
-#define OUTPUT_STRING_ELEMENT(E,F) \
- if (priv->F != NULL) \
- gdata_parser_string_append_escaped (xml_string, "<gd:" E ">", priv->F, "</gd:" E ">");
-
static void
get_xml (GDataParsable *parsable, GString *xml_string)
{
GDataGDNamePrivate *priv = GDATA_GD_NAME (parsable)->priv;
+#define OUTPUT_STRING_ELEMENT(E,F) \
+ if (priv->F != NULL) \
+ gdata_parser_string_append_escaped (xml_string, "<gd:" E ">", priv->F, "</gd:" E ">");
+
OUTPUT_STRING_ELEMENT ("givenName", given_name)
OUTPUT_STRING_ELEMENT ("additionalName", additional_name)
OUTPUT_STRING_ELEMENT ("familyName", family_name)
OUTPUT_STRING_ELEMENT ("namePrefix", prefix)
OUTPUT_STRING_ELEMENT ("nameSuffix", suffix)
OUTPUT_STRING_ELEMENT ("fullName", full_name)
+
+#undef OUTPUT_STRING_ELEMENT
}
static void
diff --git a/gdata/gd/gdata-gd-organization.c b/gdata/gd/gdata-gd-organization.c
index 209b830..ebb024f 100644
--- a/gdata/gd/gdata-gd-organization.c
+++ b/gdata/gd/gdata-gd-organization.c
@@ -384,33 +384,15 @@ pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointe
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataGDOrganizationPrivate *priv = GDATA_GD_ORGANIZATION (parsable)->priv;
- if (xmlStrcmp (node->name, (xmlChar*) "orgName") == 0) {
- /* gd:orgName */
- if (priv->name != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->name = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "orgTitle") == 0) {
- /* gd:orgTitle */
- if (priv->title != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "orgDepartment") == 0) {
- /* gd:orgDepartment */
- if (priv->department != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->department = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "orgJobDescription") == 0) {
- /* gd:orgJobDescription */
- if (priv->job_description != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->job_description = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "orgSymbol") == 0) {
- /* gd:orgSymbol */
- if (priv->symbol != NULL)
- return gdata_parser_error_duplicate_element (node, error);
- priv->symbol = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ if (gdata_parser_string_from_element (node, "orgName", P_NO_DUPES, &(priv->name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "orgTitle", P_NO_DUPES, &(priv->title), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "orgDepartment", P_NO_DUPES, &(priv->department), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "orgJobDescription", P_NO_DUPES, &(priv->job_description), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "orgSymbol", P_NO_DUPES, &(priv->symbol), &success, error) == TRUE) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
/* gd:where */
GDataGDWhere *location = GDATA_GD_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GD_WHERE, doc, node, NULL, error));
diff --git a/gdata/gd/gdata-gd-postal-address.c b/gdata/gd/gdata-gd-postal-address.c
index 4f70da7..bb524ea 100644
--- a/gdata/gd/gdata-gd-postal-address.c
+++ b/gdata/gd/gdata-gd-postal-address.c
@@ -568,31 +568,25 @@ pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointe
return TRUE;
}
-#define PARSE_STRING_ELEMENT(E,F) \
- if (xmlStrcmp (node->name, (xmlChar*) (E)) == 0) { \
- /* gd:##E */ \
- if (priv->F != NULL) \
- return gdata_parser_error_duplicate_element (node, error); \
- priv->F = (gchar*) xmlNodeListGetString (doc, node->children, TRUE); \
- }
-
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataGDPostalAddressPrivate *priv = GDATA_GD_POSTAL_ADDRESS (parsable)->priv;
- PARSE_STRING_ELEMENT ("agent", agent)
- else PARSE_STRING_ELEMENT ("housename", house_name)
- else PARSE_STRING_ELEMENT ("pobox", po_box)
- else PARSE_STRING_ELEMENT ("street", street)
- else PARSE_STRING_ELEMENT ("neighborhood", neighborhood)
- else PARSE_STRING_ELEMENT ("city", city)
- else PARSE_STRING_ELEMENT ("subregion", subregion)
- else PARSE_STRING_ELEMENT ("region", region)
- else PARSE_STRING_ELEMENT ("postcode", postcode)
- else PARSE_STRING_ELEMENT ("country", country)
- else PARSE_STRING_ELEMENT ("formattedAddress", formatted_address)
- else if (GDATA_PARSABLE_CLASS (gdata_gd_postal_address_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
+ if (gdata_parser_string_from_element (node, "agent", P_NO_DUPES, &(priv->agent), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "housename", P_NO_DUPES, &(priv->house_name), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "pobox", P_NO_DUPES, &(priv->po_box), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "street", P_NO_DUPES, &(priv->street), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "neighborhood", P_NO_DUPES, &(priv->neighborhood), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "city", P_NO_DUPES, &(priv->city), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "subregion", P_NO_DUPES, &(priv->subregion), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "region", P_NO_DUPES, &(priv->region), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "postcode", P_NO_DUPES, &(priv->postcode), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "country", P_NO_DUPES, &(priv->country), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "formattedAddress", P_NO_DUPES, &(priv->formatted_address), &success, error) == TRUE) {
+ return success;
+ } else if (GDATA_PARSABLE_CLASS (gdata_gd_postal_address_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
/* Error! */
return FALSE;
}
@@ -620,15 +614,15 @@ pre_get_xml (GDataParsable *parsable, GString *xml_string)
g_string_append (xml_string, " primary='false'");
}
-#define OUTPUT_STRING_ELEMENT(E,F) \
- if (priv->F != NULL) \
- gdata_parser_string_append_escaped (xml_string, "<gd:" E ">", priv->F, "</gd:" E ">");
-
static void
get_xml (GDataParsable *parsable, GString *xml_string)
{
GDataGDPostalAddressPrivate *priv = GDATA_GD_POSTAL_ADDRESS (parsable)->priv;
+#define OUTPUT_STRING_ELEMENT(E,F) \
+ if (priv->F != NULL) \
+ gdata_parser_string_append_escaped (xml_string, "<gd:" E ">", priv->F, "</gd:" E ">");
+
OUTPUT_STRING_ELEMENT ("agent", agent)
OUTPUT_STRING_ELEMENT ("housename", house_name)
OUTPUT_STRING_ELEMENT ("street", street)
@@ -640,6 +634,8 @@ get_xml (GDataParsable *parsable, GString *xml_string)
OUTPUT_STRING_ELEMENT ("postcode", postcode)
OUTPUT_STRING_ELEMENT ("country", country)
OUTPUT_STRING_ELEMENT ("formattedAddress", formatted_address)
+
+#undef OUTPUT_STRING_ELEMENT
}
static void
diff --git a/gdata/gdata-feed.c b/gdata/gdata-feed.c
index 2cbae6f..a071cee 100644
--- a/gdata/gdata-feed.c
+++ b/gdata/gdata-feed.c
@@ -398,6 +398,7 @@ typedef struct {
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataFeed *self;
ParseData *data = user_data;
@@ -423,25 +424,13 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
if (data != NULL)
_gdata_feed_call_progress_callback (self, data, entry);
_gdata_feed_add_entry (self, entry);
- } else if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
- /* atom:title */
- if (self->priv->title != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- self->priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "subtitle") == 0) {
- /* atom:subtitle */
- if (self->priv->subtitle != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- self->priv->subtitle = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "id") == 0 && xmlStrcmp (node->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom") == 0) {
- /* atom:id */
- /* The namespace check is necessary because there's an "id" element in the gphoto namespace (PicasaWeb service) */
- if (self->priv->id != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- self->priv->id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ } else if (gdata_parser_string_from_element (node, "title", P_NO_DUPES, &(self->priv->title), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "subtitle", P_NO_DUPES, &(self->priv->subtitle), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "id", P_NO_DUPES, &(self->priv->id), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "logo", P_NO_DUPES, &(self->priv->logo), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "icon", P_NO_DUPES, &(self->priv->icon), &success, error) == TRUE) {
+ return success;
+ /*TODO for atom:id: xmlStrcmp (node->ns->href, (xmlChar*) "http://www.w3.org/2005/Atom") == 0) {*/
} else if (xmlStrcmp (node->name, (xmlChar*) "updated") == 0) {
/* atom:updated */
xmlChar *updated_string;
@@ -465,18 +454,6 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
return FALSE;
self->priv->categories = g_list_prepend (self->priv->categories, category);
- } else if (xmlStrcmp (node->name, (xmlChar*) "logo") == 0) {
- /* atom:logo */
- if (self->priv->logo != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- self->priv->logo = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "icon") == 0) {
- /* atom:icon */
- if (self->priv->icon != NULL)
- return gdata_parser_error_duplicate_element (node, error);
-
- self->priv->icon = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "link") == 0) {
/* atom:link */
GDataLink *link = GDATA_LINK (_gdata_parsable_new_from_xml_node (GDATA_TYPE_LINK, doc, node, NULL, error));
diff --git a/gdata/gdata-parser.c b/gdata/gdata-parser.c
index 92d4a5b..6536285 100644
--- a/gdata/gdata-parser.c
+++ b/gdata/gdata-parser.c
@@ -221,6 +221,8 @@ gdata_parser_date_from_time_val (const GTimeVal *_time)
* returned in @error.
*
* Return value: %TRUE on successful parsing, %FALSE otherwise
+ *
+ * Since: 0.7.0
*/
gboolean
gdata_parser_boolean_from_property (xmlNode *element, const gchar *property_name, gboolean *output, gint default_output, GError **error)
@@ -247,6 +249,67 @@ gdata_parser_boolean_from_property (xmlNode *element, const gchar *property_name
return TRUE;
}
+/*
+ * gdata_parser_string_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 #GDataParserStringOptions, or %P_NONE
+ * @output: the return location for the parsed string content
+ * @success: the return location for a value which is %TRUE if the string 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 string content of @element if its name is @element_name, subject to various checks specified by @options.
+ *
+ * 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_string_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_string_from_element() return %TRUE, the value of @success can be examined.
+ *
+ * Return value: %TRUE if @element matched @element_name, %FALSE otherwise
+ *
+ * Since: 0.7.0
+ */
+gboolean
+gdata_parser_string_from_element (xmlNode *element, const gchar *element_name, GDataParserStringOptions options,
+ gchar **output, gboolean *success, GError **error)
+{
+ xmlChar *text;
+
+ if (xmlStrcmp (element->name, (xmlChar*) element_name) != 0)
+ return FALSE;
+
+ /* Check if the output string has already been set */
+ if (*output != NULL) {
+ if (options & P_NO_DUPES) {
+ *success = gdata_parser_error_duplicate_element (element, error);
+ return TRUE;
+ } else {
+ g_free (*output);
+ }
+ }
+
+ /* Get the string and check it for NULLness or emptiness */
+ text = xmlNodeListGetString (element->doc, element->children, TRUE);
+ if ((options & P_REQUIRED && text == NULL) || (options & P_NON_EMPTY && text != NULL && *text == '\0')) {
+ xmlFree (text);
+ *success = gdata_parser_error_required_content_missing (element, error);
+ return TRUE;
+ }
+
+ *output = (gchar*) text;
+ *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 7a445d5..4147e23 100644
--- a/gdata/gdata-parser.h
+++ b/gdata/gdata-parser.h
@@ -35,7 +35,28 @@ gboolean gdata_parser_error_duplicate_element (xmlNode *element, GError **error)
gboolean gdata_parser_time_val_from_date (const gchar *date, GTimeVal *_time);
gchar *gdata_parser_date_from_time_val (const GTimeVal *_time) G_GNUC_WARN_UNUSED_RESULT;
+/*
+ * GDataParserStringOptions:
+ * @P_NONE: no special options; the content of the element will be outputted directly without any checks
+ * @P_NO_DUPES: the element must be encountered at most once; if encountered more than once, an error will be returned
+ * @P_REQUIRED: the element content must not be %NULL if the element exists
+ * @P_NON_EMPTY: the element content must not be empty (i.e. a zero-length string) if the element exists
+ *
+ * Parsing options to be passed in a bitwise fashion to gdata_parser_string_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.
+ *
+ * Since: 0.7.0
+ */
+typedef enum {
+ P_NONE = 0,
+ P_NO_DUPES = 1 << 0,
+ P_REQUIRED = 1 << 1,
+ P_NON_EMPTY = 1 << 2
+} GDataParserStringOptions;
+
gboolean gdata_parser_boolean_from_property (xmlNode *element, const gchar *property_name, gboolean *output, gint default_output, GError **error);
+gboolean gdata_parser_string_from_element (xmlNode *element, const gchar *element_name, GDataParserStringOptions options,
+ gchar **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;
diff --git a/gdata/media/gdata-media-content.c b/gdata/media/gdata-media-content.c
index abb0f4f..0842b5b 100644
--- a/gdata/media/gdata-media-content.c
+++ b/gdata/media/gdata-media-content.c
@@ -289,7 +289,7 @@ static gboolean
pre_parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *root_node, gpointer user_data, GError **error)
{
GDataMediaContentPrivate *priv = GDATA_MEDIA_CONTENT (parsable)->priv;
- xmlChar *uri, *is_default, *expression, *medium, *duration, *filesize, *height, *width;
+ xmlChar *uri, *expression, *medium, *duration, *filesize, *height, *width;
gboolean is_default_bool;
GDataMediaExpression expression_enum;
GDataMediaMedium medium_enum;
diff --git a/gdata/media/gdata-media-group.c b/gdata/media/gdata-media-group.c
index e0753ea..346c996 100644
--- a/gdata/media/gdata-media-group.c
+++ b/gdata/media/gdata-media-group.c
@@ -138,17 +138,13 @@ gdata_media_group_finalize (GObject *object)
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataMediaGroup *self = GDATA_MEDIA_GROUP (parsable);
- if (xmlStrcmp (node->name, (xmlChar*) "title") == 0) {
- /* media:title */
- self->priv->title = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "description") == 0) {
- /* media:description */
- self->priv->description = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "keywords") == 0) {
- /* media:keywords */
- self->priv->keywords = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+ if (gdata_parser_string_from_element (node, "title", P_NONE, &(self->priv->title), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "description", P_NONE, &(self->priv->description), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "keywords", P_NONE, &(self->priv->keywords), &success, error) == TRUE) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "category") == 0) {
/* media:category */
GDataMediaCategory *category = GDATA_MEDIA_CATEGORY (_gdata_parsable_new_from_xml_node (GDATA_TYPE_MEDIA_CATEGORY, doc,
diff --git a/gdata/services/picasaweb/gdata-picasaweb-album.c b/gdata/services/picasaweb/gdata-picasaweb-album.c
index e745f43..9b705fb 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-album.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-album.c
@@ -547,6 +547,7 @@ gdata_picasaweb_album_set_property (GObject *object, guint property_id, const GV
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataPicasaWebAlbum *self = GDATA_PICASAWEB_ALBUM (parsable);
if (xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
@@ -571,20 +572,10 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
g_object_unref (self->priv->georss_where);
self->priv->georss_where = where;
- } else if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
- /* gphoto:user */
- xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
- if (user == NULL || *user == '\0')
- return gdata_parser_error_required_content_missing (node, error);
- g_free (self->priv->user);
- self->priv->user = (gchar*) user;
- } else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
- /* gphoto:nickname */
- xmlChar *nickname = xmlNodeListGetString (doc, node->children, TRUE);
- if (nickname == NULL || *nickname == '\0')
- return gdata_parser_error_required_content_missing (node, error);
- g_free (self->priv->nickname);
- self->priv->nickname = (gchar*) nickname;
+ } else 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, "location", P_NONE, &(self->priv->location), &success, error) == TRUE) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "edited") == 0) {
/* app:edited */
xmlChar *edited = xmlNodeListGetString (doc, node->children, TRUE);
@@ -595,10 +586,6 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
return FALSE;
}
xmlFree (edited);
- } else if (xmlStrcmp (node->name, (xmlChar*) "location") == 0) {
- /* gphoto:location */
- g_free (self->priv->location);
- self->priv->location = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
/* gphoto:access */
xmlChar *access = xmlNodeListGetString (doc, node->children, TRUE);
diff --git a/gdata/services/picasaweb/gdata-picasaweb-file.c b/gdata/services/picasaweb/gdata-picasaweb-file.c
index 81323ab..c4466ed 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-file.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-file.c
@@ -793,6 +793,7 @@ gdata_picasaweb_file_set_property (GObject *object, guint property_id, const GVa
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataPicasaWebFile *self = GDATA_PICASAWEB_FILE (parsable);
if (xmlStrcmp (node->name, (xmlChar*) "group") == 0) {
@@ -837,18 +838,11 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
return FALSE;
}
xmlFree (edited);
- } else if (xmlStrcmp (node->name, (xmlChar*) "imageVersion") == 0) {
- /* gphoto:imageVersion */
- g_free (self->priv->version);
- self->priv->version = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "position") == 0) {
/* gphoto:position */
xmlChar *position_str = xmlNodeListGetString (doc, node->children, TRUE);
gdata_picasaweb_file_set_position (self, g_ascii_strtod ((gchar*) position_str, NULL));
xmlFree (position_str);
- } else if (xmlStrcmp (node->name, (xmlChar*) "albumid") == 0) {
- /* gphoto:album_id */
- self->priv->album_id = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "width") == 0) {
/* gphoto:width */
xmlChar *width = xmlNodeListGetString (doc, node->children, TRUE);
@@ -864,12 +858,6 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
xmlChar *size = xmlNodeListGetString (doc, node->children, TRUE);
self->priv->size = strtoul ((gchar*) size, NULL, 10);
xmlFree (size);
- } else if (xmlStrcmp (node->name, (xmlChar*) "client") == 0) {
- /* gphoto:client */
- self->priv->client = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
- } else if (xmlStrcmp (node->name, (xmlChar*) "checksum") == 0) {
- /* gphoto:checksum */
- self->priv->checksum = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
/* gphoto:timestamp */
xmlChar *timestamp_str;
@@ -896,14 +884,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
self->priv->comment_count = strtoul ((gchar*) comment_count, NULL, 10);
xmlFree (comment_count);
- } else if (xmlStrcmp (node->name, (xmlChar*) "videostatus") == 0) {
- /* gphoto:videostatus */
- xmlChar *video_status = xmlNodeListGetString (doc, node->children, TRUE);
- if (self->priv->video_status != NULL) {
- xmlFree (video_status);
- return gdata_parser_error_duplicate_element (node, error);
- }
- self->priv->video_status = (gchar*) video_status;
+ } else if (gdata_parser_string_from_element (node, "videostatus", P_NO_DUPES, &(self->priv->video_status), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "imageVersion", P_NONE, &(self->priv->version), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "albumid", P_NONE, &(self->priv->album_id), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "client", P_NONE, &(self->priv->client), &success, error) == TRUE ||
+ gdata_parser_string_from_element (node, "checksum", P_NONE, &(self->priv->client), &success, error) == TRUE) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
/* gphoto:access */
/* Visibility is already obtained through the album. When PicasaWeb supports per-file access restrictions,
diff --git a/gdata/services/picasaweb/gdata-picasaweb-user.c b/gdata/services/picasaweb/gdata-picasaweb-user.c
index 7d61000..2863bc8 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-user.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-user.c
@@ -218,28 +218,13 @@ gdata_picasaweb_user_get_property (GObject *object, guint property_id, GValue *v
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataPicasaWebUser *self = GDATA_PICASAWEB_USER (parsable);
- if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
- /* gphoto:user */
- xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
- if (user == NULL || *user == '\0') {
- g_free (user);
- return gdata_parser_error_required_content_missing (node, error);
- }
-
- g_free (self->priv->user);
- self->priv->user = (gchar*) user;
- } else if (xmlStrcmp (node->name, (xmlChar*) "nickname") == 0) {
- /* gphoto:nickname */
- xmlChar *nickname = xmlNodeListGetString (doc, node->children, TRUE);
- if (nickname == NULL || *nickname == '\0') {
- g_free (nickname);
- return gdata_parser_error_required_content_missing (node, error);
- }
-
- g_free (self->priv->nickname);
- self->priv->nickname = (gchar*) nickname;
+ 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) {
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "quotacurrent") == 0) {
/* gphoto:quota-current */
xmlChar *quota_current = xmlNodeListGetString (doc, node->children, TRUE);
@@ -255,22 +240,12 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
xmlChar *max_photos_per_album = xmlNodeListGetString (doc, node->children, TRUE);
self->priv->max_photos_per_album = strtol ((char*) max_photos_per_album, NULL, 10);
xmlFree (max_photos_per_album);
- } else if (xmlStrcmp (node->name, (xmlChar*) "thumbnail") == 0) {
- /* gphoto:thumbnail */
- xmlChar *thumbnail = xmlNodeListGetString (doc, node->children, TRUE);
- if (thumbnail == NULL || *thumbnail == '\0') {
- g_free (thumbnail);
- return gdata_parser_error_required_content_missing (node, error);
- }
-
- g_free (self->priv->thumbnail_uri);
- self->priv->thumbnail_uri = (gchar*) thumbnail;
} else if (xmlStrcmp (node->name, (xmlChar*) "x-allowDownloads") == 0) { /* RHSTODO: see if this comes with the user */
/* gphoto:allowDownloads */
- /* Not part of public API so we're capturing and ignoring for now. See bgo #589858. */
+ /* TODO: Not part of public API so we're capturing and ignoring for now. See bgo #589858. */
} else if (xmlStrcmp (node->name, (xmlChar*) "x-allowPrints") == 0) { /* RHSTODO: see if this comes with the user */
/* gphoto:allowPrints */
- /* Not part of public API so we're capturing and ignoring for now. See bgo #589858. */
+ /* TODO: Not part of public API so we're capturing and ignoring for now. See bgo #589858. */
} else if (GDATA_PARSABLE_CLASS (gdata_picasaweb_user_parent_class)->parse_xml (parsable, doc, node, user_data, error) == FALSE) {
/* Error! */
return FALSE;
diff --git a/gdata/services/youtube/gdata-youtube-group.c b/gdata/services/youtube/gdata-youtube-group.c
index adeae5f..4792b96 100644
--- a/gdata/services/youtube/gdata-youtube-group.c
+++ b/gdata/services/youtube/gdata-youtube-group.c
@@ -90,6 +90,7 @@ gdata_youtube_group_finalize (GObject *object)
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
+ gboolean success;
GDataYouTubeGroup *self = GDATA_YOUTUBE_GROUP (parsable);
if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
@@ -139,14 +140,9 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
xmlFree (uploaded);
self->priv->uploaded = uploaded_timeval;
- } else if (xmlStrcmp (node->name, (xmlChar*) "videoid") == 0) {
+ } else if (gdata_parser_string_from_element (node, "videoid", P_NO_DUPES, &(self->priv->video_id), &success, error) == TRUE) {
/* yt:videoid */
- xmlChar *video_id = xmlNodeListGetString (doc, node->children, TRUE);
- if (self->priv->video_id != NULL) {
- xmlFree (video_id);
- return gdata_parser_error_duplicate_element (node, error);
- }
- self->priv->video_id = (gchar*) video_id;
+ return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "aspectRatio") == 0) {
/* yt:aspectRatio */
xmlChar *aspect_ratio = xmlNodeGetContent (node);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]