1 /*
2  * Portions of this file Copyright 1999-2005 University of Chicago
3  * Portions of this file Copyright 1999-2005 The University of Southern California.
4  *
5  * This file or a portion of this file is licensed under the
6  * terms of the Globus Toolkit Public License, found at
7  * http://www.globus.org/toolkit/download/license.html.
8  * If you redistribute this file, with or without
9  * modifications, you must include this notice in the file.
10  */
11
12
13 #include "xsd_QName.h"
14 #include "globus_soap_message.h"
15 #include "globus_i_xsd.h"
16
17 GLOBUS_I_XSD_DEFINE_QNAME(xsd, QName);
18
19 GLOBUS_I_XSD_DEFINE_TYPE_INFO(xsd_QName);
20
21 1301944 GLOBUS_I_XSD_DEFINE_TYPE_INIT(xsd_QName);
22 1772513 GLOBUS_I_XSD_DEFINE_TYPE_DESTROY(xsd_QName);
23 2241027 GLOBUS_I_XSD_DEFINE_TYPE_COPY(xsd_QName);
24 495406 GLOBUS_I_XSD_DEFINE_TYPE_DESERIALIZE(xsd_QName);
25 0 GLOBUS_I_XSD_DEFINE_TYPE_DESERIALIZE_POINTER(xsd_QName);
26 0 GLOBUS_I_XSD_DEFINE_TYPE_INIT_ARRAY(xsd_QName);
27 11740 GLOBUS_I_XSD_DEFINE_TYPE_DESTROY_ARRAY(xsd_QName);
28 4015 GLOBUS_I_XSD_DEFINE_TYPE_COPY_ARRAY(xsd_QName);
29 2230 GLOBUS_I_XSD_DEFINE_TYPE_SERIALIZE_ARRAY(xsd_QName);
30 1793 GLOBUS_I_XSD_DEFINE_TYPE_DESERIALIZE_ARRAY(xsd_QName);
31 509991 GLOBUS_I_XSD_DEFINE_TYPE_ARRAY_PUSH(xsd_QName)
32
33 2703 GLOBUS_I_XSD_DEFINE_ATTR_FUNCTIONS(xsd_QName, QName);
34 934 GLOBUS_I_XSD_DEFINE_INIT_CONTENTS_GENERIC(xsd_QName);
35 0 GLOBUS_I_XSD_DEFINE_LIST_FUNCTIONS(xsd_QName, QName);
36 0 GLOBUS_I_XSD_DEFINE_LIST_ATTR_FUNCTIONS(xsd_QName, QName);
37
38 globus_result_t
39 xsd_QName_copy_contents(
40     xsd_QName *                         dest,
41     const xsd_QName *                   src)
42 {
43 2230336     globus_result_t                     result = GLOBUS_SUCCESS;
44 2230336     GlobusFuncName(xsd_QName_copy_contents);
45 2230336     GlobusSoapMessageDebugEnter();
46     
47 2230336     if(dest && src)
48     {
49 2230336         if(src->Namespace)
50         {
51 2230320             dest->Namespace = globus_libc_strdup(src->Namespace);
52 2230320             if(!dest->Namespace)
53             {
54 0                 result = GlobusSoapMessageErrorOutOfMemory;
55 0                 goto error;
56             }
57         }
58         else
59         {
60 16             dest->Namespace = NULL;
61         }
62         
63 2230336         if(src->local)
64         {
65 2230336             dest->local = globus_libc_strdup(src->local);
66 2230336             if(!dest->local)
67             {
68 0                 result = GlobusSoapMessageErrorOutOfMemory;
69 0                 if(dest->Namespace)
70                 {
71 0                     globus_free(dest->Namespace);
72                 }
73 0                 goto error;
74             }
75         }
76         else
77         {
78 0             dest->local = NULL;
79         }
80     }
81
82 error:
83 2230336     GlobusSoapMessageDebugExit();
84 2230336     return result;
85 }
86
87 void
88 xsd_QName_destroy_contents(
89     xsd_QName *                         instance)
90 3395839 {
91 3395839     GlobusFuncName(xsd_QName_destroy_contents);
92 3395839     GlobusSoapMessageDebugEnter();
93
94 3395839     if(instance)
95     {
96 3395839         if(instance->Namespace)
97         {
98 3387227             free(instance->Namespace);
99 3387227             instance->Namespace = NULL;
100         }
101
102 3395839         if(instance->local)
103         {
104 3387734             free(instance->local);
105 3387734             instance->local = NULL;
106         }
107     }
108
109 3395839     GlobusSoapMessageDebugExit();
110 }
111
112 globus_result_t
113 xsd_QName_serialize(
114     xsd_QName *                         element_qname,
115     xsd_QName *                         instance,
116     globus_soap_message_handle_t        message_handle,
117     globus_xsd_element_options_t        options)
118 616788 {
119 616788     globus_result_t                     result = GLOBUS_SUCCESS;
120 616788     GlobusFuncName(xsd_QName_serialize);
121 616788     GlobusSoapMessageDebugEnter();
122
123 616788     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
124     {
125         /* add begin element */
126 616785         result = globus_soap_message_invoke_ns_callouts(
127                 message_handle,
128                 element_qname,
129                 GLOBUS_SOAP_MESSAGE_CALLOUT_NS_SET,
130                 &options);
131 616785         if(result != GLOBUS_SUCCESS)
132         {
133 0             result = GlobusSoapMessageErrorSerializeFailed(
134                 result, NULL, element_qname);
135 0             goto exit;
136         }
137
138 616785         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
139    !message_handle->c14n_subset)
140         {
141 0             result = globus_soap_message_attribute_ns_set(
142                 message_handle,
143                 "http://www.w3.org/2001/XMLSchema-instance",
144                 &options);
145 0             if(result != GLOBUS_SUCCESS)
146             {
147 0                 result = GlobusSoapMessageErrorSerializeFailed(
148                     result, NULL, element_qname);
149 0                 goto exit;
150             }
151
152 0             result = globus_soap_message_attribute_ns_set(
153                 message_handle,
154                 xsd_QName_qname.Namespace,
155                 &options);
156 0             if(result != GLOBUS_SUCCESS)
157             {
158 0                 result = GlobusSoapMessageErrorSerializeFailed(
159                     result, NULL, element_qname);
160 0                 goto exit;
161             }
162         }
163
164 616785 result = globus_soap_message_element_ns_set(
165     message_handle,
166     element_qname->Namespace,
167     &options);
168 616785 if(result != GLOBUS_SUCCESS)
169 {
170 0     result = GlobusSoapMessageErrorSerializeFailed(
171 result, NULL, element_qname);
172 0     goto exit;
173 }
174     }
175
176 616788     result = globus_soap_message_attribute_ns_set(
177 message_handle,
178 instance->Namespace,
179 &options);
180 616788     if(result != GLOBUS_SUCCESS)
181     {
182 0 result = GlobusSoapMessageErrorSerializeFailed(
183     result, NULL, element_qname);
184 0 goto exit;
185     }
186
187 616788     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
188     {
189 616785         result = globus_soap_message_invoke_callouts(
190                 message_handle,
191                 element_qname,
192                 GLOBUS_SOAP_MESSAGE_CALLOUT_BEGIN);
193 616785         if(result != GLOBUS_SUCCESS)
194         {
195 0             result = GlobusSoapMessageErrorSerializeFailed(
196                 result, NULL, element_qname);
197 0             goto exit;
198         }
199
200 616785         result = globus_soap_message_serialize_element(
201             message_handle,
202             element_qname,
203             options,
204             &xsd_QName_qname);
205 616785         if(result != GLOBUS_SUCCESS)
206         {
207 0             result = GlobusSoapMessageErrorSerializeFailed(
208                 result, NULL, element_qname);
209 0             goto exit;
210         }
211
212 616785         result = globus_soap_message_invoke_ns_callouts(
213                 message_handle,
214                 element_qname,
215                 GLOBUS_SOAP_MESSAGE_CALLOUT_NS_ADD,
216                 &options);
217 616785         if(result != GLOBUS_SUCCESS)
218         {
219 0             result = GlobusSoapMessageErrorSerializeFailed(
220                 result, NULL, element_qname);
221 0             goto exit;
222         }
223 616785         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
224    !message_handle->c14n_subset)
225         {
226 0             result = globus_soap_message_attribute_ns_add(
227                 message_handle,
228                 "http://www.w3.org/2001/XMLSchema-instance",
229                 &options);
230 0             if(result != GLOBUS_SUCCESS)
231             {
232 0                 result = GlobusSoapMessageErrorSerializeFailed(
233                     result, NULL, element_qname);
234 0                 goto exit;
235             }
236         }
237
238 616785         result = globus_soap_message_element_ns_add(
239             message_handle,
240             element_qname->Namespace,
241             &options);
242 616785         if(result != GLOBUS_SUCCESS)
243         {
244 0             result = GlobusSoapMessageErrorSerializeFailed(
245                 result, NULL, element_qname);
246 0             goto exit;
247         }
248     }
249     
250 616788     result = globus_soap_message_attribute_ns_add(
251 message_handle,
252 instance->Namespace,
253 &options);
254 616788     if(result != GLOBUS_SUCCESS)
255     {
256 0 result = GlobusSoapMessageErrorSerializeFailed(
257     result, NULL, instance);
258 0 goto exit;
259     }
260
261 616788     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
262     {
263 616785         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
264    !message_handle->c14n_subset)
265         {
266 0             xsd_QName                   type_attr;
267 0             type_attr.local = "type";
268 0             type_attr.Namespace =
269             "http://www.w3.org/2001/XMLSchema-instance";
270
271 0             result = globus_soap_message_attribute_ns_add(
272                 message_handle,
273                 type_attr.Namespace,
274                 &options);
275 0             if(result != GLOBUS_SUCCESS)
276             {
277 0                 result = GlobusSoapMessageErrorSerializeFailed(
278                     result, NULL, element_qname);
279 0                 goto exit;
280             }
281
282 0             result = globus_soap_message_attribute_ns_add(
283                 message_handle,
284                 xsd_QName_qname.Namespace,
285                 &options);
286 0             if(result != GLOBUS_SUCCESS)
287             {
288 0                 result = GlobusSoapMessageErrorSerializeFailed(
289                     result, NULL, element_qname);
290 0                 goto exit;
291             }
292
293 0             result = globus_soap_message_serialize_QName_attribute(
294                 message_handle,
295                 &type_attr,
296                 &xsd_QName_qname);
297 0             if(result != GLOBUS_SUCCESS)
298             {
299 0                 result = GlobusSoapMessageErrorSerializeFailed(
300                     result, NULL, element_qname);
301 0                 goto exit;
302             }
303         }
304 616785         result = globus_soap_message_invoke_callouts(
305             message_handle,
306             element_qname,
307             GLOBUS_SOAP_MESSAGE_CALLOUT_ATTR);
308 616785         if(result != GLOBUS_SUCCESS)
309         {
310 0             result = GlobusSoapMessageErrorSerializeFailed(
311                 result, NULL, element_qname);
312 0             goto exit;
313         }
314
315 616785         result = globus_soap_message_serialize_element_begin_close(
316             message_handle);
317 616785         if(result != GLOBUS_SUCCESS)
318         {
319 0             result = GlobusSoapMessageErrorSerializeFailed(
320                 result, NULL, element_qname);
321 0             goto exit;
322         }
323     }
324
325     /* serialize contents of type */
326 616788     result = globus_soap_message_serialize_QName(
327         message_handle, instance);
328 616788     if(result != GLOBUS_SUCCESS)
329     {
330 0         result = GlobusSoapMessageErrorSerializeFailed(
331             result, NULL, element_qname);
332 0         goto exit;
333     }
334
335 616788     if(!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
336     {
337         /* add end element */
338 616785         result = globus_soap_message_serialize_element_end(
339             message_handle,
340             element_qname,
341             options,
342             &xsd_QName_qname);
343 616785         if(result != GLOBUS_SUCCESS)
344         {
345 0             result = GlobusSoapMessageErrorSerializeFailed(
346                 result, NULL, element_qname);
347 0             goto exit;
348         }
349
350     }
351
352 616788     globus_soap_message_attribute_ns_remove(
353         message_handle, instance->Namespace, &options);
354
355 616788     if (!(options & GLOBUS_XSD_ELEMENT_CONTENTS_ONLY))
356     {
357 616785         globus_soap_message_element_ns_remove(
358             message_handle, element_qname->Namespace, &options);
359
360 616785         if(options & GLOBUS_XSD_ELEMENT_TYPE_ATTR &&
361    !message_handle->c14n_subset)
362         {
363 0             globus_soap_message_attribute_ns_remove(
364                 message_handle, 
365                 "http://www.w3.org/2001/XMLSchema-instance",
366                 &options);
367         
368 0             globus_soap_message_attribute_ns_remove(
369                 message_handle, xsd_QName_qname.Namespace, &options);
370         }
371 616785         result = globus_soap_message_invoke_ns_callouts(
372             message_handle,
373             element_qname,
374             GLOBUS_SOAP_MESSAGE_CALLOUT_NS_REMOVE,
375             &options);
376 616785         if(result != GLOBUS_SUCCESS)
377         {
378 0             result  = GlobusSoapMessageErrorSerializeFailed(
379                 result, NULL, element_qname);
380 0             goto exit;
381         }
382 616785         result = globus_soap_message_invoke_callouts(
383             message_handle,
384             element_qname,
385             GLOBUS_SOAP_MESSAGE_CALLOUT_END);
386 616785         if(result != GLOBUS_SUCCESS)
387         {
388 0             result  = GlobusSoapMessageErrorSerializeFailed(
389                 result, NULL, element_qname);
390             goto exit;
391         }
392     }
393
394  exit:
395
396 616788     GlobusSoapMessageDebugExit();
397 616788     return result;
398 }
399     
400 globus_result_t
401 xsd_QName_serialize_contents(
402     xsd_QName *                         element,
403     xsd_QName *                         instance,
404     globus_soap_message_handle_t        message_handle,
405     globus_xsd_element_options_t        options)
406 3 {
407 3     globus_result_t                     result = GLOBUS_SUCCESS;
408 3     GlobusFuncName(xsd_QName_serialize_contents);
409 3     GlobusSoapMessageDebugEnter();
410
411     /* serialize contents of type */
412 3     result = xsd_QName_serialize(
413         element, instance, message_handle,
414         (options | GLOBUS_XSD_ELEMENT_CONTENTS_ONLY));
415
416 3     GlobusSoapMessageDebugExit();
417 3     return result;
418 }
419
420 globus_result_t
421 xsd_QName_deserialize_contents(
422     xsd_QName *                         eqn,
423     xsd_QName *                         instance,
424     globus_soap_message_handle_t        message_handle,
425     globus_xsd_element_options_t        options)
426 493613 {
427 493613     globus_result_t                     result = GLOBUS_SUCCESS;
428 493613     GlobusFuncName(xsd_QName_deserialize_contents);
429 493613     GlobusSoapMessageDebugEnter();
430     
431 493613     result = globus_soap_message_deserialize_QName(
432         message_handle, instance);
433
434 493613     GlobusSoapMessageDebugExit();
435 493613     return result;
436 }
437
438 int
439 xsd_QName_strcmp(
440     char *                              s1,
441     char *                              s2)
442 2298785 {
443 2298785     GlobusFuncName(globus_l_xsd_safe_strcmp);
444 2298785     return (s1 == s2 || 
445         (s1 && s2 && strcmp(s1, s2) == 0));
446 }
447
448 int
449 xsd_QName_keyeq(
450     void *                              qname1,
451     void *                              qname2)
452 1174008 {
453 1174008     xsd_QName *                         q1 = qname1;
454 1174008     xsd_QName *                         q2 = qname2;
455 1174008     GlobusFuncName(xsd_QName_keyeq);
456
457 1174008     return (q1 == q2) || (q1 && q2 &&
458         xsd_QName_strcmp(q1->Namespace, q2->Namespace) &&
459             xsd_QName_strcmp(q1->local, q2->local));
460 }
461
462 int
463 xsd_QName_hash(
464     void *                              qname,
465     int                                 limit)
466 1235763 {
467 1235763     unsigned long                       h = 0;
468 1235763     unsigned long                       g;
469 1235763     char *                              key;
470 1235763     xsd_QName *                         q = qname;
471 1235763     GlobusFuncName(xsd_QName_hash);
472
473 1235763     key = q->Namespace;
474
475 1235763     if (key)
476     {
477 97971629         while (*key)
478         {
479 96736370             h = (h << 4) + *key++;
480
481 96736370             if ((g = (h & 0xF0000000UL)))
482             {
483 83441443                 h ^= g >> 24;
484 83441443                 h ^= g;
485             }
486         }
487     }
488 1235763     key = q->local;
489 1235763     if (key)
490     {
491 19782945         while (*key)
492         {
493 18547183             h = (h << 4) + *key++;
494
495 18547183             if ((g = (h & 0xF0000000UL)))
496             {
497 18441072                 h ^= g >> 24;
498 18441072                 h ^= g;
499             }
500         }
501     }
502
503 1235763     return h % limit;
504 }
505
506 globus_result_t
507 xsd_QName_serialize_wrapper(
508     xsd_QName *                         element_qname,
509     void *                              instance,
510     globus_soap_message_handle_t        message_handle,
511     globus_xsd_element_options_t        options)
512 0 {
513 0     return xsd_QName_serialize(
514         element_qname, (xsd_QName *) instance, message_handle, options);
515 }
516
517 globus_result_t
518 xsd_QName_serialize_contents_wrapper(
519     xsd_QName *                         element_qname,
520     void *                              instance,
521     globus_soap_message_handle_t        message_handle,
522     globus_xsd_element_options_t        options)
523 3 {
524 3     return xsd_QName_serialize_contents(
525         element_qname, (xsd_QName *) instance, message_handle, options);