Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / AnyTypeCode / append.cpp
blobaa6b2f972668f96b3335a8df04aa4ee8102a7f6f
1 //=============================================================================
2 /**
3 * @file append.cpp
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"
23 #include "tao/CDR.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
34 // the data value.
36 TAO::traverse_status
37 TAO_Marshal_Primitive::append (CORBA::TypeCode_ptr tc,
38 TAO_InputCDR *src,
39 TAO_OutputCDR *dest)
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 ();
47 switch (k)
49 case CORBA::tk_null:
50 case CORBA::tk_void:
51 break;
52 case CORBA::tk_short:
53 case CORBA::tk_ushort:
54 continue_append = dest->append_short (*src);
55 break;
56 case CORBA::tk_long:
57 case CORBA::tk_ulong:
58 case CORBA::tk_float:
59 case CORBA::tk_enum:
60 continue_append = dest->append_long (*src);
61 break;
62 case CORBA::tk_double:
63 case CORBA::tk_longlong:
64 case CORBA::tk_ulonglong:
65 continue_append = dest->append_double (*src);
66 break;
67 case CORBA::tk_boolean:
68 continue_append = dest->append_boolean (*src);
69 break;
70 case CORBA::tk_char:
71 case CORBA::tk_octet:
72 continue_append = dest->append_octet (*src);
73 break;
74 case CORBA::tk_longdouble:
75 continue_append = dest->append_longdouble (*src);
76 break;
77 case CORBA::tk_wchar:
78 continue_append = dest->append_wchar (*src);
79 break;
80 default:
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)
90 TAOLIB_DEBUG ((
91 LM_DEBUG,
92 ACE_TEXT ("TAO_Marshal_Primitive::append detected error\n")));
94 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
97 TAO::traverse_status
98 TAO_Marshal_Any::append (CORBA::TypeCode_ptr,
99 TAO_InputCDR *src,
100 TAO_OutputCDR *dest)
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);
111 // append the data
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);
124 return retval;
127 TAO::traverse_status
128 TAO_Marshal_TypeCode::append (CORBA::TypeCode_ptr,
129 TAO_InputCDR *src,
130 TAO_OutputCDR *dest)
132 CORBA::Boolean continue_append = true;
133 TAO::traverse_status retval =
134 TAO::TRAVERSE_CONTINUE;
135 CORBA::ULong kind;
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)
141 : false);
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)
149 || (kind == ~0u))
151 // Either a non-constant typecode or an indirected typecode.
152 switch (kind)
154 // Need special handling for all kinds of typecodes that
155 // have nonempty parameter lists ...
156 default:
157 // nothing to de done
158 break;
159 case CORBA::tk_string:
160 case CORBA::tk_wstring:
162 // read and write the bounds
163 retval =
164 TAO_Marshal_Object::perform_append (CORBA::_tc_long,
165 src,
166 dest);
168 break;
170 // Indirected typecodes, illegal at "top level"
171 case ~0u:
173 // read and write the negative offset
174 retval =
175 TAO_Marshal_Object::perform_append (CORBA::_tc_long,
176 src,
177 dest);
179 break;
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:
186 case CORBA::tk_enum:
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:
197 case CORBA::tk_home:
198 case CORBA::tk_event:
200 // write the encapsulation i.e., octet sequence
201 retval =
202 TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq,
203 src,
204 dest);
206 } // end of switch
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);
235 TAO::traverse_status
236 TAO_Marshal_Principal::append (CORBA::TypeCode_ptr,
237 TAO_InputCDR *src,
238 TAO_OutputCDR *dest)
240 // write the octet sequence representing the Principal
241 return TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq, src, dest);
244 TAO::traverse_status
245 TAO_Marshal_ObjRef::append (CORBA::TypeCode_ptr,
246 TAO_InputCDR *src,
247 TAO_OutputCDR *dest)
249 CORBA::Boolean continue_append = true;
251 // First, append the type hint. This will be the type_id encoded in an
252 // object reference.
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)
270 : 0);
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)
280 : 0)) == 0)
281 continue;
283 CORBA::ULong length = 0;
284 if ((continue_append = (CORBA::Boolean) (src->read_ulong (length)
285 ? dest->write_ulong (length)
286 : 0)) == 0)
287 continue;
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],
294 TAO::TRAVERSE_STOP);
295 continue_append =
296 (CORBA::Boolean) (src->read_octet_array (body, length)
297 ? dest->write_octet_array (body, length)
298 : 0);
299 delete [] body;
302 if (continue_append == 1)
303 return TAO::TRAVERSE_CONTINUE;
305 if (TAO_debug_level > 0)
306 TAOLIB_DEBUG ((
307 LM_DEBUG,
308 ACE_TEXT ("TAO_Marshal_ObjRef::append detected error\n")));
310 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
313 TAO::traverse_status
314 TAO_Marshal_Struct::append (CORBA::TypeCode_ptr tc,
315 TAO_InputCDR *src,
316 TAO_OutputCDR *dest)
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 =
324 tc->member_count ();
326 for (CORBA::ULong i = 0;
327 i < member_count && retval == TAO::TRAVERSE_CONTINUE;
328 ++i)
330 // get member type
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);
346 TAO::traverse_status
347 TAO_Marshal_Union::append (CORBA::TypeCode_ptr tc,
348 TAO_InputCDR *src,
349 TAO_OutputCDR *dest)
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;
365 switch (kind)
367 case CORBA::tk_short:
369 if (!src->read_short (short_v)
370 || !dest->write_short (short_v))
371 return TAO::TRAVERSE_STOP;
373 break;
375 case CORBA::tk_ushort:
377 if (!src->read_ushort (ushort_v)
378 || !dest->write_ushort (ushort_v))
379 return TAO::TRAVERSE_STOP;
381 break;
383 case CORBA::tk_long:
385 if (!src->read_long (long_v)
386 || !dest->write_long (long_v))
387 return TAO::TRAVERSE_STOP;
389 break;
391 case CORBA::tk_ulong:
393 if (!src->read_ulong (ulong_v)
394 || !dest->write_ulong (ulong_v))
395 return TAO::TRAVERSE_STOP;
397 break;
399 case CORBA::tk_enum:
401 if (!src->read_ulong (enum_v)
402 || !dest->write_ulong (enum_v))
403 return TAO::TRAVERSE_STOP;
405 break;
407 case CORBA::tk_char:
409 if (!src->read_char (char_v)
410 || !dest->write_char (char_v))
411 return TAO::TRAVERSE_STOP;
413 break;
415 case CORBA::tk_wchar:
417 if (!src->read_wchar (wchar_v)
418 || !dest->write_wchar (wchar_v))
419 return TAO::TRAVERSE_STOP;
421 break;
423 case CORBA::tk_boolean:
425 if (!src->read_boolean (boolean_v)
426 || !dest->write_boolean (boolean_v))
427 return TAO::TRAVERSE_STOP;
429 break;
431 default:
432 return TAO::TRAVERSE_STOP;
435 const CORBA::ULong member_count =
436 tc->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;
445 ++i)
447 CORBA::Any_var any = tc->member_label (i);
449 CORBA::Octet o;
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...
460 default_member = i;
461 continue;
464 switch (kind)
466 case CORBA::tk_short:
468 CORBA::Short d;
469 if ((any >>= d) && d == short_v)
470 current_member = i;
472 break;
474 case CORBA::tk_ushort:
476 CORBA::UShort d;
477 if ((any >>= d) && d == ushort_v)
478 current_member = i;
480 break;
482 case CORBA::tk_long:
484 CORBA::Long d;
485 if ((any >>= d) && d == long_v)
486 current_member = i;
488 break;
490 case CORBA::tk_ulong:
492 CORBA::ULong d;
493 if ((any >>= d) && d == ulong_v)
494 current_member = i;
496 break;
498 case CORBA::tk_enum:
500 CORBA::ULong d;
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);
508 if (!unk)
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);
518 else
520 TAO_OutputCDR out;
521 impl->marshal_value (out);
522 TAO_InputCDR cdr (out);
523 cdr.read_ulong (d);
526 if (d == enum_v)
528 current_member = i;
531 break;
533 case CORBA::tk_char:
535 CORBA::Char d;
536 if ((any >>= CORBA::Any::to_char (d)) && d == char_v)
537 current_member = i;
539 break;
541 case CORBA::tk_wchar:
543 CORBA::WChar d;
544 if ((any >>= CORBA::Any::to_wchar (d)) && d == wchar_v)
545 current_member = i;
547 break;
549 case CORBA::tk_boolean:
551 CORBA::Boolean d;
552 if ((any >>= CORBA::Any::to_boolean (d)) && d == boolean_v)
553 current_member = i;
555 break;
557 default:
558 return TAO::TRAVERSE_STOP;
562 if (current_member == null_member)
564 // Cannot find the current member, check if there is a
565 // default...
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 (),
572 src,
573 dest);
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 (),
586 src,
587 dest);
590 TAO::traverse_status
591 TAO_Marshal_String::append (CORBA::TypeCode_ptr,
592 TAO_InputCDR *src,
593 TAO_OutputCDR *dest)
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);
616 TAO::traverse_status
617 TAO_Marshal_Sequence::append (CORBA::TypeCode_ptr tc,
618 TAO_InputCDR *src,
619 TAO_OutputCDR *dest)
621 // Size of element.
622 CORBA::ULong bounds;
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)
631 : 0);
633 if (!continue_append)
635 TAOLIB_DEBUG ((
636 LM_DEBUG,
637 ACE_TEXT ("TAO_Marshal_Sequence::append detected error\n")));
638 throw ::CORBA::MARSHAL ();
641 if (bounds == 0)
643 return TAO::TRAVERSE_CONTINUE;
646 if (continue_append)
648 // Get element typecode.
649 CORBA::TypeCode_var tc2 =
650 tc->content_type ();
652 TAO::traverse_status retval =
653 TAO::TRAVERSE_CONTINUE;
655 CORBA::TCKind kind = tc2->kind ();
657 switch (kind)
659 case CORBA::tk_octet:
661 char* buf;
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;
669 break;
670 case CORBA::tk_boolean:
672 char* buf;
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;
680 break;
681 case CORBA::tk_char:
683 char* buf;
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;
691 break;
692 case CORBA::tk_short:
694 char* buf;
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;
702 break;
703 case CORBA::tk_ushort:
705 char* buf;
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;
713 break;
714 case CORBA::tk_wchar:
716 char* buf;
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;
724 break;
725 case CORBA::tk_long:
727 char* buf;
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;
735 break;
736 case CORBA::tk_ulong:
738 char* buf;
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;
746 break;
747 case CORBA::tk_float:
749 char* buf;
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;
757 break;
758 case CORBA::tk_double:
760 char* buf;
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;
768 break;
769 case CORBA::tk_longlong:
771 char* buf;
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;
779 break;
780 case CORBA::tk_ulonglong:
782 char* buf;
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;
790 break;
791 case CORBA::tk_longdouble:
793 char* buf;
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;
801 break;
803 default:
804 while (bounds-- && retval == TAO::TRAVERSE_CONTINUE)
806 retval = TAO_Marshal_Object::perform_append (tc2.in (),
807 src,
808 dest);
810 break;
811 }// end of switch
813 if (retval == TAO::TRAVERSE_CONTINUE)
814 return TAO::TRAVERSE_CONTINUE;
816 // error exit
817 if (TAO_debug_level > 0)
818 TAOLIB_DEBUG ((
819 LM_DEBUG,
820 ACE_TEXT ("marshaling TAO_Marshal_Sequence::append detected error\n")));
822 throw ::CORBA::MARSHAL ();
825 TAO::traverse_status
826 TAO_Marshal_Array::append (CORBA::TypeCode_ptr tc,
827 TAO_InputCDR *src,
828 TAO_OutputCDR *dest)
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 ();
839 // Return status.
840 TAO::traverse_status retval =
841 TAO::TRAVERSE_CONTINUE;
843 switch (kind)
845 case CORBA::tk_octet:
847 char* buf;
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;
855 break;
856 case CORBA::tk_boolean:
858 char* buf;
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;
866 break;
867 case CORBA::tk_char:
869 char* buf;
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;
877 break;
878 case CORBA::tk_short:
880 char* buf;
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;
888 break;
889 case CORBA::tk_ushort:
891 char* buf;
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;
899 break;
900 case CORBA::tk_wchar:
902 char* buf;
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;
910 break;
911 case CORBA::tk_long:
913 char* buf;
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;
921 break;
922 case CORBA::tk_ulong:
924 char* buf;
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;
932 break;
933 case CORBA::tk_float:
935 char* buf;
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;
943 break;
944 case CORBA::tk_double:
946 char* buf;
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;
954 break;
955 case CORBA::tk_longlong:
957 char* buf;
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;
965 break;
966 case CORBA::tk_ulonglong:
968 char* buf;
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;
976 break;
977 case CORBA::tk_longdouble:
979 char* buf;
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;
987 break;
988 default:
989 while (bounds-- && retval == TAO::TRAVERSE_CONTINUE)
991 retval = TAO_Marshal_Object::perform_append (tc2.in (),
992 src,
993 dest);
995 break;
996 }// end of switch
998 if (retval == TAO::TRAVERSE_CONTINUE)
999 return retval;
1001 // error exit
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,
1011 TAO_InputCDR *src,
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
1040 // established.
1042 // NOTE: This is asymmetric with respect to encoding exceptions.
1043 TAO::traverse_status
1044 TAO_Marshal_Except::append (CORBA::TypeCode_ptr tc,
1045 TAO_InputCDR *src,
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;
1061 i < member_count
1062 && retval == TAO::TRAVERSE_CONTINUE
1063 && continue_append == 1;
1064 ++i)
1066 param = tc->member_type (i);
1068 retval = TAO_Marshal_Object::perform_append (param.in (),
1069 src,
1070 dest);
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,
1086 TAO_InputCDR *src,
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,
1113 TAO_InputCDR *src,
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 ();
1137 if (orb_core == 0)
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.
1153 //We are done.
1154 return retval;
1156 else if (value_tag & adapter->type_info_single ())
1158 // Append repository id which is of type string.
1159 dest->append_string (*src);
1161 else
1163 //@@ boris: VT CDR
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 (),
1173 src,
1174 dest);
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 (),
1183 src,
1184 dest);
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;
1195 ++i)
1197 // get member type
1198 param = tc->member_type (i);
1200 retval =
1201 TAO_Marshal_Object::perform_append (param.in (),
1202 src,
1203 dest);
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