summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Frydrych <tf@linux.intel.com>2011-01-31 15:15:36 +0000
committerTomas Frydrych <tf@linux.intel.com>2011-02-10 12:12:34 +0000
commitdb9aefd94e376fb5a984bd59f860adb0abae532d (patch)
treecc36de9293294812aa0ecd9f3f6a1c8af315f855
parent880049882106f92ab8db7befa3d6d66ab30d4c37 (diff)
xml-node: API for manually constructing and outputting XML
Split out RestXmlNode into separate source files and added simple API for manually constructing tree of RextXmlNodes and converting such a tree to a string: * xml_node_add_child() * xml_node_add_attribute() * xml_node_set_content() * xml_node_print() Includes xml test for make check
-rw-r--r--rest/Makefile.am2
-rw-r--r--rest/rest-private.h7
-rw-r--r--rest/rest-xml-node.c399
-rw-r--r--rest/rest-xml-node.h75
-rw-r--r--rest/rest-xml-parser.c215
-rw-r--r--rest/rest-xml-parser.h36
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/xml.c85
8 files changed, 574 insertions, 248 deletions
diff --git a/rest/Makefile.am b/rest/Makefile.am
index 09acd12..f3f8517 100644
--- a/rest/Makefile.am
+++ b/rest/Makefile.am
@@ -8,6 +8,7 @@ lib_sources = \
rest-proxy.c \
rest-proxy-call.c \
rest-proxy-call-private.h \
+ rest-xml-node.c \
rest-xml-parser.c \
rest-main.c \
rest-private.h \
@@ -28,6 +29,7 @@ lib_headers = \
oauth-proxy-call.h \
oauth2-proxy.h \
oauth2-proxy-call.h \
+ rest-xml-node.h \
rest-xml-parser.h
lib_LTLIBRARIES = librest-@API_VERSION@.la
diff --git a/rest/rest-private.h b/rest/rest-private.h
index 400ead2..b0f1fe4 100644
--- a/rest/rest-private.h
+++ b/rest/rest-private.h
@@ -26,6 +26,7 @@
#include <glib.h>
#include <rest/rest-proxy.h>
#include <rest/rest-proxy-call.h>
+#include <rest/rest-xml-node.h>
#include <libsoup/soup.h>
G_BEGIN_DECLS
@@ -58,5 +59,11 @@ void _rest_proxy_cancel_message (RestProxy *proxy,
SoupMessage *message);
guint _rest_proxy_send_message (RestProxy *proxy,
SoupMessage *message);
+
+RestXmlNode *_rest_xml_node_new (void);
+void _rest_xml_node_reverse_children_siblings (RestXmlNode *node);
+RestXmlNode *_rest_xml_node_prepend (RestXmlNode *cur_node,
+ RestXmlNode *new_node);
+
G_END_DECLS
#endif /* _REST_PRIVATE */
diff --git a/rest/rest-xml-node.c b/rest/rest-xml-node.c
new file mode 100644
index 0000000..a691754
--- /dev/null
+++ b/rest/rest-xml-node.c
@@ -0,0 +1,399 @@
+/*
+ * librest - RESTful web services access
+ * Copyright (c) 2008, 2009, 2011, Intel Corporation.
+ *
+ * Authors: Rob Bradford <rob@linux.intel.com>
+ * Ross Burton <ross@linux.intel.com>
+ * Tomas Frydrych <tf@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "rest-xml-node.h"
+
+#define G(x) (gchar *)x
+
+static RestXmlNode *
+rest_xml_node_reverse_siblings (RestXmlNode *current)
+{
+ RestXmlNode *next;
+ RestXmlNode *prev = NULL;
+
+ while (current)
+ {
+ next = current->next;
+ current->next = prev;
+
+ prev = current;
+ current = next;
+ }
+
+ return prev;
+}
+
+void
+_rest_xml_node_reverse_children_siblings (RestXmlNode *node)
+{
+ GList *l, *children;
+ RestXmlNode *new_node;
+
+ children = g_hash_table_get_values (node->children);
+
+ for (l = children; l; l = l->next)
+ {
+ new_node = rest_xml_node_reverse_siblings ((RestXmlNode *)l->data);
+ g_hash_table_insert (node->children, new_node->name, new_node);
+ }
+
+ if (children)
+ g_list_free (children);
+}
+
+/*
+ * _rest_xml_node_prepend:
+ * @cur_node: a sibling #RestXmlNode to prepend the new before
+ * @new_node: new #RestXmlNode to prepend to the siblings list
+ *
+ * Prepends new_node to the list of siblings starting at cur_node.
+ *
+ * Return value: (transfer none): returns new start of the sibling list
+ */
+RestXmlNode *
+_rest_xml_node_prepend (RestXmlNode *cur_node, RestXmlNode *new_node)
+{
+ g_assert (new_node->next == NULL);
+ new_node->next = cur_node;
+
+ return new_node;
+}
+
+/*
+ * rest_xml_node_append_end:
+ * @cur_node: a member of the sibling #RestXmlNode list
+ * @new_node: new #RestXmlNode to append to the siblings list
+ *
+ * Appends new_node to end of the list of siblings containing cur_node.
+ */
+static void
+rest_xml_node_append_end (RestXmlNode *cur_node, RestXmlNode *new_node)
+{
+ RestXmlNode *tmp = cur_node;
+
+ g_return_if_fail (cur_node);
+
+ while (tmp->next)
+ tmp = tmp->next;
+
+ tmp->next = new_node;
+}
+
+GType
+rest_xml_node_get_type (void)
+{
+ static GType type = 0;
+ if (G_UNLIKELY (type == 0)) {
+ type = g_boxed_type_register_static ("RestXmlNode",
+ (GBoxedCopyFunc)rest_xml_node_ref,
+ (GBoxedFreeFunc)rest_xml_node_unref);
+ }
+ return type;
+}
+
+/*
+ * _rest_xml_node_new:
+ *
+ * Creates a new instance of #RestXmlNode.
+ *
+ * Return value: (transfer full): newly allocated #RestXmlNode.
+ */
+RestXmlNode *
+_rest_xml_node_new ()
+{
+ RestXmlNode *node;
+
+ node = g_slice_new0 (RestXmlNode);
+ node->ref_count = 1;
+ node->children = g_hash_table_new (NULL, NULL);
+ node->attrs = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ return node;
+}
+
+/**
+ * rest_xml_node_ref:
+ * @node: a #RestXmlNode
+ *
+ * Increases the reference count of @node.
+ *
+ * Returns: the same @node.
+ */
+RestXmlNode *
+rest_xml_node_ref (RestXmlNode *node)
+{
+ g_return_val_if_fail (node, NULL);
+ g_return_val_if_fail (node->ref_count > 0, NULL);
+
+ g_atomic_int_inc (&node->ref_count);
+
+ return node;
+}
+
+/**
+ * rest_xml_node_unref:
+ * @node: a #RestXmlNode
+ *
+ * Decreases the reference count of @node. When its reference count drops to 0,
+ * the node is finalized (i.e. its memory is freed).
+ */
+void
+rest_xml_node_unref (RestXmlNode *node)
+{
+ GList *l;
+ RestXmlNode *next = NULL;
+ g_return_if_fail (node);
+ g_return_if_fail (node->ref_count > 0);
+
+ /* Try and unref the chain, this is equivalent to being tail recursively
+ * unreffing the next pointer
+ */
+ while (node && g_atomic_int_dec_and_test (&node->ref_count))
+ {
+ /*
+ * Save this pointer now since we are going to free the structure it
+ * contains soon.
+ */
+ next = node->next;
+
+ l = g_hash_table_get_values (node->children);
+ while (l)
+ {
+ rest_xml_node_unref ((RestXmlNode *)l->data);
+ l = g_list_delete_link (l, l);
+ }
+
+ g_hash_table_unref (node->children);
+ g_hash_table_unref (node->attrs);
+ g_free (node->content);
+ g_slice_free (RestXmlNode, node);
+
+ /*
+ * Free the next in the chain by updating node. If we're at the end or
+ * there are no siblings then the next = NULL definition deals with this
+ * case
+ */
+ node = next;
+ }
+}
+
+G_GNUC_DEPRECATED void
+rest_xml_node_free (RestXmlNode *node)
+{
+ rest_xml_node_unref (node);
+}
+
+/**
+ * rest_xml_node_get_attr:
+ * @node: a #RestXmlNode
+ * @attr_name: the name of an attribute
+ *
+ * Get the value of the attribute named @attr_name, or %NULL if it doesn't
+ * exist.
+ *
+ * Returns: the attribute value. This string is owned by #RestXmlNode and should
+ * not be freed.
+ */
+const gchar *
+rest_xml_node_get_attr (RestXmlNode *node,
+ const gchar *attr_name)
+{
+ return g_hash_table_lookup (node->attrs, attr_name);
+}
+
+/**
+ * rest_xml_node_find:
+ * @start: a #RestXmlNode
+ * @tag: the name of a node
+ *
+ * Searches for the first child node of @start named @tag.
+ *
+ * Returns: the first child node, or %NULL if it doesn't exist.
+ */
+RestXmlNode *
+rest_xml_node_find (RestXmlNode *start,
+ const gchar *tag)
+{
+ RestXmlNode *node;
+ RestXmlNode *tmp;
+ GQueue stack = G_QUEUE_INIT;
+ GList *children, *l;
+ const char *tag_interned;
+
+ g_return_val_if_fail (start, NULL);
+ g_return_val_if_fail (start->ref_count > 0, NULL);
+
+ tag_interned = g_intern_string (tag);
+
+ g_queue_push_head (&stack, start);
+
+ while ((node = g_queue_pop_head (&stack)) != NULL)
+ {
+ if ((tmp = g_hash_table_lookup (node->children, tag_interned)) != NULL)
+ {
+ g_queue_clear (&stack);
+ return tmp;
+ }
+
+ children = g_hash_table_get_values (node->children);
+ for (l = children; l; l = l->next)
+ {
+ g_queue_push_head (&stack, l->data);
+ }
+ g_list_free (children);
+ }
+
+ g_queue_clear (&stack);
+ return NULL;
+}
+
+/**
+ * rest_xml_node_print_node:
+ * @node: #RestXmlNode
+ *
+ * Recursively outputs given node and it's children.
+ *
+ * Return value: (transfer: full): xml string representing the node.
+ */
+char *
+rest_xml_node_print (RestXmlNode *node)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ char *xml = g_strconcat ("<", node->name, NULL);
+ RestXmlNode *n;
+
+ g_hash_table_iter_init (&iter, node->attrs);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ xml = g_strconcat (xml, " ", key, "=\'", value, "\'", NULL);
+
+ xml = g_strconcat (xml, ">", NULL);
+
+ g_hash_table_iter_init (&iter, node->children);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ char *child = rest_xml_node_print ((RestXmlNode *) value);
+
+ xml = g_strconcat (xml, child, NULL);
+ g_free (child);
+ }
+
+ if (node->content)
+ xml = g_strconcat (xml, node->content, "</", node->name, ">", NULL);
+ else
+ xml = g_strconcat (xml, "</", node->name, ">", NULL);
+
+ for (n = node->next; n; n = n->next)
+ {
+ char *sibling = rest_xml_node_print (n);
+
+ xml = g_strconcat (xml, sibling, NULL);
+ g_free (sibling);
+ }
+
+ return xml;
+}
+
+/**
+ * rest_xml_node_add_child:
+ * @parent: parent #RestXmlNode, or %NULL for the top-level node
+ * @tag: name of the child node
+ *
+ * Adds a new node to the given parent node; to create the top-level node,
+ * parent should be %NULL.
+ *
+ * Return value: (transfer none): the newly added #RestXmlNode; the node object
+ * is owned by, and valid for the life time of, the #RestXmlCreator.
+ */
+RestXmlNode *
+rest_xml_node_add_child (RestXmlNode *parent, const char *tag)
+{
+ RestXmlNode *node;
+ char *escaped;
+
+ g_return_val_if_fail (tag && *tag, NULL);
+
+ escaped = g_markup_escape_text (tag, -1);
+
+ node = _rest_xml_node_new ();
+ node->name = (char *) g_intern_string (escaped);
+
+ if (parent)
+ {
+ RestXmlNode *tmp_node;
+
+ tmp_node = g_hash_table_lookup (parent->children, node->name);
+
+ if (tmp_node)
+ {
+ rest_xml_node_append_end (tmp_node, node);
+ }
+ else
+ {
+ g_hash_table_insert (parent->children, G(node->name), node);
+ }
+ }
+
+ g_free (escaped);
+
+ return node;
+}
+
+/**
+ * rest_xml_node_add_attr:
+ * @node: #RestXmlNode to add attribute to
+ * @attribute: name of the attribute
+ * @value: value to set attribute to
+ *
+ * Adds attribute to the given node.
+ */
+void
+rest_xml_node_add_attr (RestXmlNode *node,
+ const char *attribute,
+ const char *value)
+{
+ g_return_if_fail (node && attribute && *attribute);
+
+ g_hash_table_insert (node->attrs,
+ g_markup_escape_text (attribute, -1),
+ g_markup_escape_text (value, -1));
+}
+
+/**
+ * rest_xml_node_set_content:
+ * @node: #RestXmlNode to set content
+ * @value: the content
+ *
+ * Sets content for the given node.
+ */
+void
+rest_xml_node_set_content (RestXmlNode *node, const char *value)
+{
+ g_return_if_fail (node && value && *value);
+
+ g_free (node->content);
+ node->content = g_markup_escape_text (value, -1);
+}
diff --git a/rest/rest-xml-node.h b/rest/rest-xml-node.h
new file mode 100644
index 0000000..6d34f7e
--- /dev/null
+++ b/rest/rest-xml-node.h
@@ -0,0 +1,75 @@
+/*
+ * librest - RESTful web services access
+ * Copyright (c) 2008, 2009, 2011 Intel Corporation.
+ *
+ * Authors: Rob Bradford <rob@linux.intel.com>
+ * Ross Burton <ross@linux.intel.com>
+ * Tomas Frydrych <tf@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _REST_XML_NODE
+#define _REST_XML_NODE
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define REST_TYPE_XML_NODE rest_xml_node_get_type ()
+
+/**
+ * RestXmlNode:
+ * @name: the name of the element
+ * @content: the textual content of the element
+ * @children: a #GHashTable of string name to #RestXmlNode for the children of
+ * the element.
+ * @attrs: a #GHashTable of string name to string values for the attributes of
+ * the element.
+ * @next: the sibling #RestXmlNode with the same name
+ */
+typedef struct _RestXmlNode RestXmlNode;
+struct _RestXmlNode {
+ /*< private >*/
+ volatile int ref_count;
+ /*< public >*/
+ gchar *name;
+ gchar *content;
+ GHashTable *children;
+ GHashTable *attrs;
+ RestXmlNode *next;
+};
+
+GType rest_xml_node_get_type (void);
+
+RestXmlNode *rest_xml_node_ref (RestXmlNode *node);
+void rest_xml_node_unref (RestXmlNode *node);
+const gchar *rest_xml_node_get_attr (RestXmlNode *node,
+ const gchar *attr_name);
+RestXmlNode *rest_xml_node_find (RestXmlNode *start,
+ const gchar *tag);
+
+RestXmlNode *rest_xml_node_add_child (RestXmlNode *parent, const char *tag);
+char *rest_xml_node_print (RestXmlNode *node);
+void rest_xml_node_add_attr (RestXmlNode *node,
+ const char *attribute,
+ const char *value);
+void rest_xml_node_set_content (RestXmlNode *node, const char *value);
+
+G_GNUC_DEPRECATED void rest_xml_node_free (RestXmlNode *node);
+
+G_END_DECLS
+
+#endif /* _REST_XML_NODE */
diff --git a/rest/rest-xml-parser.c b/rest/rest-xml-parser.c
index 0d78273..690d757 100644
--- a/rest/rest-xml-parser.c
+++ b/rest/rest-xml-parser.c
@@ -39,215 +39,6 @@ rest_xml_parser_init (RestXmlParser *self)
{
}
-static RestXmlNode *
-rest_xml_node_reverse_siblings (RestXmlNode *current)
-{
- RestXmlNode *next;
- RestXmlNode *prev = NULL;
-
- while (current)
- {
- next = current->next;
- current->next = prev;
-
- prev = current;
- current = next;
- }
-
- return prev;
-}
-
-static void
-rest_xml_node_reverse_children_siblings (RestXmlNode *node)
-{
- GList *l, *children;
- RestXmlNode *new_node;
-
- children = g_hash_table_get_values (node->children);
-
- for (l = children; l; l = l->next)
- {
- new_node = rest_xml_node_reverse_siblings ((RestXmlNode *)l->data);
- g_hash_table_insert (node->children, new_node->name, new_node);
- }
-
- if (children)
- g_list_free (children);
-}
-
-static RestXmlNode *
-rest_xml_node_prepend (RestXmlNode *cur_node, RestXmlNode *new_node)
-{
- g_assert (new_node->next == NULL);
- new_node->next = cur_node;
-
- return new_node;
-}
-
-GType
-rest_xml_node_get_type (void)
-{
- static GType type = 0;
- if (G_UNLIKELY (type == 0)) {
- type = g_boxed_type_register_static ("RestXmlNode",
- (GBoxedCopyFunc)rest_xml_node_ref,
- (GBoxedFreeFunc)rest_xml_node_unref);
- }
- return type;
-}
-
-static RestXmlNode *
-rest_xml_node_new ()
-{
- RestXmlNode *node;
-
- node = g_slice_new0 (RestXmlNode);
- node->ref_count = 1;
- node->children = g_hash_table_new (NULL, NULL);
- node->attrs = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_free);
-
- return node;
-}
-
-/**
- * rest_xml_node_ref:
- * @node: a #RestXmlNode
- *
- * Increases the reference count of @node.
- *
- * Returns: the same @node.
- */
-RestXmlNode *
-rest_xml_node_ref (RestXmlNode *node)
-{
- g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (node->ref_count > 0, NULL);
-
- g_atomic_int_inc (&node->ref_count);
-
- return node;
-}
-
-/**
- * rest_xml_node_unref:
- * @node: a #RestXmlNode
- *
- * Decreases the reference count of @node. When its reference count drops to 0,
- * the node is finalized (i.e. its memory is freed).
- */
-void
-rest_xml_node_unref (RestXmlNode *node)
-{
- GList *l;
- RestXmlNode *next = NULL;
- g_return_if_fail (node);
- g_return_if_fail (node->ref_count > 0);
-
- /* Try and unref the chain, this is equivalent to being tail recursively
- * unreffing the next pointer
- */
- while (node && g_atomic_int_dec_and_test (&node->ref_count))
- {
- /*
- * Save this pointer now since we are going to free the structure it
- * contains soon.
- */
- next = node->next;
-
- l = g_hash_table_get_values (node->children);
- while (l)
- {
- rest_xml_node_unref ((RestXmlNode *)l->data);
- l = g_list_delete_link (l, l);
- }
-
- g_hash_table_unref (node->children);
- g_hash_table_unref (node->attrs);
- g_free (node->content);
- g_slice_free (RestXmlNode, node);
-
- /*
- * Free the next in the chain by updating node. If we're at the end or
- * there are no siblings then the next = NULL definition deals with this
- * case
- */
- node = next;
- }
-}
-
-G_GNUC_DEPRECATED void
-rest_xml_node_free (RestXmlNode *node)
-{
- rest_xml_node_unref (node);
-}
-
-/**
- * rest_xml_node_get_attr:
- * @node: a #RestXmlNode
- * @attr_name: the name of an attribute
- *
- * Get the value of the attribute named @attr_name, or %NULL if it doesn't
- * exist.
- *
- * Returns: the attribute value. This string is owned by #RestXmlNode and should
- * not be freed.
- */
-const gchar *
-rest_xml_node_get_attr (RestXmlNode *node,
- const gchar *attr_name)
-{
- return g_hash_table_lookup (node->attrs, attr_name);
-}
-
-/**
- * rest_xml_node_find:
- * @start: a #RestXmlNode
- * @tag: the name of a node
- *
- * Searches for the first child node of @start named @tag.
- *
- * Returns: the first child node, or %NULL if it doesn't exist.
- */
-RestXmlNode *
-rest_xml_node_find (RestXmlNode *start,
- const gchar *tag)
-{
- RestXmlNode *node;
- RestXmlNode *tmp;
- GQueue stack = G_QUEUE_INIT;
- GList *children, *l;
- const char *tag_interned;
-
- g_return_val_if_fail (start, NULL);
- g_return_val_if_fail (start->ref_count > 0, NULL);
-
- tag_interned = g_intern_string (tag);
-
- g_queue_push_head (&stack, start);
-
- while ((node = g_queue_pop_head (&stack)) != NULL)
- {
- if ((tmp = g_hash_table_lookup (node->children, tag_interned)) != NULL)
- {
- g_queue_clear (&stack);
- return tmp;
- }
-
- children = g_hash_table_get_values (node->children);
- for (l = children; l; l = l->next)
- {
- g_queue_push_head (&stack, l->data);
- }
- g_list_free (children);
- }
-
- g_queue_clear (&stack);
- return NULL;
-}
-
/**
* rest_xml_parser_new:
*
@@ -310,7 +101,7 @@ rest_xml_parser_parse_from_data (RestXmlParser *parser,
/* Create our new node for this tag */
- new_node = rest_xml_node_new ();
+ new_node = _rest_xml_node_new ();
new_node->name = G (g_intern_string (name));
if (!root_node)
@@ -332,7 +123,7 @@ rest_xml_parser_parse_from_data (RestXmlParser *parser,
"Prepending to the list.");
g_hash_table_insert (cur_node->children,
G(tmp_node->name),
- rest_xml_node_prepend (tmp_node, new_node));
+ _rest_xml_node_prepend (tmp_node, new_node));
} else {
REST_DEBUG (XML_PARSER, "Unseen name. Adding to the children table.");
g_hash_table_insert (cur_node->children,
@@ -386,7 +177,7 @@ rest_xml_parser_parse_from_data (RestXmlParser *parser,
/* For those children that have siblings, reverse the siblings */
node = (RestXmlNode *)g_queue_pop_head (&nodes);
- rest_xml_node_reverse_children_siblings (node);
+ _rest_xml_node_reverse_children_siblings (node);
/* Update the current node to the new top of the stack */
cur_node = (RestXmlNode *)g_queue_peek_head (&nodes);
diff --git a/rest/rest-xml-parser.h b/rest/rest-xml-parser.h
index 967c2cf..a8f51ee 100644
--- a/rest/rest-xml-parser.h
+++ b/rest/rest-xml-parser.h
@@ -24,6 +24,7 @@
#define _REST_XML_PARSER
#include <glib-object.h>
+#include <rest/rest-xml-node.h>
G_BEGIN_DECLS
@@ -44,8 +45,6 @@ G_BEGIN_DECLS
#define REST_XML_PARSER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), REST_TYPE_XML_PARSER, RestXmlParserClass))
-#define REST_TYPE_XML_NODE rest_xml_node_get_type ()
-
typedef struct {
GObject parent;
} RestXmlParser;
@@ -54,28 +53,6 @@ typedef struct {
GObjectClass parent_class;
} RestXmlParserClass;
-/**
- * RestXmlNode:
- * @name: the name of the element
- * @content: the textual content of the element
- * @children: a #GHashTable of string name to #RestXmlNode for the children of
- * the element.
- * @attrs: a #GHashTable of string name to string values for the attributes of
- * the element.
- * @next: the sibling #RestXmlNode with the same name
- */
-typedef struct _RestXmlNode RestXmlNode;
-struct _RestXmlNode {
- /*< private >*/
- volatile int ref_count;
- /*< public >*/
- gchar *name;
- gchar *content;
- GHashTable *children;
- GHashTable *attrs;
- RestXmlNode *next;
-};
-
GType rest_xml_parser_get_type (void);
RestXmlParser *rest_xml_parser_new (void);
@@ -83,17 +60,6 @@ RestXmlNode *rest_xml_parser_parse_from_data (RestXmlParser *parser,
const gchar *data,
goffset len);
-GType rest_xml_node_get_type (void);
-
-RestXmlNode * rest_xml_node_ref (RestXmlNode *node);
-void rest_xml_node_unref (RestXmlNode *node);
-G_GNUC_DEPRECATED void rest_xml_node_free (RestXmlNode *node);
-
-const gchar *rest_xml_node_get_attr (RestXmlNode *node,
- const gchar *attr_name);
-RestXmlNode *rest_xml_node_find (RestXmlNode *start,
- const gchar *tag);
-
G_END_DECLS
#endif /* _REST_XML_PARSER */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 77d39c9..f159d14 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-TESTS = proxy proxy-continuous threaded oauth oauth-async oauth2 flickr lastfm
+TESTS = proxy proxy-continuous threaded oauth oauth-async oauth2 flickr lastfm xml
AM_CPPFLAGS = $(SOUP_CFLAGS) -I$(top_srcdir) $(GCOV_CFLAGS)
AM_LDFLAGS = $(SOUP_LIBS) $(GCOV_LDFLAGS) \
@@ -14,3 +14,4 @@ oauth_async_SOURCES = oauth-async.c
oauth2_SOURCES = oauth2.c
flickr_SOURCES = flickr.c
lastfm_SOURCES = lastfm.c
+xml_SOURCES = xml.c
diff --git a/tests/xml.c b/tests/xml.c
new file mode 100644
index 0000000..4a5f2c0
--- /dev/null
+++ b/tests/xml.c
@@ -0,0 +1,85 @@
+/*
+ * librest - RESTful web services access
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * Author: Tomas Frydrych <tf@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <rest/rest-xml-parser.h>
+
+#include <string.h>
+
+#define TEST_XML "<node0 a00=\'v00\' a01=\'v01\'><node1 a10=\'v10\'></node1><node1 a10=\'v10\'></node1>Cont0</node0>"
+
+int
+main (int argc, char **argv)
+{
+ GError *error = NULL;
+ RestXmlParser *parser;
+ RestXmlNode *root, *node;
+ char *xml;
+
+ g_thread_init (NULL);
+ g_type_init ();
+
+ parser = rest_xml_parser_new ();
+
+ root = rest_xml_parser_parse_from_data (parser, TEST_XML, strlen (TEST_XML));
+ g_assert (root);
+
+ xml = rest_xml_node_print (root);
+
+ g_assert (xml);
+
+ if (strcmp (TEST_XML, xml))
+ {
+ g_error ("Generated output for parsed XML does not match:\n"
+ "in: %s\n"
+ "out: %s\n",
+ TEST_XML, xml);
+ }
+
+ rest_xml_node_unref (root);
+
+ root = rest_xml_node_add_child (NULL, "node0");
+ rest_xml_node_add_attr (root, "a00", "v00");
+ rest_xml_node_add_attr (root, "a01", "v01");
+
+ node = rest_xml_node_add_child (root, "node1");
+ rest_xml_node_add_attr (node, "a10", "v10");
+
+ node = rest_xml_node_add_child (root, "node1");
+ rest_xml_node_add_attr (node, "a10", "v10");
+
+ rest_xml_node_set_content (root, "Cont0");
+
+ xml = rest_xml_node_print (root);
+
+ g_assert (xml);
+
+ if (strcmp (TEST_XML, xml))
+ {
+ g_error ("Generated output for constructed XML does not match:\n"
+ "in: %s\n"
+ "out: %s\n",
+ TEST_XML, xml);
+ }
+
+ rest_xml_node_unref (root);
+
+ return 0;
+}