Revision: 2066
http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2066&view=rev
Author: teuf
Date: 2008-07-29 20:09:30 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
Add error handling to the plist XML parser
Modified Paths:
--------------
libgpod/trunk/ChangeLog
libgpod/trunk/src/itdb_device.c
libgpod/trunk/src/itdb_plist.c
libgpod/trunk/src/itdb_plist.h
libgpod/trunk/src/itdb_sysinfo_extended_parser.c
Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog 2008-07-27 18:15:24 UTC (rev 2065)
+++ libgpod/trunk/ChangeLog 2008-07-29 20:09:30 UTC (rev 2066)
@@ -1,3 +1,12 @@
+2008-07-27 Christophe Fergeau <[EMAIL PROTECTED]>
+
+ * src/itdb_device.c: add itdb_device_error_quark()
+ * src/itdb_plist.h:
+ * src/itdb_plist.c: add error handling to XML parsing (using
+ GError)
+ * src/itdb_sysinfo_extended_parser.c: pass a NULL GError to call to
+ plist parsing function
+
2008-07-26 Christophe Fergeau <[EMAIL PROTECTED]>
* tests/test-fw-id.c: (main): add missing call to g_type_init
Modified: libgpod/trunk/src/itdb_device.c
===================================================================
--- libgpod/trunk/src/itdb_device.c 2008-07-27 18:15:24 UTC (rev 2065)
+++ libgpod/trunk/src/itdb_device.c 2008-07-29 20:09:30 UTC (rev 2066)
@@ -1691,3 +1691,12 @@
*/
return g_hash_table_lookup (model_table->serial_hash, serial+len-3);
}
+
+GQuark itdb_device_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark) {
+ quark = g_quark_from_static_string ("itdb-device-error-quark");
+ }
+ return quark;
+}
Modified: libgpod/trunk/src/itdb_plist.c
===================================================================
--- libgpod/trunk/src/itdb_plist.c 2008-07-27 18:15:24 UTC (rev 2065)
+++ libgpod/trunk/src/itdb_plist.c 2008-07-29 20:09:30 UTC (rev 2066)
@@ -66,7 +66,7 @@
#define DEBUG(...)
#endif
-static GValue *parse_node (xmlNode *a_node);
+static GValue *parse_node (xmlNode *a_node, GError **error);
static void
value_free (GValue *val)
@@ -76,14 +76,21 @@
}
static GValue *
-parse_integer(xmlNode *a_node)
+parse_integer(xmlNode *a_node, GError **error)
{
char *str_val;
+ char *end_ptr;
gint int_val;
GValue *value;
str_val = (char *)xmlNodeGetContent(a_node);
- int_val = strtol (str_val, NULL, 0);
+ int_val = strtol (str_val, &end_ptr, 0);
+ if (*end_ptr != '\0') {
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "invalid integer value: %s", str_val);
+ xmlFree (str_val);
+ return NULL;
+ }
xmlFree (str_val);
value = g_new0(GValue, 1);
@@ -94,7 +101,7 @@
}
static GValue *
-parse_string(xmlNode *a_node)
+parse_string(xmlNode *a_node, G_GNUC_UNUSED GError **error)
{
char *str_val;
GValue *value;
@@ -111,14 +118,21 @@
}
static GValue *
-parse_real(xmlNode *a_node)
+parse_real(xmlNode *a_node, GError **error)
{
char *str_val;
+ char *end_ptr;
gfloat double_val;
GValue *value;
str_val = (char *)xmlNodeGetContent(a_node);
- double_val = g_ascii_strtod (str_val, NULL);
+ double_val = g_ascii_strtod (str_val, &end_ptr);
+ if (*end_ptr != '\0') {
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "invalid real value: %s", str_val);
+ xmlFree (str_val);
+ return NULL;
+ }
xmlFree (str_val);
value = g_new0(GValue, 1);
@@ -129,7 +143,7 @@
}
static GValue *
-parse_boolean (xmlNode *a_node)
+parse_boolean (xmlNode *a_node, GError **error)
{
gboolean bool_val;
GValue *value;
@@ -139,7 +153,8 @@
} else if (strcmp ((char *)a_node->name, "false") == 0) {
bool_val = FALSE;
} else {
- DEBUG ("unexpected boolean value\n");
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "unexpected boolean value: %s", a_node->name);
return NULL;
}
@@ -151,7 +166,7 @@
}
static GValue *
-parse_data (xmlNode *a_node)
+parse_data (xmlNode *a_node, G_GNUC_UNUSED GError **error)
{
char *str_val;
guchar *raw_data;
@@ -173,7 +188,7 @@
}
static xmlNode *
-parse_one_dict_entry (xmlNode *a_node, GHashTable *dict)
+parse_one_dict_entry (xmlNode *a_node, GHashTable *dict, GError **error)
{
xmlNode *cur_node = a_node;
xmlChar *key_name;
@@ -186,6 +201,8 @@
cur_node = cur_node->next;
}
if (cur_node == NULL) {
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "Dict entry contains no <key> node");
return NULL;
}
key_name = xmlNodeGetContent(cur_node);
@@ -194,14 +211,19 @@
cur_node = cur_node->next;
}
if (cur_node == NULL) {
- DEBUG ("<key> %s with no corresponding value node", key_name);
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "<key> %s with no corresponding value node", key_name);
xmlFree (key_name);
return NULL;
}
- value = parse_node (cur_node);
+ value = parse_node (cur_node, error);
if (value != NULL) {
g_hash_table_insert (dict, g_strdup ((char *)key_name), value);
+ } else {
+ g_warning ("Couldn't parse value for %s: %s",
+ key_name, (*error)->message);
+ g_clear_error (error);
}
xmlFree (key_name);
@@ -209,7 +231,7 @@
}
static GValue *
-parse_dict (xmlNode *a_node)
+parse_dict (xmlNode *a_node, GError **error)
{
xmlNode *cur_node = a_node->children;
GValue *value;
@@ -219,9 +241,11 @@
g_free, (GDestroyNotify)value_free);
while (cur_node != NULL) {
- cur_node = parse_one_dict_entry (cur_node, dict);
+ cur_node = parse_one_dict_entry (cur_node, dict, error);
}
-
+ if ((error != NULL) && (*error != NULL)) {
+ return NULL;
+ }
value = g_new0 (GValue, 1);
value = g_value_init (value, G_TYPE_HASH_TABLE);
g_value_take_boxed (value, dict);
@@ -229,7 +253,7 @@
return value;
}
-typedef GValue *(*ParseCallback) (xmlNode *);
+typedef GValue *(*ParseCallback) (xmlNode *, GError **);
struct Parser {
const char * const type_name;
ParseCallback parser;
@@ -245,14 +269,14 @@
{"array", parse_dict},
{NULL, NULL} };
-static GValue *parse_node (xmlNode *a_node)
+static GValue *parse_node (xmlNode *a_node, GError **error)
{
guint i = 0;
g_return_val_if_fail (a_node != NULL, FALSE);
while (parsers[i].type_name != NULL) {
if (xmlStrcmp (a_node->name, (xmlChar *)parsers[i].type_name) == 0) {
if (parsers[i].parser != NULL) {
- return parsers[i].parser (a_node);
+ return parsers[i].parser (a_node, error);
}
}
i++;
@@ -262,15 +286,17 @@
}
static GValue *
-itdb_plist_parse (xmlNode * a_node)
+itdb_plist_parse (xmlNode * a_node, GError **error)
{
xmlNode *cur_node;
if (a_node == NULL) {
- DEBUG ("empty file\n");
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "Empty XML document");
return NULL;
}
if (xmlStrcmp (a_node->name, (xmlChar *)"plist") != 0) {
- DEBUG ("not a plist file\n");
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "XML document does not seem to be a plist document");
return NULL;
}
cur_node = a_node->xmlChildrenNode;
@@ -278,13 +304,15 @@
cur_node = cur_node->next;
}
if (cur_node != NULL) {
- return parse_node (cur_node);
+ return parse_node (cur_node, error);
}
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "Empty XML document");
return NULL;
}
GValue *
-itdb_plist_parse_from_file (const char *filename)
+itdb_plist_parse_from_file (const char *filename, GError **error)
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
@@ -293,13 +321,14 @@
doc = xmlReadFile(filename, NULL, 0);
if (doc == NULL) {
- printf("error: could not parse file %s\n", filename);
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "Error during XML parsing of file %s", filename);
return NULL;
}
root_element = xmlDocGetRootElement(doc);
- parsed_doc = itdb_plist_parse (root_element);
+ parsed_doc = itdb_plist_parse (root_element, error);
xmlFreeDoc(doc);
xmlCleanupParser();
@@ -308,7 +337,7 @@
}
GValue *
-itdb_plist_parse_from_memory (const char *data, gsize len)
+itdb_plist_parse_from_memory (const char *data, gsize len, GError **error)
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
@@ -317,13 +346,14 @@
doc = xmlReadMemory(data, len, "noname.xml", NULL, 0);
if (doc == NULL) {
- printf("error: could not parse data from memory\n");
+ g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING,
+ "Error during XML parsing of in-memory data");
return NULL;
}
root_element = xmlDocGetRootElement(doc);
- parsed_doc = itdb_plist_parse (root_element);
+ parsed_doc = itdb_plist_parse (root_element, error);
xmlFreeDoc(doc);
xmlCleanupParser();
@@ -334,13 +364,15 @@
#include <glib-object.h>
#include "itdb_plist.h"
-GValue *itdb_plist_parse_from_file (G_GNUC_UNUSED const char *filename)
+GValue *itdb_plist_parse_from_file (G_GNUC_UNUSED const char *filename,
+ G_GNUC_UNUSED GError **error)
{
return NULL;
}
GValue *itdb_plist_parse_from_memory (G_GNUC_UNUSED const char *data,
- G_GNUC_UNUSED gsize len)
+ G_GNUC_UNUSED gsize len,
+ G_GNUC_UNUSED GError **error)
{
return NULL;
}
Modified: libgpod/trunk/src/itdb_plist.h
===================================================================
--- libgpod/trunk/src/itdb_plist.h 2008-07-27 18:15:24 UTC (rev 2065)
+++ libgpod/trunk/src/itdb_plist.h 2008-07-29 20:09:30 UTC (rev 2066)
@@ -33,9 +33,21 @@
G_BEGIN_DECLS
-G_GNUC_INTERNAL GValue *itdb_plist_parse_from_file (const char *filename);
+typedef enum {
+ ITDB_DEVICE_ERROR_XML_PARSING
+} ItdbDeviceError;
+
+/* Error domain */
+#define ITDB_DEVICE_ERROR itdb_device_error_quark ()
+GQuark itdb_device_error_quark (void);
+
+
+
+G_GNUC_INTERNAL GValue *itdb_plist_parse_from_file (const char *filename,
+ GError **error);
G_GNUC_INTERNAL GValue *itdb_plist_parse_from_memory (const char *data,
- gsize len);
+ gsize len,
+ GError **error);
G_END_DECLS
Modified: libgpod/trunk/src/itdb_sysinfo_extended_parser.c
===================================================================
--- libgpod/trunk/src/itdb_sysinfo_extended_parser.c 2008-07-27 18:15:24 UTC
(rev 2065)
+++ libgpod/trunk/src/itdb_sysinfo_extended_parser.c 2008-07-29 20:09:30 UTC
(rev 2066)
@@ -507,7 +507,7 @@
g_return_val_if_fail (filename != NULL, NULL);
- parsed_doc = itdb_plist_parse_from_file (filename);
+ parsed_doc = itdb_plist_parse_from_file (filename, NULL);
if (parsed_doc == NULL) {
return NULL;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2