summaryrefslogtreecommitdiff
path: root/TAO/tao/AnyTypeCode/skip.cpp
diff options
context:
space:
mode:
authorJohnny Willemsen <jwillemsen@remedy.nl>2005-08-19 08:28:35 +0000
committerJohnny Willemsen <jwillemsen@remedy.nl>2005-08-19 08:28:35 +0000
commit7c9c3741e02d1569824dd6d024bd81e03febb2c7 (patch)
tree279233684289a024587c0885378eeee4079b9f01 /TAO/tao/AnyTypeCode/skip.cpp
parent7f61ed4f18c496890fbdf75300b1135d6911d9aa (diff)
downloadATCD-7c9c3741e02d1569824dd6d024bd81e03febb2c7.tar.gz
ChangeLogTag Fri Aug 19 07:56:12 UTC 2005 Johnny Willemsen <jwillemsen@remedy.nl>
Diffstat (limited to 'TAO/tao/AnyTypeCode/skip.cpp')
-rw-r--r--TAO/tao/AnyTypeCode/skip.cpp1042
1 files changed, 1042 insertions, 0 deletions
diff --git a/TAO/tao/AnyTypeCode/skip.cpp b/TAO/tao/AnyTypeCode/skip.cpp
new file mode 100644
index 00000000000..31fd7a14552
--- /dev/null
+++ b/TAO/tao/AnyTypeCode/skip.cpp
@@ -0,0 +1,1042 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// skip.cpp
+//
+// = DESCRIPTION
+// Code for skipping different data types
+//
+// Data types encoded as CDR streams need to be skipped when they
+// are part of an Any.
+//
+// = AUTHOR
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include "Marshal.h"
+#include "TypeCode.h"
+#include "Any_Unknown_IDL_Type.h"
+#include "Any.h"
+
+#include "tao/debug.h"
+#include "tao/Valuetype_Adapter.h"
+#include "tao/ORB_Core.h"
+#include "tao/CDR.h"
+#include "tao/SystemException.h"
+
+#include "ace/Dynamic_Service.h"
+
+ACE_RCSID (tao,
+ skip,
+ "$Id$")
+
+TAO::traverse_status
+TAO_Marshal_Primitive::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+ // Status of skip operation.
+ TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
+
+ CORBA::TCKind const k = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ switch (k)
+ {
+ case CORBA::tk_null:
+ case CORBA::tk_void:
+ break;
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ continue_skipping = stream->skip_short ();
+ break;
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_float:
+ case CORBA::tk_enum:
+ continue_skipping = stream->skip_long ();
+ break;
+ case CORBA::tk_double:
+ case CORBA::tk_longlong:
+ case CORBA::tk_ulonglong:
+ continue_skipping = stream->skip_longlong ();
+ break;
+ case CORBA::tk_boolean:
+ continue_skipping = stream->skip_boolean ();
+ break;
+ case CORBA::tk_char:
+ case CORBA::tk_octet:
+ continue_skipping = stream->skip_char ();
+ break;
+ case CORBA::tk_longdouble:
+ continue_skipping = stream->skip_longdouble ();
+ break;
+ case CORBA::tk_wchar:
+ continue_skipping = stream->skip_wchar ();
+ break;
+ default:
+ retval = TAO::TRAVERSE_STOP;
+ // we are not a primitive type
+ }
+ if (retval == TAO::TRAVERSE_CONTINUE
+ && continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Primitive::skip detected error\n")
+ ));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+ }
+}
+
+TAO::traverse_status
+TAO_Marshal_Any::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ // Typecode of the element that makes the Any.
+ CORBA::TypeCode_var elem_tc;
+
+ // Status of encode operation.
+ if (!(*stream >> elem_tc.inout ()))
+ return TAO::TRAVERSE_STOP;
+
+ return TAO_Marshal_Object::perform_skip (elem_tc.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+}
+
+TAO::traverse_status
+TAO_Marshal_TypeCode::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+ // Typecode kind.
+ CORBA::ULong kind;
+
+ // Decode the "kind" field of the typecode from the stream.
+ continue_skipping = stream->read_ulong (kind);
+
+ if (continue_skipping == 1)
+ {
+ // Typecodes with empty parameter lists all have preallocated
+ // constants. We use those to reduce memory consumption and
+ // heap access ... also, to speed things up!
+ if ((kind < CORBA::TAO_TC_KIND_COUNT) ||
+ (kind == ~0u))
+ {
+ // Either a non-constant typecode or an indirected typecode.
+ switch (kind)
+ {
+ // Need special handling for all kinds of typecodes that
+ // have nonempty parameter lists ...
+ default:
+ // simple typecodes, nothing to do
+ break;
+ case CORBA::tk_string:
+ case CORBA::tk_wstring:
+ {
+ // skip the bounds
+ continue_skipping = stream->skip_ulong ();
+ }
+ break;
+
+ // Indirected typecodes, illegal at "top level".
+ case ~0u:
+ {
+ // skip the long indicating the encapsulation offset,
+ continue_skipping = stream->skip_long ();
+ }
+ break;
+
+ // The rest have "complex" parameter lists that are
+ // encoded as bulk octets ...
+ case CORBA::tk_objref:
+ case CORBA::tk_struct:
+ case CORBA::tk_union:
+ case CORBA::tk_enum:
+ case CORBA::tk_sequence:
+ case CORBA::tk_array:
+ case CORBA::tk_alias:
+ case CORBA::tk_except:
+ case CORBA::tk_value:
+ case CORBA::tk_value_box:
+ case CORBA::tk_native:
+ case CORBA::tk_abstract_interface:
+ case CORBA::tk_local_interface:
+ case CORBA::tk_component:
+ case CORBA::tk_home:
+ case CORBA::tk_event:
+ {
+ CORBA::ULong length;
+
+ // get the encapsulation length
+ continue_skipping = stream->read_ulong (length);
+ if (!continue_skipping)
+ break;
+ // skip the encapsulation
+ continue_skipping = stream->skip_bytes (length);
+ }
+ } // end of switch
+ }
+ else // bad kind_ value to be decoded
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_TypeCode::skip: ")
+ ACE_TEXT ("Bad kind_ value in CDR stream\n")));
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ TAO::TRAVERSE_STOP);
+ }
+ }
+
+ if (continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_TypeCode::skip detected error\n")
+ ));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+ }
+}
+
+TAO::traverse_status
+TAO_Marshal_Principal::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+ // specifies the number of bytes in the Principal
+ CORBA::ULong len;
+
+ continue_skipping = stream->read_ulong (len);
+ if (len > 0 && continue_skipping)
+ {
+ continue_skipping = stream->skip_bytes (len);
+ }
+
+ if (continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Principal::skip detected error\n")
+ ));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+ }
+}
+
+TAO::traverse_status
+TAO_Marshal_ObjRef::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+ // return status
+ TAO::traverse_status retval =
+ TAO::TRAVERSE_CONTINUE;
+
+ // First, skip the type hint. This will be the type_id encoded in an
+ // object reference.
+ stream->skip_string ();
+
+ // Read the profiles, discarding all until an IIOP profile comes by.
+ // Once we see an IIOP profile, ignore any further ones.
+ //
+ // XXX this will need to change someday to let different protocol
+ // code be accessed, not just IIOP. Protocol modules will be
+ // dynamically loaded from shared libraries via ORB_init (), and we
+ // just need to be able to access such preloaded libraries here as
+ // we unmarshal objrefs.
+ CORBA::ULong profiles = 0;
+
+ // get the count of profiles that follow
+ continue_skipping = stream->read_ulong (profiles);
+
+ while (profiles-- != 0 && continue_skipping)
+ {
+ CORBA::ULong tag;
+
+ // get the profile ID tag
+ if ( (continue_skipping = stream->read_ulong (tag)) == 0)
+ continue;
+
+ CORBA::ULong encap_len;
+ // ProfileData is encoded as a sequence of octet. So first get
+ // the length of the sequence.
+ // Create the decoding stream from the encapsulation in the
+ // buffer, and skip the encapsulation.
+ if ( (continue_skipping = stream->read_ulong (encap_len)) == 0)
+ continue;
+
+ continue_skipping = stream->skip_bytes (encap_len);
+ }
+
+ if (retval == TAO::TRAVERSE_CONTINUE
+ && continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_ObjRef::skip detected error\n")
+ ));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+ }
+}
+
+TAO::traverse_status
+TAO_Marshal_Struct::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_var param;
+
+ // Number of fields in the struct.
+ const CORBA::ULong member_count =
+ tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ for (CORBA::ULong i = 0;
+ i < member_count && retval == TAO::TRAVERSE_CONTINUE;
+ ++i)
+ {
+ param = tc->member_type (i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ retval = TAO_Marshal_Object::perform_skip (param.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ }
+
+ if (retval == TAO::TRAVERSE_CONTINUE)
+ return TAO::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Struct::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+}
+
+TAO::traverse_status
+TAO_Marshal_Union::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *src
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::TypeCode_var discrim_tc =
+ tc->discriminator_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ CORBA::ULong kind =
+ discrim_tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ // Save the discriminator value in a temporary variable...
+ CORBA::Short short_v;
+ CORBA::UShort ushort_v;
+ CORBA::Long long_v;
+ CORBA::ULong ulong_v;
+ CORBA::ULong enum_v;
+ CORBA::Char char_v;
+ CORBA::WChar wchar_v;
+ CORBA::Boolean boolean_v = false;;
+
+ switch (kind)
+ {
+ case CORBA::tk_short:
+ {
+ if (!src->read_short (short_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_ushort:
+ {
+ if (!src->read_ushort (ushort_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_long:
+ {
+ if (!src->read_long (long_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_ulong:
+ {
+ if (!src->read_ulong (ulong_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_enum:
+ {
+ if (!src->read_ulong (enum_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_char:
+ {
+ if (!src->read_char (char_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_wchar:
+ {
+ if (!src->read_wchar (wchar_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ case CORBA::tk_boolean:
+ {
+ if (!src->read_boolean (boolean_v))
+ return TAO::TRAVERSE_STOP;
+ }
+ break;
+
+ default:
+ return TAO::TRAVERSE_STOP;
+ }
+
+ const CORBA::ULong member_count =
+ tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ const CORBA::ULong null_member = ~static_cast<CORBA::ULong> (0U);
+
+ CORBA::ULong current_member = null_member;
+ CORBA::ULong default_member = null_member;
+
+ for (CORBA::ULong i = 0;
+ i < member_count && current_member == null_member;
+ ++i)
+ {
+ CORBA::Any_var any = tc->member_label (i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ CORBA::Octet o;
+ if ((any >>= CORBA::Any::to_octet (o)) && o == 0)
+ {
+ CORBA::ULong default_index =
+ tc->default_index (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ if (i != default_index)
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ TAO::TRAVERSE_STOP);
+ // Found the default branch, save its position and continue
+ // trying to find the current value...
+ default_member = i;
+ continue;
+ }
+
+ switch (kind)
+ {
+ case CORBA::tk_short:
+ {
+ CORBA::Short d;
+ if ((any >>= d) && d == short_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_ushort:
+ {
+ CORBA::UShort d;
+ if ((any >>= d) && d == ushort_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_long:
+ {
+ CORBA::Long d;
+ if ((any >>= d) && d == long_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_ulong:
+ {
+ CORBA::ULong d;
+ if ((any >>= d) && d == ulong_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_enum:
+ {
+ CORBA::ULong d;
+ TAO::Any_Impl *impl = any->impl ();
+
+ if (impl->encoded ())
+ {
+ TAO::Unknown_IDL_Type *unk =
+ dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
+
+ // We don't want unk's rd_ptr to move, in case
+ // we are shared by another Any, so we use this
+ // to copy the state, not the buffer.
+ TAO_InputCDR for_reading (unk->_tao_get_cdr ());
+
+ for_reading.read_ulong (d);
+ }
+ else
+ {
+ TAO_OutputCDR out;
+ impl->marshal_value (out);
+ TAO_InputCDR cdr (out);
+ cdr.read_ulong (d);
+ }
+
+ if (d == enum_v)
+ {
+ current_member = i;
+ }
+ }
+ break;
+
+ case CORBA::tk_char:
+ {
+ CORBA::Char d;
+ if ((any >>= CORBA::Any::to_char (d)) && d == char_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_wchar:
+ {
+ CORBA::WChar d;
+ if ((any >>= CORBA::Any::to_wchar (d)) && d == wchar_v)
+ current_member = i;
+ }
+ break;
+
+ case CORBA::tk_boolean:
+ {
+ CORBA::Boolean d;
+ if ((any >>= CORBA::Any::to_boolean (d)) && d == boolean_v)
+ current_member = i;
+ }
+ break;
+
+ default:
+ return TAO::TRAVERSE_STOP;
+ }
+ }
+
+ if (current_member == null_member)
+ {
+ // Cannot find the current member, check if there is a
+ // default...
+ if (default_member != null_member)
+ {
+ // Good, use the default to append...
+ CORBA::TypeCode_var member_tc =
+ tc->member_type (default_member ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ return TAO_Marshal_Object::perform_skip (member_tc.in (),
+ src
+ ACE_ENV_ARG_PARAMETER);
+ }
+
+ // If we're here, we have an implicit default case, and we
+ // should just return without skipping anything, since no
+ // union member was marshaled in the first place.
+ return TAO::TRAVERSE_CONTINUE;
+ }
+
+ // If we found the member successfully then just use that one...
+ CORBA::TypeCode_var member_tc =
+ tc->member_type (current_member ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ return TAO_Marshal_Object::perform_skip (member_tc.in (),
+ src
+ ACE_ENV_ARG_PARAMETER);
+}
+
+TAO::traverse_status
+TAO_Marshal_String::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+ // On decode, omit the check against specified string bounds, and
+ // cope with illegal "zero length" strings (all lengths on the wire
+ // must include a NUL).
+ //
+ // This is on the principle of being gracious in what we accept; we
+ // don't generate messages that fail to comply with protocol specs,
+ // but we will accept them when it's clear how to do so.
+
+ continue_skipping = stream->skip_string ();
+ if (continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_String::skip detected error\n")));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+ }
+}
+
+TAO::traverse_status
+TAO_Marshal_Sequence::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ // Size of element.
+ CORBA::ULong bounds;
+
+ // First unmarshal the sequence length ... we trust it to be right
+ // here, on the "be gracious in what you accept" principle. We
+ // don't generate illegal sequences (i.e. length > bounds).
+
+ CORBA::Boolean continue_skipping =
+ stream->read_ulong (bounds);
+
+ if (!continue_skipping)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
+ ACE_THROW_RETURN (CORBA::MARSHAL (),
+ TAO::TRAVERSE_STOP);
+ }
+
+ // No point decoding an empty sequence.
+ if (bounds == 0)
+ return TAO::TRAVERSE_CONTINUE;
+
+ // Get element typecode.
+ CORBA::TypeCode_var tc2 =
+ tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ // For CORBA basic types, the skip can be optimized
+ CORBA::TCKind kind = tc2->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ char *dummy;
+ switch (kind)
+ {
+ case CORBA::tk_octet:
+ case CORBA::tk_boolean:
+ case CORBA::tk_char:
+ {
+ stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ case CORBA::tk_wchar:
+ {
+ stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_float:
+ {
+ stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_double:
+ case CORBA::tk_longlong:
+ case CORBA::tk_ulonglong:
+ {
+ stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_longdouble:
+ {
+ stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
+ }
+ break;
+
+ default:
+ while (bounds-- && continue_skipping == 1)
+ {
+ continue_skipping =
+ TAO_Marshal_Object::perform_skip (tc2.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ }
+ break;
+ }// end of switch
+
+ if (continue_skipping)
+ return TAO::TRAVERSE_CONTINUE;
+
+ // error exit
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (),
+ TAO::TRAVERSE_STOP);
+}
+
+TAO::traverse_status
+TAO_Marshal_Array::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::Boolean continue_skipping = 1;
+
+
+ // retrieve the bounds of the array
+ CORBA::ULong bounds = tc->length (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ // get element typecode
+ // Typecode of the element.
+ CORBA::TypeCode_var tc2 = tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ // For CORBA basic types, the skip can be optimized
+ CORBA::TCKind kind = tc2->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ char *dummy;
+ switch (kind)
+ {
+ case CORBA::tk_octet:
+ case CORBA::tk_boolean:
+ case CORBA::tk_char:
+ {
+ stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ case CORBA::tk_wchar:
+ {
+ stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_float:
+ {
+ stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_double:
+ case CORBA::tk_longlong:
+ case CORBA::tk_ulonglong:
+ {
+ stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
+ }
+ break;
+ case CORBA::tk_longdouble:
+ {
+ stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
+ continue_skipping =
+ stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
+ }
+ break;
+
+ default:
+ while (bounds-- && continue_skipping == 1)
+ {
+ int stop =
+ TAO_Marshal_Object::perform_skip (tc2.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ if (stop == TAO::TRAVERSE_STOP)
+ continue_skipping = 0;
+ }
+ break;
+ }// end of switch
+
+ if (continue_skipping)
+ return TAO::TRAVERSE_CONTINUE;
+
+ // error exit
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (),
+ TAO::TRAVERSE_STOP);
+}
+
+TAO::traverse_status
+TAO_Marshal_Alias::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ // Typecode of the aliased type.
+ CORBA::TypeCode_var tc2;
+ CORBA::Boolean continue_skipping = 1;
+
+ // Status of decode operation.
+ TAO::traverse_status retval =
+ TAO::TRAVERSE_CONTINUE;
+
+ tc2 = tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ retval = TAO_Marshal_Object::perform_skip (tc2.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ // tc2->_decr_refcnt ();
+ if (retval == TAO::TRAVERSE_CONTINUE
+ && continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Alias::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+}
+
+// Decode exception For exceptions, the "hidden" type ID near the
+// front of the on-wire representation was previously unmarshaled and
+// mapped to the "tc" typcode we're using to traverse the memory ...
+// at the same time its vtable, refcount, and other state was
+// established.
+//
+// NOTE: This is asymmetric with respect to encoding exceptions.
+TAO::traverse_status
+TAO_Marshal_Except::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ TAO::traverse_status retval =
+ TAO::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_var param;
+
+ // skip the Repository ID
+ if (!stream->skip_string ())
+ return TAO::TRAVERSE_STOP;
+
+ // Number of fields in the exception
+ const CORBA::ULong member_count =
+ tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ for (CORBA::ULong i = 0;
+ i < member_count && retval == TAO::TRAVERSE_CONTINUE;
+ ++i)
+ {
+ param = tc->member_type (i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ retval = TAO_Marshal_Object::perform_skip (param.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ }
+
+ if (retval == TAO::TRAVERSE_CONTINUE)
+ return TAO::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Except::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+}
+
+// decode wstring
+TAO::traverse_status
+TAO_Marshal_WString::skip (CORBA::TypeCode_ptr,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ ACE_CDR::Boolean continue_skipping = 1;
+
+ // On decode, omit the check against specified wstring bounds, and
+ // cope with illegal "zero length" strings (all lengths on the wire
+ // must include a NUL).
+ //
+ // This is on the principle of being gracious in what we accept; we
+ // don't generate messages that fail to comply with protocol specs,
+ // but we will accept them when it's clear how to do so.
+
+ // "zero length" wstrings are legal in GIOP 1.2.
+
+ continue_skipping = stream->skip_wstring ();
+
+ if (continue_skipping == 1)
+ return TAO::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_WString::skip detected error\n")));
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+}
+
+TAO::traverse_status
+TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ ACE_ENV_ARG_DECL)
+{
+ TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_var param;
+
+ // Use the same method to skip over our base valuetype.
+ // To achive this we'll need to distinguish between
+ // first-time/nested skips so that we won't attempt to
+ // skip rep_id several times.
+ //
+ if (this->nested_processing_ == 0)
+ {
+ this->nested_processing_ = 1;
+
+ CORBA::ULong value_tag;
+
+ if (!stream->read_ulong (value_tag))
+ {
+ return TAO::TRAVERSE_STOP;
+ }
+
+ TAO_Valuetype_Adapter *adapter =
+ ACE_Dynamic_Service<TAO_Valuetype_Adapter>::instance (
+ TAO_ORB_Core::valuetype_adapter_name ()
+ );
+
+ if (adapter == 0)
+ {
+ ACE_THROW_RETURN (CORBA::INTERNAL (),
+ TAO::TRAVERSE_STOP);
+ }
+
+ if (value_tag == 0) // Null value type pointer.
+ {
+ //We are done.
+ return retval;
+ }
+ else if (value_tag & adapter->type_info_single ())
+ {
+ // Skip a single repository id which is of type string.
+ stream->skip_string ();
+ }
+ else
+ {
+ //@@ boris: VT CDR
+ return TAO::TRAVERSE_STOP;
+ }
+ }
+
+ // Handle our base valuetype if any.
+ param = tc->concrete_base_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ CORBA::TCKind const k = param->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ if (k != CORBA::tk_null)
+ {
+ retval = this->skip (param.in (), stream ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ if (retval != TAO::TRAVERSE_CONTINUE)
+ {
+ return retval;
+ }
+ }
+
+ // Number of fields in the valuetype.
+ const CORBA::ULong member_count =
+ tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ for (CORBA::ULong i = 0;
+ i < member_count && retval == TAO::TRAVERSE_CONTINUE;
+ ++i)
+ {
+ param = tc->member_type (i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+
+ retval = TAO_Marshal_Object::perform_skip (param.in (),
+ stream
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO::TRAVERSE_STOP);
+ }
+
+ if (retval == TAO::TRAVERSE_CONTINUE)
+ return TAO::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Value::skip detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (0,
+ CORBA::COMPLETED_MAYBE),
+ TAO::TRAVERSE_STOP);
+}