source: trunk/third/libsoup/libsoup/soup-soap-response.c @ 21108

Revision 21108, 12.2 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21107, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Copyright (C) 2003, Novell, Inc.
4 */
5
6#include <stdlib.h>
7#include <string.h>
8#include <libxml/tree.h>
9#include "soup-misc.h"
10#include "soup-soap-response.h"
11#include "soup-types.h"
12
13#define PARENT_TYPE G_TYPE_OBJECT
14
15struct _SoupSoapResponsePrivate {
16        /* the XML document */
17        xmlDocPtr xmldoc;
18        xmlNodePtr xml_root;
19        xmlNodePtr xml_body;
20        xmlNodePtr xml_method;
21        xmlNodePtr soap_fault;
22        GList *parameters;
23};
24
25static GObjectClass *parent_class = NULL;
26
27static void
28finalize (GObject *object)
29{
30        SoupSoapResponse *response = SOUP_SOAP_RESPONSE (object);
31
32        /* free memory */
33        if (response->priv->xmldoc) {
34                xmlFreeDoc (response->priv->xmldoc);
35                response->priv->xmldoc = NULL;
36        }
37
38        response->priv->xml_root = NULL;
39        response->priv->xml_body = NULL;
40        response->priv->xml_method = NULL;
41
42        if (response->priv->parameters != NULL) {
43                g_list_free (response->priv->parameters);
44                response->priv->parameters = NULL;
45        }
46
47        g_free (response->priv);
48        response->priv = NULL;
49
50        parent_class->finalize (object);
51}
52
53static void
54class_init (SoupSoapResponseClass *klass)
55{
56        GObjectClass *object_class;
57
58        parent_class = g_type_class_peek_parent (klass);
59
60        object_class = G_OBJECT_CLASS (klass);
61        object_class->finalize = finalize;
62}
63
64static void
65init (SoupSoapResponse *response, SoupSoapResponseClass *klass)
66{
67        response->priv = g_new0 (SoupSoapResponsePrivate, 1);
68
69        response->priv->xmldoc = xmlNewDoc ("1.0");
70}
71
72SOUP_MAKE_TYPE (soup_soap_response, SoupSoapResponse, class_init, init, PARENT_TYPE)
73
74/**
75 * soup_soap_response_new:
76 *
77 * Create a new empty %SoupSoapResponse object, which can be modified with the
78 * accessor functions provided with this class.
79 *
80 * Return value: the new %SoupSoapResponse (or %NULL if there was an error).
81 */
82SoupSoapResponse *
83soup_soap_response_new (void)
84{
85        SoupSoapResponse *response;
86
87        response = g_object_new (SOUP_TYPE_SOAP_RESPONSE, NULL);
88        return response;
89}
90
91/**
92 * soup_soap_response_new_from_string:
93 * @xmlstr: the XML string to parse.
94 *
95 * Create a new %SoupSoapResponse object from the XML string contained in
96 * @xmlstr.
97 *
98 * Return value: the new %SoupSoapResponse (or %NULL if there was an error).
99 */
100SoupSoapResponse *
101soup_soap_response_new_from_string (const char *xmlstr)
102{
103        SoupSoapResponse *response;
104
105        g_return_val_if_fail (xmlstr != NULL, NULL);
106
107        response = g_object_new (SOUP_TYPE_SOAP_RESPONSE, NULL);
108        if (!soup_soap_response_from_string (response, xmlstr)) {
109                g_object_unref (response);
110                return NULL;
111        }
112
113        return response;
114}
115
116static void
117parse_parameters (SoupSoapResponse *response, xmlNodePtr xml_method)
118{
119        xmlNodePtr tmp;
120
121        for (tmp = xml_method->xmlChildrenNode; tmp != NULL; tmp = tmp->next) {
122                if (!strcmp (tmp->name, "Fault")) {
123                        response->priv->soap_fault = tmp;
124                        continue;
125                } else {
126                        /* regular parameters */
127                        response->priv->parameters = g_list_append (response->priv->parameters, tmp);
128                }
129        }
130}
131
132/**
133 * soup_soap_response_from_string:
134 * @response: the %SoupSoapResponse object.
135 * @xmlstr: XML string to parse.
136 *
137 * Parses the string contained in @xmlstr and sets all properties from it in the
138 * @response object.
139 *
140 * Return value: %TRUE if successful, %FALSE otherwise.
141 */
142gboolean
143soup_soap_response_from_string (SoupSoapResponse *response, const char *xmlstr)
144{
145        xmlDocPtr old_doc = NULL;
146        xmlNodePtr xml_root, xml_body = NULL, xml_method = NULL;
147
148        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), FALSE);
149        g_return_val_if_fail (xmlstr != NULL, FALSE);
150
151        /* clear the previous contents */
152        if (response->priv->xmldoc)
153                old_doc = response->priv->xmldoc;
154
155        /* parse the string */
156        response->priv->xmldoc = xmlParseMemory (xmlstr, strlen (xmlstr));
157        if (!response->priv->xmldoc) {
158                response->priv->xmldoc = old_doc;
159                return FALSE;
160        }
161
162        xml_root = xmlDocGetRootElement (response->priv->xmldoc);
163        if (!xml_root) {
164                xmlFreeDoc (response->priv->xmldoc);
165                response->priv->xmldoc = old_doc;
166                return FALSE;
167        }
168
169        if (strcmp (xml_root->name, "Envelope") != 0) {
170                xmlFreeDoc (response->priv->xmldoc);
171                response->priv->xmldoc = old_doc;
172                return FALSE;
173        }
174
175        if (xml_root->xmlChildrenNode != NULL) {
176                xml_body = xml_root->xmlChildrenNode;
177                if (strcmp (xml_body->name, "Header") == 0)
178                        xml_body = xml_root->xmlChildrenNode->next;
179                if (strcmp (xml_body->name, "Body") != 0) {
180                        xmlFreeDoc (response->priv->xmldoc);
181                        response->priv->xmldoc = old_doc;
182                        return FALSE;
183                }
184
185                xml_method = xml_body->xmlChildrenNode;
186
187                /* read all parameters */
188                if (xml_method)
189                        parse_parameters (response, xml_method);
190        }
191
192        xmlFreeDoc (old_doc);
193
194        response->priv->xml_root = xml_root;
195        response->priv->xml_body = xml_body;
196        response->priv->xml_method = xml_method;
197
198        return TRUE;
199}
200
201/**
202 * soup_soap_response_get_method_name:
203 * @response: the %SoupSoapResponse object.
204 *
205 * Gets the method name from the SOAP response.
206 *
207 * Return value: the method name.
208 */
209const char *
210soup_soap_response_get_method_name (SoupSoapResponse *response)
211{
212        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
213        g_return_val_if_fail (response->priv->xml_method != NULL, NULL);
214
215        return (const char *) response->priv->xml_method->name;
216}
217
218/**
219 * soup_soap_response_set_method_name:
220 * @response: the %SoupSoapResponse object.
221 * @method_name: the method name to set.
222 *
223 * Sets the method name on the given %SoupSoapResponse.
224 */
225void
226soup_soap_response_set_method_name (SoupSoapResponse *response, const char *method_name)
227{
228        g_return_if_fail (SOUP_IS_SOAP_RESPONSE (response));
229        g_return_if_fail (response->priv->xml_method != NULL);
230        g_return_if_fail (method_name != NULL);
231
232        xmlNodeSetName (response->priv->xml_method, method_name);
233}
234
235/**
236 * soup_soap_parameter_get_name:
237 */
238const char *
239soup_soap_parameter_get_name (SoupSoapParameter *param)
240{
241        g_return_val_if_fail (param != NULL, NULL);
242
243        return (const char *) param->name;
244}
245
246/**
247 * soup_soap_parameter_get_int_value:
248 */
249int
250soup_soap_parameter_get_int_value (SoupSoapParameter *param)
251{
252        int i;
253        char *s;
254        g_return_val_if_fail (param != NULL, -1);
255
256        s = xmlNodeGetContent (param);
257        if (s) {
258                i = atoi (s);
259                xmlFree (s);
260
261                return i;
262        }
263
264        return -1;
265}
266
267/**
268 * soup_soap_parameter_get_string_value:
269 */
270char *
271soup_soap_parameter_get_string_value (SoupSoapParameter *param)
272{
273        char *xml_s, *s;
274        g_return_val_if_fail (param != NULL, NULL);
275
276        xml_s = xmlNodeGetContent (param);
277        s = g_strdup (xml_s);
278        xmlFree (xml_s);
279
280        return s;
281}
282
283/**
284 * soup_soap_parameter_get_first_child:
285 * @param: A %SoupSoapParameter.
286 *
287 * Gets the first child of the given %SoupSoapParameter. This is used
288 * for compound data types, which can contain several parameters
289 * themselves.
290 *
291 * Return value: the first child or NULL if there are no children.
292 */
293SoupSoapParameter *
294soup_soap_parameter_get_first_child (SoupSoapParameter *param)
295{
296        g_return_val_if_fail (param != NULL, NULL);
297
298        return param->xmlChildrenNode ? param->xmlChildrenNode : NULL;
299}
300
301/**
302 * soup_soap_parameter_get_first_child_by_name:
303 * @param: A %SoupSoapParameter.
304 * @name: The name of the child parameter to look for.
305 *
306 * Gets the first child of the given %SoupSoapParameter whose name
307 * is @name.
308 *
309 * Return value: the first child with the given name or NULL if there
310 * are no children.
311 */
312SoupSoapParameter *
313soup_soap_parameter_get_first_child_by_name (SoupSoapParameter *param, const char *name)
314{
315        SoupSoapParameter *tmp;
316
317        g_return_val_if_fail (param != NULL, NULL);
318        g_return_val_if_fail (name != NULL, NULL);
319
320        for (tmp = soup_soap_parameter_get_first_child (param);
321             tmp != NULL;
322             tmp = soup_soap_parameter_get_next_child (tmp)) {
323                if (!strcmp (name, tmp->name))
324                        return tmp;
325        }
326
327        return NULL;
328}
329
330/**
331 * soup_soap_parameter_get_next_child:
332 * @param: A %SoupSoapParameter.
333 */
334SoupSoapParameter *
335soup_soap_parameter_get_next_child (SoupSoapParameter *param)
336{
337        g_return_val_if_fail (param != NULL, NULL);
338
339        return param->next;
340}
341
342/**
343 * soup_soap_parameter_get_next_child_by_name:
344 */
345SoupSoapParameter *
346soup_soap_parameter_get_next_child_by_name (SoupSoapParameter *param,
347                                            const char *name)
348{
349        SoupSoapParameter *tmp;
350
351        g_return_val_if_fail (param != NULL, NULL);
352        g_return_val_if_fail (name != NULL, NULL);
353
354        for (tmp = soup_soap_parameter_get_next_child (param);
355             tmp != NULL;
356             tmp = soup_soap_parameter_get_next_child (tmp)) {
357                if (!strcmp (name, tmp->name))
358                        return tmp;
359        }
360
361        return NULL;
362}
363
364/**
365 * soup_soap_parameter_get_property:
366 * @param:
367 * @prop_name: Name of the property to retrieve.
368 */
369char *
370soup_soap_parameter_get_property (SoupSoapParameter *param, const char *prop_name)
371{
372        char *xml_s, *s;
373
374        g_return_val_if_fail (param != NULL, NULL);
375        g_return_val_if_fail (prop_name != NULL, NULL);
376
377        xml_s = xmlGetProp (param, prop_name);
378        s = g_strdup (xml_s);
379        xmlFree (xml_s);
380
381        return s;
382}
383
384/**
385 * soup_soap_response_get_parameters:
386 * @response: the %SoupSoapResponse object.
387 *
388 * Returns the list of parameters received in the SOAP response.
389 *
390 * Return value: the list of parameters, represented in
391 * SoupSoapParameter's, which is an opaque type used to
392 * represent a parameter in the SOAP response.
393 */
394const GList *
395soup_soap_response_get_parameters (SoupSoapResponse *response)
396{
397        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
398
399        return (const GList *) response->priv->parameters;
400}
401
402/**
403 * soup_soap_response_get_first_parameter:
404 * @response: the %SoupSoapResponse object.
405 *
406 * Retrieves the first parameter contained in the SOAP response.
407 *
408 * Return value: a %SoupSoapParameter representing the
409 * first parameter. This is an opaque type used to
410 * represent a parameter in the SOAP response.
411 */
412SoupSoapParameter *
413soup_soap_response_get_first_parameter (SoupSoapResponse *response)
414{
415        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
416
417        return response->priv->parameters ? response->priv->parameters->data : NULL;
418}
419
420/**
421 * soup_soap_response_get_first_parameter_by_name:
422 * @response: the %SoupSoapResponse object.
423 * @name: the name of the parameter to look for.
424 *
425 * Retrieves the first parameter contained in the SOAP response whose
426 * name is @name.
427 *
428 * Return value: a %SoupSoapParameter representing the
429 * first parameter. This is an opaque type used to
430 * represent a parameter in the SOAP response.
431 */
432SoupSoapParameter *
433soup_soap_response_get_first_parameter_by_name (SoupSoapResponse *response,
434                                                const char *name)
435{
436        GList *l;
437
438        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
439        g_return_val_if_fail (name != NULL, NULL);
440
441        for (l = response->priv->parameters; l != NULL; l = l->next) {
442                SoupSoapParameter *param = (SoupSoapParameter *) l->data;
443
444                if (!strcmp (name, param->name))
445                        return param;
446        }
447
448        return NULL;
449}
450
451/**
452 * soup_soap_response_get_next_parameter:
453 * @response: the %SoupSoapResponse object.
454 * @from: the parameter to start from.
455 *
456 * Retrieves the parameter following @from in the %SoupSoapResponse object.
457 *
458 * Return value: a %SoupSoapParameter representing the parameter.
459 */
460SoupSoapParameter *
461soup_soap_response_get_next_parameter (SoupSoapResponse *response,
462                                       SoupSoapParameter *from)
463{
464        GList *l;
465
466        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
467        g_return_val_if_fail (from != NULL, NULL);
468
469        l = g_list_find (response->priv->parameters, (gconstpointer) from);
470        if (!l)
471                return NULL;
472
473        return l->next ? (SoupSoapParameter *) l->next->data : NULL;
474}
475
476/**
477 * soup_soap_response_get_next_parameter_by_name:
478 * @response: the %SoupSoapResponse object.
479 * @from: the parameter to start from.
480 * @name: the name of the parameter to look for.
481 *
482 * Retrieves the parameter following @from in the %SoupSoapResponse object
483 * whose name matches @name.
484 *
485 * Return value: a %SoupSoapParameter representing the parameter.
486 */
487SoupSoapParameter *
488soup_soap_response_get_next_parameter_by_name (SoupSoapResponse *response,
489                                               SoupSoapParameter *from,
490                                               const char *name)
491{
492        SoupSoapParameter *param;
493
494        g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), NULL);
495        g_return_val_if_fail (from != NULL, NULL);
496        g_return_val_if_fail (name != NULL, NULL);
497
498        param = soup_soap_response_get_next_parameter (response, from);
499        while (param) {
500                const char *param_name = soup_soap_parameter_get_name (param);
501
502                if (param_name) {
503                        if (!strcmp (name, param_name))
504                                return param;
505                }
506
507                param = soup_soap_response_get_next_parameter (response, param);
508        }
509
510        return NULL;
511}
Note: See TracBrowser for help on using the repository browser.