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