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 "globus_soap_message.h"
14 #include "globus_i_soap_message.h"
15 #include "xsd_anyAttributes.h"
16
17 typedef struct
18 {
19 xsd_QName qname;
20 char * value;
21 } xsd_l_anyAttributes_element_t;
22
23 int
24 xsd_anyAttributes_size(
25 xsd_anyAttributes_t attrs)
26 11 {
27 11 return globus_hashtable_size(&attrs);
28 }
29
30 const char *
31 xsd_anyAttributes_lookup(
32 xsd_anyAttributes_t attrs,
33 xsd_QName * name)
34 0 {
35 xsd_l_anyAttributes_element_t * element;
36
37 0 element = (xsd_l_anyAttributes_element_t *)
38 globus_hashtable_lookup(&attrs, name);
39 0 if(!element)
40 {
41 0 return NULL;
42 }
43
44 0 return element->value;
45 }
46
47 int
48 xsd_anyAttributes_insert(
49 xsd_anyAttributes_t attrs,
50 xsd_QName * name,
51 const char * value)
52 0 {
53 xsd_l_anyAttributes_element_t * element;
54
55 0 element = (xsd_l_anyAttributes_element_t *)
56 globus_malloc(sizeof(xsd_l_anyAttributes_element_t));
57 0 xsd_QName_copy_contents(&element->qname, name);
58 0 element->value = globus_libc_strdup(value);
59
60 0 return globus_hashtable_insert(&attrs, &element->qname, element);
61 }
62
63 static
64 void
65 xsd_anyAttributes_element_delete(
66 void * value)
67 6633 {
68 xsd_l_anyAttributes_element_t * element;
69
70 6633 element = (xsd_l_anyAttributes_element_t *) value;
71
72 6633 if(element)
73 {
74 6633 xsd_QName_destroy_contents(&element->qname);
75 6633 if(element->value)
76 {
77 6633 globus_free(element->value);
78 }
79 6633 globus_free(element);
80 }
81 }
82
83 int
84 xsd_anyAttributes_remove(
85 xsd_anyAttributes_t attrs,
86 xsd_QName * name)
87 0 {
88 void * element;
89
90 0 element = globus_hashtable_remove(&attrs, name);
91 0 if(!element)
92 {
93 0 return GLOBUS_FAILURE;
94 }
95
96 0 xsd_anyAttributes_element_delete(element);
97 0 return GLOBUS_SUCCESS;
98 }
99
100 void
101 xsd_anyAttributes_destroy(
102 xsd_anyAttributes_t attrs)
103 49715 {
104 49715 if(attrs)
105 {
106 38969 globus_hashtable_destroy_all(&attrs, xsd_anyAttributes_element_delete);
107 }
108 }
109
110 globus_result_t
111 xsd_anyAttributes_init(
112 xsd_anyAttributes_t * attrs)
113 24937 {
114 24937 return globus_hashtable_init(attrs, 10, xsd_QName_hash, xsd_QName_keyeq);
115 }
116
117 static
118 int
119 xsd_QName_compare(
120 void * a,
121 void * b,
122 void * args)
123 0 {
124 int res;
125 xsd_QName * qa;
126 xsd_QName * qb;
127
128
129 0 if(!a)
130 {
131 0 return 1;
132 }
133
134 0 if(!b)
135 {
136 0 return 0;
137 }
138
139 0 qa = (xsd_QName *)a;
140 0 qb = (xsd_QName *)b;
141
142 0 if(!qa->Namespace && !qb->Namespace)
143 {
144 0 globus_assert_string(qa->local && qb->local,
145 "QName structs must have valid local values");
146
147 0 if(strcmp(qa->local, qb->local) <= 0)
148 {
149 0 return 1;
150 }
151
152 0 return 0;
153 }
154
155 0 if(qa->Namespace && qb->Namespace)
156 {
157 0 res = strcmp(qa->Namespace, qb->Namespace);
158 0 if(res == 0)
159 {
160 0 if(strcmp(qa->local, qb->local) <= 0)
161 {
162 0 return 1;
163 }
164
165 0 return 0;
166 }
167
168 0 if(res < 0)
169 {
170 0 return 1;
171 }
172
173 0 return 0;
174 }
175
176 0 if((!qa->Namespace) && qb->Namespace)
177 {
178 0 return 1;
179 }
180
181 0 if((!qb->Namespace) && qa->Namespace)
182 {
183 0 return 0;
184 }
185
186 0 return 1;
187 }
188
189 globus_list_t *
190 xsd_anyAttributes_lex_sort(
191 xsd_anyAttributes_t attrs)
192 0 {
193 xsd_l_anyAttributes_element_t * element;
194 0 globus_list_t * keys = NULL;
195
196 0 element = (xsd_l_anyAttributes_element_t *) globus_hashtable_first(&attrs);
197 0 while(element)
198 {
199 0 globus_list_insert(&keys, &element->qname);
200 0 element = (xsd_l_anyAttributes_element_t *)
201 globus_hashtable_next(&attrs);
202 }
203
204 0 keys = globus_list_sort(keys, xsd_QName_compare, NULL);
205
206 0 return keys;
207 }
208
209 globus_result_t
210 xsd_anyAttributes_namespace_set(
211 globus_soap_message_handle_t message,
212 xsd_anyAttributes_t attrs,
213 globus_xsd_element_options_t * options)
214 23908 {
215 23908 globus_result_t result = GLOBUS_SUCCESS;
216 xsd_l_anyAttributes_element_t * element;
217 23908 if(attrs)
218 {
219 0 element = globus_hashtable_first(&attrs);
220 0 while(element)
221 {
222 0 result = globus_soap_message_attribute_ns_set(
223 message,
224 element->qname.Namespace,
225 options);
226 0 if(result != GLOBUS_SUCCESS)
227 {
228 0 xsd_QName * eqn = &element->qname;
229 0 result = GlobusSoapMessageErrorSerializeFailed(
230 result, NULL, eqn);
231 0 goto exit;
232 }
233
234 0 element = globus_hashtable_next(&attrs);
235 }
236 }
237
238 23908 exit:
239
240 23908 return result;
241 }
242 globus_result_t
243 xsd_anyAttributes_namespace_add(
244 globus_soap_message_handle_t message,
245 xsd_anyAttributes_t attrs,
246 globus_xsd_element_options_t * options)
247 23908 {
248 23908 globus_result_t result = GLOBUS_SUCCESS;
249 xsd_l_anyAttributes_element_t * element;
250 23908 if(attrs)
251 {
252 0 element = globus_hashtable_first(&attrs);
253 0 while(element)
254 {
255 0 result = globus_soap_message_attribute_ns_add(
256 message,
257 element->qname.Namespace,
258 options);
259 0 if(result != GLOBUS_SUCCESS)
260 {
261 0 xsd_QName * eqn = &element->qname;
262 0 result = GlobusSoapMessageErrorSerializeFailed(
263 result, NULL, eqn);
264 0 goto exit;
265 }
266
267 0 element = globus_hashtable_next(&attrs);
268 }
269 }
270
271 23908 exit:
272
273 23908 return result;
274 }
275
276 globus_result_t
277 xsd_anyAttributes_namespace_remove(
278 globus_soap_message_handle_t message,
279 xsd_anyAttributes_t attrs,
280 globus_xsd_element_options_t * options)
281 23908 {
282 23908 globus_result_t result = GLOBUS_SUCCESS;
283 xsd_l_anyAttributes_element_t * element;
284 23908 if(attrs)
285 {
286 0 element = globus_hashtable_first(&attrs);
287 0 while(element)
288 {
289 0 globus_soap_message_attribute_ns_remove(
290 message,
291 element->qname.Namespace,
292 options);
293 0 if(result != GLOBUS_SUCCESS)
294 {
295 0 xsd_QName * eqn = &element->qname;
296 0 result = GlobusSoapMessageErrorSerializeFailed(
297 result, NULL, eqn);
298 0 goto exit;
299 }
300
301 0 element = globus_hashtable_next(&attrs);
302 }
303 }
304
305 23908 exit:
306
307 23908 return result;
308 }
309
310 globus_result_t
311 xsd_anyAttributes_serialize(
312 globus_soap_message_handle_t message,
313 xsd_anyAttributes_t attrs)
314 0 {
315 globus_list_t * lex_sorted_keys;
316 0 globus_result_t result = GLOBUS_SUCCESS;
317 xsd_l_anyAttributes_element_t * element;
318 xsd_QName * key;
319
320 0 lex_sorted_keys = xsd_anyAttributes_lex_sort(attrs);
321
322 0 key = globus_list_first(lex_sorted_keys);
323 0 while(key)
324 {
325 0 lex_sorted_keys = globus_list_rest(lex_sorted_keys);
326 0 element = (xsd_l_anyAttributes_element_t *)
327 globus_hashtable_lookup(&attrs, key);
328 0 if(!element)
329 {
330 0 result = GlobusSoapMessageErrorSerializeAnyAttrsFailed(
331 result, "Null element in attributes list");
332 0 goto exit;
333 }
334
335 0 result = xsd_string_serialize_attribute(
336 &element->qname, &element->value, message, 0);
337 0 if(result != GLOBUS_SUCCESS)
338 {
339 0 result = GlobusSoapMessageErrorSerializeAnyAttrsFailed(
340 result, "Failed to serialize any attribute");
341 0 goto exit;
342 }
343
344 0 key = globus_list_first(lex_sorted_keys);
345 }
346
347 0 exit:
348
349 0 return result;
350 }
351
352 globus_result_t
353 xsd_anyAttributes_serialize_lex_before(
354 globus_soap_message_handle_t message,
355 globus_list_t ** lex_sorted_keys,
356 xsd_anyAttributes_t attrs,
357 xsd_QName * comparable_value)
358 0 {
359 0 globus_result_t result = GLOBUS_SUCCESS;
360 xsd_l_anyAttributes_element_t * element;
361 xsd_QName * key;
362
363 0 while(*lex_sorted_keys)
364 {
365 0 key = globus_list_first(*lex_sorted_keys);
366
367 0 if(!xsd_QName_compare(comparable_value, key, NULL))
368 {
369 0 break;
370 }
371
372 0 element = (xsd_l_anyAttributes_element_t *)
373 globus_hashtable_lookup(&attrs, key);
374 0 if(!element)
375 {
376 0 result = GlobusSoapMessageErrorSerializeAnyAttrsFailed(
377 result, "Null element in attributes list");
378 0 goto exit;
379 }
380
381 0 result = xsd_string_serialize_attribute(
382 &element->qname, &element->value, message, 0);
383 0 if(result != GLOBUS_SUCCESS)
384 {
385 0 result = GlobusSoapMessageErrorSerializeAnyAttrsFailed(
386 result, "Failed to serialize any attribute");
387 0 goto exit;
388 }
389
390 0 *lex_sorted_keys = globus_list_rest(*lex_sorted_keys);
391 }
392
393 0 exit:
394
395 0 return result;
396 }
397
398 static
399 void
400 xsd_anyAttributes_QName_copy_callback(
401 void ** dest_key,
402 void ** dest_datum,
403 void * src_key,
404 void * src_datum)
405 942 {
406 xsd_l_anyAttributes_element_t * dest_element;
407 xsd_l_anyAttributes_element_t * src_element;
408
409 942 src_element = (xsd_l_anyAttributes_element_t *) src_datum;
410
411 942 dest_element = (xsd_l_anyAttributes_element_t *)
412 globus_malloc(sizeof(xsd_l_anyAttributes_element_t));
413
414 942 xsd_QName_copy_contents(&dest_element->qname, (const xsd_QName *) src_key);
415 942 dest_element->value = globus_libc_strdup(src_element->value);
416
417 942 *dest_datum = dest_element;
418 942 *dest_key = &dest_element->qname;
419 }
420
421 globus_result_t
422 xsd_anyAttributes_copy(
423 xsd_anyAttributes_t * dest_attrs,
424 xsd_anyAttributes_t src_attrs)
425 14032 {
426 14032 globus_result_t result = GLOBUS_SUCCESS;
427
428 14032 result = globus_hashtable_copy(dest_attrs, &src_attrs,
429 xsd_anyAttributes_QName_copy_callback);
430
431 14032 return result;
432 }
433
434 globus_result_t
435 xsd_anyAttributes_deserialize(
436 globus_soap_message_handle_t message,
437 xsd_anyAttributes_t attrs)
438 24937 {
439 24937 globus_result_t result = GLOBUS_SUCCESS;
440 24937 int res = 0;
441
442 24937 res = xmlTextReaderMoveToFirstAttribute(message->reader);
443 24937 if(res < 0)
444 {
445 0 result = GlobusSoapMessageErrorDeserializeAnyAttrsFailed(
446 message->result, NULL);
447
448 0 goto exit;
449 }
450
451 48561 while(res)
452 {
453 xmlNodePtr attrNode;
454 xsd_l_anyAttributes_element_t * element;
455
456 23624 attrNode = xmlTextReaderCurrentNode(message->reader);
457 23624 if(attrNode->type == XML_ATTRIBUTE_NODE)
458 {
459 5691 element = (xsd_l_anyAttributes_element_t *)
460 globus_malloc(sizeof(xsd_l_anyAttributes_element_t));
461 5691 element->qname.local = xmlTextReaderLocalName(message->reader);
462 5691 element->qname.Namespace =
463 xmlTextReaderNamespaceUri(message->reader);
464 5691 element->value = xmlTextReaderValue(message->reader);
465
466 5691 globus_hashtable_insert(&attrs, &element->qname, element);
467 }
468
469 23624 res = xmlTextReaderMoveToNextAttribute(message->reader);
470 23624 if(res == -1)
471 {
472 0 result = GlobusSoapMessageErrorDeserializeAnyAttrsFailed(
473 message->result, NULL);
474 0 goto exit;
475 }
476 }
477
478 24937 res = xmlTextReaderMoveToElement(message->reader);
479 24937 if(res < 0)
480 {
481 0 result = GlobusSoapMessageErrorDeserializeAnyAttrsFailed(
482 message->result, NULL);
483
484 goto exit;
485 }
486
487 24937 exit:
488
489 24937 return result;