[evolution-data-server] Prefix soup_soap_(message/response) with e_soap and add it in libedataserver so that groupwise, evol



commit ab7a5fb0b5fb42a1e83c03e6776deeda3e577f85
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Thu Oct 14 23:15:03 2010 +0530

    Prefix soup_soap_(message/response) with e_soap and add it in libedataserver so that groupwise, evolution-ews and evolution-sync for ews

 libedataserver/Makefile.am       |    4 +
 libedataserver/e-soap-message.c  |  816 ++++++++++++++++++++++++++++++++++++++
 libedataserver/e-soap-message.h  |   96 +++++
 libedataserver/e-soap-response.c |  578 +++++++++++++++++++++++++++
 libedataserver/e-soap-response.h |   68 ++++
 5 files changed, 1562 insertions(+), 0 deletions(-)
---
diff --git a/libedataserver/Makefile.am b/libedataserver/Makefile.am
index 9dd222f..f71e00c 100644
--- a/libedataserver/Makefile.am
+++ b/libedataserver/Makefile.am
@@ -23,6 +23,8 @@ libedataserver_1_2_la_SOURCES =		\
 	e-list-iterator.c		\
 	e-memory.c			\
 	e-proxy.c			\
+	e-soap-message.c		\
+	e-soap-response.c		\
 	e-sexp.c			\
 	e-source-group.c		\
 	e-source-list.c			\
@@ -58,6 +60,8 @@ libedataserverinclude_HEADERS =		\
 	e-list-iterator.h		\
 	e-memory.h			\
 	e-proxy.h			\
+	e-soap-message.h		\
+	e-soap-response.h		\
 	e-sexp.h			\
 	e-source-group.h		\
 	e-source-list.h			\
