libgaim/xmlnode.c

changeset 14498
ede839a78714
parent 14386
5563ea640401
child 14690
9287ecc4adb1
equal deleted inserted replaced
14497:3ac1961731a9 14498:ede839a78714
27 * write my own stuff. Also, re-writing this lets me be as lightweight 27 * write my own stuff. Also, re-writing this lets me be as lightweight
28 * as I want to be. Thank you libxode for giving me a good starting point */ 28 * as I want to be. Thank you libxode for giving me a good starting point */
29 29
30 #include "internal.h" 30 #include "internal.h"
31 31
32 #ifdef HAVE_LIBXML
33 #include <libxml/parser.h> 32 #include <libxml/parser.h>
34 #endif
35 #include <string.h> 33 #include <string.h>
36 #include <glib.h> 34 #include <glib.h>
37 35
38 #include "dbus-maybe.h" 36 #include "dbus-maybe.h"
39 #include "util.h" 37 #include "util.h"
179 } 177 }
180 178
181 179
182 void xmlnode_set_namespace(xmlnode *node, const char *xmlns) 180 void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
183 { 181 {
184 #ifdef HAVE_LIBXML
185 g_return_if_fail(node != NULL); 182 g_return_if_fail(node != NULL);
186 183
187 g_free(node->namespace); 184 g_free(node->namespace);
188 node->namespace = g_strdup(xmlns); 185 node->namespace = g_strdup(xmlns);
189 #else
190 xmlnode_set_attrib(node, "xmlns", xmlns);
191 #endif
192 } 186 }
193 187
194 const char *xmlnode_get_namespace(xmlnode *node) 188 const char *xmlnode_get_namespace(xmlnode *node)
195 { 189 {
196 #ifdef HAVE_LIBXML
197 g_return_val_if_fail(node != NULL, NULL); 190 g_return_val_if_fail(node != NULL, NULL);
198 191
199 return node->namespace; 192 return node->namespace;
200 #else
201 return xmlnode_get_attrib(node, "xmlns");
202 #endif
203 } 193 }
204 194
205 void 195 void
206 xmlnode_free(xmlnode *node) 196 xmlnode_free(xmlnode *node)
207 { 197 {
216 x = y; 206 x = y;
217 } 207 }
218 208
219 g_free(node->name); 209 g_free(node->name);
220 g_free(node->data); 210 g_free(node->data);
221 #ifdef HAVE_LIBXML
222 g_free(node->namespace); 211 g_free(node->namespace);
223 #endif
224 212
225 GAIM_DBUS_UNREGISTER_POINTER(node); 213 GAIM_DBUS_UNREGISTER_POINTER(node);
226 g_free(node); 214 g_free(node);
227 } 215 }
228 216
303 } 291 }
304 292
305 node_name = g_markup_escape_text(node->name, -1); 293 node_name = g_markup_escape_text(node->name, -1);
306 g_string_append_printf(text, "<%s", node_name); 294 g_string_append_printf(text, "<%s", node_name);
307 295
308 #ifdef HAVE_LIBXML
309 if (node->namespace) { 296 if (node->namespace) {
310 char *namespace = g_markup_escape_text(node->namespace, -1); 297 char *namespace = g_markup_escape_text(node->namespace, -1);
311 g_string_append_printf(text, " xmlns='%s'", namespace); 298 g_string_append_printf(text, " xmlns='%s'", namespace);
312 g_free(namespace); 299 g_free(namespace);
313 } 300 }
314 #endif
315 for(c = node->child; c; c = c->next) 301 for(c = node->child; c; c = c->next)
316 { 302 {
317 if(c->type == XMLNODE_TYPE_ATTRIB) { 303 if(c->type == XMLNODE_TYPE_ATTRIB) {
318 esc = g_markup_escape_text(c->name, -1); 304 esc = g_markup_escape_text(c->name, -1);
319 esc2 = g_markup_escape_text(c->data, -1); 305 esc2 = g_markup_escape_text(c->data, -1);
384 370
385 struct _xmlnode_parser_data { 371 struct _xmlnode_parser_data {
386 xmlnode *current; 372 xmlnode *current;
387 }; 373 };
388 374
389 #ifdef HAVE_LIBXML
390 static void 375 static void
391 xmlnode_parser_element_start_libxml(void *user_data, 376 xmlnode_parser_element_start_libxml(void *user_data,
392 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace, 377 const xmlChar *element_name, const xmlChar *prefix, const xmlChar *namespace,
393 int nb_namespaces, const xmlChar **namespaces, 378 int nb_namespaces, const xmlChar **namespaces,
394 int nb_attributes, int nb_defaulted, const xmlChar **attributes) 379 int nb_attributes, int nb_defaulted, const xmlChar **attributes)
406 node = xmlnode_new(element_name); 391 node = xmlnode_new(element_name);
407 392
408 xmlnode_set_namespace(node, namespace); 393 xmlnode_set_namespace(node, namespace);
409 394
410 for(i=0; i < nb_attributes * 5; i+=5) { 395 for(i=0; i < nb_attributes * 5; i+=5) {
411 #ifdef HAVE_LIBXML
412 char *txt; 396 char *txt;
413 #endif
414 int attrib_len = attributes[i+4] - attributes[i+3]; 397 int attrib_len = attributes[i+4] - attributes[i+3];
415 char *attrib = g_malloc(attrib_len + 1); 398 char *attrib = g_malloc(attrib_len + 1);
416 memcpy(attrib, attributes[i+3], attrib_len); 399 memcpy(attrib, attributes[i+3], attrib_len);
417 attrib[attrib_len] = '\0'; 400 attrib[attrib_len] = '\0';
418 #ifdef HAVE_LIBXML
419 txt = attrib; 401 txt = attrib;
420 attrib = gaim_unescape_html(txt); 402 attrib = gaim_unescape_html(txt);
421 g_free(txt); 403 g_free(txt);
422 #endif
423 xmlnode_set_attrib(node, attributes[i], attrib); 404 xmlnode_set_attrib(node, attributes[i], attrib);
424 g_free(attrib); 405 g_free(attrib);
425 } 406 }
426 407
427 xpd->current = node; 408 xpd->current = node;
455 return; 436 return;
456 437
457 xmlnode_insert_data(xpd->current, text, text_len); 438 xmlnode_insert_data(xpd->current, text, text_len);
458 } 439 }
459 440
460 #else
461
462 static void
463 xmlnode_parser_element_start(GMarkupParseContext *context,
464 const char *element_name, const char **attrib_names,
465 const char **attrib_values, gpointer user_data, GError **error)
466 {
467 struct _xmlnode_parser_data *xpd = user_data;
468 xmlnode *node;
469 int i;
470
471 if(!element_name) {
472 return;
473 } else {
474 if(xpd->current)
475 node = xmlnode_new_child(xpd->current, element_name);
476 else
477 node = xmlnode_new(element_name);
478
479 for(i=0; attrib_names[i]; i++)
480 xmlnode_set_attrib(node, attrib_names[i], attrib_values[i]);
481
482 xpd->current = node;
483 }
484 }
485
486 static void
487 xmlnode_parser_element_end(GMarkupParseContext *context,
488 const char *element_name, gpointer user_data, GError **error)
489 {
490 struct _xmlnode_parser_data *xpd = user_data;
491
492 if(!element_name || !xpd->current)
493 return;
494
495 if(xpd->current->parent) {
496 if(!strcmp(xpd->current->name, element_name))
497 xpd->current = xpd->current->parent;
498 }
499 }
500
501 static void
502 xmlnode_parser_element_text(GMarkupParseContext *context, const char *text,
503 gsize text_len, gpointer user_data, GError **error)
504 {
505 struct _xmlnode_parser_data *xpd = user_data;
506
507 if(!xpd->current)
508 return;
509
510 if(!text || !text_len)
511 return;
512
513 xmlnode_insert_data(xpd->current, text, text_len);
514 }
515 #endif
516
517 #ifdef HAVE_LIBXML
518 static xmlSAXHandler xmlnode_parser_libxml = { 441 static xmlSAXHandler xmlnode_parser_libxml = {
519 .internalSubset = NULL, 442 .internalSubset = NULL,
520 .isStandalone = NULL, 443 .isStandalone = NULL,
521 .hasInternalSubset = NULL, 444 .hasInternalSubset = NULL,
522 .hasExternalSubset = NULL, 445 .hasExternalSubset = NULL,
547 ._private = NULL, 470 ._private = NULL,
548 .startElementNs = xmlnode_parser_element_start_libxml, 471 .startElementNs = xmlnode_parser_element_start_libxml,
549 .endElementNs = xmlnode_parser_element_end_libxml, 472 .endElementNs = xmlnode_parser_element_end_libxml,
550 .serror = NULL 473 .serror = NULL
551 }; 474 };
552 #else
553 static GMarkupParser xmlnode_parser = {
554 xmlnode_parser_element_start,
555 xmlnode_parser_element_end,
556 xmlnode_parser_element_text,
557 NULL,
558 NULL
559 };
560 #endif
561 475
562 xmlnode * 476 xmlnode *
563 xmlnode_from_str(const char *str, gssize size) 477 xmlnode_from_str(const char *str, gssize size)
564 { 478 {
565 struct _xmlnode_parser_data *xpd; 479 struct _xmlnode_parser_data *xpd;
566 xmlnode *ret; 480 xmlnode *ret;
567 #ifndef HAVE_LIBXML
568 GMarkupParseContext *context;
569 #endif
570 gsize real_size; 481 gsize real_size;
571 482
572 g_return_val_if_fail(str != NULL, NULL); 483 g_return_val_if_fail(str != NULL, NULL);
573 484
574 real_size = size < 0 ? strlen(str) : size; 485 real_size = size < 0 ? strlen(str) : size;
575 xpd = g_new0(struct _xmlnode_parser_data, 1); 486 xpd = g_new0(struct _xmlnode_parser_data, 1);
576 487
577 #ifdef HAVE_LIBXML
578 if (xmlSAXUserParseMemory(&xmlnode_parser_libxml, xpd, str, real_size) < 0) { 488 if (xmlSAXUserParseMemory(&xmlnode_parser_libxml, xpd, str, real_size) < 0) {
579 while(xpd->current && xpd->current->parent) 489 while(xpd->current && xpd->current->parent)
580 xpd->current = xpd->current->parent; 490 xpd->current = xpd->current->parent;
581 if(xpd->current) 491 if(xpd->current)
582 xmlnode_free(xpd->current); 492 xmlnode_free(xpd->current);
583 xpd->current = NULL; 493 xpd->current = NULL;
584 } 494 }
585 #else
586 context = g_markup_parse_context_new(&xmlnode_parser, 0, xpd, NULL);
587
588 if(!g_markup_parse_context_parse(context, str, real_size, NULL)) {
589 while(xpd->current && xpd->current->parent)
590 xpd->current = xpd->current->parent;
591 if(xpd->current)
592 xmlnode_free(xpd->current);
593 xpd->current = NULL;
594 }
595 g_markup_parse_context_free(context);
596 #endif
597 ret = xpd->current; 495 ret = xpd->current;
598 g_free(xpd); 496 g_free(xpd);
599 return ret; 497 return ret;
600 } 498 }
601 499

mercurial