1 #include "config.h"
2 #include <string.h>
3 #include <orbit/orbit.h>
4 #include "orb-core-export.h"
5 #include "../util/orbit-purify.h"
6
7 static gboolean
free_entry(gpointer key,gpointer value,gpointer user_data)8 free_entry (gpointer key, gpointer value, gpointer user_data)
9 {
10 g_free (key);
11 g_free (value);
12
13 return TRUE;
14 }
15
16 static void ORBit_Context_free_fn(ORBit_RootObject ctx);
17
18 static void
free_child(gpointer value,gpointer user_data)19 free_child (gpointer value, gpointer user_data)
20 {
21 CORBA_Context ctx = value;
22
23 ctx->parent.refs = 0;
24 ctx->parent_ctx = CORBA_OBJECT_NIL;
25 ORBit_Context_free_fn (ORBIT_ROOT_OBJECT (ctx));
26 }
27
28 static void
ORBit_Context_free_fn(ORBit_RootObject obj_in)29 ORBit_Context_free_fn (ORBit_RootObject obj_in)
30 {
31 CORBA_Context ctx = (CORBA_Context) obj_in;
32
33 if (ctx->children) {
34 g_slist_foreach (ctx->children, free_child, NULL);
35 g_slist_free (ctx->children);
36 }
37
38 if (ctx->mappings) {
39 g_hash_table_foreach_remove (ctx->mappings, free_entry, NULL);
40 g_hash_table_destroy (ctx->mappings);
41 }
42
43 if (ctx->parent_ctx != CORBA_OBJECT_NIL)
44 ctx->parent_ctx->children = g_slist_remove (
45 ctx->parent_ctx->children, ctx);
46
47 g_free (ctx->the_name);
48
49 p_free (ctx, struct CORBA_Context_type);
50 }
51
52 static const ORBit_RootObject_Interface CORBA_Context_epv =
53 {
54 ORBIT_ROT_CONTEXT,
55 ORBit_Context_free_fn
56 };
57
58 static CORBA_Context
CORBA_Context_new(CORBA_Context parent,const char * name,CORBA_Environment * ev)59 CORBA_Context_new (CORBA_Context parent,
60 const char *name,
61 CORBA_Environment *ev)
62 {
63 CORBA_Context retval;
64
65 retval = g_new0 (struct CORBA_Context_type, 1);
66
67 ORBit_RootObject_init (&retval->parent, &CORBA_Context_epv);
68
69 if (name)
70 retval->the_name = g_strdup (name);
71
72 retval->parent_ctx = parent;
73 if (parent)
74 parent->children = g_slist_prepend (parent->children, retval);
75
76 return ORBit_RootObject_duplicate (retval);
77 }
78
79 void
CORBA_ORB_get_default_context(CORBA_ORB orb,CORBA_Context * ctx,CORBA_Environment * ev)80 CORBA_ORB_get_default_context (CORBA_ORB orb,
81 CORBA_Context *ctx,
82 CORBA_Environment *ev)
83 {
84 g_return_if_fail (ev != NULL);
85
86 if (!orb->default_ctx)
87 orb->default_ctx = CORBA_Context_new (
88 CORBA_OBJECT_NIL, NULL, ev);
89
90 *ctx = ORBit_RootObject_duplicate (orb->default_ctx);
91 }
92
93 void
CORBA_Context_set_one_value(CORBA_Context ctx,const CORBA_char * prop_name,const CORBA_char * value,CORBA_Environment * ev)94 CORBA_Context_set_one_value (CORBA_Context ctx,
95 const CORBA_char *prop_name,
96 const CORBA_char *value,
97 CORBA_Environment *ev)
98 {
99 gpointer old_nom, old_value;
100
101 g_return_if_fail (ev != NULL);
102
103 if (!ctx->mappings)
104 ctx->mappings = g_hash_table_new (g_str_hash, g_str_equal);
105
106 if (g_hash_table_lookup_extended (
107 ctx->mappings, prop_name, &old_nom, &old_value)) {
108 g_hash_table_remove (ctx->mappings, prop_name);
109 g_free (old_nom);
110 g_free (old_value);
111 }
112
113 g_hash_table_insert (ctx->mappings,
114 g_strdup (prop_name),
115 g_strdup (value));
116 }
117
118 void
CORBA_Context_set_values(CORBA_Context ctx,const CORBA_NVList values,CORBA_Environment * ev)119 CORBA_Context_set_values(CORBA_Context ctx,
120 const CORBA_NVList values,
121 CORBA_Environment * ev)
122 {
123 int i;
124
125 for(i = 0; i < values->list->len; i++)
126 {
127 CORBA_NamedValue *nvp;
128
129 nvp = ((CORBA_NamedValue *)values->list->data) + i;
130
131 g_assert(nvp->argument._type == TC_CORBA_string);
132
133 CORBA_Context_set_one_value(ctx, nvp->name, nvp->argument._value, ev);
134 }
135 }
136
137 typedef struct {
138 CORBA_Context ctx;
139 const CORBA_char *prop_name;
140 CORBA_NVList values;
141 CORBA_Environment *ev;
142 int len;
143 } CTXSearchInfo;
144
145 static gboolean
list_has_key(CORBA_NVList list,const char * key)146 list_has_key (CORBA_NVList list, const char *key)
147 {
148 int i;
149
150 for (i = 0; i < list->list->len; i++) {
151 CORBA_NamedValue *nvp;
152
153 nvp = ((CORBA_NamedValue *)list->list->data) + i;
154
155 if (!strcmp(nvp->name, key))
156 return TRUE;
157 }
158
159 return FALSE;
160 }
161
162 static void
search_props(gpointer key,gpointer value,CTXSearchInfo * csi)163 search_props (gpointer key,
164 gpointer value,
165 CTXSearchInfo *csi)
166 {
167 if (strncmp (key, csi->prop_name, csi->len))
168 return;
169
170 if (list_has_key (csi->values, key))
171 return;
172
173 CORBA_NVList_add_item (
174 csi->values, key, TC_CORBA_string,
175 (CORBA_OpaqueValue) &value,
176 strlen (value) + 1, CORBA_IN_COPY_VALUE, NULL);
177 }
178
179 static void
ctx_get_values(CORBA_Context ctx,CORBA_Flags op_flags,const CORBA_char * prop_name,CORBA_NVList * values,gint is_wc,CORBA_Environment * ev)180 ctx_get_values (CORBA_Context ctx,
181 CORBA_Flags op_flags,
182 const CORBA_char *prop_name,
183 CORBA_NVList *values,
184 gint is_wc,
185 CORBA_Environment *ev)
186 {
187 gboolean go_up = FALSE;
188
189 if (is_wc >= 0) {
190 CTXSearchInfo csi;
191
192 csi.ctx = ctx;
193 csi.prop_name = prop_name;
194 csi.values = *values;
195 csi.ev = ev;
196 csi.len = is_wc;
197
198 if (ctx->mappings)
199 g_hash_table_foreach (
200 ctx->mappings, (GHFunc) search_props, &csi);
201
202 go_up = TRUE;
203 } else {
204 char *val = NULL;
205
206 if (ctx->mappings)
207 val = g_hash_table_lookup (ctx->mappings, prop_name);
208
209 if (val)
210 CORBA_NVList_add_item (
211 *values, prop_name, TC_CORBA_string,
212 (CORBA_OpaqueValue) &val,
213 strlen (val) + 1, CORBA_IN_COPY_VALUE, ev);
214 else
215 go_up = TRUE;
216 }
217
218 if (go_up && ctx->parent_ctx &&
219 !(op_flags & CORBA_CTX_RESTRICT_SCOPE))
220 ctx_get_values (ctx->parent_ctx, op_flags,
221 prop_name, values, is_wc, ev);
222 }
223
224 void
CORBA_Context_get_values(CORBA_Context ctx,const CORBA_char * start_scope,const CORBA_Flags op_flags,const CORBA_char * prop_name,CORBA_NVList * values,CORBA_Environment * ev)225 CORBA_Context_get_values (CORBA_Context ctx,
226 const CORBA_char *start_scope,
227 const CORBA_Flags op_flags,
228 const CORBA_char *prop_name,
229 CORBA_NVList *values,
230 CORBA_Environment *ev)
231 {
232 if (start_scope && *start_scope) {
233 while (ctx && (!ctx->the_name ||
234 strcmp (ctx->the_name, start_scope)))
235 ctx = ctx->parent_ctx;
236
237 if (!ctx) {
238 CORBA_exception_set_system (
239 ev, ex_CORBA_INV_IDENT, CORBA_COMPLETED_NO);
240 return;
241 }
242 }
243
244 CORBA_ORB_create_list (CORBA_OBJECT_NIL, 0, values, ev);
245
246 ctx_get_values (ctx, op_flags, prop_name, values,
247 (prop_name [strlen (prop_name) - 1] == '*'), ev);
248
249 if ((*values)->list->len == 0) {
250 CORBA_NVList_free (*values, ev);
251 *values = NULL;
252 CORBA_exception_set_system (
253 ev, ex_CORBA_UNKNOWN, CORBA_COMPLETED_NO);
254 }
255 }
256
257 static void
delete_props(gpointer key,gpointer value,CTXSearchInfo * csi)258 delete_props (gpointer key, gpointer value, CTXSearchInfo *csi)
259 {
260 if (strncmp (key, csi->prop_name, csi->len))
261 return;
262
263 g_hash_table_remove (csi->ctx->mappings, key);
264 g_free (key);
265 g_free (value);
266 }
267
268 void
CORBA_Context_delete_values(CORBA_Context ctx,const CORBA_char * prop_name,CORBA_Environment * ev)269 CORBA_Context_delete_values (CORBA_Context ctx,
270 const CORBA_char *prop_name,
271 CORBA_Environment *ev)
272 {
273 char *ctmp;
274 int wc_pos;
275
276 if (!ctx->mappings)
277 return;
278
279 ctmp = strchr (prop_name, '*');
280 if (ctmp)
281 wc_pos = ctmp - prop_name;
282 else
283 wc_pos = -1;
284
285 if (wc_pos >= 0) {
286 CTXSearchInfo csi;
287
288 memset (&csi, 0, sizeof (csi));
289 csi.ctx = ctx;
290 csi.prop_name = prop_name;
291 csi.ev = ev;
292 csi.len = wc_pos;
293
294 g_hash_table_foreach (ctx->mappings, (GHFunc) delete_props, &csi);
295 } else {
296 gpointer old_nom, old_value;
297
298 if (g_hash_table_lookup_extended (
299 ctx->mappings, prop_name, &old_nom, &old_value)) {
300 g_free (old_nom);
301 g_free (old_value);
302 }
303 }
304 }
305
306 void
CORBA_Context_create_child(CORBA_Context ctx,const CORBA_char * ctx_name,CORBA_Context * child_ctx,CORBA_Environment * ev)307 CORBA_Context_create_child (CORBA_Context ctx,
308 const CORBA_char *ctx_name,
309 CORBA_Context *child_ctx,
310 CORBA_Environment *ev)
311 {
312 *child_ctx = CORBA_Context_new (ctx, ctx_name, ev);
313 }
314
315 void
CORBA_Context_delete(CORBA_Context ctx,const CORBA_Flags del_flags,CORBA_Environment * ev)316 CORBA_Context_delete (CORBA_Context ctx,
317 const CORBA_Flags del_flags,
318 CORBA_Environment *ev)
319 {
320 if ((del_flags & CORBA_CTX_DELETE_DESCENDENTS) ||
321 !ctx->children)
322 free_child (ctx, NULL);
323 }
324
325 void
ORBit_Context_marshal(CORBA_Context ctx,const ORBit_ContextMarshalItem * mlist,CORBA_unsigned_long nitems,GIOPSendBuffer * buf)326 ORBit_Context_marshal (CORBA_Context ctx,
327 const ORBit_ContextMarshalItem *mlist,
328 CORBA_unsigned_long nitems,
329 GIOPSendBuffer *buf)
330 {
331 CORBA_unsigned_long real_nitems, ltmp;
332 guchar *marker;
333 int i;
334
335 marker = giop_send_buffer_append_aligned (buf, &nitems, 4);
336
337 if (!ctx->mappings) {
338 real_nitems = 0;
339 memcpy (marker, &real_nitems, 4);
340
341 return;
342 }
343
344 for (real_nitems = i = 0; i < nitems; i++) {
345 char *value;
346
347 value = g_hash_table_lookup (ctx->mappings, mlist[i].str);
348 if (!value)
349 continue;
350
351 /* Key */
352 giop_send_buffer_append_aligned (buf, &mlist[i].len, sizeof(mlist[i].len));
353 giop_send_buffer_append (buf, mlist[i].str, mlist[i].len);
354 real_nitems++;
355
356 /* Value */
357 ltmp = strlen (value) + 1;
358 giop_send_buffer_append_aligned (buf, <mp, 4);
359 giop_send_buffer_append (buf, value, ltmp);
360 real_nitems++;
361 }
362
363 memcpy (marker, &real_nitems, 4);
364 }
365
366 #define ALIGNFOR(x) recv_buffer->cur = ALIGN_ADDRESS(recv_buffer->cur, sizeof(x))
367
368 gboolean
ORBit_Context_demarshal(CORBA_Context parent,CORBA_Context initme,GIOPRecvBuffer * buf)369 ORBit_Context_demarshal (CORBA_Context parent,
370 CORBA_Context initme,
371 GIOPRecvBuffer *buf)
372 {
373 CORBA_unsigned_long nstrings, keylen, vallen, i;
374 char *key, *value;
375
376 initme->parent.refs = ORBIT_REFCOUNT_STATIC;
377 initme->parent_ctx = parent;
378 initme->mappings = NULL;
379
380 buf->cur = ALIGN_ADDRESS (buf->cur, 4);
381 if ((buf->cur + 4) > buf->end)
382 goto errout;
383 nstrings = *(CORBA_unsigned_long *) buf->cur;
384 if (giop_msg_conversion_needed (buf))
385 nstrings = GUINT32_SWAP_LE_BE (nstrings);
386 buf->cur += 4;
387 if ((buf->cur + nstrings * 8) > buf->end)
388 goto errout;
389
390 if (nstrings)
391 initme->mappings = g_hash_table_new (g_str_hash, g_str_equal);
392 else
393 goto errout;
394
395 for (i = 0; i < nstrings; ) {
396 buf->cur = ALIGN_ADDRESS (buf->cur, 4);
397 if ((buf->cur + 4) > buf->end)
398 goto errout;
399 keylen = *(CORBA_unsigned_long *) buf->cur;
400 if (giop_msg_conversion_needed (buf))
401 keylen = GUINT32_SWAP_LE_BE(keylen);
402 buf->cur += 4;
403 if ((buf->cur + keylen) > buf->end ||
404 (buf->cur + keylen) < buf->cur)
405 goto errout;
406 key = buf->cur;
407 buf->cur += keylen;
408 i++;
409
410 if (i >= nstrings)
411 break;
412
413 buf->cur = ALIGN_ADDRESS (buf->cur, 4);
414 if ((buf->cur + 4) > buf->end)
415 goto errout;
416 vallen = *(CORBA_unsigned_long *) buf->cur;
417 if (giop_msg_conversion_needed (buf))
418 vallen = GUINT32_SWAP_LE_BE(vallen);
419 buf->cur += 4;
420 if ((buf->cur + vallen) > buf->end ||
421 (buf->cur + vallen) < buf->cur)
422 goto errout;
423 value = buf->cur;
424 buf->cur += vallen;
425 i++;
426
427 g_hash_table_insert (initme->mappings, key, value);
428 }
429
430 return FALSE;
431
432 errout:
433 if (initme->mappings)
434 g_hash_table_destroy (initme->mappings);
435
436 return TRUE;
437 }
438
439 void
ORBit_Context_server_free(CORBA_Context ctx)440 ORBit_Context_server_free (CORBA_Context ctx)
441 {
442 g_hash_table_destroy (ctx->mappings);
443 }
444