| 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 } |