From b6c9414b7ecb39df8259f5240b686d3a7afb64f9 Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Mon, 17 Nov 2003 23:14:32 +0000 Subject: [PATCH] added a bunch of initialization parameters. 2003-11-17 Rodrigo Moya * libsoup/soup-soap-message.[ch] (soup_soap_message_new, soup_soap_message_new_from_uri): added a bunch of initialization parameters. (soup_soap_message_get_xml_doc, soup_soap_message_start_envelope, soup_soap_message_end_envelope, soup_soap_message_start_body, soup_soap_message_end_body, soup_soap_message_start_element, soup_soap_message_end_element): new functions. * configure.in: depend on libxml-2.0 for the SOAP code. * libsoup/Makefile.am: use XML CFLAGS and LIBS. --- ChangeLog | 15 ++++ configure.in | 4 + libsoup/Makefile.am | 2 + libsoup/soup-soap-message.c | 209 ++++++++++++++++++++++++++++++++++++++++++-- libsoup/soup-soap-message.h | 21 ++++- 5 files changed, 243 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index eed14a2..7bca122 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2003-11-17 Rodrigo Moya + + * libsoup/soup-soap-message.[ch] (soup_soap_message_new, + soup_soap_message_new_from_uri): added a bunch of initialization + parameters. + (soup_soap_message_get_xml_doc, soup_soap_message_start_envelope, + soup_soap_message_end_envelope, soup_soap_message_start_body, + soup_soap_message_end_body, soup_soap_message_start_element, + soup_soap_message_end_element): + new functions. + + * configure.in: depend on libxml-2.0 for the SOAP code. + + * libsoup/Makefile.am: use XML CFLAGS and LIBS. + 2003-11-17 Joe Shaw * configure.in: Add in the --enable-libgpg-error flag from the 2.0 diff --git a/configure.in b/configure.in index c8a530c..c7ca988 100644 --- a/configure.in +++ b/configure.in @@ -74,6 +74,10 @@ dnl *********************** AM_PATH_GLIB_2_0(2.0.0,,,gobject) +PKG_CHECK_MODULES(XML, libxml-2.0) +AC_SUBST(XML_CFLAGS) +AC_SUBST(XML_LIBS) + dnl ********************************* dnl *** Networking library checks *** dnl ********************************* diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am index 9a8e08e..e3f8560 100644 --- a/libsoup/Makefile.am +++ b/libsoup/Makefile.am @@ -7,6 +7,7 @@ INCLUDES = \ -I$(top_srcdir) \ $(SOUP_DEBUG_FLAGS) \ $(GLIB_CFLAGS) \ + $(XML_CFLAGS) \ $(GNUTLS_CFLAGS) MARSHAL_GENERATED = soup-marshal.c soup-marshal.h @@ -52,6 +53,7 @@ libsoup_2_2_la_LDFLAGS = \ libsoup_2_2_la_LIBADD = \ $(GLIB_LIBS) \ + $(XML_LIBS) \ $(GNUTLS_LIBS) libsoup_2_2_la_SOURCES = \ diff --git a/libsoup/soup-soap-message.c b/libsoup/soup-soap-message.c index c803d5b..d8e5ab2 100644 --- a/libsoup/soup-soap-message.c +++ b/libsoup/soup-soap-message.c @@ -9,6 +9,15 @@ #define PARENT_TYPE SOUP_TYPE_MESSAGE struct _SoupSoapMessagePrivate { + /* Serialization fields */ + xmlDocPtr doc; + xmlNodePtr last_node; + xmlNsPtr soap_ns; + xmlNsPtr xsi_ns; + gchar *env_prefix; + gchar *env_uri; + gboolean body_started; + gchar *action; }; static GObjectClass *parent_class = NULL; @@ -40,10 +49,30 @@ static void init (SoupSoapMessage *msg, SoupSoapMessageClass *klass) { msg->priv = g_new0 (SoupSoapMessagePrivate, 1); + + /* initialize XML structures */ + msg->priv->doc = xmlNewDoc ("1.0"); + msg->priv->doc->standalone = FALSE; + msg->priv->doc->encoding = g_strdup ("UTF-8"); } SOUP_MAKE_TYPE (soup_soap_message, SoupSoapMessage, class_init, init, PARENT_TYPE) +static xmlNsPtr +fetch_ns (SoupSoapMessage *msg, const char *prefix, const char *ns_uri) +{ + xmlNsPtr ns = NULL; + + if (prefix && ns_uri) + ns = xmlNewNs (msg->priv->last_node, ns_uri, prefix); + else if (prefix && !ns_uri) { + ns = xmlSearchNs (msg->priv->doc, msg->priv->last_node, prefix); + if (!ns) ns = xmlNewNs (msg->priv->last_node, "", prefix); + } + + return ns; +} + /** * soup_soap_message_new: * @method: the HTTP method for the created request. @@ -55,7 +84,9 @@ SOUP_MAKE_TYPE (soup_soap_message, SoupSoapMessage, class_init, init, PARENT_TYP * parsed). */ SoupSoapMessage * -soup_soap_message_new (const char *method, const char *uri_string) +soup_soap_message_new (const char *method, const char *uri_string, + gboolean standalone, const char *xml_encoding, + const char *env_prefix, const char *env_uri) { SoupSoapMessage *msg; SoupUri *uri; @@ -64,9 +95,8 @@ soup_soap_message_new (const char *method, const char *uri_string) if (!uri) return NULL; - msg = g_object_new (SOUP_TYPE_SOAP_MESSAGE, NULL); - SOUP_MESSAGE (msg)->method = method ? method : SOUP_METHOD_GET; - soup_message_set_uri (SOUP_MESSAGE (msg), (const SoupUri *) uri); + msg = soup_soap_message_new_from_uri (method, uri, standalone, + xml_encoding, env_prefix, env_uri); soup_uri_free (uri); @@ -83,13 +113,180 @@ soup_soap_message_new (const char *method, const char *uri_string) * Returns: the new #SoupSoapMessage */ SoupSoapMessage * -soup_soap_message_new_from_uri (const char *method, const SoupUri *uri) +soup_soap_message_new_from_uri (const char *method, const SoupUri *uri, + gboolean standalone, const char *xml_encoding, + const char *env_prefix, const char *env_uri) { SoupSoapMessage *msg; msg = g_object_new (SOUP_TYPE_SOAP_MESSAGE, NULL); SOUP_MESSAGE (msg)->method = method ? method : SOUP_METHOD_GET; - soup_message_set_uri (SOUP_MESSAGE (msg), uri); + soup_message_set_uri (SOUP_MESSAGE (msg), (const SoupUri *) uri); + + msg->priv->doc->standalone = standalone; + + if (xml_encoding) { + g_free ((char *) msg->priv->doc->encoding); + msg->priv->doc->encoding = g_strdup (xml_encoding); + } + + if (env_prefix || env_uri) { + msg->priv->env_prefix = g_strdup (env_prefix); + msg->priv->env_uri = g_strdup (env_uri); + } return msg; } + +/** + * soup_soap_message_start_envelope: + * @msg: the %SoupSoapMessage. + * + * Starts the top level SOAP Envelope element. + */ +void +soup_soap_message_start_envelope (SoupSoapMessage *msg) +{ + g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg)); + + msg->priv->last_node = msg->priv->doc->xmlRootNode = + xmlNewDocNode (msg->priv->doc, NULL, "Envelope", NULL); + + msg->priv->soap_ns = xmlNewNs (msg->priv->doc->xmlRootNode, + msg->priv->env_uri ? msg->priv->env_uri : + "http://schemas.xmlsoap.org/soap/envelope/", + msg->priv->env_prefix ? msg->priv->env_prefix : "SOAP-ENV"); + if (msg->priv->env_uri) { + g_free (msg->priv->env_uri); + msg->priv->env_uri = NULL; + } + if (msg->priv->env_prefix) { + g_free (msg->priv->env_prefix); + msg->priv->env_prefix = NULL; + } + + xmlSetNs (msg->priv->doc->xmlRootNode, msg->priv->soap_ns); + + xmlNewNs (msg->priv->doc->xmlRootNode, + "http://schemas.xmlsoap.org/soap/encoding/", + "SOAP-ENC"); + xmlNewNs (msg->priv->doc->xmlRootNode, + "http://www.w3.org/1999/XMLSchema", + "xsd"); + msg->priv->xsi_ns = xmlNewNs (msg->priv->doc->xmlRootNode, + "http://www.w3.org/1999/XMLSchema-instance", + "xsi"); +} + +/** + * soup_soap_message_end_envelope: + * @msg: the %SoupSoapMessage. + * + * Closes the top level SOAP Envelope element. + */ +void +soup_soap_message_end_envelope (SoupSoapMessage *msg) +{ + soup_soap_message_end_element (msg); +} + +/** + * soup_soap_message_start_body: + * @msg: the %SoupSoapMessage. + * + * Starts the SOAP Body element. + */ +void +soup_soap_message_start_body (SoupSoapMessage *msg) +{ + g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg)); + + if (msg->priv->body_started) + return; + + msg->priv->last_node = xmlNewChild (msg->priv->last_node, + msg->priv->soap_ns, + "Body", NULL); + + msg->priv->body_started = TRUE; +} + +/** + * soup_soap_end_body: + * @msg: the %SoupSoapMessage. + * + * Closes the SOAP Body element. + */ +void +soup_soap_message_end_body (SoupSoapMessage *msg) +{ + soup_soap_message_end_element (msg); +} + +/** + * soup_soap_message_start_element: + * @msg: the %SoupSoapMessage. + * @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 +soup_soap_message_start_element (SoupSoapMessage *msg, + const char *name, + const char *prefix, + const char *ns_uri) +{ + g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg)); + + msg->priv->last_node = xmlNewChild (msg->priv->last_node, NULL, name, NULL); + + xmlSetNs (msg->priv->last_node, fetch_ns (msg, prefix, ns_uri)); + + if (msg->priv->body_started && !msg->priv->action) + msg->priv->action = g_strconcat (ns_uri ? ns_uri : "", + "#", name, NULL); +} + +/** + * soup_soap_message_end_element: + * @msg: the %SoupSoapMessage. + * + * Closes the current message element. + */ +void +soup_soap_message_end_element (SoupSoapMessage *msg) +{ + g_return_if_fail (SOUP_IS_SOAP_MESSAGE (msg)); + + msg->priv->last_node = msg->priv->last_node->parent; +} + +/** + * soup_soap_message_get_xml_doc: + * @msg: the %SoupSoapMessage. + * + * Returns the internal XML representation tree of the %SoupSoapMessage pointed + * to by @msg. + * + * Return value: the xmlDocPtr representing the SOAP message. + */ +xmlDocPtr +soup_soap_message_get_xml_doc (SoupSoapMessage *msg) +{ + g_return_val_if_fail (SOUP_IS_SOAP_MESSAGE (msg), NULL); + + return msg->priv->doc; +} diff --git a/libsoup/soup-soap-message.h b/libsoup/soup-soap-message.h index f14ea72..b508acc 100644 --- a/libsoup/soup-soap-message.h +++ b/libsoup/soup-soap-message.h @@ -6,6 +6,7 @@ #ifndef SOUP_SOAP_MESSAGE_H #define SOUP_SOAP_MESSAGE_H 1 +#include #include #define SOUP_TYPE_SOAP_MESSAGE (soup_soap_message_get_type ()) @@ -28,7 +29,23 @@ typedef struct { GType soup_soap_message_get_type (void); -SoupSoapMessage *soup_soap_message_new (const char *method, const char *uri_string); -SoupSoapMessage *soup_soap_message_new_from_uri (const char *method, const SoupUri *uri); +SoupSoapMessage *soup_soap_message_new (const char *method, const char *uri_string, + gboolean standalone, const char *xml_encoding, + const char *env_prefix, const char *env_uri); +SoupSoapMessage *soup_soap_message_new_from_uri (const char *method, const SoupUri *uri, + gboolean standalone, const char *xml_encoding, + const char *env_prefix, const char *env_uri); + +void soup_soap_message_start_envelope (SoupSoapMessage *msg); +void soup_soap_message_end_envelope (SoupSoapMessage *msg); +void soup_soap_message_start_body (SoupSoapMessage *msg); +void soup_soap_message_end_body (SoupSoapMessage *msg); +void soup_soap_message_start_element (SoupSoapMessage *msg, + const char *name, + const char *prefix, + const char *ns_uri); +void soup_soap_message_end_element (SoupSoapMessage *msg); + +xmlDocPtr soup_soap_message_get_xml_doc (SoupSoapMessage *msg); #endif -- 2.7.4