diff --git a/libedataserver/e-soap-message.c b/libedataserver/e-soap-message.c
new file mode 100644
index 0000000..1130e60
--- /dev/null
+++ b/libedataserver/e-soap-message.c
@@ -0,0 +1,816 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include <string.h>
+#include <libsoup/soup.h>
+#include "e-soap-message.h"
+
+G_DEFINE_TYPE (ESoapMessage, e_soap_message, SOUP_TYPE_MESSAGE)
+
+typedef struct {
+	/* Serialization fields */
+	xmlDocPtr doc;
+	xmlNodePtr last_node;
+	xmlNsPtr soap_ns;
+	xmlNsPtr xsi_ns;
+	xmlChar *env_prefix;
+	xmlChar *env_uri;
+	gboolean body_started;
+	gchar *action;
+} ESoapMessagePrivate;
+#define E_SOAP_MESSAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_SOAP_MESSAGE, ESoapMessagePrivate))
+
+static void
+finalize (GObject *object)
+{
+	ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (object);
+
+	if (priv->doc)
+		xmlFreeDoc (priv->doc);
+	if (priv->action)
+		g_free (priv->action);
+	if (priv->env_uri)
+                xmlFree (priv->env_uri);
+	if (priv->env_prefix)
+                xmlFree (priv->env_prefix);
+
+	G_OBJECT_CLASS (e_soap_message_parent_class)->finalize (object);
+}
+
+static void
+e_soap_message_class_init (ESoapMessageClass *e_soap_message_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (e_soap_message_class);
+
+	g_type_class_add_private (e_soap_message_class, sizeof (ESoapMessagePrivate));
+
+	object_class->finalize = finalize;
+}
+
+static void
+e_soap_message_init (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	/* initialize XML structures */
+	priv->doc = xmlNewDoc ((const xmlChar *)"1.0");
+	priv->doc->standalone = FALSE;
+	priv->doc->encoding = xmlCharStrdup ("UTF-8");
+}
+
+static xmlNsPtr
+fetch_ns (ESoapMessage *msg, const gchar *prefix, const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+        xmlNsPtr ns = NULL;
+
+        if (prefix && ns_uri)
+                ns = xmlNewNs (priv->last_node, (const xmlChar *)ns_uri, (const xmlChar *)prefix);
+        else if (prefix && !ns_uri) {
+                ns = xmlSearchNs (priv->doc, priv->last_node, (const xmlChar *)prefix);
+                if (!ns)
+			ns = xmlNewNs (priv->last_node, (const xmlChar *)"", (const xmlChar *)prefix);
+        }
+
+        return ns;
+}
+
+/**
+ * e_soap_message_new:
+ * @method: the HTTP method for the created request.
+ * @uri_string: the destination endpoint (as a string).
+ * @standalone: ??? FIXME
+ * @xml_encoding: ??? FIXME
+ * @env_prefix: ??? FIXME
+ * @env_uri: ??? FIXME
+ *
+ * Creates a new empty #ESoapMessage, which will connect to @uri_string.
+ *
+ * Returns: the new #ESoapMessage (or %NULL if @uri_string could not be
+ * parsed).
+ */
+ESoapMessage *
+e_soap_message_new (const gchar *method, const gchar *uri_string,
+		       gboolean standalone, const gchar *xml_encoding,
+		       const gchar *env_prefix, const gchar *env_uri)
+{
+	ESoapMessage *msg;
+	SoupURI *uri;
+
+	uri = soup_uri_new (uri_string);
+	if (!uri)
+		return NULL;
+
+	msg = e_soap_message_new_from_uri (method, uri, standalone,
+					      xml_encoding, env_prefix, env_uri);
+
+	soup_uri_free (uri);
+
+	return msg;
+}
+
+/**
+ * e_soap_message_new_from_uri:
+ * @method: the HTTP method for the created request.
+ * @uri: the destination endpoint (as a #SoupURI).
+ * @standalone: ??? FIXME
+ * @xml_encoding: ??? FIXME
+ * @env_prefix: ??? FIXME
+ * @env_uri: ??? FIXME
+ *
+ * Creates a new empty #ESoapMessage, which will connect to @uri
+ *
+ * Returns: the new #ESoapMessage
+ */
+ESoapMessage *
+e_soap_message_new_from_uri (const gchar *method, SoupURI *uri,
+				gboolean standalone, const gchar *xml_encoding,
+				const gchar *env_prefix, const gchar *env_uri)
+{
+	ESoapMessage *msg;
+	ESoapMessagePrivate *priv;
+
+	msg = g_object_new (E_TYPE_SOAP_MESSAGE,
+			    SOUP_MESSAGE_METHOD, method,
+			    SOUP_MESSAGE_URI, uri,
+			    NULL);
+
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->doc->standalone = standalone;
+
+	if (xml_encoding) {
+		xmlFree ((xmlChar *)priv->doc->encoding);
+		priv->doc->encoding = xmlCharStrdup (xml_encoding);
+	}
+
+	if (env_prefix)
+		priv->env_prefix = xmlCharStrdup (env_prefix);
+	if (env_uri)
+		priv->env_uri = xmlCharStrdup (env_uri);
+
+	return msg;
+}
+
+/**
+ * e_soap_message_start_envelope:
+ * @msg: the %ESoapMessage.
+ *
+ * Starts the top level SOAP Envelope element.
+ */
+void
+e_soap_message_start_envelope (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->last_node = priv->doc->xmlRootNode =
+		xmlNewDocNode (priv->doc, NULL, (const xmlChar *)"Envelope", NULL);
+
+	priv->soap_ns = xmlNewNs (priv->doc->xmlRootNode,
+				  priv->env_uri ? priv->env_uri :
+				  (const xmlChar *)"http://schemas.xmlsoap.org/soap/envelope/";,
+				  priv->env_prefix ? priv->env_prefix : (const xmlChar *)"SOAP-ENV");
+	if (priv->env_uri) {
+		xmlFree (priv->env_uri);
+		priv->env_uri = NULL;
+	}
+	if (priv->env_prefix) {
+		xmlFree (priv->env_prefix);
+		priv->env_prefix = NULL;
+	}
+
+	xmlSetNs (priv->doc->xmlRootNode, priv->soap_ns);
+
+	xmlNewNs (priv->doc->xmlRootNode,
+		  (const xmlChar *)"http://schemas.xmlsoap.org/soap/encoding/";,
+                  (const xmlChar *)"SOAP-ENC");
+	xmlNewNs (priv->doc->xmlRootNode,
+                  (const xmlChar *)"http://www.w3.org/1999/XMLSchema";,
+                  (const xmlChar *)"xsd");
+	xmlNewNs (priv->doc->xmlRootNode,
+		  (const xmlChar *)"http://schemas.xmlsoap.org/soap/envelope/";,
+		  (const xmlChar *)"SOAP-ENV");
+	priv->xsi_ns = xmlNewNs (priv->doc->xmlRootNode,
+				 (const xmlChar *)"http://www.w3.org/1999/XMLSchema-instance";,
+				 (const xmlChar *)"xsi");
+}
+
+/**
+ * e_soap_message_end_envelope:
+ * @msg: the %ESoapMessage.
+ *
+ * Closes the top level SOAP Envelope element.
+ */
+void
+e_soap_message_end_envelope (ESoapMessage *msg)
+{
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_start_body:
+ * @msg: the %ESoapMessage.
+ *
+ * Starts the SOAP Body element.
+ */
+void
+e_soap_message_start_body (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	if (priv->body_started)
+		return;
+
+	priv->last_node = xmlNewChild (priv->last_node,
+				       priv->soap_ns,
+				       (const xmlChar *)"Body", NULL);
+
+	priv->body_started = TRUE;
+}
+
+/**
+ * e_soap_message_end_body:
+ * @msg: the %ESoapMessage.
+ *
+ * Closes the SOAP Body element.
+ */
+void
+e_soap_message_end_body (ESoapMessage *msg)
+{
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_start_element:
+ * @msg: the #ESoapMessage.
+ * @name: the element name.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Starts a new arbitrary message element, with @name as the element
+ * name, @prefix as the XML Namespace prefix, and @ns_uri as the XML
+ * Namespace uri for * the created element.
+ *
+ * Passing @prefix with no @ns_uri will cause a recursive search for
+ * an existing namespace with the same prefix. Failing that a new ns
+ * will be created with an empty uri.
+ *
+ * Passing both @prefix and @ns_uri always causes new namespace
+ * attribute creation.
+ *
+ * Passing NULL for both @prefix and @ns_uri causes no prefix to be
+ * used, and the element will be in the default namespace.
+ */
+void
+e_soap_message_start_element (ESoapMessage *msg,
+				 const gchar *name,
+				 const gchar *prefix,
+				 const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->last_node = xmlNewChild (priv->last_node, NULL, (const xmlChar *)name, NULL);
+
+	xmlSetNs (priv->last_node, fetch_ns (msg, prefix, ns_uri));
+
+	if (priv->body_started && !priv->action)
+		priv->action = g_strconcat (ns_uri ? ns_uri : "",
+					    "#", name, NULL);
+}
+
+/**
+ * e_soap_message_end_element:
+ * @msg: the #ESoapMessage.
+ *
+ * Closes the current message element.
+ */
+void
+e_soap_message_end_element (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->last_node = priv->last_node->parent;
+}
+
+/**
+ * e_soap_message_start_fault:
+ * @msg: the #ESoapMessage.
+ * @faultcode: faultcode element value
+ * @faultstring: faultstring element value
+ * @faultfactor: faultfactor element value
+ *
+ * Starts a new SOAP Fault element, creating faultcode, faultstring,
+ * and faultfactor child elements.
+ *
+ * If you wish to add the faultdetail element, use
+ * e_soap_message_start_fault_detail(), and then
+ * e_soap_message_start_element() to add arbitrary sub-elements.
+ */
+void
+e_soap_message_start_fault (ESoapMessage *msg,
+			       const gchar *faultcode,
+			       const gchar *faultstring,
+			       const gchar *faultfactor)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->last_node = xmlNewChild (priv->last_node,
+				       priv->soap_ns,
+				       (const xmlChar *)"Fault", NULL);
+	xmlNewChild (priv->last_node, priv->soap_ns, (const xmlChar *)"faultcode", (const xmlChar *)faultcode);
+	xmlNewChild (priv->last_node, priv->soap_ns, (const xmlChar *)"faultstring", (const xmlChar *)faultstring);
+
+	priv->last_node = xmlNewChild (priv->last_node, priv->soap_ns,
+				       (const xmlChar *)"faultfactor", (const xmlChar *)faultfactor);
+	if (!faultfactor)
+		e_soap_message_set_null (msg);
+
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_end_fault:
+ * @msg: the #ESoapMessage.
+ *
+ * Closes the current SOAP Fault element.
+ */
+void
+e_soap_message_end_fault (ESoapMessage *msg)
+{
+        e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_start_fault_detail:
+ * @msg: the #ESoapMessage.
+ *
+ * Start the faultdetail child element of the current SOAP Fault
+ * element. The faultdetail element allows arbitrary data to be sent
+ * in a returned fault.
+ **/
+void
+e_soap_message_start_fault_detail (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+        g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+        priv->last_node = xmlNewChild (priv->last_node,
+				       priv->soap_ns,
+				       (const xmlChar *)"detail",
+				       NULL);
+}
+
+/**
+ * e_soap_message_end_fault_detail:
+ * @msg: the #ESoapMessage.
+ *
+ * Closes the current SOAP faultdetail element.
+ */
+void
+e_soap_message_end_fault_detail (ESoapMessage *msg)
+{
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_start_header:
+ * @msg: the #ESoapMessage.
+ *
+ * Creates a new SOAP Header element. You can call
+ * e_soap_message_start_header_element() after this to add a new
+ * header child element. SOAP Header elements allow out-of-band data
+ * to be transferred while not interfering with the message body.
+ *
+ * This should be called after e_soap_message_start_envelope() and
+ * before e_soap_message_start_body().
+ */
+void
+e_soap_message_start_header (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	priv->last_node = xmlNewChild (priv->last_node, priv->soap_ns,
+				       (const xmlChar *)"Header", NULL);
+}
+
+/**
+ * e_soap_message_end_header:
+ * @msg: the #ESoapMessage.
+ *
+ * Closes the current SOAP Header element.
+ */
+void
+e_soap_message_end_header (ESoapMessage *msg)
+{
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_start_header_element:
+ * @msg: the #ESoapMessage.
+ * @name: name of the header element
+ * @must_understand: whether the recipient must understand the header in order
+ * to proceed with processing the message
+ * @actor_uri: the URI which represents the destination actor for this header.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Starts a new SOAP arbitrary header element.
+ */
+void
+e_soap_message_start_header_element (ESoapMessage *msg,
+					const gchar *name,
+					gboolean must_understand,
+					const gchar *actor_uri,
+					const gchar *prefix,
+					const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	e_soap_message_start_element (msg, name, prefix, ns_uri);
+	if (actor_uri)
+		xmlNewNsProp (priv->last_node, priv->soap_ns, (const xmlChar *)"actorUri", (const xmlChar *)actor_uri);
+	if (must_understand)
+		xmlNewNsProp (priv->last_node, priv->soap_ns, (const xmlChar *)"mustUnderstand", (const xmlChar *)"1");
+}
+
+/**
+ * e_soap_message_end_header_element:
+ * @msg: the #ESoapMessage.
+ *
+ * Closes the current SOAP header element.
+ */
+void
+e_soap_message_end_header_element (ESoapMessage *msg)
+{
+	e_soap_message_end_element (msg);
+}
+
+/**
+ * e_soap_message_write_int:
+ * @msg: the #ESoapMessage.
+ * @i: the integer value to write.
+ *
+ * Writes the stringified value of @i as the current element's content.
+ */
+void
+e_soap_message_write_int (ESoapMessage *msg, glong i)
+{
+	gchar *str = g_strdup_printf ("%ld", i);
+	e_soap_message_write_string (msg, str);
+	g_free (str);
+}
+
+/**
+ * e_soap_message_write_double:
+ * @msg: the #ESoapMessage.
+ * @d: the double value to write.
+ *
+ * Writes the stringified value of @d as the current element's content.
+ */
+void
+e_soap_message_write_double (ESoapMessage *msg, gdouble d)
+{
+	gchar *str = g_strdup_printf ("%f", d);
+	e_soap_message_write_string (msg, str);
+	g_free (str);
+}
+
+/**
+ * e_soap_message_write_base64:
+ * @msg: the #ESoapMessage
+ * @string: the binary data buffer to encode
+ * @len: the length of data to encode
+ *
+ * Writes the Base-64 encoded value of @string as the current
+ * element's content.
+ **/
+void
+e_soap_message_write_base64 (ESoapMessage *msg, const gchar *string, gint len)
+{
+        gchar *str = g_base64_encode ((const guchar *)string, len);
+        e_soap_message_write_string (msg, str);
+        g_free (str);
+}
+
+/**
+ * e_soap_message_write_time:
+ * @msg: the #ESoapMessage.
+ * @timeval: pointer to a time_t to encode
+ *
+ * Writes the stringified value of @timeval as the current element's
+ * content.
+ **/
+void
+e_soap_message_write_time (ESoapMessage *msg, const time_t *timeval)
+{
+        gchar *str = g_strchomp (ctime (timeval));
+        e_soap_message_write_string (msg, str);
+}
+
+/**
+ * e_soap_message_write_string:
+ * @msg: the #ESoapMessage.
+ * @string: string to write.
+ *
+ * Writes the @string as the current element's content.
+ */
+void
+e_soap_message_write_string (ESoapMessage *msg, const gchar *string)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNodeAddContent (priv->last_node, (const xmlChar *)string);
+}
+
+/**
+ * e_soap_message_write_buffer:
+ * @msg: the #ESoapMessage.
+ * @buffer: the string data buffer to write.
+ * @len: length of @buffer.
+ *
+ * Writes the string buffer pointed to by @buffer as the current
+ * element's content.
+ */
+void
+e_soap_message_write_buffer (ESoapMessage *msg, const gchar *buffer, gint len)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNodeAddContentLen (priv->last_node, (const xmlChar *)buffer, len);
+}
+
+/**
+ * e_soap_message_set_element_type:
+ * @msg: the #ESoapMessage.
+ * @xsi_type: the type name for the element.
+ *
+ * Sets the current element's XML schema xsi:type attribute, which
+ * specifies the element's type name.
+ */
+void
+e_soap_message_set_element_type (ESoapMessage *msg, const gchar *xsi_type)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNewNsProp (priv->last_node, priv->xsi_ns, (const xmlChar *)"type", (const xmlChar *)xsi_type);
+}
+
+/**
+ * e_soap_message_set_null:
+ * @msg: the #ESoapMessage.
+ *
+ * Sets the current element's XML Schema xsi:null attribute.
+ */
+void
+e_soap_message_set_null (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNewNsProp (priv->last_node, priv->xsi_ns, (const xmlChar *)"null", (const xmlChar *)"1");
+}
+
+/**
+ * e_soap_message_add_attribute:
+ * @msg: the #ESoapMessage.
+ * @name: name of the attribute
+ * @value: value of the attribute
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI
+ *
+ * Adds an XML attribute to the current element.
+ */
+void
+e_soap_message_add_attribute (ESoapMessage *msg,
+				 const gchar *name,
+				 const gchar *value,
+				 const gchar *prefix,
+				 const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNewNsProp (priv->last_node,
+		      fetch_ns (msg, prefix, ns_uri),
+		      (const xmlChar *)name, (const xmlChar *)value);
+}
+
+/**
+ * e_soap_message_add_namespace:
+ * @msg: the #ESoapMessage.
+ * @prefix: the namespace prefix
+ * @ns_uri: the namespace URI, or NULL for empty namespace
+ *
+ * Adds a new XML namespace to the current element.
+ */
+void
+e_soap_message_add_namespace (ESoapMessage *msg, const gchar *prefix, const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNewNs (priv->last_node, (const xmlChar *)(ns_uri ? ns_uri : ""), (const xmlChar *)prefix);
+}
+
+/**
+ * e_soap_message_set_default_namespace:
+ * @msg: the #ESoapMessage.
+ * @ns_uri: the namespace URI.
+ *
+ * Sets the default namespace to the URI specified in @ns_uri. The
+ * default namespace becomes the namespace all non-explicitly
+ * namespaced child elements fall into.
+ */
+void
+e_soap_message_set_default_namespace (ESoapMessage *msg, const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	e_soap_message_add_namespace (msg, NULL, ns_uri);
+}
+
+/**
+ * e_soap_message_set_encoding_style:
+ * @msg: the #ESoapMessage.
+ * @enc_style: the new encodingStyle value
+ *
+ * Sets the encodingStyle attribute on the current element to the
+ * value of @enc_style.
+ */
+void
+e_soap_message_set_encoding_style (ESoapMessage *msg, const gchar *enc_style)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlNewNsProp (priv->last_node, priv->soap_ns, (const xmlChar *)"encodingStyle", (const xmlChar *)enc_style);
+}
+
+/**
+ * e_soap_message_reset:
+ * @msg: the #ESoapMessage.
+ *
+ * Resets the internal XML representation of the SOAP message.
+ */
+void
+e_soap_message_reset (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlFreeDoc (priv->doc);
+	priv->doc = xmlNewDoc ((const xmlChar *)"1.0");
+	priv->last_node = NULL;
+
+	g_free (priv->action);
+	priv->action = NULL;
+	priv->body_started = FALSE;
+
+	if (priv->env_uri)
+		xmlFree (priv->env_uri);
+	priv->env_uri = NULL;
+
+	if (priv->env_prefix)
+		xmlFree (priv->env_prefix);
+	priv->env_prefix = NULL;
+}
+
+/**
+ * e_soap_message_persist:
+ * @msg: the #ESoapMessage.
+ *
+ * Writes the serialized XML tree to the #SoupMessage's buffer.
+ */
+void
+e_soap_message_persist (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+	xmlChar *body;
+	gint len;
+
+	g_return_if_fail (E_IS_SOAP_MESSAGE (msg));
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	xmlDocDumpMemory (priv->doc, &body, &len);
+
+	/* serialize to SoupMessage class */
+	soup_message_set_request (SOUP_MESSAGE (msg), "text/xml",
+				  SOUP_MEMORY_TAKE, (gchar *)body, len);
+}
+
+/**
+ * e_soap_message_get_namespace_prefix:
+ * @msg: the #ESoapMessage.
+ * @ns_uri: the namespace URI.
+ *
+ * Returns the namespace prefix for @ns_uri (or an empty string if
+ * @ns_uri is set to the default namespace)
+ *
+ * Returns: The namespace prefix, or %NULL if no namespace exists
+ * for the URI given.
+ */
+const gchar *
+e_soap_message_get_namespace_prefix (ESoapMessage *msg, const gchar *ns_uri)
+{
+	ESoapMessagePrivate *priv;
+	xmlNsPtr ns = NULL;
+
+	g_return_val_if_fail (E_IS_SOAP_MESSAGE (msg), NULL);
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+	g_return_val_if_fail (ns_uri != NULL, NULL);
+
+	ns = xmlSearchNsByHref (priv->doc, priv->last_node, (const xmlChar *)ns_uri);
+	if (ns) {
+		if (ns->prefix)
+			return (const gchar *)ns->prefix;
+		else
+			return "";
+	}
+
+	return NULL;
+}
+
+/**
+ * e_soap_message_get_xml_doc:
+ * @msg: the #ESoapMessage.
+ *
+ * Returns the internal XML representation tree of the
+ * #ESoapMessage pointed to by @msg.
+ *
+ * Returns: the #xmlDocPtr representing the SOAP message.
+ */
+xmlDocPtr
+e_soap_message_get_xml_doc (ESoapMessage *msg)
+{
+	ESoapMessagePrivate *priv;
+
+	g_return_val_if_fail (E_IS_SOAP_MESSAGE (msg), NULL);
+	priv = E_SOAP_MESSAGE_GET_PRIVATE (msg);
+
+	return priv->doc;
+}
+
+/**
+ * e_soap_message_parse_response:
+ * @msg: the #ESoapMessage.
+ *
+ * Parses the response returned by the server.
+ *
+ * Returns: a #ESoapResponse representing the response from
+ * the server, or %NULL if there was an error.
+ */
+ESoapResponse *
+e_soap_message_parse_response (ESoapMessage *msg)
+{
+	g_return_val_if_fail (E_IS_SOAP_MESSAGE (msg), NULL);
+
+	return e_soap_response_new_from_string (SOUP_MESSAGE (msg)->response_body->data);
+}
diff --git a/libedataserver/e-soap-message.h b/libedataserver/e-soap-message.h
new file mode 100644
index 0000000..053f169
--- /dev/null
+++ b/libedataserver/e-soap-message.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifndef E_SOAP_MESSAGE_H
+#define E_SOAP_MESSAGE_H 1
+
+#include <time.h>
+#include <libxml/tree.h>
+#include <libsoup/soup-message.h>
+#include "e-soap-response.h"
+
+G_BEGIN_DECLS
+
+#define E_TYPE_SOAP_MESSAGE            (e_soap_message_get_type ())
+#define E_SOAP_MESSAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SOAP_MESSAGE, ESoapMessage))
+#define E_SOAP_MESSAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SOAP_MESSAGE, ESoapMessageClass))
+#define E_IS_SOAP_MESSAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SOAP_MESSAGE))
+#define E_IS_SOAP_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_SOAP_MESSAGE))
+#define E_SOAP_MESSAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_SOAP_MESSAGE, ESoapMessageClass))
+
+typedef struct {
+	SoupMessage parent;
+
+} ESoapMessage;
+
+typedef struct {
+	SoupMessageClass parent_class;
+} ESoapMessageClass;
+
+GType             e_soap_message_get_type (void);
+
+ESoapMessage  *e_soap_message_new (const gchar *method, const gchar *uri_string,
+					 gboolean standalone, const gchar *xml_encoding,
+					 const gchar *env_prefix, const gchar *env_uri);
+ESoapMessage  *e_soap_message_new_from_uri (const gchar *method, SoupURI *uri,
+						  gboolean standalone, const gchar *xml_encoding,
+						  const gchar *env_prefix, const gchar *env_uri);
+
+void              e_soap_message_start_envelope (ESoapMessage *msg);
+void              e_soap_message_end_envelope (ESoapMessage *msg);
+void              e_soap_message_start_body (ESoapMessage *msg);
+void              e_soap_message_end_body (ESoapMessage *msg);
+void              e_soap_message_start_element (ESoapMessage *msg,
+						   const gchar *name,
+						   const gchar *prefix,
+						   const gchar *ns_uri);
+void              e_soap_message_end_element (ESoapMessage *msg);
+void              e_soap_message_start_fault (ESoapMessage *msg,
+						 const gchar *faultcode,
+						 const gchar *faultstring,
+						 const gchar *faultfactor);
+void              e_soap_message_end_fault (ESoapMessage *msg);
+void              e_soap_message_start_fault_detail (ESoapMessage *msg);
+void              e_soap_message_end_fault_detail (ESoapMessage *msg);
+void              e_soap_message_start_header (ESoapMessage *msg);
+void              e_soap_message_end_header (ESoapMessage *msg);
+void              e_soap_message_start_header_element (ESoapMessage *msg,
+							  const gchar *name,
+							  gboolean must_understand,
+							  const gchar *actor_uri,
+							  const gchar *prefix,
+							  const gchar *ns_uri);
+void              e_soap_message_end_header_element (ESoapMessage *msg);
+void              e_soap_message_write_int (ESoapMessage *msg, glong i);
+void              e_soap_message_write_double (ESoapMessage *msg, gdouble d);
+void              e_soap_message_write_base64 (ESoapMessage *msg, const gchar *string, gint len);
+void              e_soap_message_write_time (ESoapMessage *msg, const time_t *timeval);
+void              e_soap_message_write_string (ESoapMessage *msg, const gchar *string);
+void              e_soap_message_write_buffer (ESoapMessage *msg, const gchar *buffer, gint len);
+void              e_soap_message_set_element_type (ESoapMessage *msg, const gchar *xsi_type);
+void              e_soap_message_set_null (ESoapMessage *msg);
+void              e_soap_message_add_attribute (ESoapMessage *msg,
+						   const gchar *name,
+						   const gchar *value,
+						   const gchar *prefix,
+						   const gchar *ns_uri);
+void              e_soap_message_add_namespace (ESoapMessage *msg,
+						   const gchar *prefix,
+						   const gchar *ns_uri);
+void              e_soap_message_set_default_namespace (ESoapMessage *msg,
+							   const gchar *ns_uri);
+void              e_soap_message_set_encoding_style (ESoapMessage *msg, const gchar *enc_style);
+void              e_soap_message_reset (ESoapMessage *msg);
+void              e_soap_message_persist (ESoapMessage *msg);
+
+const gchar       *e_soap_message_get_namespace_prefix (ESoapMessage *msg, const gchar *ns_uri);
+
+xmlDocPtr         e_soap_message_get_xml_doc (ESoapMessage *msg);
+
+ESoapResponse *e_soap_message_parse_response (ESoapMessage *msg);
+
+G_END_DECLS
+
+#endif
diff --git a/libedataserver/e-soap-response.c b/libedataserver/e-soap-response.c
new file mode 100644
index 0000000..4936c88
--- /dev/null
+++ b/libedataserver/e-soap-response.c
@@ -0,0 +1,578 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/tree.h>
+#include <libsoup/soup.h>
+#include "e-soap-response.h"
+
+G_DEFINE_TYPE (ESoapResponse, e_soap_response, G_TYPE_OBJECT)
+
+typedef struct {
+	/* the XML document */
+	xmlDocPtr xmldoc;
+	xmlNodePtr xml_root;
+	xmlNodePtr xml_body;
+	xmlNodePtr xml_method;
+	xmlNodePtr soap_fault;
+	GList *parameters;
+} ESoapResponsePrivate;
+#define E_SOAP_RESPONSE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_SOAP_RESPONSE, ESoapResponsePrivate))
+
+static xmlNode *soup_xml_real_node (xmlNode *node);
+
+static void
+finalize (GObject *object)
+{
+	ESoapResponsePrivate *priv = E_SOAP_RESPONSE_GET_PRIVATE (object);
+
+	if (priv->xmldoc)
+		xmlFreeDoc (priv->xmldoc);
+	if (priv->parameters != NULL)
+		g_list_free (priv->parameters);
+
+	G_OBJECT_CLASS (e_soap_response_parent_class)->finalize (object);
+}
+
+static void
+e_soap_response_class_init (ESoapResponseClass *e_soap_response_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (e_soap_response_class);
+
+	g_type_class_add_private (e_soap_response_class, sizeof (ESoapResponsePrivate));
+
+	object_class->finalize = finalize;
+}
+
+static void
+e_soap_response_init (ESoapResponse *response)
+{
+	ESoapResponsePrivate *priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+
+	priv->xmldoc = xmlNewDoc ((const xmlChar *)"1.0");
+}
+
+/**
+ * e_soap_response_new:
+ *
+ * Create a new empty #ESoapResponse object, which can be modified
+ * with the accessor functions provided with this class.
+ *
+ * Returns: the new #ESoapResponse (or %NULL if there was an
+ * error).
+ */
+ESoapResponse *
+e_soap_response_new (void)
+{
+	ESoapResponse *response;
+
+	response = g_object_new (E_TYPE_SOAP_RESPONSE, NULL);
+	return response;
+}
+
+/**
+ * e_soap_response_new_from_string:
+ * @xmlstr: the XML string to parse.
+ *
+ * Create a new #ESoapResponse object from the XML string contained
+ * in @xmlstr.
+ *
+ * Returns: the new #ESoapResponse (or %NULL if there was an
+ * error).
+ */
+ESoapResponse *
+e_soap_response_new_from_string (const gchar *xmlstr)
+{
+	ESoapResponse *response;
+
+	g_return_val_if_fail (xmlstr != NULL, NULL);
+
+	response = g_object_new (E_TYPE_SOAP_RESPONSE, NULL);
+	if (!e_soap_response_from_string (response, xmlstr)) {
+		g_object_unref (response);
+		return NULL;
+	}
+
+	return response;
+}
+
+static void
+parse_parameters (ESoapResponsePrivate *priv, xmlNodePtr xml_method)
+{
+	xmlNodePtr tmp;
+
+	for (tmp = soup_xml_real_node (xml_method->children);
+	     tmp != NULL;
+	     tmp = soup_xml_real_node (tmp->next)) {
+		if (!strcmp ((const gchar *)tmp->name, "Fault")) {
+			priv->soap_fault = tmp;
+			continue;
+		} else {
+			/* regular parameters */
+			priv->parameters = g_list_append (priv->parameters, tmp);
+		}
+	}
+}
+
+/**
+ * e_soap_response_from_string:
+ * @response: the #ESoapResponse object.
+ * @xmlstr: XML string to parse.
+ *
+ * Parses the string contained in @xmlstr and sets all properties from
+ * it in the @response object.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ */
+gboolean
+e_soap_response_from_string (ESoapResponse *response, const gchar *xmlstr)
+{
+	ESoapResponsePrivate *priv;
+	xmlDocPtr old_doc = NULL;
+	xmlNodePtr xml_root, xml_body, xml_method = NULL;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), FALSE);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	g_return_val_if_fail (xmlstr != NULL, FALSE);
+
+	/* clear the previous contents */
+	if (priv->xmldoc)
+		old_doc = priv->xmldoc;
+
+	/* parse the string */
+	priv->xmldoc = xmlParseMemory (xmlstr, strlen (xmlstr));
+	if (!priv->xmldoc) {
+		priv->xmldoc = old_doc;
+		return FALSE;
+	}
+
+	xml_root = xmlDocGetRootElement (priv->xmldoc);
+	if (!xml_root) {
+		xmlFreeDoc (priv->xmldoc);
+		priv->xmldoc = old_doc;
+		return FALSE;
+	}
+
+	if (strcmp ((const gchar *)xml_root->name, "Envelope") != 0) {
+		xmlFreeDoc (priv->xmldoc);
+		priv->xmldoc = old_doc;
+		return FALSE;
+	}
+
+	xml_body = soup_xml_real_node (xml_root->children);
+	if (xml_body != NULL) {
+		if (strcmp ((const gchar *)xml_body->name, "Header") == 0)
+			xml_body = soup_xml_real_node (xml_body->next);
+		if (strcmp ((const gchar *)xml_body->name, "Body") != 0) {
+			xmlFreeDoc (priv->xmldoc);
+			priv->xmldoc = old_doc;
+			return FALSE;
+		}
+
+		xml_method = soup_xml_real_node (xml_body->children);
+
+		/* read all parameters */
+		if (xml_method)
+			parse_parameters (priv, xml_method);
+	}
+
+	xmlFreeDoc (old_doc);
+
+	priv->xml_root = xml_root;
+	priv->xml_body = xml_body;
+	priv->xml_method = xml_method;
+
+	return TRUE;
+}
+
+/**
+ * e_soap_response_get_method_name:
+ * @response: the #ESoapResponse object.
+ *
+ * Gets the method name from the SOAP response.
+ *
+ * Returns: the method name.
+ */
+const gchar *
+e_soap_response_get_method_name (ESoapResponse *response)
+{
+	ESoapResponsePrivate *priv;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	g_return_val_if_fail (priv->xml_method != NULL, NULL);
+
+	return (const gchar *) priv->xml_method->name;
+}
+
+/**
+ * e_soap_response_set_method_name:
+ * @response: the #ESoapResponse object.
+ * @method_name: the method name to set.
+ *
+ * Sets the method name on the given #ESoapResponse.
+ */
+void
+e_soap_response_set_method_name (ESoapResponse *response, const gchar *method_name)
+{
+	ESoapResponsePrivate *priv;
+
+	g_return_if_fail (E_IS_SOAP_RESPONSE (response));
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	g_return_if_fail (priv->xml_method != NULL);
+	g_return_if_fail (method_name != NULL);
+
+	xmlNodeSetName (priv->xml_method, (const xmlChar *)method_name);
+}
+
+/**
+ * e_soap_parameter_get_name:
+ * @param: the parameter
+ *
+ * Returns the parameter name.
+ *
+ * Returns: the parameter name.
+ */
+const gchar *
+e_soap_parameter_get_name (ESoapParameter *param)
+{
+	g_return_val_if_fail (param != NULL, NULL);
+
+	return (const gchar *) param->name;
+}
+
+/**
+ * e_soap_parameter_get_int_value:
+ * @param: the parameter
+ *
+ * Returns the parameter's (integer) value.
+ *
+ * Returns: the parameter value as an integer
+ */
+gint
+e_soap_parameter_get_int_value (ESoapParameter *param)
+{
+	gint i;
+	xmlChar *s;
+	g_return_val_if_fail (param != NULL, -1);
+
+	s = xmlNodeGetContent (param);
+	if (s) {
+		i = atoi ((gchar *)s);
+		xmlFree (s);
+
+		return i;
+	}
+
+	return -1;
+}
+
+/**
+ * e_soap_parameter_get_string_value:
+ * @param: the parameter
+ *
+ * Returns the parameter's value.
+ *
+ * Returns: the parameter value as a string, which must be freed
+ * by the caller.
+ */
+gchar *
+e_soap_parameter_get_string_value (ESoapParameter *param)
+{
+	xmlChar *xml_s;
+	gchar *s;
+	g_return_val_if_fail (param != NULL, NULL);
+
+	xml_s = xmlNodeGetContent (param);
+	s = g_strdup ((gchar *)xml_s);
+	xmlFree (xml_s);
+
+	return s;
+}
+
+/**
+ * e_soap_parameter_get_first_child:
+ * @param: A #ESoapParameter.
+ *
+ * Gets the first child of the given #ESoapParameter. This is used
+ * for compound data types, which can contain several parameters
+ * themselves.
+ *
+ * Returns: the first child or %NULL if there are no children.
+ */
+ESoapParameter *
+e_soap_parameter_get_first_child (ESoapParameter *param)
+{
+	g_return_val_if_fail (param != NULL, NULL);
+
+	return soup_xml_real_node (param->children);
+}
+
+/**
+ * e_soap_parameter_get_first_child_by_name:
+ * @param: A #ESoapParameter.
+ * @name: The name of the child parameter to look for.
+ *
+ * Gets the first child of the given #ESoapParameter whose name is
+ * @name.
+ *
+ * Returns: the first child with the given name or %NULL if there
+ * are no children.
+ */
+ESoapParameter *
+e_soap_parameter_get_first_child_by_name (ESoapParameter *param, const gchar *name)
+{
+	ESoapParameter *tmp;
+
+	g_return_val_if_fail (param != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	for (tmp = e_soap_parameter_get_first_child (param);
+	     tmp != NULL;
+	     tmp = e_soap_parameter_get_next_child (tmp)) {
+		if (!strcmp (name, (const gchar *)tmp->name))
+			return tmp;
+	}
+
+	return NULL;
+}
+
+/**
+ * e_soap_parameter_get_next_child:
+ * @param: A #ESoapParameter.
+ *
+ * Gets the next sibling of the given #ESoapParameter. This is used
+ * for compound data types, which can contain several parameters
+ * themselves.
+ *
+ * FIXME: the name of this method is wrong
+ *
+ * Returns: the next sibling, or %NULL if there are no more
+ * siblings.
+ */
+ESoapParameter *
+e_soap_parameter_get_next_child (ESoapParameter *param)
+{
+	g_return_val_if_fail (param != NULL, NULL);
+
+	return soup_xml_real_node (param->next);
+}
+
+/**
+ * e_soap_parameter_get_next_child_by_name:
+ * @param: A #ESoapParameter.
+ * @name: The name of the sibling parameter to look for.
+ *
+ * Gets the next sibling of the given #ESoapParameter whose name is
+ * @name.
+ *
+ * FIXME: the name of this method is wrong
+ *
+ * Returns: the next sibling with the given name, or %NULL
+ */
+ESoapParameter *
+e_soap_parameter_get_next_child_by_name (ESoapParameter *param,
+					    const gchar *name)
+{
+	ESoapParameter *tmp;
+
+	g_return_val_if_fail (param != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	for (tmp = e_soap_parameter_get_next_child (param);
+	     tmp != NULL;
+	     tmp = e_soap_parameter_get_next_child (tmp)) {
+		if (!strcmp (name, (const gchar *)tmp->name))
+			return tmp;
+	}
+
+	return NULL;
+}
+
+/**
+ * e_soap_parameter_get_property:
+ * @param: the parameter
+ * @prop_name: Name of the property to retrieve.
+ *
+ * Returns the named property of @param.
+ *
+ * Returns: the property, which must be freed by the caller.
+ */
+gchar *
+e_soap_parameter_get_property (ESoapParameter *param, const gchar *prop_name)
+{
+	xmlChar *xml_s;
+	gchar *s;
+
+	g_return_val_if_fail (param != NULL, NULL);
+	g_return_val_if_fail (prop_name != NULL, NULL);
+
+	xml_s = xmlGetProp (param, (const xmlChar *)prop_name);
+	s = g_strdup ((gchar *)xml_s);
+	xmlFree (xml_s);
+
+	return s;
+}
+
+/**
+ * e_soap_response_get_parameters:
+ * @response: the #ESoapResponse object.
+ *
+ * Returns the list of parameters received in the SOAP response.
+ *
+ * Returns: a list of #ESoapParameter
+ */
+const GList *
+e_soap_response_get_parameters (ESoapResponse *response)
+{
+	ESoapResponsePrivate *priv;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+
+	return (const GList *) priv->parameters;
+}
+
+/**
+ * e_soap_response_get_first_parameter:
+ * @response: the #ESoapResponse object.
+ *
+ * Retrieves the first parameter contained in the SOAP response.
+ *
+ * Returns: a #ESoapParameter representing the first
+ * parameter, or %NULL if there are no parameters.
+ */
+ESoapParameter *
+e_soap_response_get_first_parameter (ESoapResponse *response)
+{
+	ESoapResponsePrivate *priv;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+
+	return priv->parameters ? priv->parameters->data : NULL;
+}
+
+/**
+ * e_soap_response_get_first_parameter_by_name:
+ * @response: the #ESoapResponse object.
+ * @name: the name of the parameter to look for.
+ *
+ * Retrieves the first parameter contained in the SOAP response whose
+ * name is @name.
+ *
+ * Returns: a #ESoapParameter representing the first parameter
+ * with the given name, or %NULL.
+ */
+ESoapParameter *
+e_soap_response_get_first_parameter_by_name (ESoapResponse *response,
+						const gchar *name)
+{
+	ESoapResponsePrivate *priv;
+	GList *l;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	for (l = priv->parameters; l != NULL; l = l->next) {
+		ESoapParameter *param = (ESoapParameter *) l->data;
+
+		if (!strcmp (name, (const gchar *)param->name))
+			return param;
+	}
+
+	return NULL;
+}
+
+/**
+ * e_soap_response_get_next_parameter:
+ * @response: the #ESoapResponse object.
+ * @from: the parameter to start from.
+ *
+ * Retrieves the parameter following @from in the #ESoapResponse
+ * object.
+ *
+ * Returns: a #ESoapParameter representing the parameter.
+ */
+ESoapParameter *
+e_soap_response_get_next_parameter (ESoapResponse *response,
+				       ESoapParameter *from)
+{
+	ESoapResponsePrivate *priv;
+	GList *l;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	g_return_val_if_fail (from != NULL, NULL);
+
+	l = g_list_find (priv->parameters, (gconstpointer) from);
+	if (!l)
+		return NULL;
+
+	return l->next ? (ESoapParameter *) l->next->data : NULL;
+}
+
+/**
+ * e_soap_response_get_next_parameter_by_name:
+ * @response: the #ESoapResponse object.
+ * @from: the parameter to start from.
+ * @name: the name of the parameter to look for.
+ *
+ * Retrieves the first parameter following @from in the
+ * #ESoapResponse object whose name matches @name.
+ *
+ * Returns: a #ESoapParameter representing the parameter.
+ */
+ESoapParameter *
+e_soap_response_get_next_parameter_by_name (ESoapResponse *response,
+					       ESoapParameter *from,
+					       const gchar *name)
+{
+	ESoapParameter *param;
+
+	g_return_val_if_fail (E_IS_SOAP_RESPONSE (response), NULL);
+	g_return_val_if_fail (from != NULL, NULL);
+	g_return_val_if_fail (name != NULL, NULL);
+
+	param = e_soap_response_get_next_parameter (response, from);
+	while (param) {
+		const gchar *param_name = e_soap_parameter_get_name (param);
+
+		if (param_name) {
+			if (!strcmp (name, param_name))
+				return param;
+		}
+
+		param = e_soap_response_get_next_parameter (response, param);
+	}
+
+	return NULL;
+}
+
+static xmlNode *
+soup_xml_real_node (xmlNode *node)
+{
+	while (node && (node->type == XML_COMMENT_NODE ||
+			xmlIsBlankNode (node)))
+		node = node->next;
+	return node;
+}
+
+gint
+e_soap_response_dump_response (ESoapResponse *response, FILE *buffer)
+{
+	xmlChar *xmlbuff;
+	gint buffersize, ret;
+
+	ESoapResponsePrivate *priv = E_SOAP_RESPONSE_GET_PRIVATE (response);
+	xmlDocDumpFormatMemory (priv->xmldoc, &xmlbuff, &buffersize, 1);
+
+	ret = fputs ((gchar *) xmlbuff, buffer);
+	xmlFree (xmlbuff);
+
+	return ret;
+}
diff --git a/libedataserver/e-soap-response.h b/libedataserver/e-soap-response.h
new file mode 100644
index 0000000..8b3dd1c
--- /dev/null
+++ b/libedataserver/e-soap-response.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifndef E_SOAP_RESPONSE_H
+#define E_SOAP_RESPONSE_H
+
+#include <glib-object.h>
+#include <libxml/tree.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_SOAP_RESPONSE            (e_soap_response_get_type ())
+#define E_SOAP_RESPONSE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SOAP_RESPONSE, ESoapResponse))
+#define E_SOAP_RESPONSE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SOAP_RESPONSE, ESoapResponseClass))
+#define E_IS_SOAP_RESPONSE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SOAP_RESPONSE))
+#define E_IS_SOAP_RESPONSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_SOAP_RESPONSE))
+#define E_SOAP_RESPONSE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_SOAP_RESPONSE, ESoapResponseClass))
+
+typedef struct {
+	GObject parent;
+
+} ESoapResponse;
+
+typedef struct {
+	GObjectClass parent_class;
+} ESoapResponseClass;
+
+GType             e_soap_response_get_type (void);
+
+ESoapResponse *e_soap_response_new (void);
+ESoapResponse *e_soap_response_new_from_string (const gchar *xmlstr);
+
+gboolean          e_soap_response_from_string (ESoapResponse *response, const gchar *xmlstr);
+
+const gchar       *e_soap_response_get_method_name (ESoapResponse *response);
+void              e_soap_response_set_method_name (ESoapResponse *response,
+						      const gchar *method_name);
+
+typedef xmlNode ESoapParameter;
+
+const gchar        *e_soap_parameter_get_name (ESoapParameter *param);
+gint                e_soap_parameter_get_int_value (ESoapParameter *param);
+gchar              *e_soap_parameter_get_string_value (ESoapParameter *param);
+ESoapParameter *e_soap_parameter_get_first_child (ESoapParameter *param);
+ESoapParameter *e_soap_parameter_get_first_child_by_name (ESoapParameter *param,
+								const gchar *name);
+ESoapParameter *e_soap_parameter_get_next_child (ESoapParameter *param);
+ESoapParameter *e_soap_parameter_get_next_child_by_name (ESoapParameter *param,
+							       const gchar *name);
+gchar              *e_soap_parameter_get_property (ESoapParameter *param, const gchar *prop_name);
+
+const GList       *e_soap_response_get_parameters (ESoapResponse *response);
+ESoapParameter *e_soap_response_get_first_parameter (ESoapResponse *response);
+ESoapParameter *e_soap_response_get_first_parameter_by_name (ESoapResponse *response,
+								   const gchar *name);
+ESoapParameter *e_soap_response_get_next_parameter (ESoapResponse *response,
+							  ESoapParameter *from);
+ESoapParameter *e_soap_response_get_next_parameter_by_name (ESoapResponse *response,
+								  ESoapParameter *from,
+								  const gchar *name);
+
+gint e_soap_response_dump_response (ESoapResponse *response, FILE *buffer);
+
+G_END_DECLS
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]