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_attrs.h"
14 #include "globus_soap_message_utils.h"
15 #include "globus_i_soap_message.h"
16
17 typedef struct globus_l_message_attr_s
18 {
19     char *                                   name;
20     void *                                   value;
21     globus_soap_message_attr_copy_func_t     copy;
22     globus_soap_message_attr_destroy_func_t  destroy;
23 } globus_l_message_attr_t;
24
25 void
26 globus_l_message_attr_destroy(
27     void *                              attr)
28 74707 {
29 74707     globus_l_message_attr_t *           attribute;
30 74707     GlobusFuncName(globus_l_message_attr_destroy);
31 74707     GlobusSoapMessageDebugEnter();
32
33
34 74707     attribute = (globus_l_message_attr_t *) attr;
35
36 74707     if(attribute)
37     {
38 74707         if(attribute->name)
39         {
40 74707             free(attribute->name);
41         }
42         
43 74707         if(attribute->destroy)
44         {
45 38006             attribute->destroy(attribute->value);
46         }
47
48 74707         free(attribute);
49     }
50
51 74707     GlobusSoapMessageDebugExit();
52 }
53
54 globus_result_t
55 globus_soap_message_attr_init(
56     globus_soap_message_attr_t *        attrs)
57 11705 {
58 11705     globus_result_t                     result = GLOBUS_SUCCESS;
59 11705     GlobusFuncName(globus_soap_message_attr_init);
60 11705     GlobusSoapMessageDebugEnter();
61     
62 11705     result = globus_hashtable_init(attrs, 20,
63                                    globus_hashtable_string_hash,
64                                    globus_hashtable_string_keyeq);
65     
66 11705     GlobusSoapMessageDebugExit();
67 11705     return result;
68 }
69
70 globus_result_t
71 globus_soap_message_attr_copy(
72     globus_soap_message_attr_t *        copied_attrs,
73     globus_soap_message_attr_t          attrs)
74 3709 {
75 3709     globus_soap_message_attr_t          new_attrs;
76 3709     globus_l_message_attr_t *           attr;
77 3709     globus_result_t                     result = GLOBUS_SUCCESS;
78 3709     GlobusFuncName(globus_soap_message_attr_copy);
79 3709     GlobusSoapMessageDebugEnter();
80
81 3709     globus_soap_message_attr_init(&new_attrs);
82
83 3709     attr = globus_hashtable_first(&attrs);
84 15586     while(attr)
85     {
86         /* _set will copy the attr value */
87 11877         result = globus_soap_message_attr_set(
88             new_attrs,
89             attr->name,
90             attr->copy,
91             attr->destroy,
92             attr->value);
93 11877         if(result != GLOBUS_SUCCESS)
94         {
95 0             goto exit;
96         }
97
98 11877         attr = globus_hashtable_next(&attrs);
99     }
100
101 3709     *copied_attrs = new_attrs;
102
103  exit:
104 3709     GlobusSoapMessageDebugExit();
105 3709     return result;
106 }
107
108 void
109 globus_soap_message_attr_destroy(
110     globus_soap_message_attr_t                  attrs)
111 11683 {
112 11683     GlobusFuncName(globus_soap_message_attr_destroy);
113 11683     GlobusSoapMessageDebugEnter();
114
115 11683     globus_hashtable_destroy_all(
116         &attrs, globus_l_message_attr_destroy);
117
118 11683     GlobusSoapMessageDebugExit();
119 }
120
121 globus_result_t
122 globus_soap_message_attr_set(
123     globus_soap_message_attr_t               attrs,
124     const char *                             name,
125     globus_soap_message_attr_copy_func_t     copy,
126     globus_soap_message_attr_destroy_func_t  destroy,
127     void *                                   attrvalue)
128 89941 {
129 89941     void *                              newvalue = NULL;
130 89941     globus_result_t                     result = GLOBUS_SUCCESS;
131 89941     globus_l_message_attr_t *           attr;
132 89941     GlobusFuncName(globus_soap_message_attr_set);
133 89941     GlobusSoapMessageDebugEnter();
134
135 89941     globus_assert_string(attrs, "NULL attrs in handle");
136
137 89941     globus_assert_string(name, 
138                          "attr_name passed to function is NULL");
139     
140 89941     attr = globus_hashtable_lookup(&attrs, (char *)name);
141 89941     if(!attr)
142     {
143 74718         attr = globus_malloc(sizeof(globus_l_message_attr_t));
144 74718         if(!attr)
145         {
146 0             result = GlobusSoapMessageErrorOutOfMemory;
147 0             goto exit;
148         }
149 74718         memset(attr, 0, sizeof(globus_l_message_attr_t));
150
151 74718         attr->name = globus_libc_strdup(name);
152 74718         attr->destroy = destroy;
153 74718         attr->copy = copy;
154
155 74718         result = globus_hashtable_insert(&attrs, 
156                                          attr->name, attr);
157 74718         if(result != GLOBUS_SUCCESS)
158         {
159 0             goto exit;
160         }
161     }
162     else
163     {
164 15223         if(attr->destroy)
165         {
166 10143             attr->destroy(attr->value);
167         }
168
169 15223         attr->destroy = destroy;
170 15223         attr->copy = copy;
171     }
172
173 89941     if(copy)
174     {
175 48149         copy(&newvalue, attrvalue);
176     }
177     else
178     {
179 41792         newvalue = attrvalue;
180     }
181
182 89941     attr->value = newvalue;
183
184  exit:
185     
186 89941     GlobusSoapMessageDebugExit();
187 89941     return result;
188 }
189
190 globus_result_t
191 globus_soap_message_handle_set_attr(
192     globus_soap_message_handle_t             handle,
193     const char *                             attr_name,
194     globus_soap_message_attr_copy_func_t     copy,
195     globus_soap_message_attr_destroy_func_t  destroy,
196     void *                                   attrvalue)
197 67677 {
198 67677     globus_result_t                     result = GLOBUS_SUCCESS;
199 67677     GlobusFuncName(globus_soap_message_handle_set_attr);
200 67677     GlobusSoapMessageDebugEnter();
201
202 67677     globus_assert_string(handle, "NULL handle passed to function");
203 67677     globus_assert_string(handle->attrs, "NULL attrs in handle");
204 67677     globus_assert_string(attr_name, 
205                          "attr_name passed to function is NULL");
206
207 67677     result = globus_soap_message_attr_set(
208         handle->attrs,
209         attr_name,
210         copy,
211         destroy,
212         attrvalue);
213
214     /* Hack: make the verbose attribute part of the handle struct for
215      * performance as its queried during all serialization and deserialization
216      * errors.
217      */
218 67677     if (strcmp(attr_name, GLOBUS_SOAP_MESSAGE_VERBOSE_ERRORS_KEY) == 0)
219     {
220 0         handle->verbose = (globus_bool_t) attrvalue;
221     }
222     
223 67677     GlobusSoapMessageDebugExit();
224 67677     return result;
225 }
226
227 void *
228 globus_soap_message_attr_remove(
229     globus_soap_message_attr_t          attrs,
230     const char *                        attr_name)
231 0 {
232 0     void *                              value;
233 0     globus_l_message_attr_t *           attr;
234 0     GlobusFuncName(globus_soap_message_attr_remove);
235 0     GlobusSoapMessageDebugEnter();
236     
237 0     attr = globus_hashtable_remove(&attrs, (void *)attr_name);
238 0     if(!attr)
239     {
240 0         value = NULL;
241 0         goto exit;
242     }
243
244 0     value = attr->value;
245
246 0     globus_l_message_attr_destroy(attr);
247
248  exit:
249
250 0     GlobusSoapMessageDebugExit();
251 0     return value;
252 }
253
254 void *
255 globus_soap_message_handle_remove_attr(
256     globus_soap_message_handle_t        handle,
257     const char *                        attr_name)
258 0 {
259 0     globus_assert_string(handle, "NULL handle passed to function");
260 0     globus_assert_string(handle->attrs, "NULL attrs in handle");
261 0     globus_assert_string(attr_name, 
262                          "attr_name passed to function is NULL");
263
264 0     return globus_soap_message_attr_remove(
265         handle->attrs, attr_name);
266 }
267
268 void *
269 globus_soap_message_attr_get(
270     globus_soap_message_attr_t          attrs,
271     const char *                        attr_name)
272 147288 {
273 147288     void *                              value;
274 147288     globus_l_message_attr_t *           attr;
275 147288     GlobusFuncName(globus_soap_message_attr_get);
276 147288     GlobusSoapMessageDebugEnter();
277
278 147288     attr = globus_hashtable_lookup(&attrs, (char *)attr_name);
279 147288     if(!attr)
280     {
281 69277         value = NULL;
282 69277         goto exit;
283     }
284
285 78011     value = attr->value;
286
287  exit:
288     
289 147288     GlobusSoapMessageDebugExit();
290 147288     return value;
291 }
292     
293 void *
294 globus_soap_message_handle_get_attr(
295     globus_soap_message_handle_t        handle,
296     char *                              attr_name)
297 137981 {
298 137981     void *                              value;
299 137981     GlobusFuncName(globus_soap_message_handle_get_attr);
300 137981     GlobusSoapMessageDebugEnter();
301
302 137981     value = globus_soap_message_attr_get(
303         handle->attrs,
304         attr_name);
305
306 137981     GlobusSoapMessageDebugExit();
307 137981     return value;
308 }
309
310 globus_result_t
311 globus_soap_message_handle_set_attrs(
312     globus_soap_message_handle_t        handle,
313     globus_soap_message_attr_t          attrs)
314 3675 {
315 3675     GlobusFuncName(globus_soap_message_handle_set_attr);
316 3675     GlobusSoapMessageDebugEnter();
317
318 3675     if(handle->attrs)
319     {
320 3675         globus_soap_message_attr_destroy(handle->attrs);
321     }
322
323 3675     globus_soap_message_attr_copy(
324         &handle->attrs, attrs);
325
326     /* Hack: make the verbose attribute part of the handle struct for
327      * performance as its queried during all serialization and deserialization
328      * errors.
329      */
330 3675     handle->verbose = (globus_bool_t) globus_soap_message_attr_get(
331                 attrs,
332                 GLOBUS_SOAP_MESSAGE_VERBOSE_ERRORS_KEY);
333
334 3675     GlobusSoapMessageDebugExit();
335 3675     return GLOBUS_SUCCESS;
336 }
337
338 globus_result_t
339 globus_soap_message_attr_copy_string(
340     void **                             new_str,
341     void *                              str)
342 26292 {
343 26292     *new_str = (void *) globus_libc_strdup((char *)str);
344 26292     return GLOBUS_SUCCESS;