pidgin: e13689e4: Add xmlnode_set_attrib_full that enables...

qulogic at pidgin.im qulogic at pidgin.im
Fri Mar 13 00:35:47 EDT 2009


-----------------------------------------------------------------
Revision: e13689e4856dc0f8c93c715c70c76bce6a2babca
Ancestor: a87c7d20cd4af1716e08f892a6a39895185f9f3e
Author: qulogic at pidgin.im
Date: 2009-03-13T04:29:11
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/e13689e4856dc0f8c93c715c70c76bce6a2babca

Modified files:
        ChangeLog.API libpurple/protocols/bonjour/parser.c
        libpurple/protocols/jabber/parser.c libpurple/xmlnode.c
        libpurple/xmlnode.h

ChangeLog: 

Add xmlnode_set_attrib_full that enables you to set an attribute with both
a prefix and a namespace. Also, change xmlnode_remove_attribute to remove
all existing attributes that match the name. Otherwise, it would just take
out the first one, and may not do what you want.

Change Bonjour and XMPP to use the new function.

References #7681.
Fixes #8318.

-------------- next part --------------
============================================================
--- ChangeLog.API	360e5fd079d3b227b725ddd06be2c7f1740b3a0b
+++ ChangeLog.API	21154ce150c1085870bec57991a67fd99211ef27
@@ -26,7 +26,15 @@ version 2.6.0 (??/??/2009):
 		* purple_request_field_set_ui_data
 		* purple_strequal
 		* xmlnode_from_file
+		* xmlnode_set_attrib_full
 
+		Changed:
+		* xmlnode_remove_attrib now removes all attributes with the
+		same name.  Previously, it would remove the first one found,
+		which was completely non-deterministic.  If you want to remove
+		the attribute with no namespace, then use NULL with
+		xmlnode_remove_with_namespace.
+
 		Deprecated:
 		* purple_buddy_get_local_alias
 		* purple_notify_user_info_remove_entry
@@ -40,6 +48,8 @@ version 2.6.0 (??/??/2009):
 		* purple_status_set_attr_string
 		* purple_presence_add_status
 		* purple_presence_add_list
+		* xmlnode_set_attrib_with_namespace
+		* xmlnode_set_attrib_with_prefix
 
 	pidgin:
 		Added:
