1 /*
2  * Copyright 1999-2006 University of Chicago
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "globus_soap_message.h"
18 #include "globus_i_soap_message.h"
19
20 /**
21  * Common serialization code for all primitive types.
22  * @param element_qname
23  * @param type_info
24  * @param instance
25  * @param type_serialize_contents
26  * @param message_handle
27  */
28 globus_result_t
29 globus_xsd_generic_serialize(
30     const xsd_QName *                   element_qname,
31     const globus_xsd_type_info_t        type_info,
32     const void *                        instance,
33     globus_soap_message_handle_t        message_handle,
34     globus_xsd_element_options_t        options)
35 518839 {
36 518839     globus_result_t                     result = GLOBUS_SUCCESS;
37 518839     GlobusFuncName(globus_xsd_generic_serialize);
38 518839     GlobusSoapMessageDebugEnter();
39
40 518839     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
41     {
42         /* add begin element */
43 496126         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
44            !message_handle->c14n_subset)
45         {
46 493753             result = globus_soap_message_attribute_ns_set(
47                 message_handle,
48                 element_qname,
49                 "http://www.w3.org/2001/XMLSchema-instance",
50                 &options);
51 493753             if(result != GLOBUS_SUCCESS)
52             {
53 0                 result = GlobusSoapMessageErrorSerializeFailed(
54                     result, NULL, element_qname);
55 0                 goto exit;
56             }
57
58 493753             result = globus_soap_message_attribute_ns_set(
59                 message_handle,
60                 element_qname,
61                 type_info->type->Namespace,
62                 &options);
63 493753             if(result != GLOBUS_SUCCESS)
64             {
65 0                 result = GlobusSoapMessageErrorSerializeFailed(
66                     result, NULL, element_qname);
67 0                 goto exit;
68             }
69         }
70
71 496126         result = globus_soap_message_element_ns_set(
72             message_handle,
73             element_qname,
74             element_qname->Namespace,
75             &options);
76 496126         if(result != GLOBUS_SUCCESS)
77         {
78 0             result = GlobusSoapMessageErrorSerializeFailed(
79                 result, NULL, element_qname);
80 0             goto exit;
81         }
82 496126         result = globus_soap_message_serialize_element(
83             message_handle,
84             element_qname,
85             options,
86             type_info->type);
87 496126         if(result != GLOBUS_SUCCESS)
88         {
89 0             result = GlobusSoapMessageErrorSerializeFailed(
90                 result, NULL, element_qname);
91 0             goto exit;
92         }
93
94         /* serialize namespaces */
95 496126         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
96            !message_handle->c14n_subset)
97         {
98 493753             result = globus_soap_message_attribute_ns_add(
99                 message_handle,
100                 element_qname,
101                 "http://www.w3.org/2001/XMLSchema-instance",
102                 &options);
103 493753             if(result != GLOBUS_SUCCESS)
104             {
105 0                 result = GlobusSoapMessageErrorSerializeFailed(
106                     result, NULL, element_qname);
107 0                 goto exit;
108             }
109
110 493753             result = globus_soap_message_attribute_ns_add(
111                 message_handle,
112                 element_qname,
113                 type_info->type->Namespace,
114                 &options);
115 493753             if(result != GLOBUS_SUCCESS)
116             {
117 0                 result = GlobusSoapMessageErrorSerializeFailed(
118                     result, NULL, element_qname);
119 0                 goto exit;
120             }
121         }
122
123 496126         result = globus_soap_message_element_ns_add(
124             message_handle,
125             element_qname,
126             element_qname->Namespace,
127             &options);
128 496126         if(result != GLOBUS_SUCCESS)
129         {
130 0             result = GlobusSoapMessageErrorSerializeFailed(
131                 result, NULL, element_qname);
132 0             goto exit;
133         }
134
135 496126         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
136            !message_handle->c14n_subset)
137         {
138 493753             xsd_QName                   type_attr;
139 493753             type_attr.local = "type";
140 493753             type_attr.Namespace =
141                     "http://www.w3.org/2001/XMLSchema-instance";
142 493753             result = globus_soap_message_serialize_QName_attribute(
143                 message_handle,
144                 &type_attr,
145                 type_info->type);
146 493753             if(result != GLOBUS_SUCCESS)
147             {
148 0                 result = GlobusSoapMessageErrorSerializeFailed(
149                     result, NULL, element_qname);
150 0                 goto exit;
151             }
152         }
153
154         /* serialize attributes */
155 496126         result = globus_soap_message_serialize_element_begin_close(
156             message_handle, element_qname);
157 496126         if(result != GLOBUS_SUCCESS)
158         {
159 0             result = GlobusSoapMessageErrorSerializeFailed(
160                 result, NULL, element_qname);
161 0             goto exit;
162         }
163     }
164
165     /* serialize contents of type */
166 518839     result = type_info->contents_info->serialize(
167         NULL, instance, message_handle, 0);
168 518839     if(result != GLOBUS_SUCCESS)
169     {
170 0         result = GlobusSoapMessageErrorSerializeFailed(
171             result, NULL, element_qname);
172 0         goto exit;
173     }
174
175 518839     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
176     {
177         /* add end element */
178 496126         result = globus_soap_message_serialize_element_end(
179             message_handle,
180             element_qname,
181             options,
182             type_info->type);
183 496126         if(result != GLOBUS_SUCCESS)
184         {
185 0             result = GlobusSoapMessageErrorSerializeFailed(
186                 result, NULL, element_qname);
187 0             goto exit;
188         }
189
190 496126         globus_soap_message_element_ns_remove(
191             message_handle,
192             element_qname->Namespace,
193             &options);
194
195 496126         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
196            !message_handle->c14n_subset)
197         {
198 493753             globus_soap_message_attribute_ns_remove(
199                 message_handle,
200                 "http://www.w3.org/2001/XMLSchema-instance",
201                 &options);
202
203 493753             globus_soap_message_attribute_ns_remove(
204                 message_handle,
205                 type_info->type->Namespace,
206                 &options);
207         }
208     }
209
210  exit:
211
212 518839     GlobusSoapMessageDebugExit();
213 518839     return result;
214 }
215 /* globus_xsd_generic_serialize() */
216
217
218 globus_result_t
219 globus_xsd_generic_deserialize(
220     const xsd_QName *                   element_qname,
221     const globus_xsd_type_info_t        type_info,
222     void **                             instance,
223     globus_soap_message_handle_t        message_handle,
224     globus_xsd_element_options_t        options)
225 26242 {
226 26242     globus_result_t                     result = GLOBUS_SUCCESS;
227 26242     GlobusFuncName(globus_xsd_generic_deserialize);
228 26242     GlobusSoapMessageDebugEnter();
229
230 26242     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
231     {
232 2848         result = globus_soap_message_deserialize_element(
233             message_handle, element_qname);
234 2848         if(result != GLOBUS_SUCCESS)
235         {
236 0             goto error_exit;
237         }
238
239 2848         result = globus_soap_message_deserialize_element_begin_close(
240             message_handle);
241 2848         if(result != GLOBUS_SUCCESS)
242         {
243 0             goto error_exit;
244         }
245     }
246
247 26242     result = type_info->contents_info->deserialize(
248         NULL,
249         instance,
250         message_handle,
251         0);
252 26242     if(result != GLOBUS_SUCCESS)
253     {
254 0         goto error_exit;
255     }
256
257 26242     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
258     {
259 2848         result =
260         globus_soap_message_deserialize_element_end(
261             message_handle,
262             element_qname);
263 2848         if(result != GLOBUS_SUCCESS)
264         {
265 0             goto error_exit;
266         }
267     }
268
269 0     goto exit;
270
271  error_exit:
272
273 0     if(!GlobusSoapMessageStatusCheck(result))
274     {
275 0         result = GlobusSoapMessageErrorDeserializeFailed(
276           result, element_qname);
277     }
278  exit:
279
280 26242     GlobusSoapMessageDebugExit();
281 26242     return result;
282 }
283 /* globus_xsd_generic_deserialize() */
284
285 globus_result_t
286 globus_xsd_generic_init(
287     const globus_xsd_type_info_t        type_info,
288     void **                             object)
289 2766146 {
290 2766146     globus_result_t                     result = GLOBUS_SUCCESS;
291 2766146     GlobusFuncName(globus_xsd_generic_init);
292 2766146     void *                              instance;
293
294 2766146     GlobusSoapMessageDebugEnter();
295
296 2766146     instance = calloc(1, type_info->type_size);
297 2766146     if (instance == NULL)
298     {
299 0         GlobusSoapMessageDebugExit();
300 0         return GlobusSoapMessageErrorOutOfMemory;
301     }
302
303 2766146     *object = instance;
304 2766146     GlobusSoapMessageDebugExit();
305 2766146     return result;
306 }
307 /* globus_xsd_generic_init() */
308
309
310 void
311 globus_xsd_generic_destroy(
312     const globus_xsd_type_info_t        type_info,
313     void *                              object)
314 5534950 {
315 5534950     GlobusFuncName(globus_xsd_generic_destroy);
316 5534950     GlobusSoapMessageDebugEnter();
317
318 5534950     if(!object)
319     {
320 344         goto exit;
321     }
322
323 5534606     type_info->destroy_contents(object);
324
325 5534606     free(object);
326  exit:
327 5534950     GlobusSoapMessageDebugExit();
328 }
329 /* globus_xsd_generic_destroy() */
330
331 globus_result_t
332 globus_xsd_generic_copy(
333     const globus_xsd_type_info_t        type_info,
334     void **                             dest_obj,
335     const void *                        src_obj)
336 2773359 {
337 2773359     globus_result_t                     result = GLOBUS_SUCCESS;
338 2773359     GlobusFuncName(globus_xsd_generic_copy);
339 2773359     void *                              instance;
340 2773359     GlobusSoapMessageDebugEnter();
341
342 2773359     if(!src_obj)
343     {
344 0         instance = NULL;
345 0         goto exit;
346     }
347
348 2773359     instance = malloc(type_info->type_size);
349 2773359     if (instance == NULL)
350     {
351 0         GlobusSoapMessageDebugExit();
352 0         return GlobusSoapMessageErrorOutOfMemory;
353     }
354
355 2773359     result = type_info->copy_contents(instance, src_obj);
356 2773359     if(result != GLOBUS_SUCCESS)
357     {
358 0         free(instance);
359 0         GlobusSoapMessageDebugExit();
360 0         return GlobusSoapMessageErrorOutOfMemory;
361     }
362
363 exit:
364 2773359     *dest_obj = instance;
365 2773359     GlobusSoapMessageDebugExit();
366 2773359     return result;
367 }
368 /* globus_xsd_generic_copy() */
369
370 globus_result_t
371 globus_xsd_generic_deserialize_pointer(
372     const xsd_QName *                   element_qname,
373     const globus_xsd_type_info_t        type_info,
374     void **                             ip,
375     globus_soap_message_handle_t        message_handle,
376     globus_xsd_element_options_t        options)
377 1234112 {
378 1234112     globus_result_t                     result = GLOBUS_SUCCESS;
379 1234112     GlobusFuncName(globus_xsd_generic_deserialize_pointer);
380 1234112     GlobusSoapMessageDebugEnter();
381
382 1234112     *ip = NULL;
383
384 1234112     if (!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
385     {
386 1234112         result = globus_soap_message_deserialize_element(
387             message_handle, element_qname);
388
389 1234112         if(GlobusSoapMessageStatusElementNotFoundCheck(result) ||
390            GlobusSoapMessageStatusFailedElementCheck(result) ||
391            GlobusSoapMessageStatusFailedWithTextCheck(result))
392         {
393 27             result = GLOBUS_SUCCESS;
394 27             goto exit;
395         }
396
397 1234085         if(result != GLOBUS_SUCCESS)
398         {
399 0             goto error_exit;
400         }
401     }
402
403 1234085     if (!globus_soap_message_deserialize_element_is_nil(message_handle))
404     {
405 1234085         result = type_info->initialize(ip);
406
407 1234085         if(result != GLOBUS_SUCCESS)
408         {
409 0             goto error_exit;
410         }
411
412 1234085         result = type_info->contents_info->deserialize(
413             NULL, ip, message_handle, 0);
414 1234085         if(result != GLOBUS_SUCCESS)
415         {
416 0             goto error_exit;
417         }
418     }
419
420 1234085     if (!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
421     {
422 1234085         result = globus_soap_message_deserialize_element_end(
423             message_handle,
424             element_qname);
425 1234085         if(result != GLOBUS_SUCCESS)
426         {
427 0             goto error_exit;
428         }
429
430     }
431 0     goto exit;
432
433  error_exit:
434
435 0     if(!GlobusSoapMessageStatusCheck(result))
436     {
437 0         result = GlobusSoapMessageErrorDeserializeFailed(
438             result, element_qname);
439     }
440
441  exit:
442
443 1234112     if(result != GLOBUS_SUCCESS && *ip)
444     {
445 0         type_info->destroy(*ip);
446 0         *ip = NULL;
447     }
448
449 1234112     GlobusSoapMessageDebugExit();
450 1234112     return result;
451 }