summaryrefslogtreecommitdiff
path: root/TAO/tao/decode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/decode.cpp')
-rw-r--r--TAO/tao/decode.cpp1593
1 files changed, 0 insertions, 1593 deletions
diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp
deleted file mode 100644
index 8a4277506e7..00000000000
--- a/TAO/tao/decode.cpp
+++ /dev/null
@@ -1,1593 +0,0 @@
-// ============================================================================
-//
-// $Id$
-//
-// = LIBRARY
-// TAO
-//
-// = FILENAME
-// decode.cpp
-//
-// = DESCRIPTION
-// Code for decoding different data types
-//
-// The original code had a single static decoder function defined on the CDR
-// class that called traverse to interpret the data types. This version
-// defines a virtual method "decode" on each class and avoids
-// calling traverse.
-//
-// = AUTHOR
-// Copyright 1994-1995 by Sun Microsystems Inc.
-// and
-// Aniruddha Gokhale
-//
-// ============================================================================
-
-#include "tao/corba.h"
-
-extern CORBA::TypeCode TC_opaque;
-
-// The decoder is exactly the reverse of the encoder, except that:
-//
-// * Unmarshaling some data types involve allocating memory. Such
-// types include sequences (the buffer), objrefs, Principals, Anys,
-// TypeCodes, and strings.
-//
-// * The decoder is used when retrieving typecode parameters from
-// encapsulations. This means it must deal with "CORBA::tk_indirect",
-// the magic value (~0) signifying typecode indirection.
-//
-// This second case is identified by a bit of a hack: the second
-// "data" value is used to hold the parent typecode, rather than being
-// ignored. This means that all other invocations of decoder () **
-// MUST ** pass zero for the second data parameter, in case they
-// decode a TypeCode. If they didn't, this case might be signified
-// inappropriately.
-//
-// XXX desirable to have a less hacky solution to that ... pull that
-// code out into a separate routine called both by CDR::decoder () and
-// by the code retrieving typecode parameters from encapsulations.
-
-CORBA::TypeCode_ptr __tc_consts [CORBA::TC_KIND_COUNT] =
-{
- CORBA::_tc_null,
- CORBA::_tc_void,
- CORBA::_tc_short,
- CORBA::_tc_long,
- CORBA::_tc_ushort,
-
- CORBA::_tc_ulong,
- CORBA::_tc_float,
- CORBA::_tc_double,
- CORBA::_tc_boolean,
- CORBA::_tc_char,
-
- CORBA::_tc_octet,
- CORBA::_tc_any,
- CORBA::_tc_TypeCode,
- CORBA::_tc_Principal,
-
- 0, // CORBA::_tc_Object ... type ID is CORBA_Object
- 0, // CORBA_tk_struct
- 0, // CORBA_tk_union
- 0, // CORBA_tk_enum
- 0, // CORBA::_tc_string ... unbounded
- 0, // CORBA_tk_sequence
- 0, // CORBA_tk_array
- 0, // CORBA_tk_alias
- 0, // CORBA_tk_except
-
- CORBA::_tc_longlong,
- CORBA::_tc_ulonglong,
- CORBA::_tc_longdouble,
- CORBA::_tc_wchar,
- 0 // CORBA::_tc_wstring ... unbounded
-};
-
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Primitive::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::TypeCode::traverse_status retval =
- CORBA::TypeCode::TRAVERSE_CONTINUE; // status of encode operation
-
- switch (tc->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- break;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- continue_decoding = stream->get_short (*(CORBA::Short *) data);
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- case CORBA::tk_enum:
- continue_decoding = stream->get_long (*(CORBA::Long *) data);
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) data);
- break;
- case CORBA::tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) data);
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- continue_decoding = stream->get_char (*(CORBA::Char *) data);
- break;
- case CORBA::tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) data);
- break;
- case CORBA::tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) data);
- 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::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Any::decode (CORBA::TypeCode_ptr,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Any *any = (CORBA::Any *) data;
- CORBA::TypeCode_ptr elem_tc; // typecode of the element that makes the Any
- void *value = 0; // value maintained by the Any
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::TypeCode::traverse_status retval =
- CORBA::TypeCode::TRAVERSE_CONTINUE; // status of encode operation
-
- // decode the typecode description for the element
- if (stream->decode (CORBA::_tc_TypeCode,
- &elem_tc,
- this,
- env) == CORBA::TypeCode::TRAVERSE_CONTINUE)
- {
- value = new CORBA::Octet[elem_tc->size (env)];
- if (env.exception () == 0)
- {
- // switch on the data type and handle the cases for
- // primitives here for efficiency rather than calling
- switch (elem_tc->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- break;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- continue_decoding = stream->get_short (*(CORBA::Short *) value);
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- case CORBA::tk_enum:
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) value);
- break;
- case CORBA::tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) value);
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- continue_decoding = stream->get_char (*(CORBA::Char *) value);
- break;
- case CORBA::tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) value);
- break;
- case CORBA::tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) value);
- break;
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_objref:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_string:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- case CORBA::tk_wstring:
- retval = stream->decode (elem_tc, value, 0, env);
- break;
- default:
- // anything else is an error
- retval = CORBA::TypeCode::TRAVERSE_STOP;
- }
- }
- else
- retval = CORBA::TypeCode::TRAVERSE_STOP;
- }
- if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE
- && continue_decoding == CORBA::B_TRUE)
- {
- // allocate an Any and populate it with the value and typecode. This
- // eventually appears as "data"
- (void) new (any) CORBA::Any (elem_tc, value, CORBA::B_TRUE);
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- }
- else
- {
- // free the allocated storage and release the typecode
- delete [] value;
- CORBA::release (elem_tc);
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("TAO_Marshal_Any::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-CORBA::TypeCode::traverse_status
-TAO_Marshal_TypeCode::decode (CORBA::TypeCode_ptr,
- const void *data,
- const void *parent_typecode,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::TypeCode_ptr *tcp; // typecode to be decoded
- CORBA::ULong kind; // typecode kind
- CORBA::TypeCode_ptr parent = (CORBA::TypeCode_ptr) parent_typecode; // TypeCode
- // for the
- // parent
-
- // decode the "kind" field of the typecode from the stream
- continue_decoding = stream->get_ulong (kind);
-
- if (continue_decoding == CORBA::B_TRUE)
- {
- tcp = (CORBA::TypeCode_ptr *) data; // the data has to be a TypeCode_ptr*
-
- // 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
- && (*tcp = __tc_consts [(u_int) kind]) != 0)
- *tcp = __tc_consts [(u_int) kind];
- else
- {
- if (kind == ~(CORBA::ULong)0 || kind < CORBA::TC_KIND_COUNT)
- {
- // 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: // error: missed a case!
- env.exception (new CORBA::INTERNAL (CORBA::COMPLETED_MAYBE));
- return CORBA::TypeCode::TRAVERSE_STOP;
-
- // Some have "simple" parameter lists ... some of these also
- // have preallocated constants that could be used.
- case CORBA::tk_string:
- case CORBA::tk_wstring:
- {
- CORBA::ULong bound;
-
- continue_decoding = stream->get_ulong (bound);
- if (continue_decoding)
- {
- if (bound == 0)
- {
- if (kind == CORBA::tk_string)
- *tcp = CORBA::_tc_string;
- else
- *tcp = CORBA::_tc_wstring;
- }
- else
- {
- // bounded string. Save the bounds
- *tcp = new CORBA::TypeCode ((CORBA::TCKind) kind,
- bound, 0, CORBA::B_FALSE,
- parent);
- // (*tcp)->parent_ = parent;
- }
- }
- }
- break;
-
- // Indirected typecodes, illegal at "top level" but we
- // allow unmarshaling of them here because we use the
- // same code to read "off the wire" (where they're
- // illegal) and to read out of an encapsulation
- // stream. We distinguish the case where this is
- // legal as described above.
- case ~0:
- {
- if (parent_typecode == 0)
- {
- env.exception (new CORBA::INTERNAL (CORBA::COMPLETED_MAYBE));
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-
- // Get the long indicating the encapsulation offset,
- // then set up indirection stream that's like "stream"
- // but has space enough only for the typecode and the
- // length for the encapsulated parameters.
- CDR indir_stream;
- CORBA::Long offset;
-
- continue_decoding = stream->get_long (offset);
- if (continue_decoding)
- {
- // Since indirected typecodes cannot occur at the
- // topmost level, they can occur starting only at the
- // second and subsequent levels. This means that a
- // normal encoding of that typecode occurred somewhere
- // before in the stream. As a result the offset field
- // must always be negative. See the CORBA spec for details.
- continue_decoding = (offset < 0);
- }
- if (continue_decoding)
- {
- // the offset must be such that the indir_stream.next
- // should point to the TypeCode kind value of the
- // TypeCode to which we are referring to.
- indir_stream.setup_encapsulation
- (stream->buffer () + offset, 8);
-
- // Reject indirections outside parent's scope.
- if (indir_stream.buffer () < ACE_reinterpret_cast(char*,parent->buffer_))
- continue_decoding = CORBA::B_FALSE;
- }
-
- // Get "kind" and length of target typecode
- //
- // XXX this currently assumes the TCKind to which we
- // indirect is the same byte order as the "parent"
- // typecode -- not the right assumption; see how the
- // TypeCode interpreter does it.
-
- CORBA::ULong indir_kind;
- CORBA::ULong indir_len;
-
- // retrieve the typecode kind
- if (continue_decoding)
- continue_decoding = indir_stream.get_ulong (indir_kind);
-
- if (continue_decoding
- && indir_kind >= CORBA::TC_KIND_COUNT)
- continue_decoding = CORBA::B_FALSE;
-
- // now retrieve the encapsulation length
- if (continue_decoding)
- continue_decoding = indir_stream.get_ulong (indir_len);
-
- // Now construct indirected typecode. This shares the
- // typecode octets with the "parent" typecode,
- // increasing the amount of memory sharing and
- // reducing the cost of getting typecodes.
- if (continue_decoding)
- {
- *tcp = new CORBA::TypeCode ((CORBA::TCKind) indir_kind,
- indir_len,
- indir_stream.buffer(),
- CORBA::B_FALSE,
- parent);
-#if 0
- (*tcp)->parent_ = parent;
- parent->AddRef ();
-#endif /* 0 */
- }
- }
- 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;
-#if defined(TAO_NEEDS_UNUSED_VARIABLES)
- CORBA::Octet *buffer;
-#endif
-
- continue_decoding = stream->get_ulong (length);
- if (!continue_decoding)
- break;
-
- // if length > MAXUNSIGNED, error ...
- u_int len = (u_int) length;
-
-#if 0
- buffer = new CORBA::Octet[len];
-
- for (u_int i = 0; i < len && continue_decoding; i++)
- continue_decoding = stream->get_octet (buffer [i]);
-#endif
-
- if (!continue_decoding)
- {
- // delete [] buffer;
- break;
- }
- *tcp = new CORBA::TypeCode ((CORBA::TCKind) kind,
- len,
- stream->buffer (),
- CORBA::B_FALSE,
- parent);
- // skip length number of bytes in the stream, else we may
- // leave the stream in an undefined state
- (void) stream->rd_ptr (length);
- // (*tcp)->parent_ = parent;
- }
- } // 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::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// encode Principal
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Principal::decode (CORBA::TypeCode_ptr,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::Principal_ptr *pp = (CORBA::Principal_ptr *) data;
- CORBA::ULong len;
-
- continue_decoding = stream->get_ulong (len);
- if (len == 0)
- *pp = 0; // null principal
- else
- {
- // allocate storage for Principal and its buffer
- *pp = new CORBA::Principal;
- (*pp)->id.buffer = new CORBA::Octet [ (size_t) len];
- (*pp)->id.maximum = (*pp)->id.length = len;
-
- for (u_int i = 0;
- continue_decoding != CORBA::B_FALSE && i < len;
- i++)
- continue_decoding = stream->get_octet ((*pp)->id.buffer [i]);
- }
-
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- else
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("TAO_Marshal_Principal::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// decode obj ref
-CORBA::TypeCode::traverse_status
-TAO_Marshal_ObjRef::decode (CORBA::TypeCode_ptr,
- const void *data, // where the result will go
- const void *,
- void *context, // the CDR stream (cast to CDR*)
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::TypeCode::traverse_status retval = CORBA::TypeCode::TRAVERSE_CONTINUE;
- CORBA::String type_hint;
-
- // First, read the type hint. This will be the type_id encoded in an
- // object reference.
- stream->decode (CORBA::_tc_string, &type_hint, 0, env);
-
- // 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;
- IIOP_Object *objdata = 0;
-
- // get the count of profiles that follow
- continue_decoding = stream->get_ulong (profiles);
-
- // No profiles means a NIL objref.
-
- if (profiles == 0)
- {
- *(CORBA::Object_ptr *) data = CORBA::Object::_nil ();
- CORBA::string_free (type_hint);
- type_hint = 0;
- }
- else
- {
- while (profiles-- != 0 && continue_decoding)
- {
- CORBA::ULong tmp;
-
- // get the profile ID tag
- stream->get_ulong (tmp);
-
- if (tmp != TAO_IOP_TAG_INTERNET_IOP || objdata != 0)
- {
- 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.
-
- // ProfileData is encoded as a sequence of octet. So first get the
- // length of the sequence
- char* buf;
- continue_decoding = stream->get_encapsulation (buf, tmp);
- assert (continue_decoding == CORBA::B_TRUE);
-
- // Create the decoding stream from the encapsulation in
- // the buffer, and skip the encapsulation.
- CDR str;
-
- str.setup_encapsulation (ACE_reinterpret_cast(char*,buf), tmp);
-
- // @@ (CJC) Does IIOP_Object duplicate 'type_hint' below so that
- // we can safely free it? It does now!
- objdata = new IIOP_Object (type_hint);
-
- // @@ (coryan) The IIOP_Object created here has a String_var
- // member to keep the string, this member is constructed
- // using type_hint, at that time a plain (char*). Hence the
- // string is *not* copied and it cannot be released, so the
- // following line is commented out:
- // CORBA::string_free (type_hint);
-
- IIOP::Profile *profile = &objdata->profile;
-
- // 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.get_octet (profile->iiop_version.major)
- && profile->iiop_version.major == IIOP::MY_MAJOR
- && str.get_octet (profile->iiop_version.minor)
- && profile->iiop_version.minor <= IIOP::MY_MINOR))
- {
- dmsg2 ("detected new v%d.%d IIOP profile",
- profile->iiop_version.major,
- profile->iiop_version.minor);
- objdata->type_id = (const char *) 0;
- objdata->Release ();
- objdata = 0;
- continue;
- }
-
- // Get host and port
- if (str.decode (CORBA::_tc_string, &profile->host, 0, env)
- != CORBA::TypeCode::TRAVERSE_CONTINUE
- || !str.get_ushort (profile->port))
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("error decoding IIOP host/port");
- objdata->Release ();
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-
- profile->object_addr (0);
-
- // ... and object key
-
- continue_decoding = str.decode (&TC_opaque,
- &profile->object_key,
- 0,
- env) == CORBA::TypeCode::TRAVERSE_CONTINUE;
-
- if (str.length () != 0)
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("extra data at end of IIOP profile data");
- objdata->Release ();
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- }
- }
- if (objdata == 0)
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg2 ("no IIOP v%d.%d (or earlier) profile in IOR!",
- IIOP::MY_MAJOR, IIOP::MY_MINOR);
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- else
- {
- // Create a new CORBA_Object and give it the IIOP_Object just
- // created.
- CORBA_Object *corba_proxy = new CORBA_Object (objdata);
- if (corba_proxy)
- *(CORBA_Object **)data = corba_proxy;
- else
- continue_decoding = CORBA::B_FALSE;
- }
- 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 ("marshaling encode_struct detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// decode structs
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Struct::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CDR *stream = (CDR *) context;
- CORBA::TypeCode::traverse_status retval = CORBA::TypeCode::TRAVERSE_CONTINUE;
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CORBA::TypeCode_ptr param;
- CORBA::Long size, alignment, align_offset;
-
- void *start_addr = (void *)data;
-
- // 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
- && continue_decoding == CORBA::B_TRUE;
- i++)
- {
- param = tc->member_type (i, env);
- if (env.exception () == 0)
- {
- size = param->size (env);
- if (env.exception () == 0)
- {
- alignment = param->alignment (env);
- if (env.exception () == 0)
- {
- align_offset =
- (ptr_arith_t) ptr_align_binary (data, alignment)
- - (ptr_arith_t) data
- + (ptr_arith_t) ptr_align_binary (start_addr, alignment)
- - (ptr_arith_t) start_addr;
- // if both the start_addr and data are not aligned as per
- // the alignment, we do not add the offset
- data = (const void *) ((ptr_arith_t) data +
- ((align_offset == alignment) ?
- 0 : align_offset));
- switch (param->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- break;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- continue_decoding = stream->get_short (*(CORBA::Short *) data);
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- case CORBA::tk_enum:
- continue_decoding = stream->get_long (*(CORBA::Long *) data);
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) data);
- break;
- case CORBA::tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) data);
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- continue_decoding = stream->get_char (*(CORBA::Char *) data);
- break;
- case CORBA::tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) data);
- break;
- case CORBA::tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) data);
- break;
- case CORBA::tk_string:
- case CORBA::tk_wstring:
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_objref:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- retval = stream->decode (param, data, 0, env);
- break;
- default:
- break;
- }
- data = (char *) data + size;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- }
- else
- 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));
- dmsg ("marshaling encode_struct detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// encode unions
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Union::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *data2,
- void *context,
- CORBA::Environment &env)
-{
- CDR *stream = (CDR *) context; // context is the CDR stream
- 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::ULong discrim_size_with_pad;
- const void *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;
-
- discrim_tc = tc->discriminator_type (env);
- // get the discriminator type
-
- if (env.exception () == 0)
- {
- // decode the discriminator value
- retval = stream->decode (discrim_tc, data, data2, env);
- if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
- {
- discrim_size_with_pad = tc->TAO_discrim_pad_size (env);
-
- if (env.exception () == 0)
- {
- discrim_val = data; // save the pointer to the discriminator
- // value
- // move the pointer to point to the actual value
- data = (char *) data + discrim_size_with_pad;
- data2 = (char *) data2 + discrim_size_with_pad;
- // now get ready to marshal 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; member_count-- != 0; 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->decode (member_tc, data,
- data2, 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->decode (default_tc, data, data2, 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;
- }
- }
- else
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// decode string
-CORBA::TypeCode::traverse_status
-TAO_Marshal_String::decode (CORBA::TypeCode_ptr,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::ULong len = 0;
- CORBA::String str;
-
- // 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->get_ulong (len);
- if (len != 0)
- {
- // note that the encoded length is 1 more than the length of the string
- // because it also accounts for the terminating NULL character
-
- str = (*(char **) data) = CORBA::string_alloc (len - 1);
- // only allocate the string *after* the length was validated.
-
-#if 0
- while (continue_decoding != CORBA::B_FALSE && len-- != 0)
- {
- continue_decoding = stream->get_char (*(CORBA::Char *) str);
- str++;
- }
-#endif
- continue_decoding = stream->get_string (str, len);
- }
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- else
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("TAO_Marshal_TypeCode::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// decode sequence
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context;
- TAO_Base_Sequence *seq = (TAO_Base_Sequence *)data;
-
- CORBA::TypeCode::traverse_status retval =
- CORBA::TypeCode::TRAVERSE_CONTINUE; // return status
- CORBA::TypeCode_ptr tc2; // typecode of the element
- size_t size; // size of element
- CORBA::ULong bounds;
- char *value;
-
- // 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->get_ulong (seq->length_);
- seq->maximum_ = seq->length_;
- seq->release_ = 1;
- seq->buffer_ = 0;
-
- if (continue_decoding)
- {
- // no point decoding an empty sequence
- if (seq->length_ > 0)
- {
- // get element typecode
- tc2 = tc->content_type (env);
-
- if (env.exception () == 0)
- {
- size = tc2->size (env);
-
- if (env.exception () == 0)
- {
- bounds = seq->length_;
-
- // Allocate the buffer using the virtual
- // _allocate_buffer method, hence the right
- // constructors are invoked and size for the array
- // is OK.
- // @@ Who will free this memory?
- // (coryan): the sequence will release it, since its
- // release_ field is 1.
- seq->_allocate_buffer (bounds);
-
- value = (char *) seq->buffer_;
-
- switch (tc2->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_short (*(CORBA::Short *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_boolean:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_char (*(CORBA::Char *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_longdouble:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_wchar:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_enum:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- value += size;
-
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- // handle all aggregate types here
- case CORBA::tk_objref:
- case CORBA::tk_string:
- case CORBA::tk_wstring:
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- // For those aggregate types whose size is constant, we
- // compute it only once
- while (bounds-- && retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
- {
- retval = stream->decode (tc2, value, 0, env);
- value += size;
- }
- // CORBA::release (tc2);
- if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- default:
- break;
- } // end of switch
- } // no exception computing size
- } // 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::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
-}
-
-// decode array
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Array::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context;
- CORBA::TypeCode::traverse_status retval =
- CORBA::TypeCode::TRAVERSE_CONTINUE; // return status
- CORBA::TypeCode_ptr tc2; // typecode of the element
- size_t size; // size of element
- CORBA::ULong bounds;
- char *value = (char *) data;
-
- // 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)
- {
- size = tc2->size (env);
- if (env.exception () == 0)
- {
- switch (tc2->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_short (*(CORBA::Short *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_boolean:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_char (*(CORBA::Char *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_longdouble:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_wchar:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- case CORBA::tk_enum:
- // For primitives, compute the size only once
- while (bounds-- && continue_decoding == CORBA::B_TRUE)
- {
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- value += size;
- }
- // CORBA::release (tc2);
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- // handle all aggregate types here
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_objref:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_string:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- case CORBA::tk_wstring:
- // For those aggregate types whose size is constant, we
- // compute it only once
- while (bounds-- && retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
- {
- retval = stream->decode (tc2, value, 0, env);
- value += size;
- }
- // CORBA::release (tc2);
- if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- break;
- default:
- break;
- } // end of switch
- } // no exception computing size
- } // no exception computing content type
- } // no exception computing bounds
- // error exit
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO));
- dmsg ("marshaling TAO_Marshal_Sequence::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
-}
-
-// decode alias
-CORBA::TypeCode::traverse_status
-TAO_Marshal_Alias::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::TypeCode_ptr tc2; // typecode of the aliased type
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::TypeCode::traverse_status retval =
- CORBA::TypeCode::TRAVERSE_CONTINUE; // status of decode operation
- char *value = (char *) data;
-
- tc2 = tc->content_type (env);
- if (env.exception () == 0)
- {
- // switch on the data type and handle the cases for primitives here for
- // efficiency rather than calling
- switch (tc2->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- break;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- continue_decoding = stream->get_short (*(CORBA::Short *) value);
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- case CORBA::tk_enum:
- continue_decoding = stream->get_long (*(CORBA::Long *) value);
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) value);
- break;
- case CORBA::tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) value);
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- continue_decoding = stream->get_char (*(CORBA::Char *) value);
- break;
- case CORBA::tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) value);
- break;
- case CORBA::tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) value);
- break;
- case CORBA::tk_string:
- case CORBA::tk_wstring:
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_objref:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- retval = stream->decode (tc2, data, 0, env);
- break;
- default:
- // anything else is an error
- retval = CORBA::TypeCode::TRAVERSE_STOP;
- }
- }
- // 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::decode 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::decode (CORBA::TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CDR *stream = (CDR *) context;
- CORBA::TypeCode::traverse_status retval = CORBA::TypeCode::TRAVERSE_CONTINUE;
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CORBA::TypeCode_ptr param;
- CORBA::Long size, alignment;
-
- data = (char *) data + sizeof (CORBA::Exception);
-
- // 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
- && continue_decoding == CORBA::B_TRUE; i++)
- {
- param = tc->member_type (i, env);
- if (env.exception () == 0)
- {
- size = param->size (env);
- if (env.exception () == 0)
- {
- alignment = param->alignment (env);
- if (env.exception () == 0)
- {
- data = ptr_align_binary (data, alignment);
- switch (param->kind_)
- {
- case CORBA::tk_null:
- case CORBA::tk_void:
- break;
- case CORBA::tk_short:
- case CORBA::tk_ushort:
- continue_decoding = stream->get_short (*(CORBA::Short *) data);
- break;
- case CORBA::tk_long:
- case CORBA::tk_ulong:
- case CORBA::tk_float:
- case CORBA::tk_enum:
- continue_decoding = stream->get_long (*(CORBA::Long *) data);
- break;
- case CORBA::tk_double:
- case CORBA::tk_longlong:
- case CORBA::tk_ulonglong:
- continue_decoding = stream->get_longlong (*(CORBA::LongLong *) data);
- break;
- case CORBA::tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA::Boolean *) data);
- break;
- case CORBA::tk_char:
- case CORBA::tk_octet:
- continue_decoding = stream->get_char (*(CORBA::Char *) data);
- break;
- case CORBA::tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA::LongDouble *) data);
- break;
- case CORBA::tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA::WChar *) data);
- break;
- case CORBA::tk_any:
- case CORBA::tk_TypeCode:
- case CORBA::tk_Principal:
- case CORBA::tk_objref:
- case CORBA::tk_struct:
- case CORBA::tk_union:
- case CORBA::tk_string:
- case CORBA::tk_sequence:
- case CORBA::tk_array:
- case CORBA::tk_alias:
- case CORBA::tk_except:
- case CORBA::tk_wstring:
- retval = stream->decode (param, data, 0, env);
- break;
- default:
- break;
- }
- data = (char *) data + size;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- else
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
- }
- else
- 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));
- dmsg ("TAO_Marshal_Except detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}
-
-// decode wstring
-CORBA::TypeCode::traverse_status
-TAO_Marshal_WString::decode (CORBA::TypeCode_ptr,
- const void *data,
- const void *,
- void *context,
- CORBA::Environment &env)
-{
- CORBA::Boolean continue_decoding = CORBA::B_TRUE;
- CDR *stream = (CDR *) context; // context is the CDR stream
- CORBA::WChar *str = *(CORBA::WChar **) data;
- 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->get_ulong (len);
-
- *((CORBA::WChar **) data) = str = new CORBA::WChar [(size_t) (len)];
-
- if (len != 0)
- while (continue_decoding != CORBA::B_FALSE && len--)
- {
- continue_decoding = stream->get_wchar (*str);
- str++;
- }
-
- if (continue_decoding == CORBA::B_TRUE)
- return CORBA::TypeCode::TRAVERSE_CONTINUE;
- else
- {
- env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_MAYBE));
- dmsg ("TAO_Marshal_TypeCode::decode detected error");
- return CORBA::TypeCode::TRAVERSE_STOP;
- }
-}