============================================================
--- libpurple/protocols/bonjour/parser.c	2f4fc9959ef5e33edb692e66f8ef5417dbf1cb18
+++ libpurple/protocols/bonjour/parser.c	cf14ad63b56a7e6ff3693c09ee81e1cbe5802555
@@ -91,24 +91,21 @@ bonjour_parser_element_start_libxml(void
 		xmlnode_set_namespace(node, (const char*) namespace);
 
 		for(i=0; i < nb_attributes * 5; i+=5) {
+			const char *name = (const char *)attributes[i];
+			const char *prefix = (const char *)attributes[i+1];
+			const char *attrib_ns = (const char *)attributes[i+2];
 			char *txt;
 			int attrib_len = attributes[i+4] - attributes[i+3];
 			char *attrib = g_malloc(attrib_len + 1);
-			char *attrib_ns = NULL;
 
-			if (attributes[i+2]) {
-				attrib_ns = g_strdup((char*)attributes[i+2]);
-			}
-
 			memcpy(attrib, attributes[i+3], attrib_len);
 			attrib[attrib_len] = '\0';
 
 			txt = attrib;
 			attrib = purple_unescape_html(txt);
 			g_free(txt);
-			xmlnode_set_attrib_with_namespace(node, (const char*) attributes[i], attrib_ns, attrib);
+			xmlnode_set_attrib_full(node, name, attrib_ns, prefix, attrib);
 			g_free(attrib);
-			g_free(attrib_ns);
 		}
 
 		bconv->current = node;
============================================================
--- libpurple/protocols/jabber/parser.c	194cd0b3cf0a5715df59a06101ccc520d9599a5a
+++ libpurple/protocols/jabber/parser.c	157f47562332dbe377dbbb01a4488d20203c96e8
@@ -86,6 +86,8 @@ jabber_parser_element_start_libxml(void 
 			}
 		}
 		for(i=0; i < nb_attributes * 5; i+=5) {
+			const char *name = (const char *)attributes[i];
+			const char *prefix = (const char *)attributes[i+1];
 			const char *attrib_ns = (const char *)attributes[i+2];
 			char *txt;
 			int attrib_len = attributes[i+4] - attributes[i+3];
@@ -97,7 +99,7 @@ jabber_parser_element_start_libxml(void 
 			txt = attrib;
 			attrib = purple_unescape_html(txt);
 			g_free(txt);
-			xmlnode_set_attrib_with_namespace(node, (const char*) attributes[i], attrib_ns, attrib);
+			xmlnode_set_attrib_full(node, name, attrib_ns, prefix, attrib);
 			g_free(attrib);
 		}
 
============================================================
--- libpurple/xmlnode.c	f79e5a19eb6facf7d214eb4b42656ace09e60128
+++ libpurple/xmlnode.c	e9ec80f42cb38945f0b2040c1fdaacefd26c31a1
@@ -27,6 +27,7 @@
  * libxode uses memory pools that we simply have no need for, I decided to
  * write my own stuff.  Also, re-writing this lets me be as lightweight
  * as I want to be.  Thank you libxode for giving me a good starting point */
+#define _PURPLE_XMLNODE_C_
 
 #include "debug.h"
 #include "internal.h"
@@ -126,22 +127,29 @@ xmlnode_remove_attrib(xmlnode *node, con
 	g_return_if_fail(node != NULL);
 	g_return_if_fail(attr != NULL);
 
-	for(attr_node = node->child; attr_node; attr_node = attr_node->next)
-	{
+	attr_node = node->child;
+	while (attr_node) {
 		if(attr_node->type == XMLNODE_TYPE_ATTRIB &&
 				purple_strequal(attr_node->name, attr))
 		{
-			if(sibling == NULL) {
+			if (node->lastchild == attr_node) {
+				node->lastchild = sibling;
+			}
+			if (sibling == NULL) {
 				node->child = attr_node->next;
+				xmlnode_free(attr_node);
+				attr_node = node->child;
 			} else {
 				sibling->next = attr_node->next;
+				sibling = attr_node->next;
+				xmlnode_free(attr_node);
+				attr_node = sibling;
 			}
-			if (node->lastchild == attr_node) {
-				node->lastchild = sibling;
-			}
-			xmlnode_free(attr_node);
-			return;
 		}
+		else
+		{
+			attr_node = attr_node->next;
+		}
 		sibling = attr_node;
 	}
 }
@@ -178,41 +186,24 @@ xmlnode_set_attrib(xmlnode *node, const 
 void
 xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value)
 {
-	xmlnode *attrib_node;
-
-	g_return_if_fail(node != NULL);
-	g_return_if_fail(attr != NULL);
-	g_return_if_fail(value != NULL);
-
 	xmlnode_remove_attrib(node, attr);
-
-	attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
-
-	attrib_node->data = g_strdup(value);
-
-	xmlnode_insert_child(node, attrib_node);
+	xmlnode_set_attrib_full(node, attr, NULL, NULL, value);
 }
 
 void
 xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
 {
-	xmlnode *attrib_node;
+	xmlnode_set_attrib_full(node, attr, xmlns, NULL, value);
+}
 
-	g_return_if_fail(node != NULL);
-	g_return_if_fail(attr != NULL);
-	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_set_attrib_full(node, attr, NULL, prefix, value);
 }
 
 void
-xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
+xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value)
 {
 	xmlnode *attrib_node;
 
@@ -220,9 +211,11 @@ xmlnode_set_attrib_with_prefix(xmlnode *
 	g_return_if_fail(attr != NULL);
 	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);
 	attrib_node->prefix = g_strdup(prefix);
 
 	xmlnode_insert_child(node, attrib_node);
@@ -585,7 +578,8 @@ xmlnode_parser_element_start_libxml(void
 		}
 
 		for(i=0; i < nb_attributes * 5; i+=5) {
-			const char *prefix = (const char *)attributes[i + 1];
+			const char *name = (const char *)attributes[i];
+			const char *prefix = (const char *)attributes[i+1];
 			char *txt;
 			int attrib_len = attributes[i+4] - attributes[i+3];
 			char *attrib = g_malloc(attrib_len + 1);
@@ -594,11 +588,7 @@ xmlnode_parser_element_start_libxml(void
 			txt = attrib;
 			attrib = purple_unescape_html(txt);
 			g_free(txt);
-			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);
-			}
+			xmlnode_set_attrib_full(node, name, NULL, prefix, attrib);
 			g_free(attrib);
 		}
 
============================================================
--- libpurple/xmlnode.h	aa46af3c80747926d5371962bff3ec4ee730a79d
+++ libpurple/xmlnode.h	7482ee804d18db060e638f680b8426d13b88d23c
@@ -157,6 +157,7 @@ void xmlnode_set_attrib(xmlnode *node, c
  */
 void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
 
+#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_XMLNODE_C_)
 /**
  * Sets a prefixed attribute for a node
  *
@@ -164,6 +165,8 @@ void xmlnode_set_attrib(xmlnode *node, c
  * @param attr   The name of the attribute to set
  * @param prefix The prefix of the attribute to ste
  * @param value  The value of the attribute
+ *
+ * @deprecated Use xmlnode_set_attrib_full instead.
  */
 void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value);
 
@@ -174,10 +177,27 @@ void xmlnode_set_attrib_with_prefix(xmln
  * @param attr  The name of the attribute to set
  * @param xmlns The namespace of the attribute to ste
  * @param value The value of the attribute
+ *
+ * @deprecated Use xmlnode_set_attrib_full instead.
  */
 void xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value);
+#endif /* PURPLE_DISABLE_DEPRECATED */
 
 /**
+ * Sets a namespaced 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 namespace of the attribute to ste
+ * @param prefix The prefix of the attribute to ste
+ * @param value  The value of the attribute
+ *
+ * @since 2.6.0
+ */
+void xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns,
+	const char *prefix, const char *value);
+
+/**
  * Gets an attribute from a node.
  *
  * @param node The node to get an attribute from.


More information about the Commits mailing list