1 //=============================================================================
5 * Appends a CDR stream to another CDR stream. Due to the
6 * stringent alignment requirements, it is not possible to simply
7 * append or memcpy. Instead we go thru the same CDR encoding rules
9 * @author Copyright 1994-1995 by Sun Microsystems Inc. and Aniruddha Gokhale
11 //=============================================================================
14 #include "tao/AnyTypeCode/TypeCode.h"
15 #include "tao/AnyTypeCode/Marshal.h"
16 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
17 #include "tao/AnyTypeCode/TypeCode_Constants.h"
18 #include "tao/AnyTypeCode/OctetSeqA.h"
19 #include "tao/AnyTypeCode/Any.h"
20 #include "tao/debug.h"
21 #include "tao/Valuetype_Adapter.h"
22 #include "tao/ORB_Core.h"
24 #include "tao/SystemException.h"
26 #include "ace/Dynamic_Service.h"
28 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
30 // Encode instances of arbitrary data types based only on typecode.
31 // "data" points to the data type; if it's not a primitve data type,
32 // the TypeCode interpreter is used to recursively encode its
33 // components. "context" is the marshaling stream on which to encode
37 TAO_Marshal_Primitive::append (CORBA::TypeCode_ptr tc
,
41 CORBA::Boolean continue_append
= true;
42 TAO::traverse_status retval
=
43 TAO::TRAVERSE_CONTINUE
; // status of encode operation
45 CORBA::TCKind
const k
= tc
->kind ();
53 case CORBA::tk_ushort
:
54 continue_append
= dest
->append_short (*src
);
60 continue_append
= dest
->append_long (*src
);
62 case CORBA::tk_double
:
63 case CORBA::tk_longlong
:
64 case CORBA::tk_ulonglong
:
65 continue_append
= dest
->append_double (*src
);
67 case CORBA::tk_boolean
:
68 continue_append
= dest
->append_boolean (*src
);
72 continue_append
= dest
->append_octet (*src
);
74 case CORBA::tk_longdouble
:
75 continue_append
= dest
->append_longdouble (*src
);
78 continue_append
= dest
->append_wchar (*src
);
81 retval
= TAO::TRAVERSE_STOP
;
82 // we are not a primitive type
85 if (retval
== TAO::TRAVERSE_CONTINUE
86 && continue_append
== 1)
87 return TAO::TRAVERSE_CONTINUE
;
89 if (TAO_debug_level
> 0)
92 ACE_TEXT ("TAO_Marshal_Primitive::append detected error\n")));
94 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
98 TAO_Marshal_Any::append (CORBA::TypeCode_ptr
,
102 // Typecode of the element that makes the Any.
103 CORBA::TypeCode_var elem_tc
;
105 if (!(*src
>> elem_tc
.inout ()))
106 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
108 if (!(*dest
<< elem_tc
.in ()))
109 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
112 TAO::traverse_status retval
=
113 TAO_Marshal_Object::perform_append (elem_tc
.in (), src
, dest
);
115 if (retval
!= TAO::TRAVERSE_CONTINUE
)
117 if (TAO_debug_level
> 0)
118 TAOLIB_DEBUG ((LM_DEBUG
,
119 ACE_TEXT ("TAO_Marshal_Any::append detected error\n")));
121 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
128 TAO_Marshal_TypeCode::append (CORBA::TypeCode_ptr
,
132 CORBA::Boolean continue_append
= true;
133 TAO::traverse_status retval
=
134 TAO::TRAVERSE_CONTINUE
;
137 // Decode the "kind" field of the typecode from the src for further
138 // use. However, also write it back into the destination
139 continue_append
= (CORBA::Boolean
) (src
->read_ulong (kind
)
140 ? dest
->write_ulong (kind
)
143 if (continue_append
== true)
145 // Typecodes with empty parameter lists all have preallocated
146 // constants. We use those to reduce memory consumption and
147 // heap access ... also, to speed things up!
148 if ((kind
< CORBA::TAO_TC_KIND_COUNT
)
151 // Either a non-constant typecode or an indirected typecode.
154 // Need special handling for all kinds of typecodes that
155 // have nonempty parameter lists ...
157 // nothing to de done
159 case CORBA::tk_string
:
160 case CORBA::tk_wstring
:
162 // read and write the bounds
164 TAO_Marshal_Object::perform_append (CORBA::_tc_long
,
170 // Indirected typecodes, illegal at "top level"
173 // read and write the negative offset
175 TAO_Marshal_Object::perform_append (CORBA::_tc_long
,
181 // The rest have "complex" parameter lists that are
182 // encoded as bulk octets ...
183 case CORBA::tk_objref
:
184 case CORBA::tk_struct
:
185 case CORBA::tk_union
:
187 case CORBA::tk_sequence
:
188 case CORBA::tk_array
:
189 case CORBA::tk_alias
:
190 case CORBA::tk_except
:
191 case CORBA::tk_value
:
192 case CORBA::tk_value_box
:
193 case CORBA::tk_native
:
194 case CORBA::tk_abstract_interface
:
195 case CORBA::tk_local_interface
:
196 case CORBA::tk_component
:
198 case CORBA::tk_event
:
200 // write the encapsulation i.e., octet sequence
202 TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq
,
208 else // bad kind_ value to be decoded
210 if (TAO_debug_level
> 0)
212 TAOLIB_DEBUG ((LM_DEBUG
,
213 ACE_TEXT ("TAO_Marshal_TypeCode: ")
214 ACE_TEXT ("Bad kind_ value in CDR stream\n")));
217 throw ::CORBA::BAD_TYPECODE ();
221 if (continue_append
== 1 && retval
== TAO::TRAVERSE_CONTINUE
)
223 return TAO::TRAVERSE_CONTINUE
;
226 if (TAO_debug_level
> 0)
228 TAOLIB_DEBUG ((LM_DEBUG
,
229 ACE_TEXT ("TAO_Marshal_TypeCode::append detected error\n")));
232 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
236 TAO_Marshal_Principal::append (CORBA::TypeCode_ptr
,
240 // write the octet sequence representing the Principal
241 return TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq
, src
, dest
);
245 TAO_Marshal_ObjRef::append (CORBA::TypeCode_ptr
,
249 CORBA::Boolean continue_append
= true;
251 // First, append the type hint. This will be the type_id encoded in an
253 dest
->append_string (*src
);
255 // Read the profiles, discarding all until an IIOP profile comes by.
256 // Once we see an IIOP profile, ignore any further ones.
258 // XXX this will need to change someday to let different protocol
259 // code be accessed, not just IIOP. Protocol modules will be
260 // dynamically loaded from shared libraries via ORB_init (), and we
261 // just need to be able to access such preloaded libraries here as
262 // we unmarshal objrefs.
264 CORBA::ULong profiles
= 0;
266 // get the count of profiles that follow. This will tell us the
267 // length of the sequence
268 continue_append
= (CORBA::Boolean
) (src
->read_ulong (profiles
)
269 ? dest
->write_ulong (profiles
)
272 // No profiles means a NIL objref.
273 while (profiles
-- != 0 && continue_append
)
275 CORBA::ULong tag
= 0;
277 // get the profile ID tag
278 if ((continue_append
= (CORBA::Boolean
) (src
->read_ulong (tag
)
279 ? dest
->write_ulong (tag
)
283 CORBA::ULong length
= 0;
284 if ((continue_append
= (CORBA::Boolean
) (src
->read_ulong (length
)
285 ? dest
->write_ulong (length
)
289 // @@ This can be optimized! Pre-allocating on the destination
290 // and then copying directly into that.
291 CORBA::Octet
* body
= 0;
292 ACE_NEW_RETURN (body
,
293 CORBA::Octet
[length
],
296 (CORBA::Boolean
) (src
->read_octet_array (body
, length
)
297 ? dest
->write_octet_array (body
, length
)
302 if (continue_append
== 1)
303 return TAO::TRAVERSE_CONTINUE
;
305 if (TAO_debug_level
> 0)
308 ACE_TEXT ("TAO_Marshal_ObjRef::append detected error\n")));
310 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
314 TAO_Marshal_Struct::append (CORBA::TypeCode_ptr tc
,
318 TAO::traverse_status retval
=
319 TAO::TRAVERSE_CONTINUE
;
320 CORBA::TypeCode_var param
;
322 // Number of fields in the struct.
323 const CORBA::ULong member_count
=
326 for (CORBA::ULong i
= 0;
327 i
< member_count
&& retval
== TAO::TRAVERSE_CONTINUE
;
331 param
= tc
->member_type (i
);
333 retval
= TAO_Marshal_Object::perform_append (param
.in (), src
, dest
);
336 if (retval
== TAO::TRAVERSE_CONTINUE
)
337 return TAO::TRAVERSE_CONTINUE
;
339 if (TAO_debug_level
> 0)
340 TAOLIB_DEBUG ((LM_DEBUG
,
341 ACE_TEXT ("TAO_Marshal_Struct::append detected error\n")));
343 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
347 TAO_Marshal_Union::append (CORBA::TypeCode_ptr tc
,
351 CORBA::TypeCode_var discrim_tc
= tc
->discriminator_type ();
353 CORBA::ULong kind
= discrim_tc
->kind ();
355 // Save the discriminator value in a temporary variable...
356 CORBA::Short short_v
= CORBA::Short();
357 CORBA::UShort ushort_v
= CORBA::UShort();
358 CORBA::Long long_v
= CORBA::Long();
359 CORBA::ULong ulong_v
= CORBA::ULong();
360 CORBA::ULong enum_v
= CORBA::ULong();
361 CORBA::Char char_v
= CORBA::Char();
362 CORBA::WChar wchar_v
= CORBA::WChar();
363 CORBA::Boolean boolean_v
= false;
367 case CORBA::tk_short
:
369 if (!src
->read_short (short_v
)
370 || !dest
->write_short (short_v
))
371 return TAO::TRAVERSE_STOP
;
375 case CORBA::tk_ushort
:
377 if (!src
->read_ushort (ushort_v
)
378 || !dest
->write_ushort (ushort_v
))
379 return TAO::TRAVERSE_STOP
;
385 if (!src
->read_long (long_v
)
386 || !dest
->write_long (long_v
))
387 return TAO::TRAVERSE_STOP
;
391 case CORBA::tk_ulong
:
393 if (!src
->read_ulong (ulong_v
)
394 || !dest
->write_ulong (ulong_v
))
395 return TAO::TRAVERSE_STOP
;
401 if (!src
->read_ulong (enum_v
)
402 || !dest
->write_ulong (enum_v
))
403 return TAO::TRAVERSE_STOP
;
409 if (!src
->read_char (char_v
)
410 || !dest
->write_char (char_v
))
411 return TAO::TRAVERSE_STOP
;
415 case CORBA::tk_wchar
:
417 if (!src
->read_wchar (wchar_v
)
418 || !dest
->write_wchar (wchar_v
))
419 return TAO::TRAVERSE_STOP
;
423 case CORBA::tk_boolean
:
425 if (!src
->read_boolean (boolean_v
)
426 || !dest
->write_boolean (boolean_v
))
427 return TAO::TRAVERSE_STOP
;
432 return TAO::TRAVERSE_STOP
;
435 const CORBA::ULong member_count
=
438 const CORBA::ULong null_member
= ~static_cast<CORBA::ULong
> (0U);
440 CORBA::ULong current_member
= null_member
;
441 CORBA::ULong default_member
= null_member
;
443 for (CORBA::ULong i
= 0;
444 i
< member_count
&& current_member
== null_member
;
447 CORBA::Any_var any
= tc
->member_label (i
);
451 if ((any
>>= CORBA::Any::to_octet (o
)) && o
== 0)
453 CORBA::ULong default_index
=
454 tc
->default_index ();
456 if (i
!= default_index
)
457 throw ::CORBA::BAD_TYPECODE ();
458 // Found the default branch, save its position and continue
459 // trying to find the current value...
466 case CORBA::tk_short
:
469 if ((any
>>= d
) && d
== short_v
)
474 case CORBA::tk_ushort
:
477 if ((any
>>= d
) && d
== ushort_v
)
485 if ((any
>>= d
) && d
== long_v
)
490 case CORBA::tk_ulong
:
493 if ((any
>>= d
) && d
== ulong_v
)
501 TAO::Any_Impl
*impl
= any
->impl ();
503 if (impl
->encoded ())
505 TAO::Unknown_IDL_Type
* const unk
=
506 dynamic_cast<TAO::Unknown_IDL_Type
*> (impl
);
509 throw ::CORBA::INTERNAL ();
511 // We don't want unk's rd_ptr to move, in case
512 // we are shared by another Any, so we use this
513 // to copy the state, not the buffer.
514 TAO_InputCDR
for_reading (unk
->_tao_get_cdr ());
516 for_reading
.read_ulong (d
);
521 impl
->marshal_value (out
);
522 TAO_InputCDR
cdr (out
);
536 if ((any
>>= CORBA::Any::to_char (d
)) && d
== char_v
)
541 case CORBA::tk_wchar
:
544 if ((any
>>= CORBA::Any::to_wchar (d
)) && d
== wchar_v
)
549 case CORBA::tk_boolean
:
552 if ((any
>>= CORBA::Any::to_boolean (d
)) && d
== boolean_v
)
558 return TAO::TRAVERSE_STOP
;
562 if (current_member
== null_member
)
564 // Cannot find the current member, check if there is a
566 if (default_member
!= null_member
)
568 // Good, use the default to append...
569 CORBA::TypeCode_var member_tc
=
570 tc
->member_type (default_member
);
571 return TAO_Marshal_Object::perform_append (member_tc
.in (),
576 // If we're here, we have an implicit default case, and we
577 // should just return without appending anything, since no
578 // union member was marshaled in the first place.
579 return TAO::TRAVERSE_CONTINUE
;
582 // If we found the member successfully then just use that one...
583 CORBA::TypeCode_var member_tc
=
584 tc
->member_type (current_member
);
585 return TAO_Marshal_Object::perform_append (member_tc
.in (),
591 TAO_Marshal_String::append (CORBA::TypeCode_ptr
,
595 CORBA::Boolean continue_append
= true;
597 // On decode, omit the check against specified string bounds, and
598 // cope with illegal "zero length" strings (all lengths on the wire
599 // must include a NUL).
601 // This is on the principle of being gracious in what we accept; we
602 // don't generate messages that fail to comply with protocol specs,
603 // but we will accept them when it's clear how to do so.
605 continue_append
= dest
->append_string (*src
);
606 if (continue_append
== 1)
607 return TAO::TRAVERSE_CONTINUE
;
609 if (TAO_debug_level
> 0)
610 TAOLIB_DEBUG ((LM_DEBUG
,
611 ACE_TEXT ("TAO_Marshal_TypeCode::append detected error\n")));
613 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
617 TAO_Marshal_Sequence::append (CORBA::TypeCode_ptr tc
,
624 // First unmarshal the sequence length ... we trust it to be right
625 // here, on the "be gracious in what you accept" principle. We
626 // don't generate illegal sequences (i.e. length > bounds).
628 CORBA::Boolean continue_append
=
629 (CORBA::Boolean
) (src
->read_ulong (bounds
)
630 ? dest
->write_ulong (bounds
)
633 if (!continue_append
)
637 ACE_TEXT ("TAO_Marshal_Sequence::append detected error\n")));
638 throw ::CORBA::MARSHAL ();
643 return TAO::TRAVERSE_CONTINUE
;
648 // Get element typecode.
649 CORBA::TypeCode_var tc2
=
652 TAO::traverse_status retval
=
653 TAO::TRAVERSE_CONTINUE
;
655 CORBA::TCKind kind
= tc2
->kind ();
659 case CORBA::tk_octet
:
662 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
663 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
665 if (src
->read_octet_array ((ACE_CDR::Octet
*)buf
, bounds
) == 0)
666 retval
= TAO::TRAVERSE_STOP
;
670 case CORBA::tk_boolean
:
673 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
674 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
676 if (src
->read_boolean_array ((ACE_CDR::Boolean
*)buf
, bounds
) == 0)
677 retval
= TAO::TRAVERSE_STOP
;
684 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
685 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
687 if (src
->read_char_array ((ACE_CDR::Char
*)buf
, bounds
) == 0)
688 retval
= TAO::TRAVERSE_STOP
;
692 case CORBA::tk_short
:
695 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
696 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
698 if (src
->read_short_array ((ACE_CDR::Short
*)buf
, bounds
) == 0)
699 retval
= TAO::TRAVERSE_STOP
;
703 case CORBA::tk_ushort
:
706 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
707 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
709 if (src
->read_ushort_array ((ACE_CDR::UShort
*)buf
, bounds
) == 0)
710 retval
= TAO::TRAVERSE_STOP
;
714 case CORBA::tk_wchar
:
717 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
718 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
720 if (src
->read_wchar_array ((ACE_CDR::WChar
*)buf
, bounds
) == 0)
721 retval
= TAO::TRAVERSE_STOP
;
728 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
729 ACE_CDR::LONG_ALIGN
, buf
) == 0)
731 if (src
->read_long_array ((ACE_CDR::Long
*)buf
, bounds
) == 0)
732 retval
= TAO::TRAVERSE_STOP
;
736 case CORBA::tk_ulong
:
739 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
740 ACE_CDR::LONG_ALIGN
, buf
) == 0)
742 if (src
->read_ulong_array ((ACE_CDR::ULong
*)buf
, bounds
) == 0)
743 retval
= TAO::TRAVERSE_STOP
;
747 case CORBA::tk_float
:
750 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
751 ACE_CDR::LONG_ALIGN
, buf
) == 0)
753 if (src
->read_float_array ((ACE_CDR::Float
*)buf
, bounds
) == 0)
754 retval
= TAO::TRAVERSE_STOP
;
758 case CORBA::tk_double
:
761 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
762 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
764 if (src
->read_double_array ((ACE_CDR::Double
*)buf
, bounds
) == 0)
765 retval
= TAO::TRAVERSE_STOP
;
769 case CORBA::tk_longlong
:
772 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
773 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
775 if (src
->read_longlong_array ((ACE_CDR::LongLong
*)buf
, bounds
) == 0)
776 retval
= TAO::TRAVERSE_STOP
;
780 case CORBA::tk_ulonglong
:
783 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
784 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
786 if (src
->read_ulonglong_array ((ACE_CDR::ULongLong
*)buf
, bounds
) == 0)
787 retval
= TAO::TRAVERSE_STOP
;
791 case CORBA::tk_longdouble
:
794 if (dest
->adjust (ACE_CDR::LONGDOUBLE_SIZE
* bounds
,
795 ACE_CDR::LONGDOUBLE_ALIGN
, buf
) == 0)
797 if (src
->read_longdouble_array ((ACE_CDR::LongDouble
*)buf
, bounds
) == 0)
798 retval
= TAO::TRAVERSE_STOP
;
804 while (bounds
-- && retval
== TAO::TRAVERSE_CONTINUE
)
806 retval
= TAO_Marshal_Object::perform_append (tc2
.in (),
813 if (retval
== TAO::TRAVERSE_CONTINUE
)
814 return TAO::TRAVERSE_CONTINUE
;
817 if (TAO_debug_level
> 0)
820 ACE_TEXT ("marshaling TAO_Marshal_Sequence::append detected error\n")));
822 throw ::CORBA::MARSHAL ();
826 TAO_Marshal_Array::append (CORBA::TypeCode_ptr tc
,
830 // retrieve the bounds of the array
831 CORBA::ULong bounds
= tc
->length ();
833 // get element typecode
834 CORBA::TypeCode_var tc2
= tc
->content_type ();
836 // For CORBA basic types, the copy can be optimized
837 CORBA::TCKind kind
= tc2
->kind ();
840 TAO::traverse_status retval
=
841 TAO::TRAVERSE_CONTINUE
;
845 case CORBA::tk_octet
:
848 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
849 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
851 if (src
->read_octet_array ((ACE_CDR::Octet
*)buf
, bounds
) == 0)
852 retval
= TAO::TRAVERSE_STOP
;
856 case CORBA::tk_boolean
:
859 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
860 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
862 if (src
->read_boolean_array ((ACE_CDR::Boolean
*)buf
, bounds
) == 0)
863 retval
= TAO::TRAVERSE_STOP
;
870 if (dest
->adjust (ACE_CDR::OCTET_SIZE
* bounds
,
871 ACE_CDR::OCTET_ALIGN
, buf
) == 0)
873 if (src
->read_char_array ((ACE_CDR::Char
*)buf
, bounds
) == 0)
874 retval
= TAO::TRAVERSE_STOP
;
878 case CORBA::tk_short
:
881 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
882 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
884 if (src
->read_short_array ((ACE_CDR::Short
*)buf
, bounds
) == 0)
885 retval
= TAO::TRAVERSE_STOP
;
889 case CORBA::tk_ushort
:
892 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
893 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
895 if (src
->read_ushort_array ((ACE_CDR::UShort
*)buf
, bounds
) == 0)
896 retval
= TAO::TRAVERSE_STOP
;
900 case CORBA::tk_wchar
:
903 if (dest
->adjust (ACE_CDR::SHORT_SIZE
* bounds
,
904 ACE_CDR::SHORT_ALIGN
, buf
) == 0)
906 if (src
->read_wchar_array ((ACE_CDR::WChar
*)buf
, bounds
) == 0)
907 retval
= TAO::TRAVERSE_STOP
;
914 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
915 ACE_CDR::LONG_ALIGN
, buf
) == 0)
917 if (src
->read_long_array ((ACE_CDR::Long
*)buf
, bounds
) == 0)
918 retval
= TAO::TRAVERSE_STOP
;
922 case CORBA::tk_ulong
:
925 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
926 ACE_CDR::LONG_ALIGN
, buf
) == 0)
928 if (src
->read_ulong_array ((ACE_CDR::ULong
*)buf
, bounds
) == 0)
929 retval
= TAO::TRAVERSE_STOP
;
933 case CORBA::tk_float
:
936 if (dest
->adjust (ACE_CDR::LONG_SIZE
* bounds
,
937 ACE_CDR::LONG_ALIGN
, buf
) == 0)
939 if (src
->read_float_array ((ACE_CDR::Float
*)buf
, bounds
) == 0)
940 retval
= TAO::TRAVERSE_STOP
;
944 case CORBA::tk_double
:
947 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
948 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
950 if (src
->read_double_array ((ACE_CDR::Double
*)buf
, bounds
) == 0)
951 retval
= TAO::TRAVERSE_STOP
;
955 case CORBA::tk_longlong
:
958 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
959 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
961 if (src
->read_longlong_array ((ACE_CDR::LongLong
*)buf
, bounds
) == 0)
962 retval
= TAO::TRAVERSE_STOP
;
966 case CORBA::tk_ulonglong
:
969 if (dest
->adjust (ACE_CDR::LONGLONG_SIZE
* bounds
,
970 ACE_CDR::LONGLONG_ALIGN
, buf
) == 0)
972 if (src
->read_ulonglong_array ((ACE_CDR::ULongLong
*)buf
, bounds
) == 0)
973 retval
= TAO::TRAVERSE_STOP
;
977 case CORBA::tk_longdouble
:
980 if (dest
->adjust (ACE_CDR::LONGDOUBLE_SIZE
* bounds
,
981 ACE_CDR::LONGDOUBLE_ALIGN
, buf
) == 0)
983 if (src
->read_longdouble_array ((ACE_CDR::LongDouble
*)buf
, bounds
) == 0)
984 retval
= TAO::TRAVERSE_STOP
;
989 while (bounds
-- && retval
== TAO::TRAVERSE_CONTINUE
)
991 retval
= TAO_Marshal_Object::perform_append (tc2
.in (),
998 if (retval
== TAO::TRAVERSE_CONTINUE
)
1002 if (TAO_debug_level
> 0)
1003 TAOLIB_DEBUG ((LM_DEBUG
,
1004 ACE_TEXT ("TAO_Marshal_Sequence::append detected error\n")));
1006 throw ::CORBA::MARSHAL ();
1009 TAO::traverse_status
1010 TAO_Marshal_Alias::append (CORBA::TypeCode_ptr tc
,
1012 TAO_OutputCDR
*dest
)
1014 // Typecode of the aliased type.
1015 CORBA::TypeCode_var tc2
;
1016 CORBA::Boolean continue_append
= true;
1018 // Status of decode operation.
1019 TAO::traverse_status retval
=
1020 TAO::TRAVERSE_CONTINUE
;
1022 tc2
= tc
->content_type ();
1024 retval
= TAO_Marshal_Object::perform_append (tc2
.in (), src
, dest
);
1026 if (retval
== TAO::TRAVERSE_CONTINUE
1027 && continue_append
== true)
1028 return TAO::TRAVERSE_CONTINUE
;
1030 if (TAO_debug_level
> 0)
1031 TAOLIB_DEBUG ((LM_DEBUG
,
1032 ACE_TEXT ("TAO_Marshal_Alias::append detected error\n")));
1033 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
1036 // Decode exception For exceptions, the "hidden" type ID near the
1037 // front of the on-wire representation was previously unmarshaled and
1038 // mapped to the "tc" typcode we're using to traverse the memory ...
1039 // at the same time its vtable, refcount, and other state was
1042 // NOTE: This is asymmetric with respect to encoding exceptions.
1043 TAO::traverse_status
1044 TAO_Marshal_Except::append (CORBA::TypeCode_ptr tc
,
1046 TAO_OutputCDR
*dest
)
1048 TAO::traverse_status retval
=
1049 TAO::TRAVERSE_CONTINUE
;
1050 CORBA::Boolean continue_append
= true;
1051 CORBA::TypeCode_var param
;
1053 // first append the RepositoryID
1054 continue_append
= dest
->append_string (*src
);
1056 // Number of fields in the struct.
1057 const CORBA::ULong member_count
=
1058 tc
->member_count ();
1060 for (CORBA::ULong i
= 0;
1062 && retval
== TAO::TRAVERSE_CONTINUE
1063 && continue_append
== 1;
1066 param
= tc
->member_type (i
);
1068 retval
= TAO_Marshal_Object::perform_append (param
.in (),
1073 if (retval
== TAO::TRAVERSE_CONTINUE
1074 && continue_append
== 1)
1075 return TAO::TRAVERSE_CONTINUE
;
1077 if (TAO_debug_level
> 0)
1078 TAOLIB_DEBUG ((LM_DEBUG
,
1079 ACE_TEXT ("TAO_Marshal_Except::append detected error\n")));
1081 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
1084 TAO::traverse_status
1085 TAO_Marshal_WString::append (CORBA::TypeCode_ptr
,
1087 TAO_OutputCDR
*dest
)
1089 CORBA::Boolean continue_append
= true;
1091 // On decode, omit the check against specified wstring bounds, and
1092 // cope with illegal "zero length" strings (all lengths on the wire
1093 // must include a NUL).
1095 // This is on the principle of being gracious in what we accept; we
1096 // don't generate messages that fail to comply with protocol specs,
1097 // but we will accept them when it's clear how to do so.
1099 continue_append
= dest
->append_wstring (*src
);
1101 if (continue_append
== 1)
1102 return TAO::TRAVERSE_CONTINUE
;
1104 if (TAO_debug_level
> 0)
1105 TAOLIB_DEBUG ((LM_DEBUG
,
1106 ACE_TEXT ("TAO_Marshal_WString::append detected error\n")));
1108 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
1111 TAO::traverse_status
1112 TAO_Marshal_Value::append (CORBA::TypeCode_ptr tc
,
1114 TAO_OutputCDR
*dest
)
1116 TAO::traverse_status retval
=
1117 TAO::TRAVERSE_CONTINUE
;
1119 // Use the same method to append our base valuetype.
1120 // To achive this we'll need to distinguish between
1121 // first-time/nested appends so that we won't attempt to
1122 // append rep_id several times.
1124 if (this->nested_processing_
== 0)
1126 this->nested_processing_
= 1;
1128 CORBA::ULong value_tag
;
1130 if (!src
->read_ulong (value_tag
) ||
1131 !dest
->write_ulong (value_tag
))
1133 return TAO::TRAVERSE_STOP
;
1136 TAO_ORB_Core
*orb_core
= src
->orb_core ();
1139 orb_core
= TAO_ORB_Core_instance ();
1141 if (TAO_debug_level
> 0)
1143 TAOLIB_DEBUG ((LM_WARNING
,
1144 "TAO (%P|%t) WARNING: extracting "
1145 "valuetype using default ORB_Core\n"));
1149 TAO_Valuetype_Adapter
*adapter
= orb_core
->valuetype_adapter();
1151 if (value_tag
== 0) // Null value type pointer.
1156 else if (value_tag
& adapter
->type_info_single ())
1158 // Append repository id which is of type string.
1159 dest
->append_string (*src
);
1164 return TAO::TRAVERSE_STOP
;
1168 CORBA::TypeCode_var param
;
1169 if (CORBA::tk_value_box
== tc
->kind ())
1171 param
= tc
->content_type ();
1172 retval
= TAO_Marshal_Object::perform_append (param
.in (),
1176 else // tc->kind () must be tk_value or tk_event
1178 // Handle our base valuetype if any.
1179 param
= tc
->concrete_base_type ();
1180 if (CORBA::tk_null
!= param
->kind ())
1182 retval
= this->append (param
.in (),
1187 if (retval
== TAO::TRAVERSE_CONTINUE
)
1189 // Number of fields in the struct.
1190 const CORBA::ULong member_count
=
1191 tc
->member_count ();
1193 for (CORBA::ULong i
= 0;
1194 i
< member_count
&& retval
== TAO::TRAVERSE_CONTINUE
;
1198 param
= tc
->member_type (i
);
1201 TAO_Marshal_Object::perform_append (param
.in (),
1208 if (retval
== TAO::TRAVERSE_CONTINUE
)
1209 return TAO::TRAVERSE_CONTINUE
;
1211 if (TAO_debug_level
> 0)
1212 TAOLIB_DEBUG ((LM_DEBUG
,
1213 ACE_TEXT ("TAO_Marshal_Value::append detected error\n")));
1215 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE
);
1218 TAO_END_VERSIONED_NAMESPACE_DECL