im.pidgin.pidgin: 0784efff2632d42a8b3e26eea0bf130b0fb3fc62

khc at pidgin.im khc at pidgin.im
Sat Nov 10 00:20:39 EST 2007


-----------------------------------------------------------------
Revision: 0784efff2632d42a8b3e26eea0bf130b0fb3fc62
Ancestor: 8064878064f532d8ea48803bccce445a21f9a040
Author: khc at pidgin.im
Date: 2007-11-10T05:16:58
Branch: im.pidgin.pidgin

Modified files:
        libpurple/xmlnode.c libpurple/xmlnode.h

ChangeLog: 

make our xmlnode preserve prefixes



-------------- next part --------------
============================================================
--- libpurple/xmlnode.c	30f07eb32a368a46c334da23dd104007c86d5b11
+++ libpurple/xmlnode.c	3d602916a7095d0f7882ec3bc226855491800d79
@@ -217,15 +217,32 @@ xmlnode_set_attrib_with_namespace(xmlnod
 	g_return_if_fail(value != NULL);
 
 	xmlnode_remove_attrib_with_namespace(node, attr, xmlns);
+	attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
 
+	attrib_node->data = g_strdup(value);
+	attrib_node->xmlns = g_strdup(xmlns);
+
+	xmlnode_insert_child(node, attrib_node);
+}
+
+void
+xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
+{
+	xmlnode *attrib_node;
+
+	g_return_if_fail(node != NULL);
+	g_return_if_fail(attr != NULL);
+	g_return_if_fail(value != NULL);
+
 	attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
 
 	attrib_node->data = g_strdup(value);
-	attrib_node->xmlns = g_strdup(xmlns);
+	attrib_node->prefix = g_strdup(prefix);
 
 	xmlnode_insert_child(node, attrib_node);
 }
 
