Mercurial > pidgin
comparison libpurple/xmlnode.c @ 26180: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
| 26179:413b445a6018 | 26180: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 } |
