Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / AnyTypeCode / skip.cpp
blobd78873393edd8c1e67a654d712e467adb461250e
1 //=============================================================================
2 /**
3 * @file skip.cpp
5 * Code for skipping different data types
7 * Data types encoded as CDR streams need to be skipped when they
8 * are part of an Any.
10 * @author Aniruddha Gokhale
12 //=============================================================================
15 #include "tao/AnyTypeCode/Marshal.h"
16 #include "tao/AnyTypeCode/TypeCode.h"
17 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
18 #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 TAO::traverse_status
31 TAO_Marshal_Primitive::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
33 CORBA::Boolean continue_skipping = true;
35 // Status of skip operation.
36 TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
38 CORBA::TCKind const k = tc->kind ();
40 switch (k)
42 case CORBA::tk_null:
43 case CORBA::tk_void:
44 break;
45 case CORBA::tk_short:
46 case CORBA::tk_ushort:
47 continue_skipping = stream->skip_short ();
48 break;
49 case CORBA::tk_long:
50 case CORBA::tk_ulong:
51 case CORBA::tk_float:
52 case CORBA::tk_enum:
53 continue_skipping = stream->skip_long ();
54 break;
55 case CORBA::tk_double:
56 case CORBA::tk_longlong:
57 case CORBA::tk_ulonglong:
58 continue_skipping = stream->skip_longlong ();
59 break;
60 case CORBA::tk_boolean:
61 continue_skipping = stream->skip_boolean ();
62 break;
63 case CORBA::tk_char:
64 case CORBA::tk_octet:
65 continue_skipping = stream->skip_char ();
66 break;
67 case CORBA::tk_longdouble:
68 continue_skipping = stream->skip_longdouble ();
69 break;
70 case CORBA::tk_wchar:
71 continue_skipping = stream->skip_wchar ();
72 break;
73 default:
74 retval = TAO::TRAVERSE_STOP;
75 // we are not a primitive type
77 if (retval == TAO::TRAVERSE_CONTINUE && continue_skipping)
78 return TAO::TRAVERSE_CONTINUE;
79 else
81 if (TAO_debug_level > 0)
82 TAOLIB_DEBUG ((
83 LM_DEBUG,
84 ACE_TEXT ("TAO_Marshal_Primitive::skip detected error\n")
85 ));
86 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
90 TAO::traverse_status
91 TAO_Marshal_Any::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
93 // Typecode of the element that makes the Any.
94 CORBA::TypeCode_var elem_tc;
96 // Status of encode operation.
97 if (!(*stream >> elem_tc.inout ()))
98 return TAO::TRAVERSE_STOP;
100 return TAO_Marshal_Object::perform_skip (elem_tc.in (), stream);
103 TAO::traverse_status
104 TAO_Marshal_TypeCode::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
106 CORBA::Boolean continue_skipping = true;
108 // Typecode kind.
109 CORBA::ULong kind;
111 // Decode the "kind" field of the typecode from the stream.
112 continue_skipping = stream->read_ulong (kind);
114 if (continue_skipping)
116 // Typecodes with empty parameter lists all have preallocated
117 // constants. We use those to reduce memory consumption and
118 // heap access ... also, to speed things up!
119 if ((kind < CORBA::TAO_TC_KIND_COUNT) ||
120 (kind == ~0u))
122 // Either a non-constant typecode or an indirected typecode.
123 switch (kind)
125 // Need special handling for all kinds of typecodes that
126 // have nonempty parameter lists ...
127 default:
128 // simple typecodes, nothing to do
129 break;
130 case CORBA::tk_string:
131 case CORBA::tk_wstring:
133 // skip the bounds
134 continue_skipping = stream->skip_ulong ();
136 break;
138 // Indirected typecodes, illegal at "top level".
139 case ~0u:
141 // skip the long indicating the encapsulation offset,
142 continue_skipping = stream->skip_long ();
144 break;
146 // The rest have "complex" parameter lists that are
147 // encoded as bulk octets ...
148 case CORBA::tk_objref:
149 case CORBA::tk_struct:
150 case CORBA::tk_union:
151 case CORBA::tk_enum:
152 case CORBA::tk_sequence:
153 case CORBA::tk_array:
154 case CORBA::tk_alias:
155 case CORBA::tk_except:
156 case CORBA::tk_value:
157 case CORBA::tk_value_box:
158 case CORBA::tk_native:
159 case CORBA::tk_abstract_interface:
160 case CORBA::tk_local_interface:
161 case CORBA::tk_component:
162 case CORBA::tk_home:
163 case CORBA::tk_event:
165 CORBA::ULong length;
167 // get the encapsulation length
168 continue_skipping = stream->read_ulong (length);
169 if (!continue_skipping)
170 break;
171 // skip the encapsulation
172 continue_skipping = stream->skip_bytes (length);
174 } // end of switch
176 else // bad kind_ value to be decoded
178 if (TAO_debug_level > 0)
179 TAOLIB_DEBUG ((LM_DEBUG,
180 ACE_TEXT ("TAO_Marshal_TypeCode::skip: ")
181 ACE_TEXT ("Bad kind_ value in CDR stream\n")));
182 throw ::CORBA::BAD_TYPECODE ();
186 if (continue_skipping)
187 return TAO::TRAVERSE_CONTINUE;
188 else
190 if (TAO_debug_level > 0)
191 TAOLIB_DEBUG ((
192 LM_DEBUG,
193 ACE_TEXT ("TAO_Marshal_TypeCode::skip detected error\n")
195 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
199 TAO::traverse_status
200 TAO_Marshal_Principal::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
202 CORBA::Boolean continue_skipping = true;
204 // specifies the number of bytes in the Principal
205 CORBA::ULong len;
207 continue_skipping = stream->read_ulong (len);
208 if (len > 0 && continue_skipping)
210 continue_skipping = stream->skip_bytes (len);
213 if (continue_skipping)
214 return TAO::TRAVERSE_CONTINUE;
215 else
217 if (TAO_debug_level > 0)
218 TAOLIB_DEBUG ((
219 LM_DEBUG,
220 ACE_TEXT ("TAO_Marshal_Principal::skip detected error\n")
222 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
226 TAO::traverse_status
227 TAO_Marshal_ObjRef::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
229 CORBA::Boolean continue_skipping = true;
231 // return status
232 TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
234 // First, skip the type hint. This will be the type_id encoded in an
235 // object reference.
236 stream->skip_string ();
238 // Read the profiles, discarding all until an IIOP profile comes by.
239 // Once we see an IIOP profile, ignore any further ones.
241 // XXX this will need to change someday to let different protocol
242 // code be accessed, not just IIOP. Protocol modules will be
243 // dynamically loaded from shared libraries via ORB_init (), and we
244 // just need to be able to access such preloaded libraries here as
245 // we unmarshal objrefs.
246 CORBA::ULong profiles = 0;
248 // get the count of profiles that follow
249 continue_skipping = stream->read_ulong (profiles);
251 while (profiles-- != 0 && continue_skipping)
253 CORBA::ULong tag;
255 // get the profile ID tag
256 if ( (continue_skipping = stream->read_ulong (tag)) == 0)
257 continue;
259 CORBA::ULong encap_len;
260 // ProfileData is encoded as a sequence of octet. So first get
261 // the length of the sequence.
262 // Create the decoding stream from the encapsulation in the
263 // buffer, and skip the encapsulation.
264 if ( (continue_skipping = stream->read_ulong (encap_len)) == 0)
265 continue;
267 continue_skipping = stream->skip_bytes (encap_len);
270 if (retval == TAO::TRAVERSE_CONTINUE && continue_skipping)
271 return TAO::TRAVERSE_CONTINUE;
272 else
274 if (TAO_debug_level > 0)
275 TAOLIB_DEBUG ((
276 LM_DEBUG,
277 ACE_TEXT ("TAO_Marshal_ObjRef::skip detected error\n")
279 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
283 TAO::traverse_status
284 TAO_Marshal_Struct::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
286 TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
287 CORBA::TypeCode_var param;
289 // Number of fields in the struct.
290 CORBA::ULong const member_count =
291 tc->member_count ();
293 for (CORBA::ULong i = 0;
294 i < member_count && retval == TAO::TRAVERSE_CONTINUE;
295 ++i)
297 param = tc->member_type (i);
299 retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
302 if (retval == TAO::TRAVERSE_CONTINUE)
303 return TAO::TRAVERSE_CONTINUE;
305 if (TAO_debug_level > 0)
306 TAOLIB_DEBUG ((LM_DEBUG,
307 ACE_TEXT ("TAO_Marshal_Struct::skip detected error\n")));
309 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
312 TAO::traverse_status
313 TAO_Marshal_Union::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *src)
315 CORBA::TypeCode_var discrim_tc =
316 tc->discriminator_type ();
318 CORBA::ULong const kind =
319 discrim_tc->kind ();
321 // Save the discriminator value in a temporary variable...
322 CORBA::Short short_v = CORBA::Short();
323 CORBA::UShort ushort_v = CORBA::UShort();
324 CORBA::Long long_v = CORBA::Long();
325 CORBA::ULong ulong_v = CORBA::ULong();
326 CORBA::ULong enum_v = CORBA::ULong();
327 CORBA::Char char_v = CORBA::Char();
328 CORBA::WChar wchar_v = CORBA::WChar();
329 CORBA::Boolean boolean_v = false;
331 switch (kind)
333 case CORBA::tk_short:
335 if (!src->read_short (short_v))
336 return TAO::TRAVERSE_STOP;
338 break;
340 case CORBA::tk_ushort:
342 if (!src->read_ushort (ushort_v))
343 return TAO::TRAVERSE_STOP;
345 break;
347 case CORBA::tk_long:
349 if (!src->read_long (long_v))
350 return TAO::TRAVERSE_STOP;
352 break;
354 case CORBA::tk_ulong:
356 if (!src->read_ulong (ulong_v))
357 return TAO::TRAVERSE_STOP;
359 break;
361 case CORBA::tk_enum:
363 if (!src->read_ulong (enum_v))
364 return TAO::TRAVERSE_STOP;
366 break;
368 case CORBA::tk_char:
370 if (!src->read_char (char_v))
371 return TAO::TRAVERSE_STOP;
373 break;
375 case CORBA::tk_wchar:
377 if (!src->read_wchar (wchar_v))
378 return TAO::TRAVERSE_STOP;
380 break;
382 case CORBA::tk_boolean:
384 if (!src->read_boolean (boolean_v))
385 return TAO::TRAVERSE_STOP;
387 break;
389 default:
390 return TAO::TRAVERSE_STOP;
393 const CORBA::ULong member_count =
394 tc->member_count ();
396 const CORBA::ULong null_member = ~static_cast<CORBA::ULong> (0U);
398 CORBA::ULong current_member = null_member;
399 CORBA::ULong default_member = null_member;
401 for (CORBA::ULong i = 0;
402 i < member_count && current_member == null_member;
403 ++i)
405 CORBA::Any_var any = tc->member_label (i);
407 CORBA::Octet o;
408 if ((any >>= CORBA::Any::to_octet (o)) && o == 0)
410 CORBA::ULong default_index =
411 tc->default_index ();
413 if (i != default_index)
414 throw ::CORBA::BAD_TYPECODE ();
415 // Found the default branch, save its position and continue
416 // trying to find the current value...
417 default_member = i;
418 continue;
421 switch (kind)
423 case CORBA::tk_short:
425 CORBA::Short d;
426 if ((any >>= d) && d == short_v)
427 current_member = i;
429 break;
431 case CORBA::tk_ushort:
433 CORBA::UShort d;
434 if ((any >>= d) && d == ushort_v)
435 current_member = i;
437 break;
439 case CORBA::tk_long:
441 CORBA::Long d;
442 if ((any >>= d) && d == long_v)
443 current_member = i;
445 break;
447 case CORBA::tk_ulong:
449 CORBA::ULong d;
450 if ((any >>= d) && d == ulong_v)
451 current_member = i;
453 break;
455 case CORBA::tk_enum:
457 CORBA::ULong d;
458 TAO::Any_Impl *impl = any->impl ();
460 if (impl->encoded ())
462 TAO::Unknown_IDL_Type * const unk =
463 dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
465 if (!unk)
466 throw ::CORBA::INTERNAL ();
468 // We don't want unk's rd_ptr to move, in case
469 // we are shared by another Any, so we use this
470 // to copy the state, not the buffer.
471 TAO_InputCDR for_reading (unk->_tao_get_cdr ());
473 for_reading.read_ulong (d);
475 else
477 TAO_OutputCDR out;
478 impl->marshal_value (out);
479 TAO_InputCDR cdr (out);
480 cdr.read_ulong (d);
483 if (d == enum_v)
485 current_member = i;
488 break;
490 case CORBA::tk_char:
492 CORBA::Char d;
493 if ((any >>= CORBA::Any::to_char (d)) && d == char_v)
494 current_member = i;
496 break;
498 case CORBA::tk_wchar:
500 CORBA::WChar d;
501 if ((any >>= CORBA::Any::to_wchar (d)) && d == wchar_v)
502 current_member = i;
504 break;
506 case CORBA::tk_boolean:
508 CORBA::Boolean d;
509 if ((any >>= CORBA::Any::to_boolean (d)) && d == boolean_v)
510 current_member = i;
512 break;
514 default:
515 return TAO::TRAVERSE_STOP;
519 if (current_member == null_member)
521 // Cannot find the current member, check if there is a
522 // default...
523 if (default_member != null_member)
525 // Good, use the default to append...
526 CORBA::TypeCode_var member_tc =
527 tc->member_type (default_member);
528 return TAO_Marshal_Object::perform_skip (member_tc.in (), src);
531 // If we're here, we have an implicit default case, and we
532 // should just return without skipping anything, since no
533 // union member was marshaled in the first place.
534 return TAO::TRAVERSE_CONTINUE;
537 // If we found the member successfully then just use that one...
538 CORBA::TypeCode_var member_tc =
539 tc->member_type (current_member);
541 return TAO_Marshal_Object::perform_skip (member_tc.in (), src);
544 TAO::traverse_status
545 TAO_Marshal_String::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
547 CORBA::Boolean continue_skipping = true;
549 // On decode, omit the check against specified string bounds, and
550 // cope with illegal "zero length" strings (all lengths on the wire
551 // must include a NUL).
553 // This is on the principle of being gracious in what we accept; we
554 // don't generate messages that fail to comply with protocol specs,
555 // but we will accept them when it's clear how to do so.
557 continue_skipping = stream->skip_string ();
558 if (continue_skipping)
559 return TAO::TRAVERSE_CONTINUE;
560 else
562 if (TAO_debug_level > 0)
563 TAOLIB_DEBUG ((LM_DEBUG,
564 ACE_TEXT ("TAO_Marshal_String::skip detected error\n")));
565 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
569 TAO::traverse_status
570 TAO_Marshal_Sequence::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
572 // Size of element.
573 CORBA::ULong bounds;
575 // First unmarshal the sequence length ... we trust it to be right
576 // here, on the "be gracious in what you accept" principle. We
577 // don't generate illegal sequences (i.e. length > bounds).
579 CORBA::Boolean continue_skipping =
580 stream->read_ulong (bounds);
582 if (!continue_skipping)
584 TAOLIB_DEBUG ((LM_DEBUG,
585 ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
586 throw ::CORBA::MARSHAL ();
589 // No point decoding an empty sequence.
590 if (bounds == 0)
591 return TAO::TRAVERSE_CONTINUE;
593 // Get element typecode.
594 CORBA::TypeCode_var tc2 =
595 tc->content_type ();
597 // For CORBA basic types, the skip can be optimized
598 CORBA::TCKind const kind = tc2->kind ();
600 char *dummy = 0;
601 switch (kind)
603 case CORBA::tk_octet:
604 case CORBA::tk_boolean:
605 case CORBA::tk_char:
607 stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
608 continue_skipping =
609 stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
611 break;
612 case CORBA::tk_short:
613 case CORBA::tk_ushort:
614 case CORBA::tk_wchar:
616 stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
617 continue_skipping =
618 stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
620 break;
621 case CORBA::tk_long:
622 case CORBA::tk_ulong:
623 case CORBA::tk_float:
625 stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
626 continue_skipping =
627 stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
629 break;
630 case CORBA::tk_double:
631 case CORBA::tk_longlong:
632 case CORBA::tk_ulonglong:
634 stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
635 continue_skipping =
636 stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
638 break;
639 case CORBA::tk_longdouble:
641 stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
642 continue_skipping =
643 stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
645 break;
647 default:
648 while (bounds-- && continue_skipping)
650 continue_skipping =
651 TAO_Marshal_Object::perform_skip (tc2.in (), stream);
653 break;
654 }// end of switch
656 if (continue_skipping)
657 return TAO::TRAVERSE_CONTINUE;
659 // error exit
660 if (TAO_debug_level > 0)
661 TAOLIB_DEBUG ((LM_DEBUG,
662 ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
664 throw ::CORBA::MARSHAL ();
667 TAO::traverse_status
668 TAO_Marshal_Array::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
670 CORBA::Boolean continue_skipping = true;
672 // retrieve the bounds of the array
673 CORBA::ULong bounds = tc->length ();
675 // get element typecode
676 // Typecode of the element.
677 CORBA::TypeCode_var tc2 = tc->content_type ();
679 // For CORBA basic types, the skip can be optimized
680 CORBA::TCKind const kind = tc2->kind ();
682 char *dummy;
683 switch (kind)
685 case CORBA::tk_octet:
686 case CORBA::tk_boolean:
687 case CORBA::tk_char:
689 stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
690 continue_skipping =
691 stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
693 break;
694 case CORBA::tk_short:
695 case CORBA::tk_ushort:
696 case CORBA::tk_wchar:
698 stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
699 continue_skipping =
700 stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
702 break;
703 case CORBA::tk_long:
704 case CORBA::tk_ulong:
705 case CORBA::tk_float:
707 stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
708 continue_skipping =
709 stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
711 break;
712 case CORBA::tk_double:
713 case CORBA::tk_longlong:
714 case CORBA::tk_ulonglong:
716 stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
717 continue_skipping =
718 stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
720 break;
721 case CORBA::tk_longdouble:
723 stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
724 continue_skipping =
725 stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
727 break;
729 default:
730 while (bounds-- && continue_skipping)
732 int stop =
733 TAO_Marshal_Object::perform_skip (tc2.in (), stream);
734 if (stop == TAO::TRAVERSE_STOP)
735 continue_skipping = false;
737 break;
738 }// end of switch
740 if (continue_skipping)
741 return TAO::TRAVERSE_CONTINUE;
743 // error exit
744 if (TAO_debug_level > 0)
745 TAOLIB_DEBUG ((LM_DEBUG,
746 ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
748 throw ::CORBA::MARSHAL ();
751 TAO::traverse_status
752 TAO_Marshal_Alias::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
754 // Typecode of the aliased type.
755 CORBA::TypeCode_var tc2;
756 CORBA::Boolean continue_skipping = true;
758 // Status of decode operation.
759 TAO::traverse_status retval =
760 TAO::TRAVERSE_CONTINUE;
762 tc2 = tc->content_type ();
764 retval = TAO_Marshal_Object::perform_skip (tc2.in (), stream);
766 // tc2->_decr_refcnt ();
767 if (retval == TAO::TRAVERSE_CONTINUE
768 && continue_skipping)
769 return TAO::TRAVERSE_CONTINUE;
771 if (TAO_debug_level > 0)
772 TAOLIB_DEBUG ((LM_DEBUG,
773 ACE_TEXT ("TAO_Marshal_Alias::skip detected error\n")));
775 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
778 // Decode exception For exceptions, the "hidden" type ID near the
779 // front of the on-wire representation was previously unmarshaled and
780 // mapped to the "tc" typcode we're using to traverse the memory ...
781 // at the same time its vtable, refcount, and other state was
782 // established.
784 // NOTE: This is asymmetric with respect to encoding exceptions.
785 TAO::traverse_status
786 TAO_Marshal_Except::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
788 TAO::traverse_status retval =
789 TAO::TRAVERSE_CONTINUE;
790 CORBA::TypeCode_var param;
792 // skip the Repository ID
793 if (!stream->skip_string ())
794 return TAO::TRAVERSE_STOP;
796 // Number of fields in the exception
797 const CORBA::ULong member_count =
798 tc->member_count ();
800 for (CORBA::ULong i = 0;
801 i < member_count && retval == TAO::TRAVERSE_CONTINUE;
802 ++i)
804 param = tc->member_type (i);
806 retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
809 if (retval == TAO::TRAVERSE_CONTINUE)
810 return TAO::TRAVERSE_CONTINUE;
812 if (TAO_debug_level > 0)
813 TAOLIB_DEBUG ((LM_DEBUG,
814 ACE_TEXT ("TAO_Marshal_Except::skip detected error\n")));
816 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
819 // decode wstring
820 TAO::traverse_status
821 TAO_Marshal_WString::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
823 CORBA::Boolean continue_skipping = true;
825 // On decode, omit the check against specified wstring bounds, and
826 // cope with illegal "zero length" strings (all lengths on the wire
827 // must include a NUL).
829 // This is on the principle of being gracious in what we accept; we
830 // don't generate messages that fail to comply with protocol specs,
831 // but we will accept them when it's clear how to do so.
833 // "zero length" wstrings are legal in GIOP 1.2.
835 continue_skipping = stream->skip_wstring ();
837 if (continue_skipping)
838 return TAO::TRAVERSE_CONTINUE;
840 if (TAO_debug_level > 0)
841 TAOLIB_DEBUG ((LM_DEBUG,
842 ACE_TEXT ("TAO_Marshal_WString::skip detected error\n")));
843 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
846 TAO::traverse_status
847 TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
849 TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
851 // Use the same method to skip over our base valuetype.
852 // To achive this we'll need to distinguish between
853 // first-time/nested skips so that we won't attempt to
854 // skip rep_id several times.
856 if (this->nested_processing_ == false)
858 this->nested_processing_ = true;
860 CORBA::Long value_tag;
862 if (!stream->read_long (value_tag))
864 return TAO::TRAVERSE_STOP;
867 TAO_ORB_Core *orb_core = stream->orb_core ();
868 if (orb_core == 0)
870 orb_core = TAO_ORB_Core_instance ();
872 if (TAO_debug_level > 0)
874 TAOLIB_DEBUG ((LM_WARNING,
875 "TAO (%P|%t) WARNING: extracting "
876 "valuetype using default ORB_Core\n"));
880 TAO_Valuetype_Adapter *adapter = orb_core->valuetype_adapter();
882 if (value_tag == 0) // Null value type pointer.
884 // We are done.
885 return retval;
887 else if (adapter->is_type_info_single(value_tag))
889 // Skip a single repository id which is of type string.
890 stream->skip_string ();
892 else if (adapter->is_type_info_list(value_tag))
894 CORBA::Long num_types;
895 if (!stream->read_long (num_types))
897 return TAO::TRAVERSE_STOP;
899 while (num_types > 0)
901 stream->skip_string();
902 num_types--;
905 else if (!adapter->is_type_info_implied (value_tag))
907 //@@ boris: VT CDR
908 return TAO::TRAVERSE_STOP;
911 if (adapter->is_value_chunked (value_tag))
913 CORBA::Long chunk_tag = 0;
914 while (chunk_tag != -1)
916 if (!stream->read_long (chunk_tag))
917 return TAO::TRAVERSE_STOP;
919 if (chunk_tag > 0)
921 if (!stream->skip_bytes(chunk_tag))
922 return TAO::TRAVERSE_STOP;
925 return TAO::TRAVERSE_CONTINUE;
930 CORBA::TypeCode_var param;
932 if (CORBA::tk_value_box == tc->kind ())
934 param = tc->content_type ();
935 retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
937 else // tc->kind () must be tk_value or tk_event
939 // Handle our base valuetype if any.
940 param = tc->concrete_base_type ();
941 if (CORBA::tk_null != param->kind ())
943 retval = this->skip (param.in (), stream);
946 if (retval == TAO::TRAVERSE_CONTINUE)
948 // Number of fields in the valuetype.
949 CORBA::ULong const member_count =
950 tc->member_count ();
952 for (CORBA::ULong i = 0;
953 i < member_count && retval == TAO::TRAVERSE_CONTINUE;
954 ++i)
956 param = tc->member_type (i);
957 retval = TAO_Marshal_Object::perform_skip (
958 param.in (), stream);
963 if (retval == TAO::TRAVERSE_CONTINUE)
964 return TAO::TRAVERSE_CONTINUE;
966 if (TAO_debug_level > 0)
967 TAOLIB_DEBUG ((LM_DEBUG,
968 ACE_TEXT ("TAO_Marshal_Value::skip detected error\n")));
970 throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
973 TAO_END_VERSIONED_NAMESPACE_DECL