+
 const char *
 xmlnode_get_attrib(xmlnode *node, const char *attr)
 {
@@ -276,6 +293,20 @@ const char *xmlnode_get_namespace(xmlnod
 	return node->xmlns;
 }
 
+void xmlnode_set_prefix(xmlnode *node, const char *prefix)
+{
+	g_return_if_fail(node != NULL);
+
+	g_free(node->prefix);
+	node->prefix = g_strdup(prefix);
+}
+
+const char *xmlnode_get_prefix(xmlnode *node)
+{
+	g_return_val_if_fail(node != NULL, NULL);                                   
+	return node->prefix;
+}
+
 void
 xmlnode_free(xmlnode *node)
 {
@@ -394,10 +425,22 @@ xmlnode_get_data_unescaped(xmlnode *node
 	return unescaped;
 }
 
+static void
+xmlnode_to_str_foreach_append_ns(const char *key, const char *value,
+	GString *buf)
+{
+	if (*key) {
+		g_string_append_printf(buf, " xmlns:%s='%s'", key, value);
+	} else {
+		g_string_append_printf(buf, " xmlns='%s'", value);
+	}
+}
+
 static char *
 xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
 {
 	GString *text = g_string_new("");
+	const char *prefix;
 	xmlnode *c;
 	char *node_name, *esc, *esc2, *tab = NULL;
 	gboolean need_end = FALSE, pretty = formatting;
@@ -410,9 +453,18 @@ xmlnode_to_str_helper(xmlnode *node, int
 	}
 
 	node_name = g_markup_escape_text(node->name, -1);
-	g_string_append_printf(text, "<%s", node_name);
+	prefix = xmlnode_get_prefix(node);
 
-	if (node->xmlns) {
+	if (prefix) {
+		g_string_append_printf(text, "<%s:%s", prefix, node_name);
+	} else {
+		g_string_append_printf(text, "<%s", node_name);
+	}
+
+	if (node->namespace_map) {
+		g_hash_table_foreach(node->namespace_map,
+			(GHFunc)xmlnode_to_str_foreach_append_ns, text);
+	} else if (node->xmlns) {
 		if(!node->parent || !node->parent->xmlns || strcmp(node->xmlns, node->parent->xmlns))
 		{
 			char *xmlns = g_markup_escape_text(node->xmlns, -1);
@@ -423,9 +475,14 @@ xmlnode_to_str_helper(xmlnode *node, int
 	for(c = node->child; c; c = c->next)
 	{
 		if(c->type == XMLNODE_TYPE_ATTRIB) {
+			const char *aprefix = xmlnode_get_prefix(c);
 			esc = g_markup_escape_text(c->name, -1);
 			esc2 = g_markup_escape_text(c->data, -1);
-			g_string_append_printf(text, " %s='%s'", esc, esc2);
+			if (aprefix) {
+				g_string_append_printf(text, " %s:%s='%s'", aprefix, esc, esc2);
+			} else {
+				g_string_append_printf(text, " %s='%s'", esc, esc2);
+			}
 			g_free(esc);
 			g_free(esc2);
 		} else if(c->type == XMLNODE_TYPE_TAG || c->type == XMLNODE_TYPE_DATA) {
@@ -454,7 +511,11 @@ xmlnode_to_str_helper(xmlnode *node, int
 
 		if(tab && pretty)
 			text = g_string_append(text, tab);
-		g_string_append_printf(text, "</%s>%s", node_name, formatting ? NEWLINE_S : "");
+		if (prefix) {
+			g_string_append_printf(text, "</%s:%s>%s", prefix, node_name, formatting ? NEWLINE_S : "");
+		} else {
+			g_string_append_printf(text, "</%s>%s", node_name, formatting ? NEWLINE_S : "");
+		}
 	} else {
 		g_string_append_printf(text, "/>%s", formatting ? NEWLINE_S : "");
 	}
@@ -503,7 +564,7 @@ xmlnode_parser_element_start_libxml(void
 {
 	struct _xmlnode_parser_data *xpd = user_data;
 	xmlnode *node;
-	int i;
+	int i, j;
 
 	if(!element_name || xpd->error) {
 		return;
@@ -514,8 +575,22 @@ xmlnode_parser_element_start_libxml(void
 			node = xmlnode_new((const char *) element_name);
 
 		xmlnode_set_namespace(node, (const char *) xmlns);
+		xmlnode_set_prefix(node, (const char *)prefix);
 
+		if (nb_namespaces != 0) {
+			node->namespace_map = g_hash_table_new_full(
+				g_str_hash, g_str_equal, g_free, g_free);
+
+			for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
+				const char *key = (const char *)namespaces[j];
+				const char *val = (const char *)namespaces[j + 1];
+				g_hash_table_insert(node->namespace_map,
+					g_strdup(key ? key : ""), g_strdup(val ? val : ""));
+			}
+		}
+
 		for(i=0; i < nb_attributes * 5; i+=5) {
+			const char *prefix = attributes[i + 1];
 			char *txt;
 			int attrib_len = attributes[i+4] - attributes[i+3];
 			char *attrib = g_malloc(attrib_len + 1);
@@ -524,7 +599,11 @@ xmlnode_parser_element_start_libxml(void
 			txt = attrib;
 			attrib = purple_unescape_html(txt);
 			g_free(txt);
-			xmlnode_set_attrib(node, (const char*) attributes[i], attrib);
+			if (prefix && *prefix) {
+				xmlnode_set_attrib_with_prefix(node, (const char*) attributes[i], prefix, attrib);
+			} else {
+				xmlnode_set_attrib(node, (const char*) attributes[i], attrib);
+			}
 			g_free(attrib);
 		}
 
============================================================
--- libpurple/xmlnode.h	ad49fa4e61226e97d0a9c0f25c892b9804464d99
+++ libpurple/xmlnode.h	50557bc86de8eebbe8bdd4d9ab63a370156cc3ed
@@ -55,6 +55,8 @@ struct _xmlnode
 	struct _xmlnode *child;		/**< The child node or @c NULL.*/
 	struct _xmlnode *lastchild;	/**< The last child node or @c NULL.*/
 	struct _xmlnode *next;		/**< The next node or @c NULL. */
+	char *prefix;               /**< The namespace prefix if any. */
+	GHashTable *namespace_map;  /**< The namespace map. */
 };
 
 /**
@@ -154,6 +156,16 @@ void xmlnode_set_attrib(xmlnode *node, c
 void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
 
 /**
+ * Sets a prefixed attribute for a node
+ *
+ * @param node  The node to set an attribute for.
+ * @param attr  The name of the attribute to set
+ * @param xmlns The prefix of the attribute to ste
+ * @param value The value of the attribute
+ */
+void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value);
+
+/**
  * Sets a namespaced attribute for a node
  *
  * @param node  The node to set an attribute for.
@@ -218,6 +230,22 @@ const char *xmlnode_get_namespace(xmlnod
 const char *xmlnode_get_namespace(xmlnode *node);
 
 /**
+ * Sets the prefix of a node
+ *
+ * @param node The node to qualify
+ * @param xmlns The prefix of the node
+ */
+void xmlnode_set_prefix(xmlnode *node, const char *prefix);
+
+/**
+ * Returns the prefix of a node
+ *
+ * @param node The node to get the prefix from
+ * @return The prefix of this node
+ */
+const char *xmlnode_get_prefix(xmlnode *node);
+
+/**
  * Returns the node in a string of xml.
  *
  * @param node The starting node to output.


More information about the Commits mailing list