comparison libpurple/xmlnode.c @ 26262:b03430dae08e

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.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 13 Mar 2009 04:29:11 +0000
parents 4b8c4870b13a
children 38238d41923b
comparison
equal deleted inserted replaced
26261:413b445a6018 26262:b03430dae08e
25 25
26 /* A lot of this code at least resembles the code in libxode, but since 26 /* A lot of this code at least resembles the code in libxode, but since
27 * libxode uses memory pools that we simply have no need for, I decided to 27 * libxode uses memory pools that we simply have no need for, I decided to
28 * write my own stuff. Also, re-writing this lets me be as lightweight 28 * write my own stuff. Also, re-writing this lets me be as lightweight
29 * as I want to be. Thank you libxode for giving me a good starting point */ 29 * as I want to be. Thank you libxode for giving me a good starting point */
30 #define _PURPLE_XMLNODE_C_
30 31
31 #include "debug.h" 32 #include "debug.h"
32 #include "internal.h" 33 #include "internal.h"
33 34
34 #include <libxml/parser.h> 35 #include <libxml/parser.h>
124 xmlnode *attr_node, *sibling = NULL; 125 xmlnode *attr_node, *sibling = NULL;
125 126
126 g_return_if_fail(node != NULL); 127 g_return_if_fail(node != NULL);
127 g_return_if_fail(attr != NULL); 128 g_return_if_fail(attr != NULL);
128 129
129 for(attr_node = node->child; attr_node; attr_node = attr_node->next) 130 attr_node = node->child;
130 { 131 while (attr_node) {
131 if(attr_node->type == XMLNODE_TYPE_ATTRIB && 132 if(attr_node->type == XMLNODE_TYPE_ATTRIB &&
132 purple_strequal(attr_node->name, attr)) 133 purple_strequal(attr_node->name, attr))
133 { 134 {
134 if(sibling == NULL) {
135 node->child = attr_node->next;
136 } else {
137 sibling->next = attr_node->next;
138 }
139 if (node->lastchild == attr_node) { 135 if (node->lastchild == attr_node) {
140 node->lastchild = sibling; 136 node->lastchild = sibling;
141 } 137 }
142 xmlnode_free(attr_node); 138 if (sibling == NULL) {
143 return; 139 node->child = attr_node->next;
140 xmlnode_free(attr_node);
141 attr_node = node->child;
142 } else {
143 sibling->next = attr_node->next;
144 sibling = attr_node->next;
145 xmlnode_free(attr_node);
146 attr_node = sibling;
147 }
148 }
149 else
150 {
151 attr_node = attr_node->next;
144 } 152 }
145 sibling = attr_node; 153 sibling = attr_node;
146 } 154 }
147 } 155 }
148 156
176 } 184 }
177 185
178 void 186 void
179 xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value) 187 xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value)
180 { 188 {
189 xmlnode_remove_attrib(node, attr);
190 xmlnode_set_attrib_full(node, attr, NULL, NULL, value);
191 }
192
193 void
194 xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
195 {
196 xmlnode_set_attrib_full(node, attr, xmlns, NULL, value);
197 }
198
199 void
200 xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
201 {
202 xmlnode_set_attrib_full(node, attr, NULL, prefix, value);
203 }
204
205 void
206 xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value)
207 {
181 xmlnode *attrib_node; 208 xmlnode *attrib_node;
182 209
183 g_return_if_fail(node != NULL); 210 g_return_if_fail(node != NULL);
184 g_return_if_fail(attr != NULL); 211 g_return_if_fail(attr != NULL);
185 g_return_if_fail(value != NULL); 212 g_return_if_fail(value != NULL);
186 213
187 xmlnode_remove_attrib(node, attr);
188
189 attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
190
191 attrib_node->data = g_strdup(value);
192
193 xmlnode_insert_child(node, attrib_node);
194 }
195
196 void
197 xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
198 {
199 xmlnode *attrib_node;
200
201 g_return_if_fail(node != NULL);
202 g_return_if_fail(attr != NULL);
203 g_return_if_fail(value != NULL);
204
205 xmlnode_remove_attrib_with_namespace(node, attr, xmlns); 214 xmlnode_remove_attrib_with_namespace(node, attr, xmlns);
206 attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB); 215 attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
207 216
208 attrib_node->data = g_strdup(value); 217 attrib_node->data = g_strdup(value);
209 attrib_node->xmlns = g_strdup(xmlns); 218 attrib_node->xmlns = g_strdup(xmlns);
210
211 xmlnode_insert_child(node, attrib_node);
212 }
213
214 void
215 xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
216 {
217 xmlnode *attrib_node;
218
219 g_return_if_fail(node != NULL);
220 g_return_if_fail(attr != NULL);
221 g_return_if_fail(value != NULL);
222
223 attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
224
225 attrib_node->data = g_strdup(value);
226 attrib_node->prefix = g_strdup(prefix); 219 attrib_node->prefix = g_strdup(prefix);
227 220
228 xmlnode_insert_child(node, attrib_node); 221 xmlnode_insert_child(node, attrib_node);
229 } 222 }
230 223
583 g_strdup(key ? key : ""), g_strdup(val ? val : "")); 576 g_strdup(key ? key : ""), g_strdup(val ? val : ""));
584 } 577 }
585 } 578 }
586 579
587 for(i=0; i < nb_attributes * 5; i+=5) { 580 for(i=0; i < nb_attributes * 5; i+=5) {
588 const char *prefix = (const char *)attributes[i + 1]; 581 const char *name = (const char *)attributes[i];
582 const char *prefix = (const char *)attributes[i+1];
589 char *txt; 583 char *txt;
590 int attrib_len = attributes[i+4] - attributes[i+3]; 584 int attrib_len = attributes[i+4] - attributes[i+3];
591 char *attrib = g_malloc(attrib_len + 1); 585 char *attrib = g_malloc(attrib_len + 1);
592 memcpy(attrib, attributes[i+3], attrib_len); 586 memcpy(attrib, attributes[i+3], attrib_len);
593 attrib[attrib_len] = '\0'; 587 attrib[attrib_len] = '\0';
594 txt = attrib; 588 txt = attrib;
595 attrib = purple_unescape_html(txt); 589 attrib = purple_unescape_html(txt);
596 g_free(txt); 590 g_free(txt);
597 if (prefix && *prefix) { 591 xmlnode_set_attrib_full(node, name, NULL, prefix, attrib);
598 xmlnode_set_attrib_with_prefix(node, (const char*) attributes[i], prefix, attrib);
599 } else {
600 xmlnode_set_attrib(node, (const char*) attributes[i], attrib);
601 }
602 g_free(attrib); 592 g_free(attrib);
603 } 593 }
604 594
605 xpd->current = node; 595 xpd->current = node;
606 } 596 }