1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2003, Novell, Inc.
8 #include <libxml/tree.h>
10 #include "soup-soap-response.h"
11 #include "soup-types.h"
13 #define PARENT_TYPE G_TYPE_OBJECT
15 struct _SoupSoapResponsePrivate {
16 /* the XML document */
18 xmlParserCtxtPtr ctxt;
21 xmlNodePtr xml_method;
22 xmlNodePtr soap_fault;
26 static GObjectClass *parent_class = NULL;
29 finalize (GObject *object)
31 SoupSoapResponse *response = SOUP_SOAP_RESPONSE (object);
34 if (response->priv->xmldoc) {
35 xmlFreeDoc (response->priv->xmldoc);
36 response->priv->xmldoc = NULL;
38 if (response->priv->ctxt) {
39 xmlFreeParserCtxt (response->priv->ctxt);
40 response->priv->ctxt = NULL;
44 response->priv->xml_root = NULL;
45 response->priv->xml_body = NULL;
46 response->priv->xml_method = NULL;
48 if (response->priv->parameters != NULL) {
49 g_list_free (response->priv->parameters);
50 response->priv->parameters = NULL;
53 g_free (response->priv);
54 response->priv = NULL;
56 parent_class->finalize (object);
60 class_init (SoupSoapResponseClass *klass)
62 GObjectClass *object_class;
64 parent_class = g_type_class_peek_parent (klass);
66 object_class = G_OBJECT_CLASS (klass);
67 object_class->finalize = finalize;
71 init (SoupSoapResponse *response, SoupSoapResponseClass *klass)
73 response->priv = g_new0 (SoupSoapResponsePrivate, 1);
75 response->priv->ctxt = xmlNewParserCtxt ();
76 response->priv->xmldoc = xmlNewDoc ("1.0");
79 SOUP_MAKE_TYPE (soup_soap_response, SoupSoapResponse, class_init, init, PARENT_TYPE)
82 * soup_soap_response_new:
84 * Create a new empty %SoupSoapResponse object, which can be modified with the
85 * accessor functions provided with this class.
87 * Return value: the new %SoupSoapResponse (or %NULL if there was an error).
90 soup_soap_response_new (void)
92 SoupSoapResponse *response;
94 response = g_object_new (SOUP_TYPE_SOAP_RESPONSE, NULL);
99 * soup_soap_response_new_from_string:
100 * @xmlstr: the XML string to parse.
102 * Create a new %SoupSoapResponse object from the XML string contained in
105 * Return value: the new %SoupSoapResponse (or %NULL if there was an error).
108 soup_soap_response_new_from_string (const char *xmlstr)
110 SoupSoapResponse *response;
112 g_return_val_if_fail (xmlstr != NULL, NULL);
114 response = g_object_new (SOUP_TYPE_SOAP_RESPONSE, NULL);
115 if (!soup_soap_response_from_string (response, xmlstr)) {
116 g_object_unref (response);
124 parse_parameters (SoupSoapResponse *response, xmlNodePtr xml_method)
128 for (tmp = xml_method->xmlChildrenNode; tmp != NULL; tmp = tmp->next) {
129 if (!strcmp (tmp->name, "Fault")) {
130 response->priv->soap_fault = tmp;
133 /* regular parameters */
134 response->priv->parameters = g_list_append (response->priv->parameters, tmp);
140 * soup_soap_response_from_string:
141 * @response: the %SoupSoapResponse object.
142 * @xmlstr: XML string to parse.
144 * Parses the string contained in @xmlstr and sets all properties from it in the
147 * Return value: %TRUE if successful, %FALSE otherwise.
150 soup_soap_response_from_string (SoupSoapResponse *response, const char *xmlstr)
152 xmlDocPtr old_doc = NULL;
153 xmlNodePtr xml_root, xml_body = NULL, xml_method = NULL;
155 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), FALSE);
156 g_return_val_if_fail (xmlstr != NULL, FALSE);
158 /* clear the previous contents */
159 if (response->priv->xmldoc)
160 old_doc = response->priv->xmldoc;
162 /* parse the string. We are using a parse context to make libxml
163 * ignore blanks and '\n' for this document. */
164 response->priv->xmldoc = xmlCtxtReadMemory (response->priv->ctxt, xmlstr, strlen (xmlstr), NULL, NULL, XML_PARSE_NOBLANKS);
165 if (!response->priv->xmldoc) {
166 response->priv->xmldoc = old_doc;
170 xml_root = xmlDocGetRootElement (response->priv->xmldoc);
172 xmlFreeDoc (response->priv->xmldoc);
173 response->priv->xmldoc = old_doc;
177 if (strcmp (xml_root->name, "Envelope") != 0) {
178 xmlFreeDoc (response->priv->xmldoc);
179 response->priv->xmldoc = old_doc;
183 if (xml_root->xmlChildrenNode != NULL) {
184 xml_body = xml_root->xmlChildrenNode;
185 if (strcmp (xml_body->name, "Header") == 0)
186 xml_body = xml_root->xmlChildrenNode->next;
187 if (strcmp (xml_body->name, "Body") != 0) {
188 xmlFreeDoc (response->priv->xmldoc);
189 response->priv->xmldoc = old_doc;
193 xml_method = xml_body->xmlChildrenNode;
195 /* read all parameters */
197 parse_parameters (response, xml_method);
200 xmlFreeDoc (old_doc);
202 response->priv->xml_root = xml_root;
203 response->priv->xml_body = xml_body;
204 response->priv->xml_method = xml_method;
210 * soup_soap_response_get_method_name:
211 * @response: the %SoupSoapResponse object.
213 * Gets the method name from the SOAP response.
215 * Return value: the method name.
218 soup_soap_response_get_method_name (SoupSoapResponse *response)
220 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
221 g_return_val_if_fail (response->priv->xml_method != NULL, NULL);
223 return (const char *) response->priv->xml_method->name;
227 * soup_soap_response_set_method_name:
228 * @response: the %SoupSoapResponse object.
229 * @method_name: the method name to set.
231 * Sets the method name on the given %SoupSoapResponse.
234 soup_soap_response_set_method_name (SoupSoapResponse *response, const char *method_name)
236 g_return_if_fail (SOUP_IS_SOAP_RESPONSE (response));
237 g_return_if_fail (response->priv->xml_method != NULL);
238 g_return_if_fail (method_name != NULL);
240 xmlNodeSetName (response->priv->xml_method, method_name);
244 * soup_soap_parameter_get_name:
247 soup_soap_parameter_get_name (SoupSoapParameter *param)
249 g_return_val_if_fail (param != NULL, NULL);
251 return (const char *) param->name;
255 * soup_soap_parameter_get_int_value:
258 soup_soap_parameter_get_int_value (SoupSoapParameter *param)
262 g_return_val_if_fail (param != NULL, -1);
264 s = xmlNodeGetContent (param);
276 * soup_soap_parameter_get_string_value:
279 soup_soap_parameter_get_string_value (SoupSoapParameter *param)
282 g_return_val_if_fail (param != NULL, NULL);
284 xml_s = xmlNodeGetContent (param);
285 s = g_strdup (xml_s);
292 * soup_soap_parameter_get_first_child:
293 * @param: A %SoupSoapParameter.
295 * Gets the first child of the given %SoupSoapParameter. This is used
296 * for compound data types, which can contain several parameters
299 * Return value: the first child or NULL if there are no children.
302 soup_soap_parameter_get_first_child (SoupSoapParameter *param)
304 g_return_val_if_fail (param != NULL, NULL);
306 return param->xmlChildrenNode ? param->xmlChildrenNode : NULL;
310 * soup_soap_parameter_get_first_child_by_name:
311 * @param: A %SoupSoapParameter.
312 * @name: The name of the child parameter to look for.
314 * Gets the first child of the given %SoupSoapParameter whose name
317 * Return value: the first child with the given name or NULL if there
321 soup_soap_parameter_get_first_child_by_name (SoupSoapParameter *param, const char *name)
323 SoupSoapParameter *tmp;
325 g_return_val_if_fail (param != NULL, NULL);
326 g_return_val_if_fail (name != NULL, NULL);
328 for (tmp = soup_soap_parameter_get_first_child (param);
330 tmp = soup_soap_parameter_get_next_child (tmp)) {
331 if (!strcmp (name, tmp->name))
339 * soup_soap_parameter_get_next_child:
340 * @param: A %SoupSoapParameter.
343 soup_soap_parameter_get_next_child (SoupSoapParameter *param)
345 g_return_val_if_fail (param != NULL, NULL);
351 * soup_soap_parameter_get_next_child_by_name:
354 soup_soap_parameter_get_next_child_by_name (SoupSoapParameter *param,
357 SoupSoapParameter *tmp;
359 g_return_val_if_fail (param != NULL, NULL);
360 g_return_val_if_fail (name != NULL, NULL);
362 for (tmp = soup_soap_parameter_get_next_child (param);
364 tmp = soup_soap_parameter_get_next_child (tmp)) {
365 if (!strcmp (name, tmp->name))
373 * soup_soap_parameter_get_property:
375 * @prop_name: Name of the property to retrieve.
378 soup_soap_parameter_get_property (SoupSoapParameter *param, const char *prop_name)
382 g_return_val_if_fail (param != NULL, NULL);
383 g_return_val_if_fail (prop_name != NULL, NULL);
385 xml_s = xmlGetProp (param, prop_name);
386 s = g_strdup (xml_s);
393 * soup_soap_response_get_parameters:
394 * @response: the %SoupSoapResponse object.
396 * Returns the list of parameters received in the SOAP response.
398 * Return value: the list of parameters, represented in
399 * SoupSoapParameter's, which is an opaque type used to
400 * represent a parameter in the SOAP response.
403 soup_soap_response_get_parameters (SoupSoapResponse *response)
405 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
407 return (const GList *) response->priv->parameters;
411 * soup_soap_response_get_first_parameter:
412 * @response: the %SoupSoapResponse object.
414 * Retrieves the first parameter contained in the SOAP response.
416 * Return value: a %SoupSoapParameter representing the
417 * first parameter. This is an opaque type used to
418 * represent a parameter in the SOAP response.
421 soup_soap_response_get_first_parameter (SoupSoapResponse *response)
423 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
425 return response->priv->parameters ? response->priv->parameters->data : NULL;
429 * soup_soap_response_get_first_parameter_by_name:
430 * @response: the %SoupSoapResponse object.
431 * @name: the name of the parameter to look for.
433 * Retrieves the first parameter contained in the SOAP response whose
436 * Return value: a %SoupSoapParameter representing the
437 * first parameter. This is an opaque type used to
438 * represent a parameter in the SOAP response.
441 soup_soap_response_get_first_parameter_by_name (SoupSoapResponse *response,
446 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
447 g_return_val_if_fail (name != NULL, NULL);
449 for (l = response->priv->parameters; l != NULL; l = l->next) {
450 SoupSoapParameter *param = (SoupSoapParameter *) l->data;
452 if (!strcmp (name, param->name))
460 * soup_soap_response_get_next_parameter:
461 * @response: the %SoupSoapResponse object.
462 * @from: the parameter to start from.
464 * Retrieves the parameter following @from in the %SoupSoapResponse object.
466 * Return value: a %SoupSoapParameter representing the parameter.
469 soup_soap_response_get_next_parameter (SoupSoapResponse *response,
470 SoupSoapParameter *from)
474 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
475 g_return_val_if_fail (from != NULL, NULL);
477 l = g_list_find (response->priv->parameters, (gconstpointer) from);
481 return l->next ? (SoupSoapParameter *) l->next->data : NULL;
485 * soup_soap_response_get_next_parameter_by_name:
486 * @response: the %SoupSoapResponse object.
487 * @from: the parameter to start from.
488 * @name: the name of the parameter to look for.
490 * Retrieves the parameter following @from in the %SoupSoapResponse object
491 * whose name matches @name.
493 * Return value: a %SoupSoapParameter representing the parameter.
496 soup_soap_response_get_next_parameter_by_name (SoupSoapResponse *response,
497 SoupSoapParameter *from,
500 SoupSoapParameter *param;
502 g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
503 g_return_val_if_fail (from != NULL, NULL);
504 g_return_val_if_fail (name != NULL, NULL);
506 param = soup_soap_response_get_next_parameter (response, from);
508 const char *param_name = soup_soap_parameter_get_name (param);
511 if (!strcmp (name, param_name))
515 param = soup_soap_response_get_next_parameter (response, param);