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 67080 {
29 67080     globus_l_message_attr_t *           attribute;
30 67080     GlobusFuncName(globus_l_message_attr_destroy);
31 67080     GlobusSoapMessageDebugEnter();
32
33
34 67080     attribute = (globus_l_message_attr_t *) attr;
35
36 67080     if(attribute)
37     {
38 67080         if(attribute->name)
39         {
40 67080             free(attribute->name);
41         }
42         
43 67080         if(attribute->destroy)
44         {
45 35118             attribute->destroy(attribute->value);
46         }
47
48 67080         free(attribute);
49     }
50
51 67080     GlobusSoapMessageDebugExit();
52 }
53
54 globus_result_t
55 globus_soap_message_attr_init(
56     globus_soap_message_attr_t *        attrs)
57 10760 {
58 10760     globus_result_t                     result = GLOBUS_SUCCESS;
59 10760     GlobusFuncName(globus_soap_message_attr_init);
60 10760     GlobusSoapMessageDebugEnter();
61     
62 10760     result = globus_hashtable_init(attrs, 20,
63                                    globus_hashtable_string_hash,
64                                    globus_hashtable_string_keyeq);
65     
66 10760     GlobusSoapMessageDebugExit();
67 10760     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 3240 {
75 3240     globus_soap_message_attr_t          new_attrs;
76 3240     globus_l_message_attr_t *           attr;
77 3240     globus_result_t                     result = GLOBUS_SUCCESS;
78 3240     GlobusFuncName(globus_soap_message_attr_copy);
79 3240     GlobusSoapMessageDebugEnter();
80
81 3240     globus_soap_message_attr_init(&new_attrs);
82
83 3240     attr = globus_hashtable_first(&attrs);
84 12798     while(attr)
85     {
86         /* _set will copy the attr value */
87 9558         result = globus_soap_message_attr_set(
88             new_attrs,
89             attr->name,
90             attr->copy,
91             attr->destroy,
92             attr->value);
93 9558         if(result != GLOBUS_SUCCESS)
94         {
95 0             goto exit;
96         }
97
98 9558         attr = globus_hashtable_next(&attrs);
99     }
100
101 3240     *copied_attrs = new_attrs;
102
103  exit:
104 3240     GlobusSoapMessageDebugExit();
105 3240     return result;
106 }
107
108 void
109 globus_soap_message_attr_destroy(
110     globus_soap_message_attr_t                  attrs)
111 10738 {
112 10738     GlobusFuncName(globus_soap_message_attr_destroy);
113 10738     GlobusSoapMessageDebugEnter();
114
115 10738     globus_hashtable_destroy_all(
116         &attrs, globus_l_message_attr_destroy);
117
118 10738     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 79524 {
129 79524     void *                              newvalue = NULL;
130 79524     globus_result_t                     result = GLOBUS_SUCCESS;
131 79524     globus_l_message_attr_t *           attr;
132 79524     GlobusFuncName(globus_soap_message_attr_set);
133 79524     GlobusSoapMessageDebugEnter();
134
135 79524     globus_assert_string(attrs, "NULL attrs in handle");
136
137 79524     globus_assert_string(name, 
138                          "attr_name passed to function is NULL");
139     
140 79524     attr = globus_hashtable_lookup(&attrs, (char *)name);
141 79524     if(!attr)
142     {
143 67091         attr = globus_malloc(sizeof(globus_l_message_attr_t));
144 67091         if(!attr)
145         {
146 0             result = GlobusSoapMessageErrorOutOfMemory;
147 0             goto exit;
148         }
149 67091         memset(attr, 0, sizeof(globus_l_message_attr_t));
150
151 67091         attr->name = globus_libc_strdup(name);
152 67091         attr->destroy = destroy;
153 67091         attr->copy = copy;
154
155 67091         result = globus_hashtable_insert(&attrs, 
156                                          attr->name, attr);
157 67091         if(result != GLOBUS_SUCCESS)
158         {
159 0             goto exit;
160         }
161     }
162     else
163     {
164 12433         if(attr->destroy)
165         {
166 8283             attr->destroy(attr->value);
167         }
168
169 12433         attr->destroy = destroy;
170 12433         attr->copy = copy;
171     }
172
173 79524     if(copy)
174     {
175 43401         copy(&newvalue, attrvalue);
176     }
177     else
178     {
179 36123         newvalue = attrvalue;
180     }
181
182 79524     attr->value = newvalue;
183
184  exit:
185     
186 79524     GlobusSoapMessageDebugExit();
187 79524     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 61448 {
198 61448     globus_result_t                     result = GLOBUS_SUCCESS;
199 61448     GlobusFuncName(globus_soap_message_handle_set_attr);
200 61448     GlobusSoapMessageDebugEnter();
201
202 61448     globus_assert_string(handle, "NULL handle passed to function");
203 61448     globus_assert_string(handle->attrs, "NULL attrs in handle");
204 61448     globus_assert_string(attr_name, 
205                          "attr_name passed to function is NULL");
206
207 61448     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 61448     if (strcmp(attr_name, GLOBUS_SOAP_MESSAGE_VERBOSE_ERRORS_KEY) == 0)
219     {
220 0         handle->verbose = (globus_bool_t) attrvalue;
221     }
222     
223 61448     GlobusSoapMessageDebugExit();
224 61448     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 132975 {
273 132975     void *                              value;
274 132975     globus_l_message_attr_t *           attr;
275 132975     GlobusFuncName(globus_soap_message_attr_get);
276 132975     GlobusSoapMessageDebugEnter();
277
278 132975     attr = globus_hashtable_lookup(&attrs, (char *)attr_name);
279 132975     if(!attr)
280     {
281 60196         value = NULL;
282 60196         goto exit;
283     }
284
285 72779     value = attr->value;
286
287  exit:
288     
289 132975     GlobusSoapMessageDebugExit();
290 132975     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 126047 {
298 126047     void *                              value;
299 126047     GlobusFuncName(globus_soap_message_handle_get_attr);
300 126047     GlobusSoapMessageDebugEnter();
301
302 126047     value = globus_soap_message_attr_get(
303         handle->attrs,
304         attr_name);
305
306 126047     GlobusSoapMessageDebugExit();
307 126047     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 3206 {
315 3206     GlobusFuncName(globus_soap_message_handle_set_attr);
316 3206     GlobusSoapMessageDebugEnter();
317
318 3206     if(handle->attrs)
319     {
320 3206         globus_soap_message_attr_destroy(handle->attrs);
321     }
322
323 3206     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 3206     handle->verbose = (globus_bool_t) globus_soap_message_attr_get(
331                 attrs,
332                 GLOBUS_SOAP_MESSAGE_VERBOSE_ERRORS_KEY);
333
334 3206     GlobusSoapMessageDebugExit();
335 3206     return GLOBUS_SUCCESS;
336 }
337
338 globus_result_t
339 globus_soap_message_attr_copy_string(
340     void **                             new_str,
341     void *                              str)
342 24389 {
343 24389     *new_str = (void *) globus_libc_strdup((char *)str);
344 24389     return GLOBUS_SUCCESS;