1 #include "config.h"
2 #include <orbit/orbit.h>
3 #include <string.h>
4 #include "../util/orbit-purify.h"
5
6 typedef struct {
7 CORBA_TypeCode tc;
8 guint index;
9 } TCRecursionNode;
10
11 typedef struct {
12 GSList *prior_tcs; /* Could be a hash table by typecode */
13 guint start_idx;
14 } TCEncodeContext;
15
16 typedef struct {
17 GSList *prior_tcs; /* Could be a hash table by offset */
18 guint current_idx; /* The offset from the start of the toplevel buffer of this buffer */
19 } TCDecodeContext;
20
21 /* Two methods called in co-recursion */
22 static gboolean tc_dec (CORBA_TypeCode *t,
23 GIOPRecvBuffer *c,
24 TCDecodeContext *ctx);
25 static void tc_enc (CORBA_TypeCode tc,
26 GIOPSendBuffer *buf,
27 TCEncodeContext *ctx);
28
29 #define get_wptr(buf) (buf->msg.header.message_size - ctx->start_idx)
30 #define get_rptr(buf) (buf->cur-buf->message_body)
31
32 #define CDR_put_string(buf,str) (giop_send_buffer_append_string ((buf), (str)))
33 #define CDR_put_ulong(buf, n) (giop_send_buffer_align(buf, sizeof(n)), \
34 giop_send_buffer_append(buf, &(n), sizeof(n)))
35 #define CDR_put_long(buf, n) CDR_put_ulong(buf, n)
36 #define CDR_put_ulong_long(buf, n) CDR_put_ulong(buf, n)
37 #define CDR_put_wchar(buf, n) CDR_put_ulong(buf, n)
38 #define CDR_put_octet(buf, n) CDR_put_ulong(buf, n)
39 #define CDR_put_ushort(buf, n) CDR_put_ulong(buf, n)
40 #define CDR_put_short(buf, n) CDR_put_ulong(buf, n)
41
42 typedef void (*CORBA_TypeCodeEncoder)(CORBA_TypeCode t,
43 GIOPSendBuffer *c,
44 TCEncodeContext* ctx);
45
46 typedef gboolean (*CORBA_TypeCodeDecoder)(CORBA_TypeCode t,
47 GIOPRecvBuffer *c,
48 TCDecodeContext* ctx);
49
50 typedef enum {
51 TK_EMPTY,
52 TK_SIMPLE,
53 TK_COMPLEX
54 } TkType;
55
56 typedef struct {
57 TkType type;
58 CORBA_TypeCodeEncoder encoder;
59 CORBA_TypeCodeDecoder decoder;
60 CORBA_TypeCode basic_type;
61 } TkInfo;
62
63 #define DEF_TC_BASIC(nom, c_align) \
64 ORBIT2_MAYBE_CONST struct CORBA_TypeCode_struct TC_CORBA_##nom##_struct = { \
65 {&ORBit_TypeCode_epv, ORBIT_REFCOUNT_STATIC}, \
66 CORBA_tk_##nom, \
67 0, 0, c_align, \
68 0, 0, NULL, NULL, \
69 #nom, \
70 "IDL:omg.org/CORBA/" #nom ":1.0", \
71 NULL, CORBA_OBJECT_NIL, -1 \
72 }
73
74 #define CORBA_tk_Object CORBA_tk_objref
75 #define CORBA_tk_unsigned_long CORBA_tk_ulong
76 #define CORBA_tk_long_long CORBA_tk_longlong
77 #define CORBA_tk_unsigned_long_long CORBA_tk_ulonglong
78 #define CORBA_tk_unsigned_short CORBA_tk_ushort
79 #define CORBA_tk_long_double CORBA_tk_longdouble
80
81 ORBIT2_MAYBE_CONST struct CORBA_TypeCode_struct TC_null_struct = {
82 {&ORBit_TypeCode_epv, ORBIT_REFCOUNT_STATIC},
83 CORBA_tk_null, 0, 0, -1, 0, 0, NULL,
84 CORBA_OBJECT_NIL, "null", "IDL:omg.org/CORBA/Null:1.0"
85 };
86
87 ORBIT2_MAYBE_CONST struct CORBA_TypeCode_struct TC_void_struct = {
88 {&ORBit_TypeCode_epv, ORBIT_REFCOUNT_STATIC},
89 CORBA_tk_void, 0, 0, -1, 0, 0, NULL,
90 CORBA_OBJECT_NIL, "void", "IDL:omg.org/CORBA/void:1.0"
91 };
92
93 DEF_TC_BASIC(char, ORBIT_ALIGNOF_CORBA_CHAR);
94 DEF_TC_BASIC(wchar, ORBIT_ALIGNOF_CORBA_WCHAR);
95 DEF_TC_BASIC(string, ORBIT_ALIGNOF_CORBA_POINTER);
96 DEF_TC_BASIC(long, ORBIT_ALIGNOF_CORBA_LONG);
97 DEF_TC_BASIC(unsigned_long, ORBIT_ALIGNOF_CORBA_LONG);
98 DEF_TC_BASIC(float, ORBIT_ALIGNOF_CORBA_FLOAT);
99 DEF_TC_BASIC(double, ORBIT_ALIGNOF_CORBA_DOUBLE);
100 DEF_TC_BASIC(short, ORBIT_ALIGNOF_CORBA_SHORT);
101 DEF_TC_BASIC(unsigned_short, ORBIT_ALIGNOF_CORBA_SHORT);
102 DEF_TC_BASIC(boolean, ORBIT_ALIGNOF_CORBA_BOOLEAN);
103 DEF_TC_BASIC(octet, ORBIT_ALIGNOF_CORBA_OCTET);
104 DEF_TC_BASIC(any, ORBIT_ALIGNOF_CORBA_ANY);
105 DEF_TC_BASIC(TypeCode, ORBIT_ALIGNOF_CORBA_POINTER);
106 DEF_TC_BASIC(Principal, 1); /* Hmm */
107 DEF_TC_BASIC(Object, ORBIT_ALIGNOF_CORBA_POINTER);
108 DEF_TC_BASIC(wstring, ORBIT_ALIGNOF_CORBA_POINTER);
109 DEF_TC_BASIC(long_double, ORBIT_ALIGNOF_CORBA_LONG_DOUBLE);
110 DEF_TC_BASIC(long_long, ORBIT_ALIGNOF_CORBA_LONG_LONG);
111 DEF_TC_BASIC(unsigned_long_long, ORBIT_ALIGNOF_CORBA_LONG_LONG);
112
113 static void
tc_enc_tk_objref(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)114 tc_enc_tk_objref(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
115 {
116 CDR_put_string (c, t->repo_id);
117 CDR_put_string (c, t->name);
118 }
119
120 static void
tc_enc_tk_sequence(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)121 tc_enc_tk_sequence(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
122 {
123 tc_enc (*t->subtypes, c, ctx);
124 CDR_put_ulong (c, t->length);
125 }
126
127 static void
tc_enc_tk_string(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)128 tc_enc_tk_string(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
129 {
130 CDR_put_ulong(c, t->length);
131 }
132
133 static void
tc_enc_tk_struct(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)134 tc_enc_tk_struct(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
135 {
136 CORBA_unsigned_long i;
137
138 CDR_put_string(c, t->repo_id);
139 CDR_put_string(c, t->name);
140 CDR_put_ulong(c, t->sub_parts);
141
142 for(i = 0; i < t->sub_parts; i++) {
143 CDR_put_string (c, t->subnames [i]);
144 tc_enc (t->subtypes [i], c, ctx);
145 }
146 }
147
148 static void
tc_enc_tk_union(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)149 tc_enc_tk_union (CORBA_TypeCode t,
150 GIOPSendBuffer *c,
151 TCEncodeContext *ctx)
152 {
153 CORBA_unsigned_long i;
154
155 CDR_put_string (c, t->repo_id);
156 CDR_put_string (c, t->name);
157 tc_enc (t->discriminator, c, ctx);
158 CDR_put_long (c, t->default_index);
159 CDR_put_ulong (c, t->sub_parts);
160
161 i = t->sub_parts;
162
163 #define MEMBER_LOOPER_ENC(putname, typename, tkname) \
164 case CORBA_tk_##tkname: \
165 for(i = 0; i < t->sub_parts; i++) { \
166 CORBA_##typename tmp; \
167 tmp = (CORBA_##typename) t->sublabels [i]; \
168 CDR_put_##putname (c, tmp); \
169 CDR_put_string (c, t->subnames [i]); \
170 tc_enc (t->subtypes [i], c, ctx); \
171 } \
172 break
173
174 #define UNION_MEMBERS(dir) \
175 MEMBER_LOOPER_##dir(ulong, long, long); \
176 case CORBA_tk_enum: /* fall through */ \
177 MEMBER_LOOPER_##dir(ulong, unsigned_long, ulong); \
178 MEMBER_LOOPER_##dir(octet, boolean, boolean); \
179 MEMBER_LOOPER_##dir(octet, char, char); \
180 MEMBER_LOOPER_##dir(ushort, short, short); \
181 MEMBER_LOOPER_##dir(ushort, unsigned_short, ushort); \
182 MEMBER_LOOPER_##dir(ulong_long, long_long, longlong); \
183 MEMBER_LOOPER_##dir(ulong_long, unsigned_long_long, ulonglong); \
184 MEMBER_LOOPER_##dir(wchar, wchar, wchar);
185
186 switch (t->discriminator->kind) {
187 UNION_MEMBERS (ENC);
188 default:
189 g_error ("tc_enc_tk_union: Illegal union discriminator "
190 "type %s\n", t->discriminator->name);
191 break;
192 }
193 }
194
195 static void
tc_enc_tk_enum(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)196 tc_enc_tk_enum(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
197 {
198 CORBA_unsigned_long i;
199 CDR_put_string(c, t->repo_id);
200 CDR_put_string(c, t->name);
201 CDR_put_ulong(c, t->sub_parts);
202 for(i=0;i<t->sub_parts;i++)
203 CDR_put_string(c, t->subnames[i]);
204 }
205
206 static void
tc_enc_tk_alias(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)207 tc_enc_tk_alias(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
208 {
209 CDR_put_string(c, t->repo_id);
210 CDR_put_string(c, t->name);
211 tc_enc(*t->subtypes, c, ctx);
212 }
213
214 static void
tc_enc_tk_except(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)215 tc_enc_tk_except(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
216 {
217 gulong i;
218 CDR_put_string(c, t->repo_id);
219 CDR_put_string(c, t->name);
220 CDR_put_ulong(c, t->sub_parts);
221 for(i=0;i<t->sub_parts;i++){
222 CDR_put_string(c, t->subnames[i]);
223 tc_enc(t->subtypes[i], c, ctx);
224 }
225 }
226
227 static void
tc_enc_tk_array(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)228 tc_enc_tk_array(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
229 {
230 tc_enc(*t->subtypes, c, ctx);
231 CDR_put_ulong(c, t->length);
232 }
233
234 static void
tc_enc_tk_wstring(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)235 tc_enc_tk_wstring(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
236 {
237 CDR_put_ulong(c, t->length);
238 }
239
240 static void
tc_enc_tk_fixed(CORBA_TypeCode t,GIOPSendBuffer * c,TCEncodeContext * ctx)241 tc_enc_tk_fixed(CORBA_TypeCode t, GIOPSendBuffer *c, TCEncodeContext* ctx)
242 {
243 CDR_put_ushort(c, t->digits);
244 CDR_put_short(c, t->scale);
245 }
246
247 static void
ORBit_TypeCode_free_fn(ORBit_RootObject obj_in)248 ORBit_TypeCode_free_fn (ORBit_RootObject obj_in)
249 {
250 CORBA_TypeCode tc = (CORBA_TypeCode) obj_in;
251 int i;
252
253 g_free ((char*)(tc->name));
254 g_free ((char*)(tc->repo_id));
255
256 for (i = 0; i < tc->sub_parts; i++) {
257 if (tc->subnames)
258 g_free ((char*)(tc->subnames [i]));
259
260 if (tc->subtypes)
261 ORBit_RootObject_release_T (tc->subtypes [i]);
262 }
263
264 g_free (tc->subnames);
265 g_free (tc->subtypes);
266 g_free (tc->sublabels);
267
268 if (tc->discriminator)
269 ORBit_RootObject_release_T (tc->discriminator);
270
271 p_free (tc, struct CORBA_TypeCode_struct);
272 }
273
274 static gboolean
CDR_get(GIOPRecvBuffer * buf,guchar * ptr,guint len)275 CDR_get (GIOPRecvBuffer *buf,
276 guchar *ptr,
277 guint len)
278 {
279 buf->cur = ALIGN_ADDRESS (buf->cur, len);
280
281 if ((buf->cur + len) > buf->end)
282 return TRUE;
283
284 memcpy (ptr, buf->cur, len);
285
286 if (len != 1 && giop_msg_conversion_needed (buf))
287 switch (len) {
288 case 2:
289 *(guint16 *)ptr = GUINT16_SWAP_LE_BE (*(guint16 *)ptr);
290 break;
291 case 4:
292 *(guint32 *)ptr = GUINT32_SWAP_LE_BE (*(guint32 *)ptr);
293 break;
294 case 8:
295 *(guint64 *)ptr = GUINT64_SWAP_LE_BE (*(guint64 *)ptr);
296 break;
297 default:
298 g_assert_not_reached ();
299 break;
300 }
301
302 buf->cur += len;
303
304 return FALSE;
305 }
306
307 #define CDR_get_ulong(x, y) CDR_get(x, (guchar *)y, 4)
308 #define CDR_get_ushort(x, y) CDR_get(x, (guchar *)y, 2)
309 #define CDR_get_short(x, y) CDR_get(x, (guchar *)y, 2)
310 #define CDR_get_ulong_long(x, y) CDR_get(x, (guchar *)y, 8)
311 #define CDR_get_octet(x, y) CDR_get(x, (guchar *)y, 1)
312 #define CDR_get_wchar(x, y) CDR_get(x, (guchar *)y, 2)
313
314 static gboolean
CDR_get_const_string(GIOPRecvBuffer * buf,char ** ptr)315 CDR_get_const_string(GIOPRecvBuffer *buf, char **ptr)
316 {
317 CORBA_unsigned_long len;
318
319 if(CDR_get_ulong(buf, &len))
320 return TRUE;
321
322 if((buf->cur + len) > buf->end
323 || (buf->cur + len) < buf->cur)
324 return TRUE;
325 *ptr = g_memdup(buf->cur, len);
326 buf->cur += len;
327
328 return FALSE;
329 }
330
331 static CORBA_short
ORBit_TC_find_c_alignment(CORBA_TypeCode tc)332 ORBit_TC_find_c_alignment (CORBA_TypeCode tc)
333 {
334 CORBA_short retval = 1;
335 int i;
336
337 while (tc->kind == CORBA_tk_alias)
338 tc = tc->subtypes[0];
339
340 switch(tc->kind) {
341 case CORBA_tk_union:
342 retval = MAX (retval,
343 ORBit_TC_find_c_alignment (tc->discriminator));
344 case CORBA_tk_except:
345 case CORBA_tk_struct:
346 #if ORBIT_ALIGNOF_CORBA_STRUCT > 1
347 retval = MAX (retval, ORBIT_ALIGNOF_CORBA_STRUCT);
348 #endif
349 for(i = 0; i < tc->sub_parts; i++)
350 retval = MAX (retval,
351 ORBit_TC_find_c_alignment (tc->subtypes[i]));
352 return retval;
353 case CORBA_tk_ulong:
354 case CORBA_tk_long:
355 case CORBA_tk_enum:
356 return ORBIT_ALIGNOF_CORBA_LONG;
357 case CORBA_tk_ushort:
358 case CORBA_tk_short:
359 case CORBA_tk_wchar:
360 return ORBIT_ALIGNOF_CORBA_SHORT;
361 case CORBA_tk_longlong:
362 case CORBA_tk_ulonglong:
363 return ORBIT_ALIGNOF_CORBA_LONG_LONG;
364 case CORBA_tk_float:
365 return ORBIT_ALIGNOF_CORBA_FLOAT;
366 case CORBA_tk_double:
367 return ORBIT_ALIGNOF_CORBA_DOUBLE;
368 case CORBA_tk_longdouble:
369 return ORBIT_ALIGNOF_CORBA_LONG_DOUBLE;
370 case CORBA_tk_boolean:
371 case CORBA_tk_char:
372 case CORBA_tk_octet:
373 return ORBIT_ALIGNOF_CORBA_CHAR;
374 case CORBA_tk_string:
375 case CORBA_tk_wstring:
376 case CORBA_tk_TypeCode:
377 case CORBA_tk_objref:
378 return ORBIT_ALIGNOF_CORBA_POINTER;
379 case CORBA_tk_sequence:
380 return ORBIT_ALIGNOF_CORBA_SEQ;
381 case CORBA_tk_any:
382 return ORBIT_ALIGNOF_CORBA_ANY;
383 case CORBA_tk_array:
384 return ORBit_TC_find_c_alignment (tc->subtypes[0]);
385 case CORBA_tk_fixed:
386 return ORBIT_ALIGNOF_CORBA_FIXED;
387 default:
388 return 1;
389 }
390 }
391
392 static gboolean
tc_dec_tk_objref(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)393 tc_dec_tk_objref (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
394 {
395 if (CDR_get_const_string (c, &t->repo_id))
396 return TRUE;
397 if (CDR_get_const_string (c, &t->name))
398 return TRUE;
399 return FALSE;
400 }
401
402 static gboolean
tc_dec_tk_sequence(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)403 tc_dec_tk_sequence (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
404 {
405 t->subtypes = g_new0 (CORBA_TypeCode, 1);
406 if (tc_dec (&t->subtypes[0], c, ctx))
407 return TRUE;
408 t->sub_parts = 1;
409 if (CDR_get_ulong (c, &t->length))
410 return TRUE;
411 return FALSE;
412 }
413
414 static gboolean
tc_dec_tk_string(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)415 tc_dec_tk_string (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
416 {
417 if (CDR_get_ulong (c, &t->length))
418 return TRUE;
419 return FALSE;
420 }
421
422 static gboolean
tc_dec_tk_struct(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)423 tc_dec_tk_struct (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
424 {
425 CORBA_unsigned_long i;
426
427 if (CDR_get_const_string (c, &t->repo_id))
428 return TRUE;
429 if (CDR_get_const_string (c, &t->name))
430 return TRUE;
431 if (CDR_get_ulong (c, &t->sub_parts))
432 return TRUE;
433
434 t->subnames = g_new0 (char*, t->sub_parts);
435 t->subtypes = g_new0 (CORBA_TypeCode, t->sub_parts);
436
437 for (i = 0; i < t->sub_parts; i++) {
438 if (CDR_get_const_string (c, &t->subnames [i]))
439 return TRUE;
440 if (tc_dec (&t->subtypes [i], c, ctx))
441 return TRUE;
442 }
443
444 return FALSE;
445 }
446
447 static gboolean
tc_dec_tk_union(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)448 tc_dec_tk_union (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
449 {
450 CORBA_unsigned_long i;
451
452 if (CDR_get_const_string (c, &t->repo_id))
453 return TRUE;
454 if (CDR_get_const_string (c, &t->name))
455 return TRUE;
456 if (tc_dec (&t->discriminator, c, ctx))
457 return TRUE;
458 if (CDR_get_ulong (c, &t->default_index))
459 return TRUE;
460 if (CDR_get_ulong (c, &t->sub_parts))
461 return TRUE;
462
463 t->sublabels = g_new0 (CORBA_long, t->sub_parts);
464 t->subnames = g_new0 (char *, t->sub_parts);
465 t->subtypes = g_new0 (CORBA_TypeCode, t->sub_parts);
466
467 #define MEMBER_LOOPER_DEC(getname, typename, tkname) \
468 case CORBA_tk_##tkname: \
469 for(i = 0; i < t->sub_parts; i++){ \
470 CORBA_##typename tmp; \
471 if (CDR_get_##getname (c, &tmp)) \
472 return TRUE; \
473 t->sublabels [i] = (CORBA_long) tmp; \
474 if (CDR_get_const_string (c, &t->subnames[i])) \
475 return TRUE; \
476 if (tc_dec (&t->subtypes[i], c, ctx)) \
477 return TRUE; \
478 } \
479 break
480
481 switch (t->discriminator->kind) {
482 UNION_MEMBERS (DEC);
483 default:
484 /* XXX: what is correct error handling? */
485 g_error("Don't know how to handle this type (%d) of discriminator.",
486 t->discriminator->kind);
487 }
488
489 return FALSE;
490 }
491
492 static gboolean
tc_dec_tk_enum(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)493 tc_dec_tk_enum (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
494 {
495 CORBA_unsigned_long i;
496
497 if (CDR_get_const_string (c, &t->repo_id))
498 return TRUE;
499 if (CDR_get_const_string (c, &t->name))
500 return TRUE;
501 if (CDR_get_ulong (c, &t->sub_parts))
502 return TRUE;
503
504 t->subnames = g_new0 (char*, t->sub_parts);
505 for(i = 0; i < t->sub_parts; i++) {
506 if (CDR_get_const_string (c, &t->subnames[i]))
507 return TRUE;
508 }
509
510 return FALSE;
511 }
512
513 static gboolean
tc_dec_tk_alias(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)514 tc_dec_tk_alias (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
515 {
516 CDR_get_const_string (c, &t->repo_id);
517 CDR_get_const_string (c, &t->name);
518
519 t->subtypes = g_new0 (CORBA_TypeCode, 1);
520 if (tc_dec (t->subtypes, c, ctx))
521 return TRUE;
522 t->sub_parts = 1;
523
524 return FALSE;
525 }
526
527
528 static gboolean
tc_dec_tk_except(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)529 tc_dec_tk_except (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
530 {
531 gulong i;
532
533 if (CDR_get_const_string (c, &t->repo_id))
534 return TRUE;
535 if (CDR_get_const_string (c, &t->name))
536 return TRUE;
537 if (CDR_get_ulong (c, &t->sub_parts))
538 return TRUE;
539
540 t->subtypes = g_new0 (CORBA_TypeCode, t->sub_parts);
541 t->subnames = g_new0 (char *, t->sub_parts);
542
543 for (i = 0; i < t->sub_parts; i++) {
544 if (CDR_get_const_string (c, &t->subnames[i]))
545 return TRUE;
546 if (tc_dec (&t->subtypes[i], c, ctx))
547 return TRUE;
548 }
549
550 return FALSE;
551 }
552
553 static gboolean
tc_dec_tk_array(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)554 tc_dec_tk_array (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
555 {
556 t->subtypes = g_new (CORBA_TypeCode, 1);
557
558 if (tc_dec (t->subtypes, c, ctx))
559 return TRUE;
560
561 t->sub_parts = 1;
562 if (CDR_get_ulong (c, &t->length))
563 return TRUE;
564
565 return FALSE;
566 }
567
568
569 static gboolean
tc_dec_tk_wstring(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)570 tc_dec_tk_wstring (CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
571 {
572 if (CDR_get_ulong (c, &t->length))
573 return TRUE;
574 return FALSE;
575 }
576
577 static gboolean
tc_dec_tk_fixed(CORBA_TypeCode t,GIOPRecvBuffer * c,TCDecodeContext * ctx)578 tc_dec_tk_fixed(CORBA_TypeCode t, GIOPRecvBuffer *c, TCDecodeContext* ctx)
579 {
580 if (CDR_get_ushort (c, &t->digits))
581 return TRUE;
582 if (CDR_get_short (c, &t->scale))
583 return TRUE;
584
585 return FALSE;
586 }
587
588 /* FIXME: Right now this function doesn't record whether or not it has
589 already visited a given TypeCode. I'm not sure if every recursive
590 type will have a tk_recursive node in it; if not, then this will
591 need to be reworked a bit. */
592 static CORBA_boolean
typecode_equiv_internal(CORBA_TypeCode obj,CORBA_TypeCode tc,gboolean strict_equal,CORBA_Environment * ev)593 typecode_equiv_internal (CORBA_TypeCode obj,
594 CORBA_TypeCode tc,
595 gboolean strict_equal,
596 CORBA_Environment *ev)
597 {
598 int i;
599
600 g_return_val_if_fail (tc != NULL, CORBA_FALSE);
601 g_return_val_if_fail (obj != NULL, CORBA_FALSE);
602
603 if (!strict_equal) {
604 while (obj->kind == CORBA_tk_alias)
605 obj = obj->subtypes [0];
606
607 while (tc->kind == CORBA_tk_alias)
608 tc = tc->subtypes [0];
609 }
610
611 if (obj->kind != tc->kind)
612 return CORBA_FALSE;
613
614 switch (obj->kind) {
615 case CORBA_tk_wstring:
616 case CORBA_tk_string:
617 return obj->length == tc->length;
618 case CORBA_tk_objref:
619 return ! strcmp (obj->repo_id, tc->repo_id);
620 case CORBA_tk_except:
621 case CORBA_tk_struct:
622 if (strcmp (obj->repo_id, tc->repo_id)
623 || obj->sub_parts != tc->sub_parts)
624 return CORBA_FALSE;
625 for (i = 0; i < obj->sub_parts; ++i)
626 if (! typecode_equiv_internal (obj->subtypes[i],
627 tc->subtypes[i],
628 strict_equal, ev))
629 return CORBA_FALSE;
630 break;
631 case CORBA_tk_union:
632 if (strcmp (obj->repo_id, tc->repo_id)
633 || obj->sub_parts != tc->sub_parts
634 || ! typecode_equiv_internal (obj->discriminator,
635 tc->discriminator,
636 strict_equal, ev)
637 || obj->default_index != tc->default_index)
638 return CORBA_FALSE;
639 for (i = 0; i < obj->sub_parts; ++i)
640
641 if (! typecode_equiv_internal (obj->subtypes[i],
642 tc->subtypes[i],
643 strict_equal, ev)
644 || obj->sublabels [i] != tc->sublabels [i])
645 return CORBA_FALSE;
646
647 break;
648 case CORBA_tk_enum:
649 if (obj->sub_parts != tc->sub_parts
650 || strcmp (obj->repo_id, tc->repo_id))
651 return CORBA_FALSE;
652 for (i = 0; i < obj->sub_parts; ++i)
653 if (strcmp (obj->subnames[i], tc->subnames[i]))
654 return CORBA_FALSE;
655 break;
656 case CORBA_tk_sequence:
657 case CORBA_tk_array:
658 if (obj->length != tc->length)
659 return CORBA_FALSE;
660 g_assert (obj->sub_parts == 1);
661 g_assert (tc->sub_parts == 1);
662 return typecode_equiv_internal (obj->subtypes[0],
663 tc->subtypes[0],
664 strict_equal, ev);
665 case CORBA_tk_alias:
666 if (strcmp (obj->repo_id, tc->repo_id))
667 return CORBA_FALSE;
668
669 g_assert (obj->sub_parts == 1);
670 g_assert (tc->sub_parts == 1);
671
672 return typecode_equiv_internal (obj->subtypes[0],
673 tc->subtypes[0],
674 strict_equal, ev);
675 break;
676 case CORBA_tk_recursive:
677 return obj->recurse_depth == tc->recurse_depth;
678 case CORBA_tk_fixed:
679 return obj->digits == tc->digits && obj->scale == tc->scale;
680
681 default:
682 /* Everything else is primitive. */
683 break;
684 }
685
686 return CORBA_TRUE;
687 }
688
689 CORBA_boolean
CORBA_TypeCode_equal(CORBA_TypeCode obj,const CORBA_TypeCode tc,CORBA_Environment * ev)690 CORBA_TypeCode_equal (CORBA_TypeCode obj,
691 const CORBA_TypeCode tc,
692 CORBA_Environment *ev)
693 {
694 return typecode_equiv_internal (obj, tc, TRUE, ev);
695 }
696
697 CORBA_boolean
CORBA_TypeCode_equivalent(CORBA_TypeCode obj,const CORBA_TypeCode tc,CORBA_Environment * ev)698 CORBA_TypeCode_equivalent (CORBA_TypeCode obj,
699 const CORBA_TypeCode tc,
700 CORBA_Environment *ev)
701 {
702 return typecode_equiv_internal (obj, tc, FALSE, ev);
703 }
704
705 CORBA_TypeCode
CORBA_TypeCode_get_compact_typecode(CORBA_TypeCode typecode,CORBA_Environment * ev)706 CORBA_TypeCode_get_compact_typecode (CORBA_TypeCode typecode,
707 CORBA_Environment *ev)
708 {
709 /* FIXME: implement */
710 CORBA_exception_set_system (
711 ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
712
713 return CORBA_OBJECT_NIL;
714 }
715
716 CORBA_TCKind
CORBA_TypeCode_kind(CORBA_TypeCode typecode,CORBA_Environment * ev)717 CORBA_TypeCode_kind (CORBA_TypeCode typecode,
718 CORBA_Environment *ev)
719 {
720 return typecode->kind;
721 }
722
723 CORBA_RepositoryId
CORBA_TypeCode_id(CORBA_TypeCode typecode,CORBA_Environment * ev)724 CORBA_TypeCode_id (CORBA_TypeCode typecode,
725 CORBA_Environment *ev)
726 {
727 if (!(typecode->kind == CORBA_tk_objref ||
728 typecode->kind == CORBA_tk_value ||
729 typecode->kind == CORBA_tk_value_box ||
730 typecode->kind == CORBA_tk_abstract_interface ||
731 typecode->kind == CORBA_tk_native ||
732 typecode->kind == CORBA_tk_struct ||
733 typecode->kind == CORBA_tk_union ||
734 typecode->kind == CORBA_tk_enum ||
735 typecode->kind == CORBA_tk_alias ||
736 typecode->kind == CORBA_tk_except)) {
737 CORBA_exception_set (
738 ev, CORBA_USER_EXCEPTION,
739 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
740 return NULL;
741 }
742
743 return CORBA_string_dup (typecode->repo_id);
744 }
745
746 CORBA_Identifier
CORBA_TypeCode_name(CORBA_TypeCode typecode,CORBA_Environment * ev)747 CORBA_TypeCode_name (CORBA_TypeCode typecode,
748 CORBA_Environment *ev)
749 {
750 if (!(typecode->kind == CORBA_tk_objref ||
751 typecode->kind == CORBA_tk_struct ||
752 typecode->kind == CORBA_tk_union ||
753 typecode->kind == CORBA_tk_enum ||
754 typecode->kind == CORBA_tk_alias ||
755 typecode->kind == CORBA_tk_abstract_interface ||
756 typecode->kind == CORBA_tk_value ||
757 typecode->kind == CORBA_tk_value_box ||
758 typecode->kind == CORBA_tk_native ||
759 typecode->kind == CORBA_tk_except)) {
760 CORBA_exception_set (
761 ev, CORBA_USER_EXCEPTION,
762 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
763 return NULL;
764 }
765
766 return CORBA_string_dup (typecode->name);
767 }
768
769 CORBA_unsigned_long
CORBA_TypeCode_member_count(CORBA_TypeCode typecode,CORBA_Environment * ev)770 CORBA_TypeCode_member_count (CORBA_TypeCode typecode,
771 CORBA_Environment *ev)
772 {
773 if (!(typecode->kind == CORBA_tk_struct ||
774 typecode->kind == CORBA_tk_union ||
775 typecode->kind == CORBA_tk_value ||
776 typecode->kind == CORBA_tk_enum ||
777 typecode->kind == CORBA_tk_except)) {
778 CORBA_exception_set (
779 ev, CORBA_USER_EXCEPTION,
780 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
781 return 0;
782 }
783
784 return typecode->sub_parts;
785 }
786
787 CORBA_Identifier
CORBA_TypeCode_member_name(CORBA_TypeCode typecode,const CORBA_unsigned_long index,CORBA_Environment * ev)788 CORBA_TypeCode_member_name (CORBA_TypeCode typecode,
789 const CORBA_unsigned_long index,
790 CORBA_Environment *ev)
791 {
792 if (!(typecode->kind == CORBA_tk_struct ||
793 typecode->kind == CORBA_tk_union ||
794 typecode->kind == CORBA_tk_value ||
795 typecode->kind == CORBA_tk_enum ||
796 typecode->kind == CORBA_tk_except)) {
797 CORBA_exception_set (
798 ev, CORBA_USER_EXCEPTION,
799 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
800 return NULL;
801 }
802
803 if (index > typecode->sub_parts) {
804 CORBA_exception_set (
805 ev, CORBA_USER_EXCEPTION,
806 "IDL:omg.org/CORBA/TypeCode/Bounds/1.0", NULL);
807 return NULL;
808 }
809
810 return CORBA_string_dup (typecode->subnames [index]);
811 }
812
813 CORBA_TypeCode
CORBA_TypeCode_member_type(CORBA_TypeCode typecode,const CORBA_unsigned_long index,CORBA_Environment * ev)814 CORBA_TypeCode_member_type (CORBA_TypeCode typecode,
815 const CORBA_unsigned_long index,
816 CORBA_Environment *ev)
817 {
818 if (!(typecode->kind == CORBA_tk_struct ||
819 typecode->kind == CORBA_tk_union ||
820 typecode->kind == CORBA_tk_value ||
821 typecode->kind == CORBA_tk_enum ||
822 typecode->kind == CORBA_tk_except)) {
823 CORBA_exception_set (
824 ev, CORBA_USER_EXCEPTION,
825 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
826 return NULL;
827 }
828
829 if (index > typecode->sub_parts) {
830 CORBA_exception_set (
831 ev, CORBA_USER_EXCEPTION,
832 "IDL:omg.org/CORBA/TypeCode/Bounds/1.0", NULL);
833 return NULL;
834 }
835
836 return ORBit_RootObject_duplicate (typecode->subtypes [index]);
837 }
838
839 CORBA_any *
CORBA_TypeCode_member_label(CORBA_TypeCode typecode,const CORBA_unsigned_long index,CORBA_Environment * ev)840 CORBA_TypeCode_member_label (CORBA_TypeCode typecode,
841 const CORBA_unsigned_long index,
842 CORBA_Environment *ev)
843 {
844 CORBA_any *retval;
845
846 if (typecode->kind != CORBA_tk_union) {
847 CORBA_exception_set (
848 ev, CORBA_USER_EXCEPTION,
849 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
850 return NULL;
851 }
852
853 if (index > typecode->sub_parts) {
854 CORBA_exception_set (
855 ev, CORBA_USER_EXCEPTION,
856 "IDL:omg.org/CORBA/TypeCode/Bounds/1.0", NULL);
857 return NULL;
858 }
859
860 retval = CORBA_any__alloc ();
861
862 retval->_type = ORBit_RootObject_duplicate (typecode->discriminator);
863 retval->_value = ORBit_copy_value (&typecode->sublabels [index],
864 typecode->discriminator);
865 retval->_release = CORBA_TRUE;
866
867 return retval;
868 }
869
870 CORBA_TypeCode
CORBA_TypeCode_discriminator_type(CORBA_TypeCode typecode,CORBA_Environment * ev)871 CORBA_TypeCode_discriminator_type (CORBA_TypeCode typecode,
872 CORBA_Environment *ev)
873 {
874 if (typecode->kind != CORBA_tk_union) {
875 CORBA_exception_set (
876 ev, CORBA_USER_EXCEPTION,
877 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
878 return NULL;
879 }
880
881 return ORBit_RootObject_duplicate (typecode->discriminator);
882 }
883
884 CORBA_long
CORBA_TypeCode_default_index(CORBA_TypeCode typecode,CORBA_Environment * ev)885 CORBA_TypeCode_default_index (CORBA_TypeCode typecode,
886 CORBA_Environment *ev)
887 {
888 if (typecode->kind != CORBA_tk_union) {
889 CORBA_exception_set (
890 ev, CORBA_USER_EXCEPTION,
891 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
892 return 0;
893 }
894
895 return typecode->default_index;
896 }
897
898 CORBA_unsigned_long
CORBA_TypeCode_length(CORBA_TypeCode typecode,CORBA_Environment * ev)899 CORBA_TypeCode_length (CORBA_TypeCode typecode,
900 CORBA_Environment *ev)
901 {
902 if (!(typecode->kind == CORBA_tk_string ||
903 typecode->kind == CORBA_tk_wstring ||
904 typecode->kind == CORBA_tk_sequence ||
905 typecode->kind == CORBA_tk_array)) {
906 CORBA_exception_set (
907 ev, CORBA_USER_EXCEPTION,
908 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
909 return 0;
910 }
911
912 return typecode->length;
913 }
914
915 CORBA_TypeCode
CORBA_TypeCode_content_type(CORBA_TypeCode typecode,CORBA_Environment * ev)916 CORBA_TypeCode_content_type (CORBA_TypeCode typecode,
917 CORBA_Environment *ev)
918 {
919 if (!(typecode->kind == CORBA_tk_sequence ||
920 typecode->kind == CORBA_tk_array ||
921 typecode->kind == CORBA_tk_value_box ||
922 typecode->kind == CORBA_tk_alias)) {
923 CORBA_exception_set (
924 ev, CORBA_USER_EXCEPTION,
925 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
926 return NULL;
927 }
928
929 g_assert (typecode->sub_parts == 1);
930
931 return ORBit_RootObject_duplicate (typecode->subtypes [0]);
932 }
933
934 CORBA_unsigned_short
CORBA_TypeCode_fixed_digits(CORBA_TypeCode typecode,CORBA_Environment * ev)935 CORBA_TypeCode_fixed_digits (CORBA_TypeCode typecode,
936 CORBA_Environment *ev)
937 {
938 if (typecode->kind != CORBA_tk_fixed) {
939 CORBA_exception_set (
940 ev, CORBA_USER_EXCEPTION,
941 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
942 return 0;
943 }
944
945 return typecode->digits;
946 }
947
948 CORBA_short
CORBA_TypeCode_fixed_scale(CORBA_TypeCode typecode,CORBA_Environment * ev)949 CORBA_TypeCode_fixed_scale (CORBA_TypeCode typecode,
950 CORBA_Environment *ev)
951 {
952 if (typecode->kind != CORBA_tk_fixed) {
953 CORBA_exception_set (
954 ev, CORBA_USER_EXCEPTION,
955 "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", NULL);
956 return 0;
957 }
958
959 return typecode->scale;
960 }
961
962 CORBA_Visibility
CORBA_TypeCode_member_visibility(CORBA_TypeCode typecode,const CORBA_unsigned_long index,CORBA_Environment * ev)963 CORBA_TypeCode_member_visibility (CORBA_TypeCode typecode,
964 const CORBA_unsigned_long index,
965 CORBA_Environment *ev)
966 {
967 /* FIXME: implement */
968 CORBA_exception_set_system (
969 ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
970
971 return 0;
972 }
973
974 CORBA_ValueModifier
CORBA_TypeCode_type_modifier(CORBA_TypeCode typecode,CORBA_Environment * ev)975 CORBA_TypeCode_type_modifier (CORBA_TypeCode typecode,
976 CORBA_Environment *ev)
977 {
978 /* FIXME: implement */
979 CORBA_exception_set_system (
980 ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
981
982 return 0;
983 }
984
985 CORBA_TypeCode
CORBA_TypeCode_concrete_base_type(CORBA_TypeCode typecode,CORBA_Environment * ev)986 CORBA_TypeCode_concrete_base_type (CORBA_TypeCode typecode,
987 CORBA_Environment *ev)
988 {
989 /* FIXME: implement */
990 CORBA_exception_set_system (
991 ev, ex_CORBA_NO_IMPLEMENT, CORBA_COMPLETED_NO);
992
993 return CORBA_OBJECT_NIL;
994 }
995
996 const char *
ORBit_tk_to_name(CORBA_unsigned_long tk)997 ORBit_tk_to_name (CORBA_unsigned_long tk)
998 {
999 #define CSE(a, b) \
1000 case CORBA_tk_ ## a: return b;
1001
1002 switch (tk) {
1003 CSE (null, "null");
1004 CSE (void, "void");
1005 CSE (short, "short");
1006 CSE (long, "long");
1007 CSE (ushort, "ushort");
1008 CSE (ulong, "ulong");
1009 CSE (float, "float");
1010 CSE (double, "double");
1011 CSE (boolean, "boolean");
1012 CSE (char, "char");
1013 CSE (octet, "octet");
1014 CSE (any, "any");
1015 CSE (TypeCode, "TypeCode");
1016 CSE (Principal, "Principal");
1017 CSE (objref, "objref");
1018 CSE (struct, "struct");
1019 CSE (union, "union");
1020 CSE (enum, "enum");
1021 CSE (string, "string");
1022 CSE (sequence, "sequence");
1023 CSE (array, "array");
1024 CSE (alias, "alias");
1025 CSE (except, "except");
1026 CSE (longlong, "longlong");
1027 CSE (ulonglong, "ulonglong");
1028 CSE (longdouble, "longdouble");
1029 CSE (wchar, "wchar");
1030 CSE (wstring, "wstring");
1031 CSE (fixed, "fixed");
1032 CSE (value, "value");
1033 CSE (value_box, "value_box");
1034 CSE (native, "native");
1035 CSE (abstract_interface, "abstract_interface");
1036 default:
1037 return "Invalid type";
1038 }
1039 }
1040
1041 static const TkInfo tk_info[CORBA_tk_last]= {
1042 { TK_EMPTY, NULL, NULL, TC_null }, /* tk_null */
1043 { TK_EMPTY, NULL, NULL, TC_void }, /* tk_void */
1044 { TK_EMPTY, NULL, NULL, TC_CORBA_short }, /* tk_short */
1045 { TK_EMPTY, NULL, NULL, TC_CORBA_long }, /* tk_long */
1046 { TK_EMPTY, NULL, NULL, TC_CORBA_unsigned_short }, /* tk_ushort */
1047 { TK_EMPTY, NULL, NULL, TC_CORBA_unsigned_long }, /* tk_ulong */
1048 { TK_EMPTY, NULL, NULL, TC_CORBA_float }, /* tk_float */
1049 { TK_EMPTY, NULL, NULL, TC_CORBA_double }, /* tk_double */
1050 { TK_EMPTY, NULL, NULL, TC_CORBA_boolean }, /* tk_boolean */
1051 { TK_EMPTY, NULL, NULL, TC_CORBA_char }, /* tk_char */
1052 { TK_EMPTY, NULL, NULL, TC_CORBA_octet }, /* tk_octet */
1053 { TK_EMPTY, NULL, NULL, TC_CORBA_any }, /* tk_any */
1054 { TK_EMPTY, NULL, NULL, TC_CORBA_TypeCode }, /* tk_TypeCode */
1055 { TK_EMPTY, NULL, NULL, TC_CORBA_Principal }, /* tk_Principal */
1056 { TK_COMPLEX, tc_enc_tk_objref, tc_dec_tk_objref }, /* tk_objref */
1057 { TK_COMPLEX, tc_enc_tk_struct, tc_dec_tk_struct }, /* tk_struct */
1058 { TK_COMPLEX, tc_enc_tk_union, tc_dec_tk_union }, /* tk_union */
1059 { TK_COMPLEX, tc_enc_tk_enum, tc_dec_tk_enum }, /* tk_enum */
1060 { TK_SIMPLE, tc_enc_tk_string, tc_dec_tk_string }, /* tk_string */
1061 { TK_COMPLEX, tc_enc_tk_sequence, tc_dec_tk_sequence }, /* tk_sequence */
1062 { TK_COMPLEX, tc_enc_tk_array, tc_dec_tk_array }, /* tk_array */
1063 { TK_COMPLEX, tc_enc_tk_alias, tc_dec_tk_alias }, /* tk_alias */
1064 { TK_COMPLEX, tc_enc_tk_except, tc_dec_tk_except }, /* tk_except */
1065 { TK_EMPTY, NULL, NULL, TC_CORBA_long_long}, /* tk_longlong */
1066 { TK_EMPTY, NULL, NULL, TC_CORBA_unsigned_long_long }, /* tk_ulonglong */
1067 { TK_EMPTY, NULL, NULL, TC_CORBA_long_double }, /* tk_longdouble */
1068 { TK_EMPTY, NULL, NULL, TC_CORBA_wchar }, /* tk_wchar */
1069 { TK_SIMPLE, tc_enc_tk_wstring, tc_dec_tk_wstring}, /* tk_wstring */
1070 { TK_SIMPLE, tc_enc_tk_fixed, tc_dec_tk_fixed} /* tk_fixed */
1071 };
1072
1073 ORBIT2_MAYBE_CONST ORBit_RootObject_Interface ORBit_TypeCode_epv = {
1074 ORBIT_ROT_TYPECODE,
1075 ORBit_TypeCode_free_fn
1076 };
1077
1078 static gboolean
tc_dec(CORBA_TypeCode * t,GIOPRecvBuffer * c,TCDecodeContext * ctx)1079 tc_dec (CORBA_TypeCode *t,
1080 GIOPRecvBuffer *c,
1081 TCDecodeContext *ctx)
1082 {
1083 guint tmp_index;
1084 const TkInfo *info;
1085 CORBA_TCKind kind;
1086 GIOPRecvBuffer *encaps;
1087 TCRecursionNode *node;
1088 CORBA_unsigned_long lkind;
1089
1090 if (CDR_get_ulong (c, &lkind))
1091 return TRUE;
1092
1093 kind = lkind;
1094
1095 if (lkind >= CORBA_tk_last) {
1096 CORBA_long offset;
1097 GSList *l;
1098
1099 if (lkind != CORBA_tk_recursive) {
1100 g_warning ("%s: invalid CORBA_TCKind, lkind=%lu",
1101 G_STRFUNC, (unsigned long int) lkind);
1102 return TRUE;
1103 }
1104
1105 if (CDR_get_ulong (c, &offset))
1106 return TRUE;
1107
1108 for (l = ctx->prior_tcs; l; l = l->next) {
1109 node = l->data;
1110 if (offset == node->index - ctx->current_idx - get_rptr (c)) {
1111 *t = ORBit_RootObject_duplicate (node->tc);
1112 return FALSE;
1113 }
1114 /* else
1115 g_warning ("back tc mismactch '%d' == '%d - %d - %d' = '%d' Tk %d",
1116 offset, node->index, ctx->current_idx, get_rptr (c),
1117 node->index - ctx->current_idx - get_rptr (c),
1118 node->tc->kind);*/
1119 }
1120
1121 /* FIXME: we should handle this slightly gracefully */
1122 g_error ("tc_dec: Invalid CORBA_TypeCode recursion "
1123 "offset in input buffer\n");
1124 g_assert_not_reached ();
1125 }
1126
1127 g_assert (kind < CORBA_tk_last);
1128
1129 node = g_new (TCRecursionNode, 1);
1130 node->index = ctx->current_idx + get_rptr(c) - 4; /* -4 for the TCKind */
1131 info = &tk_info [kind];
1132
1133 if (info->type == TK_EMPTY)
1134 node->tc = info->basic_type;
1135
1136 else {
1137 CORBA_TypeCode tc;
1138
1139 tc = g_new0 (struct CORBA_TypeCode_struct, 1);
1140
1141 ORBit_RootObject_init (&tc->parent, &ORBit_TypeCode_epv);
1142 ORBit_RootObject_duplicate (tc);
1143
1144 tc->kind = kind;
1145
1146 switch (info->type) {
1147
1148 case TK_EMPTY:
1149 g_assert_not_reached ();
1150 break;
1151
1152 case TK_COMPLEX:
1153 tmp_index = ctx->current_idx;
1154 ctx->current_idx += get_rptr (c) + 4;
1155 /* NB. the encaps buffer is for data validation */
1156 encaps = giop_recv_buffer_use_encaps_buf (c);
1157 info->decoder (tc, encaps, ctx);
1158 ctx->current_idx = tmp_index;
1159 giop_recv_buffer_unuse (encaps);
1160 break;
1161
1162 case TK_SIMPLE:
1163 info->decoder (tc, c, ctx);
1164 break;
1165 }
1166
1167 tc->c_align = ORBit_TC_find_c_alignment (tc);
1168 node->tc = tc;
1169 }
1170
1171 *t = node->tc;
1172 ctx->prior_tcs = g_slist_prepend (ctx->prior_tcs, node);
1173
1174 return FALSE;
1175 }
1176
1177 gboolean
ORBit_decode_CORBA_TypeCode(CORBA_TypeCode * tc,GIOPRecvBuffer * buf)1178 ORBit_decode_CORBA_TypeCode (CORBA_TypeCode *tc,
1179 GIOPRecvBuffer *buf)
1180 {
1181 GSList *l;
1182 gboolean retval;
1183 TCDecodeContext ctx;
1184
1185 ctx.current_idx = 0;
1186 ctx.prior_tcs = NULL;
1187
1188 retval = tc_dec (tc, buf, &ctx);
1189
1190 for (l = ctx.prior_tcs; l; l = l->next)
1191 g_free (l->data);
1192
1193 g_slist_free (ctx.prior_tcs);
1194
1195 return retval;
1196 }
1197
1198 /* Encode a typecode to a codec, possibly recursively */
1199 static void
tc_enc(CORBA_TypeCode tc,GIOPSendBuffer * buf,TCEncodeContext * ctx)1200 tc_enc (CORBA_TypeCode tc, GIOPSendBuffer *buf, TCEncodeContext *ctx)
1201 {
1202 TCRecursionNode *node;
1203 const TkInfo *info;
1204 GSList *l;
1205 CORBA_unsigned_long len, tmp;
1206 guchar *marker;
1207 gint8 endianness;
1208
1209 g_assert (CLAMP (0, tc->kind, CORBA_tk_last) == tc->kind);
1210
1211 giop_send_buffer_align (buf, 4);
1212
1213 info = &tk_info [tc->kind];
1214
1215 /* For base types it is better to marshal just the tc->kind */
1216 if (info->type != TK_EMPTY) {
1217
1218 for (l = ctx->prior_tcs; l; l = l->next) {
1219 node = l->data;
1220
1221 if (node->tc == tc) {
1222 tmp = CORBA_tk_recursive;
1223 giop_send_buffer_append_aligned (buf, &tmp, 4);
1224 len = node->index - buf->msg.header.message_size - 4;
1225 giop_send_buffer_append_aligned (buf, &len, 4);
1226 return;
1227 }
1228 }
1229
1230 /* only keep track of larger, more complex typecodes */
1231 node = g_new (TCRecursionNode, 1);
1232 node->tc = tc;
1233 node->index = buf->msg.header.message_size;
1234 ctx->prior_tcs = g_slist_prepend (ctx->prior_tcs, node);
1235 }
1236
1237 giop_send_buffer_append (buf, &tc->kind, sizeof (tc->kind));
1238
1239 switch (info->type) {
1240 case TK_EMPTY:
1241 break;
1242 case TK_COMPLEX:
1243 marker = giop_send_buffer_append_aligned (buf, NULL, 4);
1244
1245 tmp = buf->msg.header.message_size;
1246 endianness = GIOP_FLAG_ENDIANNESS;
1247
1248 giop_send_buffer_append (buf, &endianness, 1);
1249
1250 info->encoder (tc, buf, ctx);
1251
1252 len = buf->msg.header.message_size - tmp;
1253
1254 memcpy (marker, &len, 4);
1255 break;
1256 case TK_SIMPLE:
1257 info->encoder (tc, buf, ctx);
1258 break;
1259 }
1260 }
1261
1262 void
ORBit_encode_CORBA_TypeCode(CORBA_TypeCode tc,GIOPSendBuffer * buf)1263 ORBit_encode_CORBA_TypeCode (CORBA_TypeCode tc,
1264 GIOPSendBuffer *buf)
1265 {
1266 GSList *l;
1267 TCEncodeContext ctx;
1268
1269 ctx.start_idx = buf->msg.header.message_size;
1270 ctx.prior_tcs = NULL;
1271
1272 tc_enc (tc, buf, &ctx);
1273
1274 for (l = ctx.prior_tcs; l; l = l->next)
1275 g_free (l->data);
1276
1277 g_slist_free (ctx.prior_tcs);
1278 }
1279