summaryrefslogtreecommitdiff
path: root/TAO/tao/skip.cpp
diff options
context:
space:
mode:
authorgokhale <asgokhale@users.noreply.github.com>1998-04-14 19:09:33 +0000
committergokhale <asgokhale@users.noreply.github.com>1998-04-14 19:09:33 +0000
commit44dbcae7fbbc45d362e9a108952846f2f95de935 (patch)
tree2cb384ef4a293f6a7a2cdbefc86fb2f99d48c8a2 /TAO/tao/skip.cpp
parentdc91dcc9c80369d1a005b95336c6baefc83b6032 (diff)
downloadATCD-44dbcae7fbbc45d362e9a108952846f2f95de935.tar.gz
*** empty log message ***
Diffstat (limited to 'TAO/tao/skip.cpp')
-rw-r--r--TAO/tao/skip.cpp751
1 files changed, 751 insertions, 0 deletions
diff --git a/TAO/tao/skip.cpp b/TAO/tao/skip.cpp
new file mode 100644
index 00000000000..7bd33e93642
--- /dev/null
+++ b/TAO/tao/skip.cpp
@@ -0,0 +1,751 @@
+// $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 "tao/corba.h"
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Primitive::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ // status of skip operation
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ switch (tc->kind_)
+ {
+ case CORBA::tk_null:
+ case CORBA::tk_void:
+ break;
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ continue_decoding = stream->skip_short ();
+ break;
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_float:
+ case CORBA::tk_enum:
+ continue_decoding = stream->skip_long ();
+ break;
+ case CORBA::tk_double:
+ case CORBA::tk_longlong:
+ case CORBA::tk_ulonglong:
+ continue_decoding = stream->skip_longlong ();
+ break;
+ case CORBA::tk_boolean:
+ continue_decoding = stream->skip_boolean ();
+ break;
+ case CORBA::tk_char:
+ case CORBA::tk_octet:
+ continue_decoding = stream->skip_char ();
+ break;
+ case CORBA::tk_longdouble:
+ continue_decoding = stream->skip_longdouble ();
+ break;
+ case CORBA::tk_wchar:
+ continue_decoding = stream->skip_wchar ();
+ break;
+ default:
+ retval = CORBA::TypeCode::TRAVERSE_STOP;
+ // we are not a primitive type
+ }
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE
+ && continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Primitive::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Any::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ // Typecode of the element that makes the Any.
+ CORBA::TypeCode_ptr elem_tc;
+
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ // Status of encode operation.
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ // first retrieve the TypeCode for the element so that we can skip the value
+ // based on this typecode
+ if (stream->decode (CORBA::_tc_TypeCode,
+ &elem_tc,
+ 0,
+ env) == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ {
+ if (env.exception () == 0)
+ retval = stream->skip (elem_tc, env);
+ else
+ retval = CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ return retval;
+}
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_TypeCode::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ // Typecode to be decoded.
+ CORBA::TypeCode_ptr *tcp;
+
+ // Typecode kind.
+ CORBA::ULong kind;
+
+ // Decode the "kind" field of the typecode from the stream
+ continue_decoding = stream->read_ulong (kind);
+
+ if (continue_decoding == CORBA::B_TRUE)
+ {
+ // 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::TC_KIND_COUNT) ||
+ (kind == ~(CORBA::ULong)0))
+ {
+ // 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_decoding = stream->skip_ulong ();
+ }
+ break;
+
+ // Indirected typecodes, illegal at "top level".
+ case ~0:
+ {
+ // skip the long indicating the encapsulation offset,
+ continue_decoding = 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:
+ {
+ CORBA::ULong length;
+
+ // get the encapsulation length
+ continue_decoding = stream->read_ulong (length);
+ if (!continue_decoding)
+ break;
+ // skip the encapsulation
+ continue_decoding = stream->skip_bytes (length);
+ }
+ } // end of switch
+ }
+ else // bad kind_ value to be decoded
+ {
+ env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO));
+ dmsg ("TAO_Marshal_TypeCode: Bad kind_ value in CDR stream");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+
+ if (continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_TypeCode::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// Encode Principal.
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Principal::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ // specifies the number of bytes in the Principal
+ CORBA::ULong len;
+
+ continue_decoding = stream->read_ulong (len);
+ if (len > 0 && continue_decoding)
+ {
+ continue_decoding = stream->skip_bytes (len);
+ }
+
+ if (continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Principal::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_ObjRef::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ // return status
+ CORBA::TypeCode::traverse_status retval = CORBA::TypeCode::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_decoding = stream->read_ulong (profiles);
+
+ while (profiles-- != 0 && continue_decoding)
+ {
+ CORBA::ULong tag;
+
+ // get the profile ID tag
+ if ( (continue_decoding = stream->read_ulong (tag)) == CORBA::B_FALSE)
+ continue;
+
+ if (tag != TAO_IOP_TAG_INTERNET_IOP)
+ {
+ continue_decoding = stream->skip_string ();
+ continue;
+ }
+
+ // OK, we've got an IIOP profile. It's going to be
+ // encapsulated ProfileData. Create a new decoding stream and
+ // context for it, and tell the "parent" stream that this data
+ // isn't part of it any more.
+
+ 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_decoding = stream->read_ulong (encap_len)) == CORBA::B_FALSE)
+ continue;
+
+ TAO_InputCDR str (*stream, encap_len);
+
+ continue_decoding =
+ str.good_bit ()
+ && stream->skip_bytes (encap_len);
+
+ if (!continue_decoding)
+ continue;
+
+ // Read and verify major, minor versions, ignoring IIOP
+ // profiles whose versions we don't understand.
+ //
+ // XXX this doesn't actually go back and skip the whole
+ // encapsulation...
+ if (!(str.skip_octet ()
+ && str.skip_octet ()))
+ continue;
+
+ // skip host and port
+ if (!str.skip_string ()
+ || !str.skip_ushort ())
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("error decoding IIOP host/port");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ // ... and object key.
+ if (str.skip (&TC_opaque,
+ env) != CORBA::TypeCode::TRAVERSE_CONTINUE)
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE
+ && continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ ACE_DEBUG ((LM_DEBUG, "marshaling decode_objref detected error"));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// Decode structs.
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Struct::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_ptr param;
+
+ // Number of fields in the struct.
+ int member_count = tc->member_count (env);
+
+ if (env.exception () == 0)
+ for (int i = 0; i < member_count
+ && retval == CORBA::TypeCode::TRAVERSE_CONTINUE;
+ i++)
+ {
+ param = tc->member_type (i, env);
+ if (env.exception () == 0)
+ {
+ retval = stream->skip (param, env);
+ }
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("marshaling encode_struct detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// Encode unions.
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Union::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ CORBA::TypeCode_ptr discrim_tc;
+ CORBA::TypeCode_ptr member_tc;
+ CORBA::Any_ptr member_label;
+ CORBA::Long discrim_val;
+ CORBA::ULong member_count;
+ CORBA::Long default_index;
+ CORBA::ULong i;
+ CORBA::TypeCode_ptr default_tc = 0;
+ CORBA::Boolean discrim_matched = CORBA::B_FALSE;
+
+ // get the discriminator type which will enable us to skip the discriminator
+ // value
+ discrim_tc = tc->discriminator_type (env);
+
+ if (env.exception () == 0)
+ {
+ // decode the discriminator value
+ retval = stream->decode (discrim_tc, &discrim_val, 0, env);
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ {
+ // now get ready to skip the actual union value
+ default_index = tc->default_index (env);
+
+ if (env.exception () == 0)
+ {
+ member_count = tc->member_count (env);
+ if (env.exception () == 0)
+ {
+ // check which label value matches with the discriminator
+ // value. Accordingly, marshal the corresponding
+ // member_type. If none match, check if default exists
+ // and marshal accordingly. Otherwise it is an error.
+
+ for (i = 0; i < member_count; i++)
+ {
+ member_label = tc->member_label (i, env);
+ if (env.exception () == 0)
+ {
+ // do the matching
+ switch (member_label->type ()->kind (env))
+ {
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ if (*(CORBA::Short *) member_label->value () ==
+ *(CORBA::Short *) discrim_val)
+ discrim_matched = CORBA::B_TRUE;
+ break;
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_enum:
+ if (*(CORBA::ULong *) member_label->value () ==
+ *(CORBA::ULong *) discrim_val)
+ discrim_matched = CORBA::B_TRUE;
+ break;
+ case CORBA::tk_char:
+ if (*(CORBA::Char *) member_label->value () ==
+ *(CORBA::Char *) discrim_val)
+ discrim_matched = CORBA::B_TRUE;
+ break;
+ case CORBA::tk_wchar:
+ if (*(CORBA::WChar *) member_label->value () ==
+ *(CORBA::WChar *) discrim_val)
+ discrim_matched = CORBA::B_TRUE;
+ break;
+ case CORBA::tk_boolean:
+ if (*(CORBA::Boolean *) member_label->value () ==
+ *(CORBA::Boolean *) discrim_val)
+ discrim_matched = CORBA::B_TRUE;
+ break;
+ default:
+ env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }// end of switch
+
+ // get the member typecode
+ member_tc = tc->member_type (i, env);
+ if (env.exception () == 0)
+ {
+ if (default_index >= 0 && default_index-- == 0)
+ // have we reached the default label?, if so,
+ // save a handle to the typecode for the default
+ default_tc = member_tc;
+ if (discrim_matched)
+ // marshal according to the matched typecode
+ return stream->skip (member_tc, env);
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ } // end of for loop
+ // we are here only if there was no match
+ if (default_tc)
+ return stream->skip (default_tc, env);
+ else
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// decode string
+CORBA::TypeCode::traverse_status
+TAO_Marshal_String::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+
+ // 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_decoding = stream->skip_string ();
+ if (continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_TypeCode::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// Decode sequence.
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Sequence::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ // Return status.
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+ // Typecode of the element.
+ CORBA::TypeCode_ptr tc2;
+ // 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).
+
+ continue_decoding = stream->read_ulong (bounds);
+
+ if (continue_decoding)
+ {
+ // No point decoding an empty sequence.
+ if (bounds > 0)
+ {
+ // Get element typecode.
+ tc2 = tc->content_type (env);
+
+ if (env.exception () == 0)
+ {
+ while (bounds-- && continue_decoding == CORBA::B_TRUE)
+ {
+ continue_decoding = stream->skip (tc2, env);
+ }
+ } // no exception computing content type
+ } // length is > 0
+ else
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ }
+ // error exit
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+}
+
+// Decode array.
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Array::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ // Return status.
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ // Typecode of the element.
+ CORBA::TypeCode_ptr tc2;
+
+ CORBA::ULong bounds;
+
+ // retrieve the bounds of the array
+ bounds = tc->length (env);
+ if (env.exception () == 0)
+ {
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ while (bounds-- && continue_decoding == CORBA::B_TRUE)
+ {
+ continue_decoding = stream->skip (tc2, env);
+ }
+ } // no exception computing content type
+ } // no exception computing bounds
+ // error exit
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+}
+
+// Decode alias.
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Alias::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ // Typecode of the aliased type.
+ CORBA::TypeCode_ptr tc2;
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+
+ // Context is the CDR stream.
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+
+ // Status of decode operation.
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ retval = stream->skip (tc2, env);
+ }
+ // tc2->Release ();
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE
+ && continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Alias::skip detected error");
+ return CORBA::TypeCode::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.
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Except::skip (CORBA::TypeCode_ptr tc,
+ void *context,
+ CORBA::Environment &env)
+{
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_ptr param;
+
+ // Number of fields in the exception
+ int member_count = tc->member_count (env);
+ if (env.exception () == 0)
+ {
+ for (int i = 0; i < member_count
+ && retval == CORBA::TypeCode::TRAVERSE_CONTINUE;
+ i++)
+ {
+ param = tc->member_type (i, env);
+ if (env.exception () == 0)
+ {
+ retval = stream->skip (param, env);
+ }
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Except detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// decode wstring
+CORBA::TypeCode::traverse_status
+TAO_Marshal_WString::skip (CORBA::TypeCode_ptr,
+ void *context,
+ CORBA::Environment &env)
+{
+ CORBA::Boolean continue_decoding = CORBA::B_TRUE;
+ TAO_InputCDR *stream = (TAO_InputCDR *) context;
+ CORBA::ULong len;
+
+ // 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.
+
+ continue_decoding = stream->read_ulong (len);
+
+ if (len != 0)
+ while (continue_decoding != CORBA::B_FALSE && len--)
+ {
+ continue_decoding = stream->skip_wchar ();
+ }
+
+ if (continue_decoding == CORBA::B_TRUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ else
+ {
+ env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_TypeCode::skip detected error");
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+}