1 #include "config.h"
2 #include <orbit/orbit.h>
3 #include "orb-core-private.h"
4 #include <string.h>
5
6 #define PTR_PLUS(ptr, offset) \
7 ((gpointer) (((guchar *)(ptr)) + (offset)))
8 #define CONST_PTR_PLUS(ptr, offset) \
9 ((gconstpointer) (((const guchar *)(ptr)) + (offset)))
10
11 /** Adds the size of TYPE to the gpointer PTR. */
12 #define ADDSIZE(ptr, type) \
13 ((gpointer) (((guchar *)(ptr)) + sizeof (type)))
14
15 #define SKIP_ALIAS(tc) \
16 while ((tc)->kind == CORBA_tk_alias) { (tc) = (tc)->subtypes [0]; }
17
18 static void
giop_byteswap(guchar * outdata,const guchar * data,gulong datalen)19 giop_byteswap (guchar *outdata,
20 const guchar *data,
21 gulong datalen)
22 {
23 const guchar *source_ptr = data;
24 guchar *dest_ptr = (guchar *) outdata + datalen - 1;
25
26 while (dest_ptr >= outdata)
27 *dest_ptr-- = *source_ptr++;
28 }
29
30 size_t
ORBit_gather_alloc_info(CORBA_TypeCode tc)31 ORBit_gather_alloc_info (CORBA_TypeCode tc)
32 {
33 SKIP_ALIAS (tc);
34
35 switch (tc->kind) {
36 case CORBA_tk_long:
37 case CORBA_tk_ulong:
38 case CORBA_tk_enum:
39 return sizeof (CORBA_long);
40 case CORBA_tk_short:
41 case CORBA_tk_ushort:
42 return sizeof (CORBA_short);
43 case CORBA_tk_float:
44 return sizeof (CORBA_float);
45 case CORBA_tk_double:
46 return sizeof (CORBA_double);
47 case CORBA_tk_boolean:
48 case CORBA_tk_char:
49 case CORBA_tk_octet:
50 return sizeof (CORBA_octet);
51 case CORBA_tk_any:
52 return sizeof (CORBA_any);
53 case CORBA_tk_TypeCode:
54 return sizeof (CORBA_TypeCode);
55 case CORBA_tk_Principal:
56 return sizeof (CORBA_Principal);
57 case CORBA_tk_objref:
58 return sizeof (CORBA_Object);
59 case CORBA_tk_except:
60 case CORBA_tk_struct: {
61 int i, sum;
62
63 for (sum = i = 0; i < tc->sub_parts; i++) {
64 sum = ALIGN_VALUE (sum, tc->subtypes[i]->c_align);
65 sum += ORBit_gather_alloc_info (tc->subtypes[i]);
66 }
67 sum = ALIGN_VALUE (sum, tc->c_align);
68
69 return sum;
70 }
71 case CORBA_tk_union: {
72 int i, n, align, prevalign, prev, sum;
73 sum = ORBit_gather_alloc_info (tc->discriminator);
74 n = -1;
75 align = 1;
76 for (prev = prevalign = i = 0; i < tc->sub_parts; i++) {
77 prevalign = align;
78 align = tc->subtypes[i]->c_align;
79 if (align > prevalign)
80 n = i;
81
82 prev = MAX (prev, ORBit_gather_alloc_info (tc->subtypes[i]));
83 }
84 if (n >= 0)
85 sum = ALIGN_VALUE (sum, tc->subtypes[n]->c_align);
86 sum += prev;
87 sum = ALIGN_VALUE (sum, tc->c_align);
88 return sum;
89 }
90 case CORBA_tk_wstring:
91 case CORBA_tk_string:
92 return sizeof (char *);
93 case CORBA_tk_sequence:
94 return sizeof (CORBA_sequence_CORBA_octet);
95 case CORBA_tk_array:
96 return ORBit_gather_alloc_info (tc->subtypes[0]) * tc->length;
97 case CORBA_tk_longlong:
98 case CORBA_tk_ulonglong:
99 return sizeof (CORBA_long_long);
100 case CORBA_tk_longdouble:
101 return sizeof (CORBA_long_double);
102 case CORBA_tk_wchar:
103 return sizeof (CORBA_wchar);
104 case CORBA_tk_fixed:
105 return sizeof (CORBA_fixed_d_s);
106 case CORBA_tk_void:
107 case CORBA_tk_null:
108 default:
109 return 0;
110 }
111 }
112
113 /*
114 * ORBit_marshal_value:
115 * @buf: the send buffer.
116 * @val: a pointer to the location of the value.
117 * @tc: the TypeCode indicating the type of the value.
118 *
119 * Marshals the value onto the buffer and changes @val to point
120 * to the location after the value.
121 */
122 void
ORBit_marshal_value(GIOPSendBuffer * buf,gconstpointer * val,CORBA_TypeCode tc)123 ORBit_marshal_value (GIOPSendBuffer *buf,
124 gconstpointer *val,
125 CORBA_TypeCode tc)
126 {
127 CORBA_unsigned_long i, ulval;
128 gconstpointer subval;
129
130 SKIP_ALIAS (tc);
131
132 switch (tc->kind) {
133 case CORBA_tk_wchar:
134 case CORBA_tk_ushort:
135 case CORBA_tk_short:
136 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_short));
137 *val = ((guchar *)*val) + sizeof (CORBA_short);
138 break;
139 case CORBA_tk_enum:
140 case CORBA_tk_long:
141 case CORBA_tk_ulong:
142 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_long));
143 *val = ((guchar *)*val) + sizeof (CORBA_long);
144 break;
145 case CORBA_tk_float:
146 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_float));
147 *val = ((guchar *)*val) + sizeof (CORBA_float);
148 break;
149 case CORBA_tk_double:
150 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_double));
151 *val = ((guchar *)*val) + sizeof (CORBA_double);
152 break;
153 case CORBA_tk_boolean:
154 case CORBA_tk_char:
155 case CORBA_tk_octet:
156 giop_send_buffer_append (buf, *val, sizeof (CORBA_octet));
157 *val = ((guchar *)*val) + sizeof (CORBA_octet);
158 break;
159 case CORBA_tk_any:
160 ORBit_marshal_any (buf, *val);
161 *val = ((guchar *)*val) + sizeof (CORBA_any);
162 break;
163 case CORBA_tk_Principal:
164 ulval = *(CORBA_unsigned_long *) (*val);
165 giop_send_buffer_append (buf, *val, sizeof (CORBA_unsigned_long));
166
167 giop_send_buffer_append (buf,
168 *(char **) ((char *)*val + sizeof (CORBA_unsigned_long)),
169 ulval);
170 *val = ((guchar *)*val) + sizeof (CORBA_Principal);
171 break;
172 case CORBA_tk_objref:
173 ORBit_marshal_object (buf, *(CORBA_Object *)*val);
174 *val = ((guchar *)*val) + sizeof (CORBA_Object);
175 break;
176 case CORBA_tk_TypeCode:
177 ORBit_encode_CORBA_TypeCode (*(CORBA_TypeCode *)*val, buf);
178 *val = ((guchar *)*val) + sizeof (CORBA_TypeCode);
179 break;
180 case CORBA_tk_except:
181 case CORBA_tk_struct: {
182 gconstpointer val0 = *val;
183 int offset;
184 for (i = offset = 0; i < tc->sub_parts; i++) {
185 offset = ALIGN_VALUE (offset, tc->subtypes[i]->c_align);
186 *val = PTR_PLUS (val0, offset);
187 ORBit_marshal_value (buf, val, tc->subtypes[i]);
188 offset += ORBit_gather_alloc_info (tc->subtypes[i]);
189 }
190 offset = ALIGN_VALUE (offset, tc->c_align);
191 *val = PTR_PLUS (val0, offset);
192 break;
193 }
194 case CORBA_tk_union: {
195 gconstpointer val0 = *val;
196 gconstpointer discrim, body;
197 CORBA_TypeCode subtc;
198 int sz = 0;
199
200 discrim = *val;
201 ORBit_marshal_value (buf, val, tc->discriminator);
202
203 subtc = ORBit_get_union_tag (tc, &discrim, FALSE);
204 for (i = 0; i < tc->sub_parts; i++)
205 sz = MAX (sz, ORBit_gather_alloc_info (tc->subtypes[i]));
206
207 *val = PTR_PLUS (val0, ALIGN_VALUE (ORBit_gather_alloc_info (tc->discriminator),
208 tc->c_align));
209 body = *val;
210 ORBit_marshal_value (buf, &body, subtc);
211 /* FIXME:
212 * WATCHOUT: end of subtc may not be end of union
213 */
214 *val = PTR_PLUS (*val, ALIGN_VALUE (sz, tc->c_align));
215 break;
216 }
217 case CORBA_tk_wstring: {
218 CORBA_wchar endian_marker = 0xfeff;
219
220 ulval = (CORBA_wstring_len (*(CORBA_wchar **)*val) + 1) * 2;
221 giop_send_buffer_append_aligned (buf, &ulval,
222 sizeof (CORBA_unsigned_long));
223 giop_send_buffer_append (buf, &endian_marker, 2);
224 giop_send_buffer_append (buf, *(CORBA_wchar **)*val, ulval - 2);
225 *val = ((guchar *)*val) + sizeof (CORBA_wchar *);
226 break;
227 }
228 case CORBA_tk_string:
229 giop_send_buffer_append_string (buf, *(char **)*val);
230 *val = ((guchar *)*val) + sizeof (char *);
231 break;
232 case CORBA_tk_sequence: {
233 const CORBA_sequence_CORBA_octet *sval;
234 sval = *val;
235 giop_send_buffer_align (buf, sizeof (CORBA_unsigned_long));
236 giop_send_buffer_append (buf, &sval->_length,
237 sizeof (CORBA_unsigned_long));
238
239 subval = sval->_buffer;
240
241 switch (tc->subtypes[0]->kind) {
242 case CORBA_tk_boolean:
243 case CORBA_tk_char:
244 case CORBA_tk_octet:
245 giop_send_buffer_append (buf, subval, sval->_length);
246 break;
247 default:
248 for (i = 0; i < sval->_length; i++)
249 ORBit_marshal_value (buf, &subval, tc->subtypes[0]);
250 break;
251 }
252 *val = ((guchar *)*val) + sizeof (CORBA_sequence_CORBA_octet);
253 break;
254 }
255 case CORBA_tk_array:
256 switch (tc->subtypes[0]->kind) {
257 case CORBA_tk_boolean:
258 case CORBA_tk_char:
259 case CORBA_tk_octet:
260 giop_send_buffer_append (buf, *val, tc->length);
261 *val = ((guchar *)*val) + tc->length;
262 break;
263 default:
264 for (i = 0; i < tc->length; i++)
265 ORBit_marshal_value (buf, val, tc->subtypes[0]);
266 break;
267 }
268 break;
269 case CORBA_tk_longlong:
270 case CORBA_tk_ulonglong:
271 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_long_long));
272 *val = ((guchar *)*val) + sizeof (CORBA_long_long);
273 break;
274 case CORBA_tk_longdouble:
275 giop_send_buffer_append_aligned (buf, *val, sizeof (CORBA_long_double));
276 *val = ((guchar *)*val) + sizeof (CORBA_long_double);
277 break;
278 case CORBA_tk_fixed:
279 /* XXX todo */
280 g_error ("CORBA_fixed NYI");
281 break;
282 case CORBA_tk_null:
283 case CORBA_tk_void:
284 break;
285 default:
286 g_error ("Can't encode unknown type %d", tc->kind);
287 break;
288 }
289 }
290
291 static glong
ORBit_get_union_switch(CORBA_TypeCode tc,gconstpointer * val,gboolean update)292 ORBit_get_union_switch (CORBA_TypeCode tc,
293 gconstpointer *val,
294 gboolean update)
295 {
296 glong retval = 0; /* Quiet gcc */
297
298 SKIP_ALIAS (tc);
299
300 switch (tc->kind) {
301 case CORBA_tk_ulong:
302 case CORBA_tk_long:
303 case CORBA_tk_enum: {
304 CORBA_long tmp;
305
306 memcpy (&tmp, *val, sizeof (CORBA_long));
307 retval = (glong) tmp;
308
309 if (update)
310 *val = ((guchar *)*val) + sizeof (CORBA_long);
311 break;
312 }
313 case CORBA_tk_ushort:
314 case CORBA_tk_short: {
315 CORBA_short tmp;
316
317 memcpy (&tmp, *val, sizeof (CORBA_short));
318 retval = (glong) tmp;
319
320 if (update)
321 *val = ((guchar *)*val) + sizeof (CORBA_short);
322 break;
323 }
324 case CORBA_tk_char:
325 case CORBA_tk_boolean:
326 case CORBA_tk_octet:
327 retval = *(CORBA_octet *)*val;
328 if (update)
329 *val = ((guchar *)*val) + sizeof (CORBA_char);
330 break;
331 default:
332 g_error ("Wow, some nut has passed us a weird "
333 "type[%d] as a union discriminator!", tc->kind);
334 }
335
336 return retval;
337 }
338
339 /* This function (and the one above it) exist for the
340 sole purpose of finding out which CORBA_TypeCode a union discriminator value
341 indicates.
342
343 If {update} is TRUE, {*val} will be advanced by the native size
344 of the descriminator type.
345
346 Hairy stuff.
347 */
348 CORBA_TypeCode
ORBit_get_union_tag(CORBA_TypeCode union_tc,gconstpointer * val,gboolean update)349 ORBit_get_union_tag (CORBA_TypeCode union_tc,
350 gconstpointer *val,
351 gboolean update)
352 {
353 CORBA_TypeCode retval = CORBA_OBJECT_NIL;
354 glong discrim_val;
355 int i;
356
357 discrim_val = ORBit_get_union_switch (
358 union_tc->discriminator, val, update);
359
360 for (i = 0; i < union_tc->sub_parts; i++) {
361 if (i == union_tc->default_index)
362 continue;
363
364 if (union_tc->sublabels [i] == discrim_val) {
365 retval = union_tc->subtypes[i];
366 break;
367 }
368 }
369
370 if (retval)
371 return retval;
372
373 else if (union_tc->default_index >= 0)
374 return union_tc->subtypes[union_tc->default_index];
375
376 else
377 return TC_null;
378 }
379
380 void
ORBit_marshal_arg(GIOPSendBuffer * buf,gconstpointer val,CORBA_TypeCode tc)381 ORBit_marshal_arg (GIOPSendBuffer *buf,
382 gconstpointer val,
383 CORBA_TypeCode tc)
384 {
385 ORBit_marshal_value (buf, &val, tc);
386 }
387
388 void
ORBit_marshal_any(GIOPSendBuffer * buf,const CORBA_any * val)389 ORBit_marshal_any (GIOPSendBuffer *buf, const CORBA_any *val)
390 {
391 gconstpointer mval = val->_value;
392
393 ORBit_encode_CORBA_TypeCode (val->_type, buf);
394
395 ORBit_marshal_value (buf, &mval, val->_type);
396 }
397
398 /* FIXME: we need two versions of this - one for swap
399 * endianness, and 1 for not */
400 gboolean
ORBit_demarshal_value(CORBA_TypeCode tc,gpointer * val,GIOPRecvBuffer * buf,CORBA_ORB orb)401 ORBit_demarshal_value (CORBA_TypeCode tc,
402 gpointer *val,
403 GIOPRecvBuffer *buf,
404 CORBA_ORB orb)
405 {
406 CORBA_long i;
407
408 SKIP_ALIAS (tc);
409
410 switch (tc->kind) {
411 case CORBA_tk_short:
412 case CORBA_tk_ushort:
413 case CORBA_tk_wchar: {
414 CORBA_unsigned_short *ptr;
415 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_short));
416 if ((buf->cur + sizeof (CORBA_short)) > buf->end)
417 return TRUE;
418 ptr = *val;
419 *ptr = *(CORBA_unsigned_short *)buf->cur;
420 if (giop_msg_conversion_needed (buf))
421 *ptr = GUINT16_SWAP_LE_BE (*ptr);
422 buf->cur += sizeof (CORBA_short);
423 *val = ((guchar *)*val) + sizeof (CORBA_short);
424 break;
425 }
426 case CORBA_tk_long:
427 case CORBA_tk_ulong:
428 case CORBA_tk_enum: {
429 CORBA_unsigned_long *ptr;
430 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long));
431 if ((buf->cur + sizeof (CORBA_long)) > buf->end)
432 return TRUE;
433 ptr = *val;
434 *ptr = *(CORBA_unsigned_long *)buf->cur;
435 if (giop_msg_conversion_needed (buf))
436 *ptr = GUINT32_SWAP_LE_BE (*ptr);
437 buf->cur += sizeof (CORBA_long);
438 *val = ((guchar *)*val) + sizeof (CORBA_long);
439 break;
440 }
441 case CORBA_tk_longlong:
442 case CORBA_tk_ulonglong: {
443 CORBA_unsigned_long_long *ptr;
444 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long_long));
445 if ((buf->cur + sizeof (CORBA_long_long)) > buf->end)
446 return TRUE;
447 ptr = *val;
448 *ptr = *(CORBA_unsigned_long_long *)buf->cur;
449 if (giop_msg_conversion_needed (buf))
450 *ptr = GUINT64_SWAP_LE_BE (*ptr);
451 buf->cur += sizeof (CORBA_long_long);
452 *val = ((guchar *)*val) + sizeof (CORBA_long_long);
453 break;
454 }
455 case CORBA_tk_longdouble: {
456 CORBA_long_double *ptr;
457 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long_double));
458 if ((buf->cur + sizeof (CORBA_long_double)) > buf->end)
459 return TRUE;
460 ptr = *val;
461 if (giop_msg_conversion_needed (buf))
462 giop_byteswap ((guchar *)ptr, buf->cur, sizeof (CORBA_long_double));
463 else
464 *ptr = *(CORBA_long_double *)buf->cur;
465 buf->cur += sizeof (CORBA_long_double);
466 *val = ((guchar *)*val) + sizeof (CORBA_long_double);
467 break;
468 }
469 case CORBA_tk_float: {
470 CORBA_float *ptr;
471 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_float));
472 if ((buf->cur + sizeof (CORBA_float)) > buf->end)
473 return TRUE;
474 ptr = *val;
475 if (giop_msg_conversion_needed (buf))
476 giop_byteswap ((guchar *)ptr, buf->cur, sizeof (CORBA_float));
477 else
478 *ptr = *(CORBA_float *)buf->cur;
479 buf->cur += sizeof (CORBA_float);
480
481 *val = ((guchar *)*val) + sizeof (CORBA_float);
482 break;
483 }
484 case CORBA_tk_double: {
485 CORBA_double *ptr;
486 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_double));
487 if ((buf->cur + sizeof (CORBA_double)) > buf->end)
488 return TRUE;
489 ptr = *val;
490 if (giop_msg_conversion_needed (buf))
491 giop_byteswap ((guchar *)ptr, buf->cur, sizeof (CORBA_double));
492 else
493 *ptr = *(CORBA_double *)buf->cur;
494 buf->cur += sizeof (CORBA_double);
495
496 *val = ((guchar *)*val) + sizeof (CORBA_double);
497 break;
498 }
499 case CORBA_tk_boolean:
500 case CORBA_tk_char:
501 case CORBA_tk_octet: {
502 CORBA_octet *ptr;
503 if ((buf->cur + sizeof (CORBA_octet)) > buf->end)
504 return TRUE;
505 ptr = *val;
506 *ptr = *buf->cur;
507 buf->cur++;
508
509 *val = ((guchar *)*val) + sizeof (CORBA_octet);
510 break;
511 }
512 case CORBA_tk_any: {
513 CORBA_any *decoded;
514
515 decoded = *val;
516 decoded->_release = CORBA_FALSE;
517 if (ORBit_demarshal_any (buf, decoded, orb))
518 return TRUE;
519 *val = ((guchar *)*val) + sizeof (CORBA_any);
520 break;
521 }
522 case CORBA_tk_Principal: {
523 CORBA_Principal *p;
524
525 p = *val;
526 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long));
527 p->_release = TRUE;
528 if ((buf->cur + sizeof (CORBA_unsigned_long)) > buf->end)
529 return TRUE;
530 if (giop_msg_conversion_needed (buf))
531 p->_length = GUINT32_SWAP_LE_BE (*(CORBA_unsigned_long *)buf->cur);
532 else
533 p->_length = *(CORBA_unsigned_long *)buf->cur;
534 buf->cur += sizeof (CORBA_unsigned_long);
535 if ((buf->cur + p->_length) > buf->end
536 || (buf->cur + p->_length) < buf->cur)
537 return TRUE;
538 p->_buffer = ORBit_alloc_simple (p->_length);
539 memcpy (p->_buffer, buf->cur, p->_length);
540 buf->cur += p->_length;
541 *val = ((guchar *)*val) + sizeof (CORBA_sequence_CORBA_octet);
542 break;
543 }
544 case CORBA_tk_objref:
545 if (ORBit_demarshal_object ((CORBA_Object *)*val, buf, orb))
546 return TRUE;
547 *val = ((guchar *)*val) + sizeof (CORBA_Object);
548 break;
549 case CORBA_tk_TypeCode:
550 if (ORBit_decode_CORBA_TypeCode (*val, buf))
551 return TRUE;
552 *val = ((guchar *)*val) + sizeof (CORBA_TypeCode);
553 break;
554 case CORBA_tk_except:
555 case CORBA_tk_struct: {
556 int offset;
557 gpointer val0 = *val;
558 for (i = offset = 0; i < tc->sub_parts; i++) {
559 offset = ALIGN_VALUE (offset, tc->subtypes[i]->c_align);
560 *val = PTR_PLUS (val0, offset);
561 if (ORBit_demarshal_value (tc->subtypes[i], val, buf, orb))
562 return TRUE;
563 offset += ORBit_gather_alloc_info (tc->subtypes[i]);
564 }
565 offset = ALIGN_VALUE (offset, tc->c_align);
566 *val = PTR_PLUS (val0, offset);
567 break;
568 }
569 case CORBA_tk_union: {
570 gpointer val0 = *val;
571 CORBA_TypeCode subtc;
572 gpointer discrim;
573 gpointer body;
574 int sz = 0;
575
576 discrim = *val;
577 if (ORBit_demarshal_value (tc->discriminator, val, buf, orb))
578 return TRUE;
579
580 subtc = ORBit_get_union_tag (tc, (gconstpointer*)&discrim, FALSE);
581 for (i = 0; i < tc->sub_parts; i++)
582 sz = MAX (sz, ORBit_gather_alloc_info (tc->subtypes[i]));
583
584 *val = PTR_PLUS (val0, ALIGN_VALUE (ORBit_gather_alloc_info (tc->discriminator),
585 tc->c_align));
586 body = *val;
587 if (ORBit_demarshal_value (subtc, &body, buf, orb))
588 return TRUE;
589
590 /* WATCHOUT: end subtc body may not be end of union */
591 *val = PTR_PLUS (*val, ALIGN_VALUE (sz, tc->c_align));
592 break;
593 }
594 case CORBA_tk_string:
595 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long));
596 if ((buf->cur + sizeof (CORBA_long)) > buf->end)
597 return TRUE;
598 i = *(CORBA_unsigned_long *)buf->cur;
599 if (giop_msg_conversion_needed (buf))
600 i = GUINT32_SWAP_LE_BE (i);
601 buf->cur += sizeof (CORBA_unsigned_long);
602 if ((buf->cur + i) > buf->end
603 || (buf->cur + i) < buf->cur)
604 return TRUE;
605 *(char **)*val = CORBA_string_dup ((char *)buf->cur);
606 *val = ((guchar *)*val) + sizeof (CORBA_char *);
607 buf->cur += i;
608 break;
609 case CORBA_tk_wstring: {
610 CORBA_wchar endian_marker = 0, *ptr;
611
612 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long));
613 if ((buf->cur + sizeof (CORBA_long)) > buf->end)
614 return TRUE;
615 i = *(CORBA_unsigned_long *)buf->cur;
616 if (giop_msg_conversion_needed (buf))
617 i = GUINT32_SWAP_LE_BE (i);
618 buf->cur += sizeof (CORBA_unsigned_long);
619 if ((buf->cur + i) > buf->end
620 || (buf->cur + i) < buf->cur)
621 return TRUE;
622 if (i >= 2) {
623 endian_marker = *(CORBA_wchar *)buf->cur;
624 if (endian_marker != 0xfeff &&
625 endian_marker != 0xfffe)
626 endian_marker = 0;
627 else {
628 i -= 2;
629 buf->cur += 2;
630 }
631 }
632 if (!endian_marker) {
633 ((unsigned char *)&endian_marker)[0] = 0xfe;
634 ((unsigned char *)&endian_marker)[1] = 0xff;
635 }
636 ptr = CORBA_wstring_alloc ((i + 1) / 2);
637 *(CORBA_wchar **)*val = ptr;
638 if (endian_marker == 0xfffe) {
639 while(i >= 2) {
640 *ptr++ = GUINT16_SWAP_LE_BE(
641 *((CORBA_wchar *)buf->cur));
642 buf->cur += 2;
643 i -= 2;
644 }
645 *ptr = 0;
646 } else {
647 memcpy(ptr, buf->cur, i);
648 ptr[(i + 1) / 2] = 0;
649 buf->cur += i;
650 i = 0;
651 }
652 *val = ((guchar *)*val) + sizeof (CORBA_wchar *);
653 buf->cur += i;
654 break;
655 }
656 case CORBA_tk_sequence: {
657 CORBA_sequence_CORBA_octet *p;
658 gpointer subval;
659
660 p = *val;
661 p->_release = TRUE;
662 buf->cur = ALIGN_ADDRESS (buf->cur, sizeof (CORBA_long));
663 if ((buf->cur + sizeof (CORBA_long)) > buf->end)
664 return TRUE;
665 if (giop_msg_conversion_needed (buf))
666 p->_length = GUINT32_SWAP_LE_BE (*(CORBA_unsigned_long *)buf->cur);
667 else
668 p->_length = *(CORBA_unsigned_long *)buf->cur;
669 buf->cur += sizeof (CORBA_long);
670
671 p->_maximum = p->_length;
672 if (p->_length == 0)
673 p->_buffer = NULL;
674
675 else if (tc->subtypes[0]->kind == CORBA_tk_octet ||
676 tc->subtypes[0]->kind == CORBA_tk_boolean ||
677 tc->subtypes[0]->kind == CORBA_tk_char) {
678 /* This special-casing could be taken further to apply to
679 all atoms... */
680 if ((buf->cur + p->_length) > buf->end ||
681 (buf->cur + p->_length) < buf->cur)
682 return TRUE;
683 p->_buffer = ORBit_alloc_simple (p->_length);
684 memcpy (p->_buffer, buf->cur, p->_length);
685 buf->cur = ((guchar *)buf->cur) + p->_length;
686 } else {
687 CORBA_unsigned_long alloc = 4096;
688
689 p->_buffer = ORBit_alloc_tcval (tc->subtypes[0],
690 MIN (p->_length, alloc));
691 subval = p->_buffer;
692
693 for (i = 0; i < p->_length; i++) {
694 if (i == alloc) {
695 size_t delta = (guchar *)subval - (guchar *)p->_buffer;
696
697 p->_buffer = ORBit_realloc_tcval (
698 p->_buffer, tc->subtypes [0],
699 alloc, MIN (alloc * 2, p->_length));
700 alloc = alloc * 2; /* exponential */
701 subval = p->_buffer + delta;
702 }
703
704 if (ORBit_demarshal_value (tc->subtypes[0], &subval,
705 buf, orb)) {
706 CORBA_free (p->_buffer);
707 p->_buffer = NULL;
708 p->_length = 0;
709 return TRUE;
710 }
711 }
712 }
713
714 *val = ((guchar *)*val) + sizeof (CORBA_sequence_CORBA_octet);
715 break;
716 }
717 case CORBA_tk_array:
718 for (i = 0; i < tc->length; i++)
719 if (ORBit_demarshal_value (tc->subtypes[0], val, buf, orb))
720 return TRUE;
721 break;
722 case CORBA_tk_void:
723 case CORBA_tk_null:
724 break;
725 case CORBA_tk_fixed:
726 default:
727 return TRUE;
728 break;
729 }
730
731 return FALSE;
732 }
733
734 gpointer
ORBit_demarshal_arg(GIOPRecvBuffer * buf,CORBA_TypeCode tc,CORBA_ORB orb)735 ORBit_demarshal_arg (GIOPRecvBuffer *buf,
736 CORBA_TypeCode tc,
737 CORBA_ORB orb)
738 {
739 gpointer retval, val;
740
741 retval = val = ORBit_alloc_by_tc (tc);
742
743 if (ORBit_demarshal_value (tc, &val, buf, orb))
744 {
745 CORBA_free (retval);
746 return NULL;
747 }
748
749 return retval;
750 }
751
752 gboolean
ORBit_demarshal_any(GIOPRecvBuffer * buf,CORBA_any * retval,CORBA_ORB orb)753 ORBit_demarshal_any (GIOPRecvBuffer *buf,
754 CORBA_any *retval,
755 CORBA_ORB orb)
756 {
757 gpointer val;
758
759 CORBA_any_set_release (retval, CORBA_TRUE);
760
761 if (ORBit_decode_CORBA_TypeCode (&retval->_type, buf))
762 return TRUE;
763
764 val = retval->_value = ORBit_alloc_by_tc (retval->_type);
765 if (ORBit_demarshal_value (retval->_type, &val, buf, orb))
766 return TRUE;
767
768 return FALSE;
769 }
770
771 gpointer
CORBA_any__freekids(gpointer mem,gpointer dat)772 CORBA_any__freekids (gpointer mem, gpointer dat)
773 {
774 CORBA_any *t;
775
776 t = mem;
777 if (t->_type)
778 ORBit_RootObject_release_T (
779 (ORBit_RootObject) t->_type);
780
781 if (t->_release)
782 ORBit_free_T (t->_value);
783
784 return t + 1;
785 }
786
787 CORBA_any *
CORBA_any__alloc(void)788 CORBA_any__alloc (void)
789 {
790 return ORBit_alloc_by_tc (TC_CORBA_any);
791 }
792
793 void
ORBit_copy_value_core(gconstpointer * val,gpointer * newval,CORBA_TypeCode tc)794 ORBit_copy_value_core (gconstpointer *val,
795 gpointer *newval,
796 CORBA_TypeCode tc)
797 {
798 CORBA_long i;
799 gconstpointer pval1;
800 gpointer pval2;
801
802 SKIP_ALIAS (tc);
803
804 switch (tc->kind) {
805 case CORBA_tk_wchar:
806 case CORBA_tk_short:
807 case CORBA_tk_ushort:
808 *(CORBA_short *)*newval = *(CORBA_short *)*val;
809 *val = ((guchar *)*val) + sizeof (CORBA_short);
810 *newval = ((guchar *)*newval) + sizeof (CORBA_short);
811 break;
812 case CORBA_tk_enum:
813 case CORBA_tk_long:
814 case CORBA_tk_ulong:
815 *(CORBA_long *)*newval = *(CORBA_long *)*val;
816 *val = ((guchar *)*val) + sizeof (CORBA_long);
817 *newval = ((guchar *)*newval) + sizeof (CORBA_long);
818 break;
819 case CORBA_tk_longlong:
820 case CORBA_tk_ulonglong:
821 *(CORBA_long_long *)*newval = *(CORBA_long_long *)*val;
822 *val = ((guchar *)*val) + sizeof (CORBA_long_long);
823 *newval = ((guchar *)*newval) + sizeof (CORBA_long_long);
824 break;
825 case CORBA_tk_longdouble:
826 *(CORBA_long_double *)*newval = *(CORBA_long_double *)*val;
827 *val = ((guchar *)*val) + sizeof (CORBA_long_double);
828 *newval = ((guchar *)*newval) + sizeof (CORBA_long_double);
829 break;
830 case CORBA_tk_float:
831 *(CORBA_long *)*newval = *(CORBA_long *)*val;
832 *val = ((guchar *)*val) + sizeof (CORBA_float);
833 *newval = ((guchar *)*newval) + sizeof (CORBA_float);
834 break;
835 case CORBA_tk_double:
836 *(CORBA_double *)*newval = *(CORBA_double *)*val;
837 *val = ((guchar *)*val) + sizeof (CORBA_double);
838 *newval = ((guchar *)*newval) + sizeof (CORBA_double);
839 break;
840 case CORBA_tk_boolean:
841 case CORBA_tk_char:
842 case CORBA_tk_octet:
843 *(CORBA_octet *)*newval = *(CORBA_octet *)*val;
844 *val = ((guchar *)*val) + sizeof (CORBA_octet);
845 *newval = ((guchar *)*newval) + sizeof (CORBA_octet);
846 break;
847 case CORBA_tk_any: {
848 const CORBA_any *oldany;
849 CORBA_any *newany;
850 oldany = *val;
851 newany = *newval;
852 newany->_type = ORBit_RootObject_duplicate (oldany->_type);
853 newany->_value = ORBit_copy_value (oldany->_value, oldany->_type);
854 newany->_release = CORBA_TRUE;
855 *val = ((guchar *)*val) + sizeof (CORBA_any);
856 *newval = ((guchar *)*newval) + sizeof (CORBA_any);
857 break;
858 }
859 case CORBA_tk_Principal:
860 *(CORBA_Principal *)*newval = *(CORBA_Principal *)*val;
861 ((CORBA_Principal *)*newval)->_buffer =
862 CORBA_sequence_CORBA_octet_allocbuf (((CORBA_Principal *)*newval)->_length);
863 ((CORBA_Principal *)*newval)->_release = CORBA_TRUE;
864 memcpy (((CORBA_Principal *)*newval)->_buffer,
865 ((CORBA_Principal *)*val)->_buffer,
866 ((CORBA_Principal *)*val)->_length);
867 *val = ((guchar *)*val) + sizeof (CORBA_Principal);
868 *newval = ((guchar *)*newval) + sizeof (CORBA_Principal);
869 break;
870 case CORBA_tk_TypeCode:
871 case CORBA_tk_objref:
872 *(CORBA_Object *)*newval = ORBit_RootObject_duplicate (*(CORBA_Object *)*val);
873 *val = ((guchar *)*val) + sizeof (CORBA_Object);
874 *newval = ((guchar *)*newval) + sizeof (CORBA_Object);
875 break;
876 case CORBA_tk_struct:
877 case CORBA_tk_except: {
878 int offset;
879 gconstpointer val0 = *val;
880 gpointer newval0 = *newval;
881
882 for (i = offset = 0; i < tc->sub_parts; i++) {
883 offset = ALIGN_VALUE (offset, tc->subtypes[i]->c_align);
884 *val = PTR_PLUS (val0, offset);
885 *newval = PTR_PLUS (newval0, offset);
886 ORBit_copy_value_core (val, newval, tc->subtypes[i]);
887 offset += ORBit_gather_alloc_info (tc->subtypes[i]);
888 }
889 offset = ALIGN_VALUE (offset, tc->c_align);
890 *val = PTR_PLUS (val0, offset);
891 *newval = PTR_PLUS (newval0, offset);
892 break;
893 }
894 case CORBA_tk_union: {
895 gconstpointer val0 = *val;
896 gpointer newval0 = *newval;
897 CORBA_TypeCode utc;
898 gint union_align = tc->c_align;
899 size_t union_size = ORBit_gather_alloc_info (tc);
900 size_t aligned_size;
901
902 pval1 = *val;
903 pval2 = *newval;
904
905 utc = ORBit_get_union_tag (tc, (gconstpointer *)val, FALSE);
906
907 ORBit_copy_value_core (&pval1, &pval2, tc->discriminator);
908
909 aligned_size = ALIGN_VALUE (ORBit_gather_alloc_info (tc->discriminator),
910 union_align);
911 pval1 = PTR_PLUS (val0, aligned_size);
912 pval2 = PTR_PLUS (newval0, aligned_size);
913
914 ORBit_copy_value_core (&pval1, &pval2, utc);
915
916 *val = ((guchar *)*val) + union_size;
917 *newval = ((guchar *)*newval) + union_size;
918 break;
919 }
920 case CORBA_tk_wstring:
921 case CORBA_tk_string:
922 *(CORBA_char **)*newval = CORBA_string_dup (*(CORBA_char **)*val);
923 *val = ((guchar *)*val) + sizeof (CORBA_char *);
924 *newval = ((guchar *)*newval) + sizeof (CORBA_char *);
925 break;
926 case CORBA_tk_sequence:
927 ((CORBA_Principal *)*newval)->_release = CORBA_TRUE;
928 ((CORBA_Principal *)*newval)->_length =
929 ((CORBA_Principal *)*newval)->_maximum =
930 ((CORBA_Principal *)*val)->_length;
931 ((CORBA_Principal *)*newval)->_buffer = pval2 =
932 ORBit_alloc_tcval (tc->subtypes[0],
933 ((CORBA_Principal *)*val)->_length);
934 pval1 = ((CORBA_Principal *)*val)->_buffer;
935
936 for (i = 0; i < ((CORBA_Principal *)*newval)->_length; i++)
937 ORBit_copy_value_core (&pval1, &pval2, tc->subtypes [0]);
938 *val = ((guchar *)*val) + sizeof (CORBA_sequence_CORBA_octet);
939 *newval = ((guchar *)*newval) + sizeof (CORBA_sequence_CORBA_octet);
940 break;
941 case CORBA_tk_array:
942 for (i = 0; i < tc->length; i++)
943 ORBit_copy_value_core (val, newval, tc->subtypes[0]);
944 break;
945 case CORBA_tk_fixed:
946 g_error ("CORBA_fixed NYI!");
947 break;
948 case CORBA_tk_void:
949 case CORBA_tk_null:
950 break;
951 default:
952 g_error ("Can't handle copy of value kind %d", tc->kind);
953 }
954 }
955
956 gpointer
ORBit_copy_value(gconstpointer value,CORBA_TypeCode tc)957 ORBit_copy_value (gconstpointer value, CORBA_TypeCode tc)
958 {
959 gpointer retval, newval;
960
961 if (!value)
962 return NULL;
963
964 retval = newval = ORBit_alloc_by_tc (tc);
965 ORBit_copy_value_core (&value, &newval, tc);
966
967 return retval;
968 }
969
970 void
CORBA_any__copy(CORBA_any * out,const CORBA_any * in)971 CORBA_any__copy (CORBA_any *out, const CORBA_any *in)
972 {
973 out->_type = ORBit_RootObject_duplicate (in->_type);
974 out->_value = ORBit_copy_value (in->_value, in->_type);
975 out->_release = CORBA_TRUE;
976 }
977
978 #define ALIGN_COMPARE(a,b,tk,type,align) \
979 case CORBA_tk_##tk: \
980 ret = *(CORBA_##type *) *a == *(CORBA_##type *) *b; \
981 *a = ((guchar *) *a) + sizeof (CORBA_##type); \
982 *b = ((guchar *) *b) + sizeof (CORBA_##type); \
983 return ret
984
985 CORBA_boolean
ORBit_value_equivalent(gpointer * a,gpointer * b,CORBA_TypeCode tc,CORBA_Environment * ev)986 ORBit_value_equivalent (gpointer *a, gpointer *b,
987 CORBA_TypeCode tc,
988 CORBA_Environment *ev)
989 {
990 gboolean ret;
991 int i;
992
993 SKIP_ALIAS (tc);
994
995 switch (tc->kind) {
996 case CORBA_tk_null:
997 case CORBA_tk_void:
998 return TRUE;
999
1000 ALIGN_COMPARE (a, b, short, short, ORBIT_ALIGNOF_CORBA_SHORT);
1001 ALIGN_COMPARE (a, b, ushort, short, ORBIT_ALIGNOF_CORBA_SHORT);
1002 ALIGN_COMPARE (a, b, wchar, short, ORBIT_ALIGNOF_CORBA_SHORT);
1003
1004 ALIGN_COMPARE (a, b, enum, long, ORBIT_ALIGNOF_CORBA_LONG);
1005 ALIGN_COMPARE (a, b, long, long, ORBIT_ALIGNOF_CORBA_LONG);
1006 ALIGN_COMPARE (a, b, ulong, long, ORBIT_ALIGNOF_CORBA_LONG);
1007
1008 ALIGN_COMPARE (a, b, longlong, long_long, ORBIT_ALIGNOF_CORBA_LONG_LONG);
1009 ALIGN_COMPARE (a, b, ulonglong, long_long, ORBIT_ALIGNOF_CORBA_LONG_LONG);
1010
1011 ALIGN_COMPARE (a, b, longdouble, long_double, ORBIT_ALIGNOF_CORBA_LONG_DOUBLE);
1012
1013 ALIGN_COMPARE (a, b, float, float, ORBIT_ALIGNOF_CORBA_FLOAT);
1014 ALIGN_COMPARE (a, b, double, double, ORBIT_ALIGNOF_CORBA_DOUBLE);
1015
1016 ALIGN_COMPARE (a, b, char, octet, ORBIT_ALIGNOF_CORBA_OCTET);
1017 ALIGN_COMPARE (a, b, octet, octet, ORBIT_ALIGNOF_CORBA_OCTET);
1018
1019 case CORBA_tk_boolean: {
1020 gboolean ba, bb;
1021
1022 ba = *(CORBA_octet *) *a;
1023 bb = *(CORBA_octet *) *b;
1024 *a = ((guchar *) *a) + sizeof (CORBA_octet);
1025 *b = ((guchar *) *b) + sizeof (CORBA_octet);
1026
1027 return (ba && bb) || (!ba && !bb);
1028 }
1029
1030 case CORBA_tk_string:
1031 ret = !strcmp (*(char **)*a, *(char **)*b);
1032 *a = ((guchar *) *a) + sizeof (CORBA_char *);
1033 *b = ((guchar *) *b) + sizeof (CORBA_char *);
1034 return ret;
1035
1036 case CORBA_tk_wstring:
1037 g_warning ("wstring totaly broken");
1038 return FALSE;
1039
1040 case CORBA_tk_TypeCode:
1041 case CORBA_tk_objref:
1042 ret = CORBA_Object_is_equivalent (*a, *b, ev);
1043 *a = ((guchar *) *a) + sizeof (CORBA_Object);
1044 *b = ((guchar *) *b) + sizeof (CORBA_Object);
1045 return ret;
1046
1047 case CORBA_tk_any: {
1048 CORBA_any *any_a, *any_b;
1049
1050 any_a = *((CORBA_any **) *a);
1051 any_b = *((CORBA_any **) *b);
1052
1053 ret = ORBit_any_equivalent (any_a, any_b, ev);
1054
1055 *a = ((guchar *) *a) + sizeof (CORBA_any *);
1056 *b = ((guchar *) *b) + sizeof (CORBA_any *);
1057
1058 return ret;
1059 }
1060
1061 case CORBA_tk_struct:
1062 case CORBA_tk_except: {
1063 int offset;
1064 gpointer a0 = *a;
1065 gpointer b0 = *b;
1066 int i;
1067
1068 for (i = offset = 0; i < tc->sub_parts; i++) {
1069 offset = ALIGN_VALUE (offset, tc->subtypes[i]->c_align);
1070 *a = PTR_PLUS (a0, offset);
1071 *b = PTR_PLUS (b0, offset);
1072 if (!ORBit_value_equivalent (a, b, tc->subtypes [i], ev))
1073 return FALSE;
1074 offset += ORBit_gather_alloc_info (tc->subtypes[i]);
1075 }
1076
1077 offset = ALIGN_VALUE (offset, tc->c_align);
1078 *a = PTR_PLUS (a0, offset);
1079 *b = PTR_PLUS (b0, offset);
1080 return TRUE;
1081 }
1082
1083 case CORBA_tk_sequence: {
1084 CORBA_Principal *ap, *bp;
1085 gpointer a_val, b_val;
1086
1087 ap = (CORBA_Principal *) *a;
1088 bp = (CORBA_Principal *) *b;
1089
1090 if (ap->_length != bp->_length)
1091 return FALSE;
1092
1093 a_val = ap->_buffer;
1094 b_val = bp->_buffer;
1095
1096 for (i = 0; i < ap->_length; i++) {
1097 if (!ORBit_value_equivalent (&a_val, &b_val, tc->subtypes [0], ev))
1098 return FALSE;
1099 }
1100 *a = ((guchar *) *a) + sizeof (CORBA_sequence_CORBA_octet);
1101 *b = ((guchar *) *b) + sizeof (CORBA_sequence_CORBA_octet);
1102 return TRUE;
1103 }
1104
1105 case CORBA_tk_union: {
1106 CORBA_TypeCode utc_a, utc_b;
1107 gint union_align = tc->c_align;
1108 size_t union_size = ORBit_gather_alloc_info (tc);
1109 gpointer a_orig, b_orig;
1110 size_t aligned_size;
1111
1112 a_orig = *a;
1113 b_orig = *b;
1114
1115 utc_a = ORBit_get_union_tag (tc, (gconstpointer *)a, FALSE);
1116 utc_b = ORBit_get_union_tag (tc, (gconstpointer *)b, FALSE);
1117
1118 if (!CORBA_TypeCode_equal (utc_a, utc_b, ev))
1119 return FALSE;
1120
1121 if (!ORBit_value_equivalent (a, b, tc->discriminator, ev))
1122 return FALSE;
1123
1124 aligned_size = ALIGN_VALUE (ORBit_gather_alloc_info (tc->discriminator),
1125 union_align);
1126 *a = PTR_PLUS (a_orig, aligned_size);
1127 *b = PTR_PLUS (b_orig, aligned_size);
1128 if (!ORBit_value_equivalent (a, b, utc_a, ev))
1129 return FALSE;
1130
1131 *a = ((guchar *) a_orig) + ALIGN_VALUE (union_size, union_align);
1132 *b = ((guchar *) b_orig) + ALIGN_VALUE (union_size, union_align);
1133 return TRUE;
1134 }
1135
1136 case CORBA_tk_array:
1137 for (i = 0; i < tc->length; i++) {
1138 if (!ORBit_value_equivalent (a, b, tc->subtypes [0], ev))
1139 return FALSE;
1140 }
1141 return TRUE;
1142
1143 default:
1144 g_warning ("ORBit_value_equivalent unimplemented");
1145 return FALSE;
1146 };
1147 }
1148
1149 /*
1150 * Compares the typecodes of each any
1151 */
1152 CORBA_boolean
ORBit_any_equivalent(CORBA_any * obj,CORBA_any * any,CORBA_Environment * ev)1153 ORBit_any_equivalent (CORBA_any *obj, CORBA_any *any, CORBA_Environment *ev)
1154 {
1155 gpointer a, b;
1156
1157 /* Is this correct ? */
1158 if (obj == NULL &&
1159 any == NULL)
1160 return TRUE;
1161 if (!obj || !any)
1162 return FALSE;
1163 if (!obj->_type || !any->_type) {
1164 CORBA_exception_set_system (
1165 ev, ex_CORBA_BAD_PARAM, CORBA_COMPLETED_NO);
1166 return FALSE;
1167 }
1168
1169 if (!CORBA_TypeCode_equal (obj->_type, any->_type, ev))
1170 return FALSE;
1171
1172 if (ev->_major != CORBA_NO_EXCEPTION)
1173 return FALSE;
1174
1175 a = obj->_value;
1176 b = any->_value;
1177
1178 return ORBit_value_equivalent (&a, &b, any->_type, ev);
1179 }
1180
1181 /* Friendly sequence allocators */
1182
1183 #define BASE_TYPES \
1184 CORBA_tk_short: \
1185 case CORBA_tk_long: \
1186 case CORBA_tk_enum: \
1187 case CORBA_tk_ushort: \
1188 case CORBA_tk_ulong: \
1189 case CORBA_tk_float: \
1190 case CORBA_tk_double: \
1191 case CORBA_tk_boolean: \
1192 case CORBA_tk_char: \
1193 case CORBA_tk_octet: \
1194 case CORBA_tk_longlong: \
1195 case CORBA_tk_ulonglong: \
1196 case CORBA_tk_longdouble: \
1197 case CORBA_tk_wchar
1198
1199 gpointer
ORBit_sequence_alloc(CORBA_TypeCode sequence_tc,CORBA_unsigned_long length)1200 ORBit_sequence_alloc (CORBA_TypeCode sequence_tc,
1201 CORBA_unsigned_long length)
1202 {
1203 CORBA_TypeCode tc = sequence_tc;
1204 CORBA_sequence_CORBA_octet *seq;
1205
1206 g_return_val_if_fail (sequence_tc != NULL, NULL);
1207
1208 SKIP_ALIAS (tc);
1209 g_return_val_if_fail (tc->kind == CORBA_tk_sequence, NULL);
1210
1211 seq = ORBit_alloc_by_tc (sequence_tc);
1212 seq->_buffer = ORBit_small_allocbuf (tc, length);
1213 seq->_length = length;
1214 seq->_maximum = length;
1215
1216 CORBA_sequence_set_release (seq, CORBA_TRUE);
1217
1218 g_assert (ORBit_alloc_get_tcval (seq) == sequence_tc);
1219
1220 return seq;
1221 }
1222
1223 void
ORBit_sequence_set_size(gpointer sequence,CORBA_unsigned_long length)1224 ORBit_sequence_set_size (gpointer sequence,
1225 CORBA_unsigned_long length)
1226 {
1227 CORBA_TypeCode tc, subtc;
1228 CORBA_sequence_CORBA_octet *seq = sequence;
1229
1230 g_return_if_fail (seq != NULL);
1231 g_return_if_fail (seq->_length <= seq->_maximum);
1232
1233 if (seq->_length == length)
1234 return;
1235
1236 tc = ORBit_alloc_get_tcval (sequence);
1237 SKIP_ALIAS (tc);
1238 g_return_if_fail (tc->kind == CORBA_tk_sequence);
1239 subtc = tc->subtypes[0];
1240
1241 if (length < seq->_length) {
1242 guint i;
1243
1244 switch (subtc->kind) {
1245 case BASE_TYPES: /* leave some in-line values */
1246 break;
1247 default: {
1248 guint element_size = ORBit_gather_alloc_info (subtc);
1249
1250 for (i = length; i < seq->_length; i++)
1251 ORBit_freekids_via_TypeCode
1252 (subtc, (guchar *)seq->_buffer + i * element_size);
1253
1254 /* Don't trust the API user not to poke at it again */
1255 memset ((guchar *)seq->_buffer + length * element_size,
1256 0, (seq->_length - length) * element_size);
1257 break;
1258 }
1259 }
1260 } else {
1261 if (length > seq->_maximum) {
1262 guint new_len = MAX (length, seq->_maximum * 2);
1263
1264 seq->_buffer = ORBit_realloc_tcval
1265 (seq->_buffer, subtc,
1266 seq->_maximum, new_len);
1267 seq->_maximum = new_len;
1268 }
1269 }
1270 seq->_length = length;
1271 }
1272
1273 void
ORBit_sequence_append(gpointer sequence,gconstpointer element)1274 ORBit_sequence_append (gpointer sequence,
1275 gconstpointer element)
1276 {
1277 guint element_size;
1278 guchar *dest;
1279 CORBA_TypeCode tc, subtc;
1280 CORBA_sequence_CORBA_octet *seq = sequence;
1281
1282 g_return_if_fail (seq != NULL);
1283 g_return_if_fail (seq->_length <= seq->_maximum);
1284
1285 tc = ORBit_alloc_get_tcval (sequence);
1286 SKIP_ALIAS (tc);
1287 subtc = tc->subtypes [0];
1288 g_return_if_fail (tc->kind == CORBA_tk_sequence);
1289
1290 if (seq->_length == seq->_maximum) {
1291 guint new_len = MAX (2, (seq->_maximum * 2));
1292
1293 seq->_buffer = ORBit_realloc_tcval
1294 (seq->_buffer, subtc,
1295 seq->_maximum, new_len );
1296 seq->_maximum = new_len;
1297 }
1298
1299 element_size = ORBit_gather_alloc_info (subtc);
1300
1301 dest = seq->_buffer;
1302 dest += element_size * seq->_length;
1303 ORBit_copy_value_core (&element, (gpointer)&dest, subtc);
1304
1305 seq->_length++;
1306 }
1307
1308 void
ORBit_sequence_remove(gpointer sequence,guint idx)1309 ORBit_sequence_remove (gpointer sequence,
1310 guint idx)
1311 {
1312 guint element_size, remaining;
1313 guchar *elem;
1314 CORBA_TypeCode tc, subtc;
1315 CORBA_sequence_CORBA_octet *seq = sequence;
1316
1317 tc = ORBit_alloc_get_tcval (sequence);
1318 SKIP_ALIAS (tc);
1319 g_return_if_fail (tc->kind == CORBA_tk_sequence);
1320 g_return_if_fail (seq != NULL);
1321 g_return_if_fail (seq->_length <= seq->_maximum);
1322 g_return_if_fail (idx < seq->_length);
1323
1324 subtc = tc->subtypes [0];
1325 element_size = ORBit_gather_alloc_info (subtc);
1326 elem = seq->_buffer + element_size*idx;
1327 remaining = seq->_length - idx - 1;
1328 ORBit_freekids_via_TypeCode (subtc, elem);
1329 /* shift remaining elements into free slot */
1330 memmove (elem, elem + element_size, element_size*remaining);
1331 /* zero last element */
1332 memset (elem + element_size*remaining, 0, element_size);
1333
1334 seq->_length--;
1335 }
1336
1337 void
ORBit_sequence_concat(gpointer sequence,gconstpointer append)1338 ORBit_sequence_concat (gpointer sequence,
1339 gconstpointer append)
1340 {
1341 gint i;
1342 guint element_size;
1343 guchar *src;
1344 CORBA_TypeCode tc, subtc;
1345 CORBA_sequence_CORBA_octet *seq = (CORBA_sequence_CORBA_octet *)append;
1346
1347 g_return_if_fail (seq != NULL);
1348 g_return_if_fail (seq->_length <= seq->_maximum);
1349
1350 tc = ORBit_alloc_get_tcval (sequence);
1351 SKIP_ALIAS (tc);
1352 subtc = tc->subtypes [0];
1353 g_return_if_fail (tc->kind == CORBA_tk_sequence);
1354
1355 element_size = ORBit_gather_alloc_info (subtc);
1356
1357 src = seq->_buffer;
1358
1359 for (i = 0; i < seq->_length; ++i, src += element_size)
1360 ORBit_sequence_append (sequence, (gpointer)src);
1361 }
1362