summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKa-Hing Cheung <khc@pidgin.im>2007-11-10 05:16:58 +0000
committerKa-Hing Cheung <khc@pidgin.im>2007-11-10 05:16:58 +0000
commitb48b87811e87338179b4cf661ecd0aa3f44d1da0 (patch)
tree425f22898b7d51931c73e511e87eec44450f6f7e
parent62ffec02e46f7e99b55f8ec373979f585a3c27b5 (diff)
downloadpidgin-b48b87811e87338179b4cf661ecd0aa3f44d1da0.tar.gz
make our xmlnode preserve prefixes
-rw-r--r--libpurple/xmlnode.c93
-rw-r--r--libpurple/xmlnode.h28
2 files changed, 114 insertions, 7 deletions
diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c
index e2f72694cf..e069082eca 100644
--- a/libpurple/xmlnode.c
+++ b/libpurple/xmlnode.c
@@ -217,7 +217,6 @@ xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *x
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);
@@ -226,6 +225,24 @@ xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *x
xmlnode_insert_child(node, attrib_node);
}
+void
+xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
+{
+ xmlnode *attrib_node;
+
+ g_return_if_fail(node != NULL);
+ g_return_if_fail(attr != NULL);
+ g_return_if_fail(value != NULL);
+
+ attrib_node = new_node(attr, XMLNODE_TYPE_ATTRIB);
+
+ attrib_node->data = g_strdup(value);
+ attrib_node->prefix = g_strdup(prefix);
+
+ xmlnode_insert_child(node, attrib_node);
+}
+
+
const char *
xmlnode_get_attrib(xmlnode *node, const char *attr)
{
@@ -276,6 +293,20 @@ const char *xmlnode_get_namespace(xmlnode *node)
return node->xmlns;
}
+void xmlnode_set_prefix(xmlnode *node, const char *prefix)
+{
+ g_return_if_fail(node != NULL);
+
+ g_free(node->prefix);
+ node->prefix = g_strdup(prefix);
+}
+
+const char *xmlnode_get_prefix(xmlnode *node)
+{
+ g_return_val_if_fail(node != NULL, NULL);
+ return node->prefix;
+}
+
void
xmlnode_free(xmlnode *node)
{
@@ -394,10 +425,22 @@ xmlnode_get_data_unescaped(xmlnode *node)
return unescaped;
}
+static void
+xmlnode_to_str_foreach_append_ns(const char *key, const char *value,
+ GString *buf)
+{
+ if (*key) {
+ g_string_append_printf(buf, " xmlns:%s='%s'", key, value);
+ } else {
+ g_string_append_printf(buf, " xmlns='%s'", value);
+ }
+}
+
static char *
xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
{
GString *text = g_string_new("");
+ const char *prefix;
xmlnode *c;
char *node_name, *esc, *esc2, *tab = NULL;
gboolean need_end = FALSE, pretty = formatting;
@@ -410,9 +453,18 @@ xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
}
node_name = g_markup_escape_text(node->name, -1);
- g_string_append_printf(text, "<%s", node_name);
+ prefix = xmlnode_get_prefix(node);
+
+ if (prefix) {
+ g_string_append_printf(text, "<%s:%s", prefix, node_name);
+ } else {
+ g_string_append_printf(text, "<%s", node_name);
+ }
- if (node->xmlns) {
+ if (node->namespace_map) {
+ g_hash_table_foreach(node->namespace_map,
+ (GHFunc)xmlnode_to_str_foreach_append_ns, text);
+ } else if (node->xmlns) {
if(!node->parent || !node->parent->xmlns || strcmp(node->xmlns, node->parent->xmlns))
{
char *xmlns = g_markup_escape_text(node->xmlns, -1);
@@ -423,9 +475,14 @@ xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
for(c = node->child; c; c = c->next)
{
if(c->type == XMLNODE_TYPE_ATTRIB) {
+ const char *aprefix = xmlnode_get_prefix(c);
esc = g_markup_escape_text(c->name, -1);
esc2 = g_markup_escape_text(c->data, -1);
- g_string_append_printf(text, " %s='%s'", esc, esc2);
+ if (aprefix) {
+ g_string_append_printf(text, " %s:%s='%s'", aprefix, esc, esc2);
+ } else {
+ g_string_append_printf(text, " %s='%s'", esc, esc2);
+ }
g_free(esc);
g_free(esc2);
} else if(c->type == XMLNODE_TYPE_TAG || c->type == XMLNODE_TYPE_DATA) {
@@ -454,7 +511,11 @@ xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
if(tab && pretty)
text = g_string_append(text, tab);
- g_string_append_printf(text, "</%s>%s", node_name, formatting ? NEWLINE_S : "");
+ if (prefix) {
+ g_string_append_printf(text, "</%s:%s>%s", prefix, node_name, formatting ? NEWLINE_S : "");
+ } else {
+ g_string_append_printf(text, "</%s>%s", node_name, formatting ? NEWLINE_S : "");
+ }
} else {
g_string_append_printf(text, "/>%s", formatting ? NEWLINE_S : "");
}
@@ -503,7 +564,7 @@ xmlnode_parser_element_start_libxml(void *user_data,
{
struct _xmlnode_parser_data *xpd = user_data;
xmlnode *node;
- int i;
+ int i, j;
if(!element_name || xpd->error) {
return;
@@ -514,8 +575,22 @@ xmlnode_parser_element_start_libxml(void *user_data,
node = xmlnode_new((const char *) element_name);
xmlnode_set_namespace(node, (const char *) xmlns);
+ xmlnode_set_prefix(node, (const char *)prefix);
+
+ if (nb_namespaces != 0) {
+ node->namespace_map = g_hash_table_new_full(
+ g_str_hash, g_str_equal, g_free, g_free);
+
+ for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
+ const char *key = (const char *)namespaces[j];
+ const char *val = (const char *)namespaces[j + 1];
+ g_hash_table_insert(node->namespace_map,
+ g_strdup(key ? key : ""), g_strdup(val ? val : ""));
+ }
+ }
for(i=0; i < nb_attributes * 5; i+=5) {
+ const char *prefix = attributes[i + 1];
char *txt;
int attrib_len = attributes[i+4] - attributes[i+3];
char *attrib = g_malloc(attrib_len + 1);
@@ -524,7 +599,11 @@ xmlnode_parser_element_start_libxml(void *user_data,
txt = attrib;
attrib = purple_unescape_html(txt);
g_free(txt);
- xmlnode_set_attrib(node, (const char*) attributes[i], attrib);
+ 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);
+ }
g_free(attrib);
}
diff --git a/libpurple/xmlnode.h b/libpurple/xmlnode.h
index 25c9f1e743..c3c5d7e8f1 100644
--- a/libpurple/xmlnode.h
+++ b/libpurple/xmlnode.h
@@ -55,6 +55,8 @@ struct _xmlnode
struct _xmlnode *child; /**< The child node or @c NULL.*/
struct _xmlnode *lastchild; /**< The last child node or @c NULL.*/
struct _xmlnode *next; /**< The next node or @c NULL. */
+ char *prefix; /**< The namespace prefix if any. */
+ GHashTable *namespace_map; /**< The namespace map. */
};
/**
@@ -154,6 +156,16 @@ char *xmlnode_get_data_unescaped(xmlnode *node);
void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
/**
+ * Sets a prefixed 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 prefix of the attribute to ste
+ * @param value The value of the attribute
+ */
+void xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value);
+
+/**
* Sets a namespaced attribute for a node
*
* @param node The node to set an attribute for.
@@ -218,6 +230,22 @@ void xmlnode_set_namespace(xmlnode *node, const char *xmlns);
const char *xmlnode_get_namespace(xmlnode *node);
/**
+ * Sets the prefix of a node
+ *
+ * @param node The node to qualify
+ * @param xmlns The prefix of the node
+ */
+void xmlnode_set_prefix(xmlnode *node, const char *prefix);
+
+/**
+ * Returns the prefix of a node
+ *
+ * @param node The node to get the prefix from
+ * @return The prefix of this node
+ */
+const char *xmlnode_get_prefix(xmlnode *node);
+
+/**
* Returns the node in a string of xml.
*
* @param node The starting node to output.