summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authorgokhale <asgokhale@users.noreply.github.com>1997-06-24 19:33:19 +0000
committergokhale <asgokhale@users.noreply.github.com>1997-06-24 19:33:19 +0000
commit99993337110453fd8df47fd1f9a637822afe863a (patch)
treed6619bc217f6b9ed7bf18fb28795c8ac1b1933ae /TAO
parentb5f0b2c4cb72322e6bf206d43e8c228b32271dcc (diff)
downloadATCD-99993337110453fd8df47fd1f9a637822afe863a.tar.gz
Added optimizations to TAO's IIOP interpreter.
Diffstat (limited to 'TAO')
-rw-r--r--TAO/IIOP/lib/align.h8
-rw-r--r--TAO/IIOP/lib/any.cpp3
-rw-r--r--TAO/IIOP/lib/boa.cpp6
-rw-r--r--TAO/IIOP/lib/cdr.cpp349
-rw-r--r--TAO/IIOP/lib/cdr.h111
-rw-r--r--TAO/IIOP/lib/cdr.i450
-rw-r--r--TAO/IIOP/lib/debug.cpp2
-rw-r--r--TAO/IIOP/lib/debug.h2
-rw-r--r--TAO/IIOP/lib/decode.cpp1611
-rw-r--r--TAO/IIOP/lib/deep_copy.cpp1309
-rw-r--r--TAO/IIOP/lib/deep_free.cpp1028
-rw-r--r--TAO/IIOP/lib/encode.cpp1423
-rw-r--r--TAO/IIOP/lib/except.cpp25
-rw-r--r--TAO/IIOP/lib/giop.cpp61
-rw-r--r--TAO/IIOP/lib/giop.h4
-rw-r--r--TAO/IIOP/lib/iioporb.cpp8
-rw-r--r--TAO/IIOP/lib/interp.cpp9
-rw-r--r--TAO/IIOP/lib/invoke.cpp3
-rw-r--r--TAO/IIOP/lib/marshal.cpp1139
-rw-r--r--TAO/IIOP/lib/marshal.h520
-rw-r--r--TAO/IIOP/lib/marshal.i216
-rw-r--r--TAO/IIOP/lib/nvlist.cpp4
-rw-r--r--TAO/IIOP/lib/object.cpp5
-rw-r--r--TAO/IIOP/lib/object.h20
-rw-r--r--TAO/IIOP/lib/orb.h3
-rw-r--r--TAO/IIOP/lib/orbobj.cpp1
-rw-r--r--TAO/IIOP/lib/request.cpp6
-rw-r--r--TAO/IIOP/lib/roa.cpp9
-rw-r--r--TAO/IIOP/lib/svrrqst.cpp8
-rw-r--r--TAO/IIOP/lib/t-xdr.cpp12
-rw-r--r--TAO/IIOP/lib/tc_const.cpp21
-rw-r--r--TAO/IIOP/lib/typecode.cpp836
-rw-r--r--TAO/IIOP/lib/typecode.h210
-rw-r--r--TAO/IIOP/lib/typecode.i309
34 files changed, 8095 insertions, 1636 deletions
diff --git a/TAO/IIOP/lib/align.h b/TAO/IIOP/lib/align.h
index cf75fb1bafe..cf11ac0447e 100644
--- a/TAO/IIOP/lib/align.h
+++ b/TAO/IIOP/lib/align.h
@@ -46,6 +46,7 @@ typedef u_long long ptr_arith_t;
// boundaries are binary powers and that we're using two's complement
// arithmetic.
+#if 0
static inline ptr_arith_t
align_binary (const ptr_arith_t value,
size_t alignment)
@@ -54,6 +55,9 @@ align_binary (const ptr_arith_t value,
return (value + temp) & ~temp;
}
+#endif
+#define align_binary(ptr, align_sub_1) \
+ ((ptr + (align_sub_1)) & (~(align_sub_1)))
// Efficiently round "ptr" up to an "alignment" boundary, knowing that
// all such boundaries are binary powers and that we're using two's
@@ -62,11 +66,15 @@ align_binary (const ptr_arith_t value,
// XXX Returned as "byte pointer" -- CDR module would change to be
// seen as a "void *". May want to change this to add XDR cleanly.
+#if 0
static inline u_char *
ptr_align_binary (const u_char *ptr,
size_t alignment)
{
return (u_char *) align_binary ((ptr_arith_t) ptr, alignment);
}
+#endif
+#define ptr_align_binary(ptr, alignment) \
+ ((u_char *) align_binary(((ptr_arith_t) (ptr)), ((alignment)-1)))
#endif /* TAO_ALIGN_H */
diff --git a/TAO/IIOP/lib/any.cpp b/TAO/IIOP/lib/any.cpp
index ac50068f043..1c2c02eae12 100644
--- a/TAO/IIOP/lib/any.cpp
+++ b/TAO/IIOP/lib/any.cpp
@@ -35,9 +35,8 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
-#include <orb.h>
-#include "debug.h"
+#include "orb.h"
#include <initguid.h>
diff --git a/TAO/IIOP/lib/boa.cpp b/TAO/IIOP/lib/boa.cpp
index 5979fce8316..facd571aa53 100644
--- a/TAO/IIOP/lib/boa.cpp
+++ b/TAO/IIOP/lib/boa.cpp
@@ -14,10 +14,8 @@
#include <stdio.h>
#include <string.h>
-#include <orb.h>
-#include <boa.h>
-
-#include "debug.h"
+#include "orb.h"
+#include "boa.h"
// XXX this should not know implementation or other details of any
// protocol modules! This is an implementation shortcut only.
diff --git a/TAO/IIOP/lib/cdr.cpp b/TAO/IIOP/lib/cdr.cpp
index c22e4643383..1ec3a87872a 100644
--- a/TAO/IIOP/lib/cdr.cpp
+++ b/TAO/IIOP/lib/cdr.cpp
@@ -37,318 +37,62 @@
#include <limits.h>
#include <string.h>
-#include <orb.h>
-
-#include "debug.h"
+#include "orb.h"
#include "cdr.h"
-// ENCODING routines ... pad, store. Never swap. Padding uses
-// whatever value is already in the buffer.
-
-CORBA_Boolean
-CDR::put_byte (char c)
+#if !defined(ACE_INLINE)
+inline
+#endif
+void CDR::swap_long(unsigned char *orig, CORBA_Long &target)
{
- if (remaining < sizeof (char) && grow (0) == CORBA_B_FALSE)
- return CORBA_B_FALSE;
+ register unsigned char *lp = (unsigned char *) &target;
- *next++ = (u_char) c;
- remaining--;
- return CORBA_B_TRUE;
+ lp [ 3] = *orig++;
+ lp [ 2] = *orig++;
+ lp [ 1] = *orig++;
+ lp [ 0] = *orig++;
}
-CORBA_Boolean
-CDR::put_short (CORBA_Short s)
+#if !defined(ACE_INLINE)
+inline
+#endif
+void CDR::swap_longlong(unsigned char *orig, CORBA_LongLong &target)
{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes; maybe
- // grow the buffer if there's not enough left
-
- tmp_next = ptr_align_binary (next, SHORT_SIZE);
- temp = SHORT_SIZE + (tmp_next - next);
-
- if (temp > remaining)
- {
- if (grow (0) == CORBA_B_FALSE)
- return CORBA_B_FALSE;
- tmp_next = next + temp - SHORT_SIZE;
- }
-
- remaining -= temp;
-
- // copy the half word, native byte order
-
- *(CORBA_Short *) tmp_next = s;
- next = tmp_next + SHORT_SIZE;
- return CORBA_B_TRUE;
+ register unsigned char *llp = (unsigned char *) &target;
+
+ llp [ 7] = *orig++;
+ llp [ 6] = *orig++;
+ llp [ 5] = *orig++;
+ llp [ 4] = *orig++;
+ llp [ 3] = *orig++;
+ llp [ 2] = *orig++;
+ llp [ 1] = *orig++;
+ llp [ 0] = *orig++;
}
-CORBA_Boolean
-CDR::put_long (CORBA_Long l)
+#if !defined(ACE_INLINE)
+inline
+#endif
+void CDR::swap_longdouble(unsigned char *orig, CORBA_LongDouble &target)
{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes; maybe
- // grow the buffer if there's not enough left
-
- tmp_next = ptr_align_binary (next, LONG_SIZE);
- temp = LONG_SIZE + (tmp_next - next);
-
- if (temp > remaining)
- {
- if (grow (0) == CORBA_B_FALSE)
- return CORBA_B_FALSE;
- tmp_next = next + temp - LONG_SIZE;
- }
-
- remaining -= temp;
-
- // copy the word, native byte order
-
- *(CORBA_Long *) tmp_next = l;
-
- next = tmp_next + LONG_SIZE;
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::put_longlong (const CORBA_LongLong &ll)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes; maybe grow the
- // buffer if there's not enough left
-
- tmp_next = ptr_align_binary (next, LONGLONG_SIZE);
- temp = LONGLONG_SIZE + (tmp_next - next);
-
- if (temp > remaining)
- {
- if (grow (0) == CORBA_B_FALSE)
- return CORBA_B_FALSE;
- tmp_next = next + temp - LONGLONG_SIZE;
- }
- remaining -= temp;
-
- // copy the double word in "native" byte order.
-
- *(CORBA_LongLong *) tmp_next = ll;
- next = tmp_next + LONGLONG_SIZE;
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::put_longdouble (CORBA_LongDouble &ld)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes; maybe
- // grow the buffer if there's not enough left
-
- tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE);
- temp = LONGDOUBLE_SIZE + (tmp_next - next);
-
- if (temp > remaining)
- {
- if (grow (0) == CORBA_B_FALSE)
- return CORBA_B_FALSE;
- tmp_next = next + temp - LONGDOUBLE_SIZE;
- }
- remaining -= temp;
-
- // copy the long double in "native" byte order.
- *(CORBA_LongDouble *) tmp_next = ld;
- next = tmp_next + LONGDOUBLE_SIZE;
- return CORBA_B_TRUE;
-}
-
-// DECODING routines ... adjust pointer, then byteswap as needed.
-
-CORBA_Boolean
-CDR::get_byte (char &c)
-{
- if (remaining < sizeof (char))
- return CORBA_B_FALSE;
-
- c = (char) *next++;
- remaining--;
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::get_short (CORBA_Short &s)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes
-
- tmp_next = ptr_align_binary (next, SHORT_SIZE);
- temp = SHORT_SIZE + (tmp_next - next);
-
- if (temp > remaining)
- return CORBA_B_FALSE;
- remaining -= temp;
-
- // decode halfword, swapping as needed
-
- if (!do_byteswap)
- {
- s = *(CORBA_Short *) tmp_next;
- next = tmp_next + SHORT_SIZE;
- }
- else
- {
- register u_char *sp = (u_char *) &s;
-
- sp [1] = *tmp_next++;
- sp [0] = *tmp_next++;
- next = tmp_next;
- }
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::get_long (CORBA_Long &l)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes
-
- tmp_next = ptr_align_binary (next, LONG_SIZE);
- temp = LONG_SIZE + (tmp_next - next);
- if (temp > remaining)
- return CORBA_B_FALSE;
- remaining -= temp;
-
- // decode word, swapping as needed
-
- if (!do_byteswap)
- {
- l = *(CORBA_Long *) tmp_next;
- next = tmp_next + LONG_SIZE;
- }
- else
- {
- register u_char *lp = (u_char *) &l;
-
- // NOTE: environment-specific speedups abound for this kind of
- // stuff. This generic code takes advanage of none of them.
-
- lp [3] = *tmp_next++;
- lp [2] = *tmp_next++;
- lp [1] = *tmp_next++;
- lp [0] = *tmp_next++;
- next = tmp_next;
- }
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::get_longlong (CORBA_LongLong &ll)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes
-
- tmp_next = ptr_align_binary (next, LONGLONG_SIZE);
- temp = LONGLONG_SIZE + (tmp_next - next);
- if (temp > remaining)
- return CORBA_B_FALSE;
- remaining -= temp;
-
- // decode doubleword, swapping as needed
-
- if (!do_byteswap)
- {
- ll = *(CORBA_LongLong *) tmp_next;
- next = tmp_next + LONGLONG_SIZE;
- }
- else
- {
- register u_char *llp = (u_char *) &ll;
-
- // NOTE: environment-specific speedups abound for this kind
- // of stuff. This generic code takes advanage of none of them.
-
- llp [7] = *tmp_next++;
- llp [6] = *tmp_next++;
- llp [5] = *tmp_next++;
- llp [4] = *tmp_next++;
- llp [3] = *tmp_next++;
- llp [2] = *tmp_next++;
- llp [1] = *tmp_next++;
- llp [0] = *tmp_next++;
- next = tmp_next;
- }
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::get_longdouble (CORBA_LongDouble &ld)
-{
- register u_char *tmp_next;
- register u_int temp;
-
- // Adjust pointer and count of remaining bytes
-
- tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE);
- temp = LONGDOUBLE_SIZE + (tmp_next - next);
- if (temp > remaining)
- return CORBA_B_FALSE;
- remaining -= temp;
-
- // copy the long double, swapping bytes as needed
-
- if (!do_byteswap)
- {
- ld = *(CORBA_LongDouble *) tmp_next;
- next = tmp_next + LONGDOUBLE_SIZE;
- }
- else
- {
- register u_char *ldp = (u_char *) &ld;
-
- // NOTE: this is a single SPARC V9 instruction
-
- ldp [15] = *tmp_next++;
- ldp [14] = *tmp_next++;
- ldp [13] = *tmp_next++;
- ldp [12] = *tmp_next++;
- ldp [11] = *tmp_next++;
- ldp [10] = *tmp_next++;
- ldp [ 9] = *tmp_next++;
- ldp [ 8] = *tmp_next++;
- ldp [ 7] = *tmp_next++;
- ldp [ 6] = *tmp_next++;
- ldp [ 5] = *tmp_next++;
- ldp [ 4] = *tmp_next++;
- ldp [ 3] = *tmp_next++;
- ldp [ 2] = *tmp_next++;
- ldp [ 1] = *tmp_next++;
- ldp [ 0] = *tmp_next++;
- next = tmp_next;
- }
- return CORBA_B_TRUE;
-}
-
-CORBA_Boolean
-CDR::skip_string (void) // ISO/1 or octet string
-{
- CORBA_ULong len;
-
- if (get_ulong (len) == CORBA_B_FALSE || len > remaining)
- return CORBA_B_FALSE; // buffer's changed
-
- next += (u_int) len;
- remaining -= (u_int) len;
- return CORBA_B_TRUE;
+ register unsigned char *ldp = (unsigned char *) &target;
+
+ ldp [15] = *orig++;
+ ldp [14] = *orig++;
+ ldp [13] = *orig++;
+ ldp [12] = *orig++;
+ ldp [11] = *orig++;
+ ldp [10] = *orig++;
+ ldp [ 9] = *orig++;
+ ldp [ 8] = *orig++;
+ ldp [ 7] = *orig++;
+ ldp [ 6] = *orig++;
+ ldp [ 5] = *orig++;
+ ldp [ 4] = *orig++;
+ ldp [ 3] = *orig++;
+ ldp [ 2] = *orig++;
+ ldp [ 1] = *orig++;
+ ldp [ 0] = *orig++;
}
// Grow the CDR buffer, either to a known size (incoming message) or
@@ -438,3 +182,4 @@ CDR::grow (size_t newsize)
return CORBA_B_TRUE;
}
+
diff --git a/TAO/IIOP/lib/cdr.h b/TAO/IIOP/lib/cdr.h
index 1b48b18f2be..9072fcce750 100644
--- a/TAO/IIOP/lib/cdr.h
+++ b/TAO/IIOP/lib/cdr.h
@@ -48,14 +48,16 @@
#include <assert.h>
#include "ace/OS.h"
+#include "align.h"
+
#if defined(__IIOP_BUILD)
# include "orb.h"
+# include "marshal.h"
#else
# include <corba/orb.h>
+# include <marshal.h>
#endif
-#include <align.h>
-
// Identify byte order ... this is basically dependent on processor,
// but some processors support different byte orders (e.g. MIPS,
// UltraSPARC, PowerPC) as required for different software
@@ -148,7 +150,6 @@ struct ACE_Svc_Export CDR
// frames as large as the system page size (often 4Kb) can easily
// overrun the "redzone" at the bottom of most VM-based stacks.
};
-
// = ENCODING SUPPORT
// Adjust pointers as needed, then store in the native byte order.
@@ -158,26 +159,53 @@ struct ACE_Svc_Export CDR
// plus the interpretive encoder.
CORBA_Boolean put_byte (char c);
+ // encode a byte in the CDR stream
+
CORBA_Boolean put_short (CORBA_Short s);
+ // encode a short in the CDR stream
+
CORBA_Boolean put_long (CORBA_Long l);
+ // encode a long into the CDR stream
+
CORBA_Boolean put_longlong (const CORBA_LongLong &ll);
+ // encode a longlong into the CDR stream
+
CORBA_Boolean put_char (CORBA_Char c);
+ // encode a char into the CDR stream
+
CORBA_Boolean put_wchar (CORBA_WChar wc);
+ // encode a wide char into the CDR stream
+
CORBA_Boolean put_boolean (CORBA_Boolean b);
+ // encode a boolean into the CDR stream
+
CORBA_Boolean put_octet (CORBA_Octet o);
+ // encode a octet into the CDR stream
+
CORBA_Boolean put_ushort (CORBA_UShort s);
+ // encode an unsigned short into the CDR stream
+
CORBA_Boolean put_ulong (CORBA_ULong l);
+ // encode an unsigned long into the CDR stream
+
CORBA_Boolean put_ulonglong (const CORBA_ULongLong &ll);
+ // encode an unsigned longlong into the CDR stream
+
CORBA_Boolean put_float (float f);
+ // encode a float into the CDR stream
+
CORBA_Boolean put_double (const double &d);
+ // encode a double into the CDR stream
+
CORBA_Boolean put_longdouble (CORBA_LongDouble &ld);
+ // encode a longdouble into the CDR stream
+
- static CORBA_TypeCode::traverse_status encoder (CORBA_TypeCode_ptr tc,
+ CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
const void *data,
const void *,
- void *context,
CORBA_Environment &env);
- // Marshaling interpreter ... <context> really points to a <CDR>.
+ // Marshaling. ... <context> really points to a <CDR>.
// = DECODING SUPPORT
@@ -186,34 +214,76 @@ struct ACE_Svc_Export CDR
// do it that way than to use virtual functions.
CORBA_Boolean get_byte (char &c);
+ // decode a byte from the CDR stream
+
CORBA_Boolean get_short (CORBA_Short &s);
+ // decode a short from the CDR stream
+
CORBA_Boolean get_long (CORBA_Long &l);
+ // decode a long from the CDR stream
+
CORBA_Boolean get_longlong (CORBA_LongLong &ll);
+ // decode a longlong from the CDR stream
+
CORBA_Boolean get_char (CORBA_Char &o);
+ // decode a char from the CDR stream
+
CORBA_Boolean get_wchar (CORBA_WChar &wc);
+ // decode a wide char from the CDR stream
+
CORBA_Boolean get_boolean (CORBA_Boolean &b);
+ // decode a boolean from the CDR stream
+
CORBA_Boolean get_octet (CORBA_Octet &o);
+ // decode an octet from the CDR stream
+
CORBA_Boolean get_ushort (CORBA_UShort &s);
+ // decode an unsigned short from the CDR stream
+
CORBA_Boolean get_ulong (CORBA_ULong &l);
+ // decode an unsigned long from the CDR stream
+
CORBA_Boolean get_ulonglong (const CORBA_ULongLong &ull);
+ // decode an unsigned longlong from the CDR stream
+
CORBA_Boolean get_float (float &f);
+ // decode a float from the CDR stream
+
CORBA_Boolean get_double (double &d);
+ // decode a double from the CDR stream
+
CORBA_Boolean get_longdouble (CORBA_LongDouble &ld);
+ // decode a longdouble from the CDR stream
+
- static CORBA_TypeCode::traverse_status decoder (CORBA_TypeCode_ptr tc,
+ CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
const void *data,
const void *,
- void *context,
CORBA_Environment &env);
// Unmarshaling interpreter ... <context> really points to a <CDR>.
+ CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env);
+ // Does a deep copy for hierarchical data types
+
+ CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env);
+ // Deallocates memory for hierarchical data structures
+
CDR (u_char *buf = 0,
u_int len = 0,
int byte_order = MY_BYTE_SEX,
- int consume_buf = 0);
+ int consume_buf = 0,
+ TAO_MarshalFactory *f = TAO_DEFAULT_MARSHAL_FACTORY);
+ // constructor
~CDR (void);
+ // destructor
void *operator new (size_t, void *_FAR p);
void *operator new (size_t s);
@@ -225,7 +295,10 @@ struct ACE_Svc_Export CDR
// reported.
CORBA_Boolean skip_string (void);
+ // skip a string field in a typecode
+
CORBA_Boolean skip_bytes (u_int nbytes);
+ // skip given number of bytes in a typecode
void setup_encapsulation (u_char *buf, u_int len);
// Also used when interpreting typecodes, but more generally when
@@ -263,7 +336,24 @@ struct ACE_Svc_Export CDR
// Length of the dynamically allocated memory.
int do_byteswap;
- // Decode ONLY.
+ // for decoding only.
+
+private:
+ static void swap_long(unsigned char *orig, CORBA_Long &target);
+ // do byte swapping for longs
+
+ static void swap_longlong(unsigned char *orig, CORBA_LongLong &target);
+ // do byte swapping for longlongs
+
+ static void swap_longdouble(unsigned char *orig, CORBA_LongDouble &target);
+ // do byte swapping for longdoubles
+
+ TAO_MarshalFactory *factory_;
+ // maintain a factory that can make specialized marshaling objects
+
+ TAO_MarshalObject *mobj_;
+ // maintain an instance of a marshaling object. The CDR stream delegates the
+ // marshaling activity to mobj_;
};
// In this ONE case, we make a substantial exception to how inline
@@ -281,7 +371,6 @@ struct ACE_Svc_Export CDR
# endif
# include "cdr.i"
-
# if defined(do_undef_on_ACE_INLINE)
# undef do_undef_on_ACE_INLINE
# undef ACE_INLINE
diff --git a/TAO/IIOP/lib/cdr.i b/TAO/IIOP/lib/cdr.i
index d05e798e87e..2e10ab48a48 100644
--- a/TAO/IIOP/lib/cdr.i
+++ b/TAO/IIOP/lib/cdr.i
@@ -2,7 +2,8 @@ ACE_INLINE
CDR::CDR (u_char *buf,
u_int len,
int byte_order,
- int consume_buf)
+ int consume_buf,
+ TAO_MarshalFactory *f)
// Constructor ... buffer must be aligned for the strictest CDR
// alignment requirement, since the algorithms used here only
// maintain alignment with respect to &buffer [0].
@@ -10,7 +11,9 @@ CDR::CDR (u_char *buf,
// Yes, that complicates the grow() primitive.
: real_buffer(buf),
do_free(consume_buf),
- do_byteswap(byte_order != MY_BYTE_SEX)
+ do_byteswap(byte_order != MY_BYTE_SEX),
+ factory_(f),
+ mobj_(0)
{
ptr_arith_t temp = (ptr_arith_t) buf;
@@ -76,6 +79,20 @@ CDR::put_octet (CORBA_Octet o)
}
ACE_INLINE CORBA_Boolean
+CDR::put_byte (
+ char c
+)
+{
+ if (remaining < sizeof (char) && grow (0) == CORBA_B_FALSE)
+ return CORBA_B_FALSE;
+
+ *next++ = (unsigned char) c;
+ remaining--;
+ return CORBA_B_TRUE;
+}
+
+
+ACE_INLINE CORBA_Boolean
CDR::put_ushort (CORBA_UShort s)
{
return put_short ((CORBA_Short) s);
@@ -175,11 +192,47 @@ CDR::get_double (double &d)
ACE_INLINE CORBA_Boolean
CDR::skip_bytes (u_int nbytes)
{
- if (remaining < nbytes)
- return CORBA_B_FALSE;
- remaining -= nbytes;
- next += nbytes;
- return CORBA_B_TRUE;
+ if (remaining >= nbytes)
+ {
+ remaining -= nbytes;
+ next += nbytes;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::skip_string () // ISO/1 or octet string
+{
+ CORBA_ULong len;
+
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes
+ //
+ tmp_next = ptr_align_binary (next, LONG_SIZE);
+ temp = LONG_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+
+ //
+ // decode word, swapping as needed
+ //
+ if (!do_byteswap) {
+ len = *(CORBA_Long *)tmp_next;
+ next = tmp_next + LONG_SIZE;
+ } else {
+ swap_long(tmp_next, *(CORBA_Long *)&len);
+ }
+
+ // skip that many bytes
+ next += (unsigned) len;
+ remaining -= (unsigned) len;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
}
ACE_INLINE void
@@ -200,3 +253,386 @@ CDR::bytes_remaining (void)
{
return remaining;
}
+
+ACE_INLINE CORBA_Boolean
+CDR::put_short (
+ CORBA_Short s
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes; maybe
+ // grow the buffer if there's not enough left
+ //
+ tmp_next = ptr_align_binary (next, SHORT_SIZE);
+ temp = SHORT_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+
+ //
+ // copy the half word, native byte order
+ //
+ *(CORBA_Short *)tmp_next = s;
+ next = tmp_next + SHORT_SIZE;
+ return CORBA_B_TRUE;
+ } else {
+ if (grow (0) == CORBA_B_TRUE) {
+ tmp_next = next + temp - SHORT_SIZE;
+ remaining -= temp;
+
+ //
+ // copy the half word, native byte order
+ //
+ *(CORBA_Short *)tmp_next = s;
+ next = tmp_next + SHORT_SIZE;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+ }
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::put_long (
+ CORBA_Long l
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes; maybe
+ // grow the buffer if there's not enough left
+ //
+ tmp_next = ptr_align_binary (next, LONG_SIZE);
+ temp = LONG_SIZE + (tmp_next - next);
+ if (temp <= remaining)
+ {
+ remaining -= temp;
+
+ //
+ // copy the word, native byte order
+ //
+ *(CORBA_Long *)tmp_next = l;
+
+ next = tmp_next + LONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ else
+ {
+ if (grow (0) == CORBA_B_TRUE)
+ {
+ tmp_next = next + temp - LONG_SIZE;
+ remaining -= temp;
+
+ //
+ // copy the word, native byte order
+ //
+ *(CORBA_Long *)tmp_next = l;
+
+ next = tmp_next + LONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+ }
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::put_longlong (
+ const CORBA_LongLong &ll
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes; maybe
+ // grow the buffer if there's not enough left
+ //
+ tmp_next = ptr_align_binary (next, LONGLONG_SIZE);
+ temp = LONGLONG_SIZE + (tmp_next - next);
+ if (temp <= remaining)
+ {
+ remaining -= temp;
+ //
+ // copy the double word in "native" byte order.
+ //
+ *(CORBA_LongLong *)tmp_next = ll;
+ next = tmp_next + LONGLONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ else
+ {
+ if (grow (0) == CORBA_B_TRUE)
+ {
+ tmp_next = next + temp - LONGLONG_SIZE;
+ remaining -= temp;
+ //
+ // copy the double word in "native" byte order.
+ //
+ *(CORBA_LongLong *)tmp_next = ll;
+ next = tmp_next + LONGLONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+ }
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::put_longdouble (
+ CORBA_LongDouble &ld
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes; maybe
+ // grow the buffer if there's not enough left
+ //
+ tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE);
+ temp = LONGDOUBLE_SIZE + (tmp_next - next);
+ if (temp <= remaining)
+ {
+ remaining -= temp;
+ //
+ // copy the longdouble in native byte order
+ //
+ *(CORBA_LongDouble *)tmp_next = ld;
+ next = tmp_next + LONGDOUBLE_SIZE;
+ return CORBA_B_TRUE;
+ }
+ else
+ {
+ if (grow (0) == CORBA_B_TRUE)
+ {
+ tmp_next = next + temp - LONGDOUBLE_SIZE;
+ remaining -= temp;
+ //
+ // copy the longdouble in native byte order
+ //
+ *(CORBA_LongDouble *)tmp_next = ld;
+ next = tmp_next + LONGDOUBLE_SIZE;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+ }
+}
+
+
+//
+// DECODING routines ... adjust pointer, then byteswap as needed.
+//
+
+ACE_INLINE CORBA_Boolean
+CDR::get_byte (
+ char &c
+ )
+{
+ if (remaining >= sizeof (char))
+ {
+ c = (char) *next++;
+ remaining--;
+ return CORBA_B_TRUE;
+ }
+ return CORBA_B_FALSE;
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::get_short (
+ CORBA_Short &s
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes
+ //
+ tmp_next = ptr_align_binary (next, SHORT_SIZE);
+ temp = SHORT_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+ //
+ // decode halfword, swapping as needed
+ //
+ if (!do_byteswap) {
+ s = *(CORBA_Short *)tmp_next;
+ next = tmp_next + SHORT_SIZE;
+ return CORBA_B_TRUE; // put a return here to avoid a jump
+ } else {
+ // do swapping
+ register unsigned char *sp = (unsigned char *) &s;
+
+ sp [1] = *tmp_next++;
+ sp [0] = *tmp_next++;
+ next = tmp_next;
+ return CORBA_B_TRUE;
+ }
+ }
+ return CORBA_B_FALSE;
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::get_long (
+ CORBA_Long &l
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes
+ //
+ tmp_next = ptr_align_binary (next, LONG_SIZE);
+ temp = LONG_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+ //
+ // decode word, swapping as needed
+ //
+ if (!do_byteswap) {
+ l = *(CORBA_Long *)tmp_next;
+ next = tmp_next + LONG_SIZE;
+ return CORBA_B_TRUE;
+ } else {
+ //
+ // NOTE: environment-specific speedups abound for this kind
+ // of stuff. This generic code takes advantage of none of them.
+ //
+ swap_long(tmp_next, l);
+ next = tmp_next + LONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ }
+ return CORBA_B_FALSE;
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::get_longlong (
+ CORBA_LongLong &ll
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes
+ //
+ tmp_next = ptr_align_binary (next, LONGLONG_SIZE);
+ temp = LONGLONG_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+ //
+ // decode doubleword, swapping as needed
+ //
+ if (!do_byteswap) {
+ ll = *(CORBA_LongLong *)tmp_next;
+ next = tmp_next + LONGLONG_SIZE;
+ return CORBA_B_TRUE;
+ } else {
+ swap_longlong(tmp_next, ll);
+ next = tmp_next + LONGLONG_SIZE;
+ return CORBA_B_TRUE;
+ }
+ }
+ return CORBA_B_FALSE;
+}
+
+ACE_INLINE CORBA_Boolean
+CDR::get_longdouble (
+ CORBA_LongDouble &ld
+ )
+{
+ register unsigned char *tmp_next;
+ register unsigned temp;
+
+ //
+ // Adjust pointer and count of remaining bytes
+ //
+ tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE);
+ temp = LONGDOUBLE_SIZE + (tmp_next - next);
+ if (temp <= remaining) {
+ remaining -= temp;
+
+ //
+ // copy the long double, swapping bytes as needed
+ //
+ if (!do_byteswap) {
+ ld = *(CORBA_LongDouble *)tmp_next;
+ next = tmp_next + LONGDOUBLE_SIZE;
+ return CORBA_B_TRUE;
+ } else {
+ swap_longdouble(tmp_next, ld);
+ next = tmp_next + LONGDOUBLE_SIZE;
+ return CORBA_B_TRUE;
+ }
+ }
+ return CORBA_B_FALSE;
+}
+
+// Encode data into CDR stream
+ACE_INLINE CORBA_TypeCode::traverse_status
+CDR::encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env)
+{
+ this->mobj_ = this->factory_->make_marshal_object(tc);
+ if (this->mobj_)
+ {
+ return this->mobj_->encode(tc, data, data2, this, env);
+ }
+ else
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// Decode the CDR stream
+ACE_INLINE CORBA_TypeCode::traverse_status
+CDR::decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env)
+{
+ this->mobj_ = this->factory_->make_marshal_object(tc);
+ if (this->mobj_)
+ {
+ return this->mobj_->decode(tc, data, data2, this, env);
+ }
+ else
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+#if 0
+// allocate buffers and make a deep copy
+ACE_INLINE CORBA_TypeCode::traverse_status
+CDR::deep_copy (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env)
+{
+ this->mobj_ = this->factory_->make_marshal_object(tc);
+ return this->mobj_->deep_copy(tc, data, data2, this, env);
+}
+
+// free the buffers allocated for the specified data structure
+ACE_INLINE CORBA_TypeCode::traverse_status
+CDR::deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env)
+{
+ this->mobj_ = this->factory_->make_marshal_object(tc);
+ return this->mobj_->deep_free(tc, data, data2, this, env);
+}
+#endif
+
+
+
diff --git a/TAO/IIOP/lib/debug.cpp b/TAO/IIOP/lib/debug.cpp
index 89c5b2487b5..2b542132c9c 100644
--- a/TAO/IIOP/lib/debug.cpp
+++ b/TAO/IIOP/lib/debug.cpp
@@ -65,7 +65,7 @@ static pid_t my_pid;
//
static pthread_once_t debug_init = PTHREAD_ONCE_INIT;
-#define setup () pthread_once (&debug_init, setup_once)
+#define setup() pthread_once (&debug_init, setup_once)
static void
setup_once ()
diff --git a/TAO/IIOP/lib/debug.h b/TAO/IIOP/lib/debug.h
index 57459eb9af2..97bd08664a8 100644
--- a/TAO/IIOP/lib/debug.h
+++ b/TAO/IIOP/lib/debug.h
@@ -33,7 +33,7 @@ extern "C" char *strerror (int);
// "tao_debug_level", etc. to protect the namespace.
// 0 to ??; higher == more
-extern u_int TAO_debug_level;
+extern unsigned int TAO_debug_level;
// set by getopt
extern char *TAO_debug_filter;
diff --git a/TAO/IIOP/lib/decode.cpp b/TAO/IIOP/lib/decode.cpp
new file mode 100644
index 00000000000..814c17e0eef
--- /dev/null
+++ b/TAO/IIOP/lib/decode.cpp
@@ -0,0 +1,1611 @@
+// ============================================================================
+//
+// = 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 <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "orb.h"
+#include "cdr.h"
+#include "giop.h"
+
+#if defined (HAVE_WIDEC_H)
+# include <widec.h>
+#else
+extern "C"
+{
+ u_int wslen (const CORBA_WChar *);
+ CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *);
+}
+#endif
+
+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 "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 [TC_KIND_COUNT] =
+{
+ _tc_CORBA_Null
+ , _tc_CORBA_Void
+ , _tc_CORBA_Short
+ , _tc_CORBA_Long
+ , _tc_CORBA_UShort
+
+ , _tc_CORBA_ULong
+ , _tc_CORBA_Float
+ , _tc_CORBA_Double
+ , _tc_CORBA_Boolean
+ , _tc_CORBA_Char
+
+ , _tc_CORBA_Octet
+ , _tc_CORBA_Any
+ , _tc_CORBA_TypeCode
+ , _tc_CORBA_Principal
+ , 0 // _tc_CORBA_Object ... type ID is CORBA::Object
+
+ , 0 // tk_struct
+ , 0 // tk_union
+ , 0 // tk_enum
+ , 0 // _tc_CORBA_String ... unbounded
+ , 0 // tk_sequence
+
+ , 0 // tk_array
+
+ , 0 // tk_alias
+ , 0 // tk_except
+
+ , _tc_CORBA_LongLong
+ , _tc_CORBA_ULongLong
+ , _tc_CORBA_LongDouble
+ , _tc_CORBA_WChar
+ , 0 // _tc_CORBA_WString ... unbounded
+};
+
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Primitive::decode(
+ CORBA_TypeCode_ptr tc,
+ 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::traverse_status retval =
+ CORBA_TypeCode::TRAVERSE_CONTINUE; // status of encode operation
+
+ switch(tc->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_decoding = stream->get_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_decoding = stream->get_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_decoding = stream->get_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_decoding = stream->get_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_decoding = stream->get_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_decoding = stream->get_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_decoding = stream->get_wchar(*(wchar_t *)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(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 tc,
+ const void *data,
+ const void *parent_typecode,
+ 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; // 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
+
+ // encode the typecode description for the element
+ if (stream->decode(_tc_CORBA_TypeCode, &elem_tc, 0, 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_decoding = stream->get_short (*(CORBA_Short *)value);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_decoding = stream->get_long(*(CORBA_Long *)value);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_decoding = stream->get_longlong (*(CORBA_LongLong *)value);
+ break;
+ case tk_boolean:
+ continue_decoding = stream->get_boolean (*(CORBA_Boolean *)value);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_decoding = stream->get_char(*(CORBA_Char *)value);
+ break;
+ case tk_longdouble:
+ continue_decoding = stream->get_longdouble(*(CORBA_LongDouble *)value);
+ break;
+ case tk_wchar:
+ continue_decoding = stream->get_wchar(*(wchar_t *)value);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case 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(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 tc,
+ 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 encoded
+ CORBA_ULong kind;
+
+ // decode the "kind" field of the typecode
+ continue_decoding = stream->get_ulong ((CORBA_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 (((*tcp) = __tc_consts [(u_int) kind]) != 0)
+ {
+ *tcp = __tc_consts [(u_int) kind];
+ }
+ else
+ {
+ 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 (COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+
+ // Some have "simple" parameter lists ... some of these also
+ // have preallocated constants that could be used.
+ case tk_string:
+ case tk_wstring:
+ {
+ CORBA_ULong bound;
+
+ continue_decoding = stream->get_ulong (bound);
+ if (continue_decoding)
+ {
+ if (bound == 0)
+ {
+ if (kind == tk_string)
+ *tcp = _tc_CORBA_String;
+ else
+ *tcp = _tc_CORBA_WString;
+ }
+ else
+ {
+ *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind,
+ bound, 0, CORBA_B_TRUE);
+ }
+ }
+ }
+ 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:
+ {
+ CORBA_TypeCode_ptr parent;
+
+ if (parent_typecode == 0)
+ {
+ env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ parent = (CORBA_TypeCode_ptr) parent_typecode;
+
+ // 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)
+ continue_decoding = (offset < 0);
+ if (continue_decoding)
+ {
+ indir_stream.buffer = indir_stream.next
+ = stream->next + offset;
+ indir_stream.remaining = indir_stream.length = 8;
+
+ // Reject indirections outside parent's scope.
+ if (indir_stream.next < 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;
+
+ if (continue_decoding)
+ continue_decoding = stream->get_ulong (indir_kind);
+ if (continue_decoding
+ && indir_kind >= TC_KIND_COUNT)
+ continue_decoding = CORBA_B_FALSE;
+ if (continue_decoding)
+ continue_decoding = 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.next,
+ CORBA_B_FALSE);
+ (*tcp)->_parent = parent;
+ parent->AddRef ();
+ }
+ }
+ break;
+
+ // The rest have "complex" parameter lists that are
+ // encoded as bulk octets ...
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_enum:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ {
+ u_int len;
+ u_int i;
+ CORBA_ULong length;
+ CORBA_Octet *buffer;
+
+ continue_decoding = stream->get_ulong (length);
+ if (!continue_decoding)
+ break;
+
+ // if length > MAXUNSIGNED, error ...
+ len = (u_int) length;
+
+ buffer = new CORBA_Octet [len];
+
+ for (i = 0; i < len && continue_decoding; i++)
+ continue_decoding = stream->get_octet (buffer [i]);
+
+ if (!continue_decoding) {
+ delete buffer;
+ break;
+ }
+ *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind,
+ len,
+ buffer,
+ CORBA_B_TRUE);
+ }
+ }
+ }
+
+ }
+ if (continue_decoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(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 tc,
+ 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::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ 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(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 tc,
+ 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::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 (_tc_CORBA_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 ();
+ delete type_hint;
+ }
+ else
+ {
+ while (profiles-- != 0 && continue_decoding)
+ {
+ CORBA_ULong tmp;
+
+ // get the profile ID tag
+ stream->get_ulong (tmp);
+ if (tmp != 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
+ continue_decoding = stream->get_ulong (tmp);
+ assert (stream->remaining >= tmp);
+
+ // Create the decoding stream from the encapsulation in
+ // the buffer, and skip the encapsulation.
+ CDR str;
+
+ str.setup_encapsulation (stream->next, (size_t) tmp);
+
+ stream->next += (u_int) tmp;
+ stream->remaining -= (u_int) tmp;
+
+ objdata = new IIOP_Object (type_hint);
+
+ IIOP::ProfileBody *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 = 0;
+ objdata->Release ();
+ objdata = 0;
+ continue;
+ }
+
+ // Get host and port
+ if (str.decode (_tc_CORBA_String, &profile->host, 0, env)
+ != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || !str.get_ushort (profile->port))
+ {
+ env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE));
+ dmsg ("error decoding IIOP host/port");
+ objdata->Release ();
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+ // ... and object key
+
+ continue_decoding = str.decode (&TC_opaque,
+ &profile->object_key,
+ 0,
+ env) == CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ if (str.remaining != 0)
+ {
+ env.exception (new CORBA_MARSHAL (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 (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
+ {
+ // retrieve the CORBA_Object from the IIOP_Object we created before.
+ if (objdata->QueryInterface (IID_CORBA_Object,
+ (void **) data) != NOERROR)
+ continue_decoding = CORBA_B_FALSE;
+ objdata->Release ();
+ }
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE && continue_decoding ==
+ CORBA_B_TRUE){
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ } else {
+ env.exception (new CORBA_MARSHAL(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 *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CDR *stream = (CDR *)context;
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_Boolean continue_decoding = CORBA_B_TRUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_decoding = stream->get_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_decoding = stream->get_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_decoding = stream->get_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_decoding = stream->get_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_decoding = stream->get_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_decoding = stream->get_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_decoding = stream->get_wchar(*(wchar_t *)data);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case 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(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
+ )
+{
+ 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_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.
+ i = 0;
+ while (member_count-- != 0)
+ {
+ member_label = tc->member_label(i, env);
+ if (env.exception() == 0)
+ {
+ // do the matching
+ switch (member_label->type()->kind(env))
+ {
+ case tk_short:
+ case tk_ushort:
+ if (*(CORBA_Short *)member_label->value() ==
+ *(CORBA_Short *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_enum:
+ if (*(CORBA_ULong *)member_label->value() ==
+ *(CORBA_ULong *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_char:
+ if (*(CORBA_Char *)member_label->value() ==
+ *(CORBA_Char *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_wchar:
+ if (*(CORBA_WChar *)member_label->value() ==
+ *(CORBA_WChar *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case 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(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(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ i++;
+ } // end of while
+ // 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(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// decode string
+CORBA_TypeCode::traverse_status
+TAO_Marshal_String::decode (
+ CORBA_TypeCode_ptr tc,
+ 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::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_ULong len = 0;
+ CORBA_ULong bounds;
+ 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);
+ *((CORBA_String*) data) = str = new CORBA_Char [(size_t) (len)];
+
+ if (len != 0)
+ while (continue_decoding != CORBA_B_FALSE && len-- != 0)
+ {
+ continue_decoding = stream->get_char (*(CORBA_Char *) str);
+ str++;
+ }
+ if (continue_decoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(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 *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_decoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *)context;
+ CORBA_OctetSeq *seq = (CORBA_OctetSeq *) 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;
+ CORBA_ULong len;
+ 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->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 a buffer to hold the sequence
+ seq->buffer = new CORBA_Octet [size * (size_t) seq->maximum];
+ value = (char *)seq->buffer;
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case 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 tk_long:
+ case tk_ulong:
+ case 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 tk_double:
+ case tk_longlong:
+ case 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 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 tk_char:
+ case 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 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 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 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 tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case 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
+ } // length is > 0
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ // error exit
+ env.exception (new CORBA_MARSHAL(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 *parent_typecode,
+ 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 tk_null:
+ case tk_void:
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case 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 tk_long:
+ case tk_ulong:
+ case 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 tk_double:
+ case tk_longlong:
+ case 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 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 tk_char:
+ case 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 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 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 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 tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case 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(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 *parent_typecode,
+ 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_decoding = stream->get_short (*(CORBA_Short *)value);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_decoding = stream->get_long(*(CORBA_Long *)value);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_decoding = stream->get_longlong (*(CORBA_LongLong *)value);
+ break;
+ case tk_boolean:
+ continue_decoding = stream->get_boolean (*(CORBA_Boolean *)value);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_decoding = stream->get_char(*(CORBA_Char *)value);
+ break;
+ case tk_longdouble:
+ continue_decoding = stream->get_longdouble(*(CORBA_LongDouble *)value);
+ break;
+ case tk_wchar:
+ continue_decoding = stream->get_wchar(*(wchar_t *)value);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ retval = stream->decode(tc2, value, 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(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 *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CDR *stream = (CDR *)context;
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ 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);
+
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_decoding = stream->get_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_decoding = stream->get_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_decoding = stream->get_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_decoding = stream->get_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_decoding = stream->get_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_decoding = stream->get_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_decoding = stream->get_wchar(*(wchar_t *)data);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case 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(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 tc,
+ 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::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_WChar *str = *(CORBA_WChar **) data;
+ CORBA_ULong len;
+ CORBA_ULong bounds;
+
+ // 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(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_TypeCode::decode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
diff --git a/TAO/IIOP/lib/deep_copy.cpp b/TAO/IIOP/lib/deep_copy.cpp
new file mode 100644
index 00000000000..4bd71c70eea
--- /dev/null
+++ b/TAO/IIOP/lib/deep_copy.cpp
@@ -0,0 +1,1309 @@
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// deep_copy.cpp
+//
+// = DESCRIPTION
+// Code for deep_copy
+// The original code had a single static deep_copy function that called
+// traverse to interpret the data types. This version defines a static method
+// "deep_copy" on each class and avoids calling traverse.
+//
+//
+// Helper routine for "Any" copy constructor ...
+//
+// "Deep Copy" from source to dest. Memory is always there to be
+// copied to ... if this calls other deep_copy methods, it ensures that
+// this remains true (only really an issue for sequences) .
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "orb.h"
+#include "cdr.h"
+#include "giop.h"
+
+#if defined (HAVE_WIDEC_H)
+# include <widec.h>
+#else
+extern "C"
+{
+ u_int wslen (const CORBA_WChar *);
+ CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *);
+}
+#endif
+
+extern CORBA_TypeCode TC_opaque;
+
+ // Deep copy from "source" to "dest" ... this code "knows" a bit
+ // about representations, verify it when porting to oddball
+ // platforms with non-IEEE floating point values or atypical byte
+ // and word sizes.
+ //
+
+
+static CORBA_TypeCode::traverse_status
+DEEP_COPY(
+ CORBA_TypeCode_ptr param,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ switch(param->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *)dest = *(CORBA_Short *)source;
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *)dest = *(CORBA_Long *)source;
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source;
+ break;
+ case tk_boolean:
+ *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source;
+ break;
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Char *)dest = *(CORBA_Char *)source;
+ break;
+ case tk_longdouble:
+ *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source;
+ break;
+ case tk_wchar:
+ *(CORBA_WChar *)dest = *(CORBA_WChar *)source;
+ break;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_copy(param, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_copy(param, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_copy(param, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_copy(param, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_copy(param, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_copy(param, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_copy(param, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_copy(param, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_copy(param, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_copy(param, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_copy(param, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_copy(param, source, dest, env);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ } // end of switch
+ return retval;
+}
+
+// deep copy for primitives
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Primitive::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TCKind my_kind;
+
+ if (tc)
+ {
+ my_kind = tc->kind (env);
+
+ if (env.exception() == 0)
+ {
+
+ switch (my_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Octet *) dest = *(CORBA_Octet *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *) dest = *(CORBA_Short *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_wchar:
+ *(CORBA_WChar *) dest = *(CORBA_WChar *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *) dest = *(CORBA_Long *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_double:
+ *(CORBA_LongLong *) dest = *(CORBA_LongLong *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_longdouble:
+ *(CORBA_LongDouble *) dest = *(CORBA_LongDouble *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ case tk_boolean:
+ *(CORBA_Boolean *) dest = *(CORBA_Boolean *) source;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ default:
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Primitive::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ dmsg ("TAO_Marshal_Primitive::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_MAYBE) );
+ dmsg ("TAO_Marshal_Primitive::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy for Principal
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Principal::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode::traverse_status retval =
+ CORBA_TypeCode::TRAVERSE_CONTINUE; // status of encode operation
+ CORBA_Principal_ptr src, dst;
+
+ if (tc)
+ {
+ src = *(CORBA_Principal_ptr *) source;
+ dst = *(CORBA_Principal_ptr *) dest = new CORBA_Principal;
+
+ if (dst)
+ {
+ // Principals are just opaque IDs ... copy them
+ assert (src->id.length <= UINT_MAX);
+ dst->id.length = dst->id.maximum = src->id.length;
+
+ if (dst->id.length > 0)
+ {
+ dst->id.buffer = new CORBA_Octet [ (unsigned) dst->id.length];
+ if (dst->id.buffer)
+ {
+ ACE_OS::memcpy (dst->id.buffer, src->id.buffer,
+ (size_t) dst->id.length);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_NO_MEMORY (COMPLETED_MAYBE) );
+ dmsg ("TAO_Marshal_Principal::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ dst->id.buffer = 0;
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA_NO_MEMORY (COMPLETED_MAYBE) );
+ dmsg ("TAO_Marshal_Principal::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_MAYBE) );
+ dmsg ("TAO_Marshal_Primitive::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy structs
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Struct::deep_copy (
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+ CDR stream;
+
+ if (tc)
+ {
+ // compute the number of fields in the struct
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(i=0; i < member_count && retval ==
+ CORBA_TypeCode::TRAVERSE_CONTINUE; i++)
+ {
+ // get the typecode for the ith field
+ param = tc->member_type(i, env);
+ if (env.exception() == 0)
+ {
+ // get the size of the field
+ size = param->size(env);
+ if (env.exception() == 0)
+ {
+ // get the alignment of the field
+ alignment = param->alignment(env);
+ if (env.exception() == 0)
+ {
+ switch(param->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *)dest = *(CORBA_Short *)source;
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *)dest = *(CORBA_Long *)source;
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source;
+ break;
+ case tk_boolean:
+ *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source;
+ break;
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Char *)dest = *(CORBA_Char *)source;
+ break;
+ case tk_longdouble:
+ *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source;
+ break;
+ case tk_wchar:
+ *(CORBA_WChar *)dest = *(CORBA_WChar *)source;
+ break;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_copy(param, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_copy(param, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_copy(param, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_copy(param, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_copy(param, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_copy(param, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_copy(param, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_copy(param, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_copy(param, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_copy(param, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_copy(param, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_copy(param, source, dest, env);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ } // end of switch
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ else // exception computing alignment
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing size
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing typecode
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // end of loop
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting member count
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy for union
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Union::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ 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)
+ {
+ // deep_copy the discriminator value
+ retval = DEEP_COPY(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.
+ i = 0;
+ while (member_count-- != 0)
+ {
+ member_label = tc->member_label(i, env);
+ if (env.exception() == 0)
+ {
+ // do the matching
+ switch (member_label->type()->kind(env))
+ {
+ case tk_short:
+ case tk_ushort:
+ if (*(CORBA_Short *)member_label->value() ==
+ *(CORBA_Short *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_enum:
+ if (*(CORBA_ULong *)member_label->value() ==
+ *(CORBA_ULong *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_char:
+ if (*(CORBA_Char *)member_label->value() ==
+ *(CORBA_Char *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_wchar:
+ if (*(CORBA_WChar *)member_label->value() ==
+ *(CORBA_WChar *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case 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(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 DEEP_COPY(member_tc, data,
+ data2, env);
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ i++;
+ } // end of while
+ // we are here only if there was no match
+ if (default_tc)
+ {
+ return DEEP_COPY(default_tc, data, data2, env);
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+}
+
+// deep_copy for Sequence
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Sequence::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ 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 *value1, *value2;
+ CORBA_OctetSeq *src, *dst;
+ CDR stream; // used only to access the marshal_object factory
+
+ // Rely on binary format of sequences -- all are the same
+ // except for the type pointed to by "buffer"
+
+ if (tc)
+ {
+ src = (CORBA_OctetSeq *) source;
+ dst = (CORBA_OctetSeq *) dest;
+
+ assert (src->length <= UINT_MAX);
+ dst->length = dst->maximum = src->length;
+
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ // get the size of the element
+ size = tc2->size (env);
+ if (env.exception() == 0)
+ {
+ // compute the length of the sequence
+ bounds = src->length;
+
+ // allocate a buffer to hold the sequence
+ dst->buffer = new CORBA_Octet [size * (size_t) src->maximum];
+ if (dst->buffer)
+ {
+ value1 = (char *)src->buffer;
+ value2 = (char *)dst->buffer;
+
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ case tk_enum:
+ // just do a memcpy rather than copying each element
+ ACE_OS::memcpy(value2, value1, size*bounds);
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ // handle all aggregate types here
+ case tk_any:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_TypeCode:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_TypeCode::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_Principal:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Principal::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_objref:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_ObjRef::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_struct:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Struct::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_union:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Union::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_string:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ retval = TAO_Marshal_String::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_sequence:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Sequence::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_array:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Array::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_alias:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Alias::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_except:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Except::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ case tk_wstring:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_WString::deep_copy(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ value2 = (char *)value2 + size;
+ }
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ break;
+ } // end of switch
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ // error exit
+ env.exception (new CORBA_MARSHAL(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ // error exit
+ CORBA_release(tc2);
+ env.exception (new CORBA_NO_MEMORY(COMPLETED_MAYBE));
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing size
+ {
+ CORBA_release(tc2);
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_copy detected error");
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing content type
+ {
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_copy detected error");
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy for Array
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Array::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ 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;
+ CDR stream; // used only to access the marshal_object factory
+
+ // Rely on binary format of sequences -- all are the same
+ // except for the type pointed to by "buffer"
+
+ if (tc)
+ {
+ bounds = tc->length(env);
+ if (env.exception() == 0)
+ {
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ // get the size of the element type
+ size = tc2->size (env);
+ if (env.exception() == 0)
+ {
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ case tk_enum:
+ // just do a memcpy rather than copying each element
+ ACE_OS::memcpy((char *)dest, (char *)source, size*bounds);
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ // handle all aggregate types here
+ case tk_any:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_TypeCode:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_TypeCode::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_Principal:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Principal::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_objref:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_ObjRef::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_struct:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Struct::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_union:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Union::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_string:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ retval = TAO_Marshal_String::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_sequence:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Sequence::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_array:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Array::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_alias:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Alias::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_except:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Except::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ case tk_wstring:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_WString::deep_copy(tc2, source, dest, env);
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ break;
+ } // end of switch
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ // error exit
+ env.exception (new CORBA_MARSHAL(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // no exception computing size
+ else
+ {
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // no exception computing content type
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // bounds are fine
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy alias
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Alias::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode_ptr tc2; // typecode of the aliased type
+ CDR stream; // to access the marshal object
+ CORBA_TypeCode::traverse_status retval =
+ CORBA_TypeCode::TRAVERSE_CONTINUE; // status of deep_copy operation
+
+ if (tc)
+ {
+ // get element type
+ tc2 = tc->content_type(env);
+ if (env.exception() == 0)
+ {
+ // switch on the data type and handle the cases for primitives here for
+ // efficiency
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *)dest = *(CORBA_Short *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *)dest = *(CORBA_Long *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_boolean:
+ *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Char *)dest = *(CORBA_Char *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_longdouble:
+ *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_wchar:
+ *(CORBA_WChar *)dest = *(CORBA_WChar *)source;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_copy(tc2, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_copy(tc2, source, dest, env);
+ break;
+ default:
+ // anything else is an error
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Alias::decode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting content_type
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_copy structs
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Except::deep_copy (
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+ CDR stream;
+
+ if (tc)
+ {
+ // Exceptions in memory have a "hidden" typecode up front, used
+ // to ensure that memory is appropriately freed and to hold the
+ // exception ID. We just copy that typecode
+
+ *(CORBA_TypeCode_ptr *) dest = *(CORBA_TypeCode_ptr *) source;
+ (void) (*(CORBA_TypeCode_ptr *) dest)->AddRef ();
+
+ // compute the number of fields in the struct
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(i=0; i < member_count && retval ==
+ CORBA_TypeCode::TRAVERSE_CONTINUE; i++)
+ {
+ // get the typecode for the ith field
+ param = tc->member_type(i, env);
+ if (env.exception() == 0)
+ {
+ // get the size of the field
+ size = param->size(env);
+ if (env.exception() == 0)
+ {
+ // get the alignment of the field
+ alignment = param->alignment(env);
+ if (env.exception() == 0)
+ {
+ switch(param->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *)dest = *(CORBA_Short *)source;
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *)dest = *(CORBA_Long *)source;
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source;
+ break;
+ case tk_boolean:
+ *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source;
+ break;
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Char *)dest = *(CORBA_Char *)source;
+ break;
+ case tk_longdouble:
+ *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source;
+ break;
+ case tk_wchar:
+ *(CORBA_WChar *)dest = *(CORBA_WChar *)source;
+ break;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_copy(param, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_copy(param, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_copy(param, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_copy(param, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_copy(param, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_copy(param, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_copy(param, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_copy(param, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_copy(param, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_copy(param, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_copy(param, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_copy(param, source, dest, env);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ } // end of switch
+ source = (char *)source + size;
+ dest = (char *)dest + size;
+ }
+ else // exception computing alignment
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing size
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing typecode
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // end of loop
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting member count
+ {
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_copy detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
diff --git a/TAO/IIOP/lib/deep_free.cpp b/TAO/IIOP/lib/deep_free.cpp
new file mode 100644
index 00000000000..f451154b821
--- /dev/null
+++ b/TAO/IIOP/lib/deep_free.cpp
@@ -0,0 +1,1028 @@
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// deep_free.cpp
+//
+// = DESCRIPTION
+// Code for deep_free
+// The original code had a single static deep_free function that called
+// traverse to interpret the data types. This version defines a static method
+// "deep_free" on each class and avoids calling traverse.
+//
+// Helper routine for "Any" destructor.
+//
+// This frees all the memory pointed to by any given value held inside
+// of an "Any". For most data types it does nothing, since most data
+// types don't hold any memory. For a few, it calls other deep_free methods
+// to free the memory
+//
+
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "orb.h"
+#include "cdr.h"
+#include "giop.h"
+
+#if defined (HAVE_WIDEC_H)
+# include <widec.h>
+#else
+extern "C"
+{
+ u_int wslen (const CORBA_WChar *);
+ CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *);
+}
+#endif
+
+extern CORBA_TypeCode TC_opaque;
+
+ // Deep copy from "source" to "dest" ... this code "knows" a bit
+ // about representations, verify it when porting to oddball
+ // platforms with non-IEEE floating point values or atypical byte
+ // and word sizes.
+ //
+
+
+static CORBA_TypeCode::traverse_status
+DEEP_FREE(
+ CORBA_TypeCode_ptr param,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ switch(param->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ *(CORBA_Short *)dest = *(CORBA_Short *)source;
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ *(CORBA_Long *)dest = *(CORBA_Long *)source;
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source;
+ break;
+ case tk_boolean:
+ *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source;
+ break;
+ case tk_char:
+ case tk_octet:
+ *(CORBA_Char *)dest = *(CORBA_Char *)source;
+ break;
+ case tk_longdouble:
+ *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source;
+ break;
+ case tk_wchar:
+ *(CORBA_WChar *)dest = *(CORBA_WChar *)source;
+ break;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_free(param, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_free(param, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_free(param, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_free(param, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_free(param, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_free(param, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_free(param, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_free(param, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_free(param, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_free(param, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_free(param, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_free(param, source, dest, env);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ } // end of switch
+ return retval;
+}
+
+// deep copy for primitives
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Primitive::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TCKind my_kind;
+
+ if (tc)
+ {
+ my_kind = tc->kind (env);
+
+ if (env.exception() == 0)
+ {
+
+ switch (my_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_char:
+ case tk_octet:
+ case tk_short:
+ case tk_ushort:
+ case tk_wchar:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_double:
+ case tk_longdouble:
+ case tk_boolean:
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ default:
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Primitive::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ dmsg ("TAO_Marshal_Primitive::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_MAYBE) );
+ dmsg ("TAO_Marshal_Primitive::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free structs
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Struct::deep_free (
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+ CDR stream;
+
+ if (tc)
+ {
+ // compute the number of fields in the struct
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(i=0; i < member_count && retval ==
+ CORBA_TypeCode::TRAVERSE_CONTINUE; i++)
+ {
+ // get the typecode for the ith field
+ param = tc->member_type(i, env);
+ if (env.exception() == 0)
+ {
+ // get the size of the field
+ size = param->size(env);
+ if (env.exception() == 0)
+ {
+ // get the alignment of the field
+ alignment = param->alignment(env);
+ if (env.exception() == 0)
+ {
+ switch(param->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ break;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_free(param, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_free(param, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_free(param, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_free(param, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_free(param, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_free(param, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_free(param, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_free(param, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_free(param, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_free(param, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_free(param, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_free(param, source, dest, env);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ } // end of switch
+ source = (char *)source + size;
+ }
+ else // exception computing alignment
+ {
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing size
+ {
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing typecode
+ {
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // end of loop
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting member count
+ {
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free for union
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Union::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ 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)
+ {
+ // deep_free the discriminator value
+ retval = DEEP_FREE(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.
+ i = 0;
+ while (member_count-- != 0)
+ {
+ member_label = tc->member_label(i, env);
+ if (env.exception() == 0)
+ {
+ // do the matching
+ switch (member_label->type()->kind(env))
+ {
+ case tk_short:
+ case tk_ushort:
+ if (*(CORBA_Short *)member_label->value() ==
+ *(CORBA_Short *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_enum:
+ if (*(CORBA_ULong *)member_label->value() ==
+ *(CORBA_ULong *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_char:
+ if (*(CORBA_Char *)member_label->value() ==
+ *(CORBA_Char *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_wchar:
+ if (*(CORBA_WChar *)member_label->value() ==
+ *(CORBA_WChar *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case 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(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 DEEP_FREE(member_tc, data,
+ data2, env);
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ i++;
+ } // end of while
+ // we are here only if there was no match
+ if (default_tc)
+ {
+ return DEEP_FREE(default_tc, data, data2, env);
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free for Sequence
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Sequence::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ 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 *value1;
+ CORBA_OctetSeq *src;
+ CDR stream; // used only to access the marshal_object factory
+
+ // Rely on binary format of sequences -- all are the same
+ // except for the type pointed to by "buffer"
+
+ if (tc)
+ {
+ src = (CORBA_OctetSeq *) source;
+
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ // get the size of the element
+ size = tc2->size (env);
+ if (env.exception() == 0)
+ {
+ // compute the length of the sequence
+ bounds = src->length;
+
+ value1 = (char *)src->buffer;
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ case tk_enum:
+ delete src->buffer;
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ // handle all aggregate types here
+ case tk_any:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_TypeCode:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_TypeCode::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_Principal:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Principal::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_objref:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_ObjRef::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_struct:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Struct::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_union:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Union::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_string:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ retval = TAO_Marshal_String::deep_free(tc2, source, dest, env);
+ break;
+ case tk_sequence:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Sequence::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_array:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Array::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_alias:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Alias::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_except:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Except::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ case tk_wstring:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_WString::deep_free(tc2, source, dest, env);
+ value1 = (char *)value1 + size;
+ }
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ break;
+ } // end of switch
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ // error exit
+ env.exception (new CORBA_MARSHAL(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing size
+ {
+ CORBA_release(tc2);
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_free detected error");
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing content type
+ {
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_free detected error");
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free for Array
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Array::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ 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;
+ CDR stream; // used only to access the marshal_object factory
+
+ // Rely on binary format of sequences -- all are the same
+ // except for the type pointed to by "buffer"
+
+ if (tc)
+ {
+ bounds = tc->length(env);
+ if (env.exception() == 0)
+ {
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ // get the size of the element type
+ size = tc2->size (env);
+ if (env.exception() == 0)
+ {
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ case tk_enum:
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ // handle all aggregate types here
+ case tk_any:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Any::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_TypeCode:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_TypeCode::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_Principal:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Principal::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_objref:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_ObjRef::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_struct:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Struct::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_union:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Union::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_string:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_String::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_sequence:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Sequence::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_array:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Array::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_alias:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Alias::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_except:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_Except::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ case tk_wstring:
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = TAO_Marshal_WString::deep_free(tc2, source, dest, env);
+ source = (char *)source + size;
+ }
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ break;
+ } // end of switch
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ // error exit
+ env.exception (new CORBA_MARSHAL(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ } // no exception computing size
+ else
+ {
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception computing content type
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting bounds
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free alias
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Alias::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode_ptr tc2; // typecode of the aliased type
+ CDR stream; // to access the marshal object
+ CORBA_TypeCode::traverse_status retval =
+ CORBA_TypeCode::TRAVERSE_CONTINUE; // status of encode operation
+
+ if (tc)
+ {
+ // get element type
+ tc2 = tc->content_type(env);
+ if (env.exception() == 0)
+ {
+ // switch on the data type and handle the cases for primitives here for
+ // efficiency
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ CORBA_release(tc2);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_any:
+ retval = TAO_Marshal_Any::deep_free(tc2, source, dest, env);
+ break;
+ case tk_TypeCode:
+ retval = TAO_Marshal_TypeCode::deep_free(tc2, source, dest, env);
+ break;
+ case tk_Principal:
+ retval = TAO_Marshal_Principal::deep_free(tc2, source, dest, env);
+ break;
+ case tk_objref:
+ retval = TAO_Marshal_ObjRef::deep_free(tc2, source, dest, env);
+ break;
+ case tk_struct:
+ retval = TAO_Marshal_Struct::deep_free(tc2, source, dest, env);
+ break;
+ case tk_union:
+ retval = TAO_Marshal_Union::deep_free(tc2, source, dest, env);
+ break;
+ case tk_string:
+ retval = TAO_Marshal_String::deep_free(tc2, source, dest, env);
+ break;
+ case tk_sequence:
+ retval = TAO_Marshal_Sequence::deep_free(tc2, source, dest, env);
+ break;
+ case tk_array:
+ retval = TAO_Marshal_Array::deep_free(tc2, source, dest, env);
+ break;
+ case tk_alias:
+ retval = TAO_Marshal_Alias::deep_free(tc2, source, dest, env);
+ break;
+ case tk_except:
+ retval = TAO_Marshal_Except::deep_free(tc2, source, dest, env);
+ break;
+ case tk_wstring:
+ retval = TAO_Marshal_WString::deep_free(tc2, source, dest, env);
+ break;
+ default:
+ // anything else is an error
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ CORBA_release(tc2);
+ if (retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Alias::decode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // exception getting content_type
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// deep_free structs
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Except::deep_free (
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+ CDR stream;
+
+ if (tc)
+ {
+ // XXX: Exceptions are currently leaked because of bugs lurking
+ // in this area. Keep in mind that there are two things to
+ // free: (a) the typecode in the exception base class; (b) any
+ // pointers held by a user-defined exception, such as an objref
+ // or string.
+ //
+ // Since this code does nothing, it should leak BOTH of those
+ // kinds of memory. Since it's not supposed to be called except
+ // when the exception really is being freed, it should only be
+ // called when the reference count in the exception base class
+ // is zero.
+ //
+ // It's not clear which of those assertions actually hold.
+ //
+ // The code SHOULD be just like the traverse () call for a
+ // structure, with (a) a precondition that the reference count
+ // is zero, (b) an assertion that the typecode in the exception
+ // and "tc" are equivalent, (c) releasing that typecode found
+ // within the exception.
+ //
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else // no typecode
+ {
+ env.exception (new CORBA_BAD_TYPECODE(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Struct::deep_free detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
diff --git a/TAO/IIOP/lib/encode.cpp b/TAO/IIOP/lib/encode.cpp
new file mode 100644
index 00000000000..8d316292690
--- /dev/null
+++ b/TAO/IIOP/lib/encode.cpp
@@ -0,0 +1,1423 @@
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// encode.cpp
+//
+// = DESCRIPTION
+// Code for encoding different data types
+//
+// The original code had a single static encoder function defined on the CDR
+// class that called traverse to interpret the data types. This version
+// defines a virtual method "encode" on each class and avoids calling traverse.
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "orb.h"
+#include "cdr.h"
+#include "giop.h"
+
+#if defined (HAVE_WIDEC_H)
+# include <widec.h>
+#else
+extern "C"
+{
+ u_int wslen (const CORBA_WChar *);
+ CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *);
+}
+#endif
+
+extern CORBA_TypeCode TC_opaque;
+
+// Encode instances of arbitrary data types based only on typecode.
+// "data" points to the data type; if it's not a primitve data type,
+// the TypeCode interpreter is used to recursively encode its
+// components. "context" is the marshaling stream on which to encode
+// the data value.
+//
+
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Primitive::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_encoding = stream->put_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_encoding = stream->put_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_encoding = stream->put_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_encoding = stream->put_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_encoding = stream->put_wchar(*(wchar_t *)data);
+ break;
+ default:
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ // we are not a primitive type
+ }
+ if ((retval == CORBA_TypeCode::TRAVERSE_CONTINUE) && (continue_encoding ==
+ CORBA_B_TRUE))
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Primitive::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Any::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ 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; // value maintained by the Any
+ CORBA_Boolean continue_encoding = 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
+
+ elem_tc = any->type();
+ // encode the typecode description for the element
+ if (stream->encode(_tc_CORBA_TypeCode, &elem_tc, 0, env)
+ == CORBA_TypeCode::TRAVERSE_CONTINUE) {
+ value = any->value();
+ // switch on the data type and handle the cases for primitives here for
+ // efficiency rather than calling
+ switch(elem_tc->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_encoding = stream->put_short (*(CORBA_Short *)value);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_encoding = stream->put_long(*(CORBA_Long *)value);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)value);
+ break;
+ case tk_boolean:
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)value);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_encoding = stream->put_char(*(CORBA_Char *)value);
+ break;
+ case tk_longdouble:
+ continue_encoding = stream->put_longdouble(*(CORBA_LongDouble *)value);
+ break;
+ case tk_wchar:
+ continue_encoding = stream->put_wchar(*(wchar_t *)value);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ retval = stream->encode(elem_tc, value, 0, env);
+ break;
+ default:
+ // anything else is an error
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ if ((retval == CORBA_TypeCode::TRAVERSE_CONTINUE) && (continue_encoding ==
+ CORBA_B_TRUE))
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Any::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+CORBA_TypeCode::traverse_status
+TAO_Marshal_TypeCode::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *) context; // context is the CDR stream
+ CORBA_TypeCode_ptr tc2; // typecode to be encoded
+
+ tc2 = *(CORBA_TypeCode_ptr *) data; // the data has to be a TypeCode_ptr
+
+ // encode the "kind" field of the typecode
+ continue_encoding = stream->put_ulong ((CORBA_ULong) tc2->_kind);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ // now encode the parameters, if any
+ switch (tc2->_kind)
+ {
+ // Most TypeCodes have empty parameter lists
+ default:
+ break;
+
+ // A few have "simple" parameter lists
+ case tk_string:
+ case tk_wstring:
+ continue_encoding = stream->put_ulong (tc2->_length);
+ break;
+
+ // Indirected typecodes can't occur at "top level" like
+ // this, only nested inside others!
+ case ~0:
+ dmsg ("indirected typecode at top level!");
+ continue_encoding = CORBA_B_FALSE;
+ break;
+
+ // The rest have "complex" parameter lists that are
+ // already encoded as bulk octets ... put length, then
+ // octets.
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_enum:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ {
+ continue_encoding = stream->put_ulong (tc2->_length);
+
+ for (u_int i = 0; i < tc2->_length && continue_encoding; i++)
+ continue_encoding = stream->put_octet (tc2->_buffer [i]);
+ }
+ }
+ }
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_TypeCode::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// encode Principal
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Principal::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *) context; // context is the CDR stream
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ CORBA_Principal_ptr p = *(CORBA_Principal_ptr *) data;
+
+ if (p != 0)
+ {
+ continue_encoding = stream->put_long (p->id.length);
+
+ for (u_int i = 0; continue_encoding && i < p->id.length; i++)
+ continue_encoding = stream->put_octet (p->id.buffer [i]);
+ }
+ else
+ {
+ continue_encoding = stream->put_long (0);
+ }
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Principal::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// encode obj ref
+CORBA_TypeCode::traverse_status
+TAO_Marshal_ObjRef::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *) context; // context is the CDR stream
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+
+ // Current version: objref is really an IIOP_Object.
+ //
+ // This will change in the future; STUB_Object knows how to
+ // marshal itself, that will be used.
+ //
+ // XXX this doesn't actually verify that the stuff got written
+ // OK to the "wire" ...
+ CORBA_Object_ptr obj = *(CORBA_Object_ptr *) data;
+
+ // NIL objrefs ... marshal as empty type hint, no elements.
+
+ if (CORBA_is_nil (obj))
+ {
+ continue_encoding =
+ stream->put_ulong (1) // strlen
+ && stream->put_char (0) // NUL
+ && stream->put_ulong (0); // no profiles
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+
+ // All other objrefs ... narrow to a "real type" that we
+ // recognize, then marshal.
+ //
+ // XXX this will be changed so it narrows to STUB_Object and
+ // then asks that surrogate/proxy to marshal itself.
+ //
+ // For now, the original code is minimally changed.
+
+ IIOP_Object *objdata;
+ IIOP::ProfileBody *profile;
+
+ if (obj->QueryInterface (IID_IIOP_Object,
+ (void **) &objdata) != NOERROR)
+ {
+ env.exception (new CORBA_MARSHAL (COMPLETED_NO));
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ obj->Release ();
+ profile = &objdata->profile;
+
+ // STRING, a type ID hint
+ stream->encode(_tc_CORBA_String, &objdata->type_id, 0, env);
+
+ // UNSIGNED LONG, value one, count of the sequence of
+ // encapsulated protocol profiles;
+ stream->put_ulong (1);
+
+ // UNSIGNED LONG, tag for this protocol profile;
+ stream->put_ulong (IOP::TAG_INTERNET_IOP);
+
+ // UNSIGNED LONG, number of succeeding bytes in the
+ // encapsulation. We don't actually need to make the
+ // encapsulation, as nothing needs stronger alignment than
+ // this longword; it guarantees the rest is aligned for us.
+ u_int hostlen;
+
+ hostlen = ACE_OS::strlen ((char *) profile->host);
+ stream->put_ulong (1 // byte order
+ + 3 // version + pad byte
+ + 4 // sizeof (strlen)
+ + hostlen + 1 // strlen + null
+ + (~hostlen & 01) // optional pad byte
+ + 2 // port
+ + (hostlen & 02) // optional pad short
+ + 4 // sizeof (key length)
+ + profile->object_key.length); // key length
+
+ // CHAR describing byte order, starting the encapsulation
+
+ stream->put_char (MY_BYTE_SEX);
+
+ // IIOP::Version, two characters (version 1.0) padding
+ stream->put_char (profile->iiop_version.major);
+ stream->put_char (profile->iiop_version.minor);
+
+ // STRING hostname from profile
+ stream->encode(_tc_CORBA_String, &profile->host, 0, env);
+
+ // UNSIGNED SHORT port number
+ stream->put_ushort (profile->port);
+
+ // OCTET SEQUENCE for object key
+ stream->encode (&TC_opaque, &profile->object_key, 0, env);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+}
+
+// encode structs
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Struct::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CDR *stream = (CDR *)context;
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(i=0; i < member_count && retval ==
+ CORBA_TypeCode::TRAVERSE_CONTINUE && continue_encoding ==
+ 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_encoding = stream->put_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_encoding = stream->put_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_encoding = stream->put_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_encoding = stream->put_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_encoding = stream->put_wchar(*(wchar_t *)data);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ retval = stream->encode(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_encoding ==
+ CORBA_B_TRUE){
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ } else {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("marshaling encode_struct detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// encode unions
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Union::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *data2,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ 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)
+ {
+ // encode the discriminator value
+ retval = stream->encode(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.
+ i = 0;
+ while (member_count-- != 0)
+ {
+ member_label = tc->member_label(i, env);
+ if (env.exception() == 0)
+ {
+ // do the matching
+ switch (member_label->type()->kind(env))
+ {
+ case tk_short:
+ case tk_ushort:
+ if (*(CORBA_Short *)member_label->value() ==
+ *(CORBA_Short *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_enum:
+ if (*(CORBA_ULong *)member_label->value() ==
+ *(CORBA_ULong *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_char:
+ if (*(CORBA_Char *)member_label->value() ==
+ *(CORBA_Char *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case tk_wchar:
+ if (*(CORBA_WChar *)member_label->value() ==
+ *(CORBA_WChar *)discrim_val)
+ {
+ discrim_matched = CORBA_B_TRUE;
+ }
+ break;
+ case 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(COMPLETED_NO));
+ dmsg("Union::encode - Bad discriminant type");
+ 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->encode(member_tc, data,
+ data2, env);
+ }
+ }
+ else // error getting member type
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ dmsg1 ("Union::encode - error getting member type:%d",i);
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+
+ }
+ else // error getting member label
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ dmsg1("Union::encode - error member label : %d", i);
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ i++;
+ } // end of while
+ // we are here only if there was no match
+ if (default_tc)
+ {
+ return stream->encode(default_tc, data, data2, env);
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ else // error getting member count
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("Union::encode - error getting member count");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // error getting default index
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ dmsg ("Union::encode - error getting default used");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // error getting discrim_pad_size
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ dmsg ("Union::encode - error getting discrim padded size");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // error encoding discriminant
+ {
+ env.exception(new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("Union::encode - error encoding discriminant");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else // error getting the discriminant
+ {
+ env.exception(new CORBA_BAD_TYPECODE(COMPLETED_NO));
+ dmsg ("Union::encode - error getting the discriminant typecode");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+// encode string
+CORBA_TypeCode::traverse_status
+TAO_Marshal_String::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *) context; // context is the CDR stream
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_String str = *(CORBA_String *) data;
+ CORBA_ULong len;
+ CORBA_ULong bounds;
+
+ // Be nice to programmers: treat nulls as empty strings not
+ // errors. (OMG-IDL supports languages that don't use the
+ // C/C++ notion of null v. empty strings; nulls aren't part of
+ // the OMG-IDL string model.)
+ if (str != 0)
+ {
+
+ // Verify string satisfies bounds requirements. We're not so
+ // permissive as to send messages violating the interface spec
+ // by having excessively long strings!
+ bounds = tc->length(env);
+ if (env.exception () == 0)
+ {
+ // get the actual length of the string
+ len = ACE_OS::strlen ((char *) str);
+
+ // if it is an unbounded string or if the length is less than the
+ // bounds for an unbounded string
+ if ((bounds == 0) || (len <= bounds))
+ {
+
+ // Encode the string, followed by a NUL character.
+
+ for (continue_encoding = stream->put_ulong (len + 1);
+ continue_encoding != CORBA_B_FALSE && *str;
+ continue_encoding = stream->put_char (*str++))
+ continue;
+
+ stream->put_char (0);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ // empty string
+ stream->put_ulong (1);
+ stream->put_char (0);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+}
+
+// encode sequence
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Sequence::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *)context;
+ CORBA_OctetSeq *seq = (CORBA_OctetSeq *) 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;
+ CORBA_ULong len = seq ? seq->length : 0;
+ char *value;
+
+ //
+ // First marshal the sequence length, verifying that
+ // it's within the sequence bounds ...
+ //
+ if (len > 0)
+ {
+ // retrieve the bounds of the sequence
+ bounds = tc->length (env);
+ if (env.exception () == 0)
+ {
+ // encode only if it is an unbounded sequence or if length is
+ // less/equal to the bounds
+ if (bounds == 0 || len <= bounds)
+ {
+ bounds = len; // number of times you encode
+ continue_encoding = stream->put_ulong (seq->length);
+ if (continue_encoding && seq->length != 0)
+ {
+ // get element typecode
+ tc2 = tc->content_type (env);
+ if (env.exception () == 0)
+ {
+ size = tc2->size (env);
+ if (env.exception() == 0)
+ {
+ value = (char *)seq->buffer;
+ switch(tc2->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case tk_ushort:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_short (*(CORBA_Short *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_long (*(CORBA_Long *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_boolean:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_char:
+ case tk_octet:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_char (*(CORBA_Char *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_longdouble:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_longdouble (*(CORBA_LongDouble *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_wchar:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_wchar (*(CORBA_WChar *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_enum:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_long (*(CORBA_Long *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ // handle all aggregate types here
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ // For those aggregate types whose size is constant, we
+ // compute it only once
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = stream->encode(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
+ } // seq length not 0
+ } // within bounds or unbounded
+ } // no exception computing bounds
+ } // length is > 0
+ else
+ {
+ // length is 0, encode it
+ continue_encoding = stream->put_ulong (len);
+ if (continue_encoding == CORBA_B_TRUE) {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ }
+ // error exit
+ env.exception (new CORBA_MARSHAL(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+}
+
+// encode array
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Array::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = 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 tk_null:
+ case tk_void:
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ case tk_short:
+ case tk_ushort:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_short (*(CORBA_Short *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_long (*(CORBA_Long *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_boolean:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_char:
+ case tk_octet:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_char (*(CORBA_Char *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_longdouble:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_longdouble (*(CORBA_LongDouble *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_wchar:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_wchar (*(CORBA_WChar *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ case tk_enum:
+ // For primitives, compute the size only once
+ while (bounds-- && continue_encoding == CORBA_B_TRUE)
+ {
+ continue_encoding = stream->put_long (*(CORBA_Long *)value);
+ value += size;
+ }
+ CORBA_release(tc2);
+ if (continue_encoding == CORBA_B_TRUE)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ break;
+ // handle all aggregate types here
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ // For those aggregate types whose size is constant, we
+ // compute it only once
+ while (bounds-- && retval == CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ retval = stream->encode(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(COMPLETED_NO));
+ dmsg ("marshaling TAO_Marshal_Sequence::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+}
+
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Alias::encode(
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_TypeCode_ptr tc2; // typecode of the aliased type
+ CORBA_Boolean continue_encoding = 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
+ 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_encoding = stream->put_short (*(CORBA_Short *)value);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_encoding = stream->put_long(*(CORBA_Long *)value);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)value);
+ break;
+ case tk_boolean:
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)value);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_encoding = stream->put_char(*(CORBA_Char *)value);
+ break;
+ case tk_longdouble:
+ continue_encoding = stream->put_longdouble(*(CORBA_LongDouble *)value);
+ break;
+ case tk_wchar:
+ continue_encoding = stream->put_wchar(*(wchar_t *)value);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ retval = stream->encode(tc2, value, 0, env);
+ break;
+ default:
+ // anything else is an error
+ retval = CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ tc2->Release();
+ if ((retval == CORBA_TypeCode::TRAVERSE_CONTINUE) && (continue_encoding ==
+ CORBA_B_TRUE))
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Alias::encode detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+
+// encode exception
+CORBA_TypeCode::traverse_status
+TAO_Marshal_Except::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CDR *stream = (CDR *)context;
+ CORBA_Long i,
+ member_count; // number of fields in the struct
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CORBA_TypeCode_ptr param;
+ CORBA_Long size, alignment;
+
+ data = (char *)data + sizeof(CORBA_Exception);
+
+ member_count = tc->member_count(env);
+ if (env.exception() == 0)
+ {
+ for(i=0; i < member_count && retval ==
+ CORBA_TypeCode::TRAVERSE_CONTINUE && continue_encoding ==
+ 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 tk_null:
+ case tk_void:
+ break;
+ case tk_short:
+ case tk_ushort:
+ continue_encoding = stream->put_short (*(CORBA_Short *)data);
+ break;
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ continue_encoding = stream->put_long(*(CORBA_Long *)data);
+ break;
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ continue_encoding = stream->put_longlong (*(CORBA_LongLong *)data);
+ break;
+ case tk_boolean:
+ continue_encoding = stream->put_boolean (*(CORBA_Boolean *)data);
+ break;
+ case tk_char:
+ case tk_octet:
+ continue_encoding = stream->put_char(*(CORBA_Char *)data);
+ break;
+ case tk_longdouble:
+ continue_encoding = stream->put_longdouble(*(CORBA_LongDouble *)data);
+ break;
+ case tk_wchar:
+ continue_encoding = stream->put_wchar(*(wchar_t *)data);
+ break;
+ case tk_any:
+ case tk_TypeCode:
+ case tk_Principal:
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_string:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ case tk_wstring:
+ retval = stream->encode(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_encoding ==
+ CORBA_B_TRUE){
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ } else {
+ env.exception (new CORBA_MARSHAL(COMPLETED_MAYBE));
+ dmsg ("TAO_Marshal_Except detected error");
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+}
+
+
+// encode wstring
+CORBA_TypeCode::traverse_status
+TAO_Marshal_WString::encode (
+ CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env
+ )
+{
+ CORBA_Boolean continue_encoding = CORBA_B_TRUE;
+ CDR *stream = (CDR *) context; // context is the CDR stream
+ CORBA_TypeCode::traverse_status retval = CORBA_TypeCode::TRAVERSE_CONTINUE;
+ CORBA_WChar *str = *(CORBA_WChar **) data;
+ CORBA_ULong len;
+ CORBA_ULong bounds;
+
+ // Be nice to programmers: treat nulls as empty strings not
+ // errors. (OMG-IDL supports languages that don't use the
+ // C/C++ notion of null v. empty strings; nulls aren't part of
+ // the OMG-IDL string model.)
+ if (str != 0)
+ {
+
+ // Verify string satisfies bounds requirements. We're not so
+ // permissive as to send messages violating the interface spec
+ // by having excessively long strings!
+ bounds = tc->length(env);
+ if (env.exception () == 0)
+ {
+ // get the actual length of the string
+ len = wslen ((CORBA_WChar *) str);
+
+ // if it is an unbounded string or if the length is less than the
+ // bounds for an unbounded string
+ if ((bounds == 0) || (len <= bounds))
+ {
+
+ // Encode the string, followed by a NUL character.
+
+ for (continue_encoding = stream->put_ulong (len + 1);
+ continue_encoding != CORBA_B_FALSE && *str;
+ continue_encoding = stream->put_wchar (*str++))
+ continue;
+
+ stream->put_wchar (0);
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ return CORBA_TypeCode::TRAVERSE_STOP;
+ }
+ }
+ else
+ {
+ // empty string
+ stream->put_ulong (1);
+ stream->put_wchar (0);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+}
+
diff --git a/TAO/IIOP/lib/except.cpp b/TAO/IIOP/lib/except.cpp
index 27c6c6b1f8f..faa4bbe4157 100644
--- a/TAO/IIOP/lib/except.cpp
+++ b/TAO/IIOP/lib/except.cpp
@@ -17,7 +17,6 @@
#include <orb.h>
#include "cdr.h"
-#include "debug.h"
#include <initguid.h>
@@ -240,25 +239,25 @@ make_standard_typecode (CORBA_TypeCode_ptr tcp,
assert (strlen (full_id) <= sizeof full_id);
if (stream.put_byte (MY_BYTE_SEX) != CORBA_B_TRUE
- || CDR::encoder (_tc_CORBA_String,
+ || stream.encode (_tc_CORBA_String,
&strptr, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_String,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_String,
&name, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
|| stream.put_ulong (2L) != CORBA_B_TRUE
- || CDR::encoder (_tc_CORBA_String,
+ || stream.encode (_tc_CORBA_String,
&minor, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_TypeCode,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_TypeCode,
&_tc_CORBA_ULong, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_String,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_String,
&completion, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_TypeCode,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_TypeCode,
&completion_status, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) {
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE) {
env.exception (new CORBA_INITIALIZE (COMPLETED_NO));
return;
}
diff --git a/TAO/IIOP/lib/giop.cpp b/TAO/IIOP/lib/giop.cpp
index 44f0ae30fc5..8e531fe881f 100644
--- a/TAO/IIOP/lib/giop.cpp
+++ b/TAO/IIOP/lib/giop.cpp
@@ -49,13 +49,12 @@
#include "ace/Log_Msg.h"
#include "ace/SOCK_Stream.h"
+#include "orb.h"
+
#include "orbobj.h"
#include "factories.h"
-#include <orb.h>
-
#include "cdr.h"
-#include "debug.h"
#include "giop.h"
// defined by GIOP 1.0 protocol
@@ -159,8 +158,9 @@ GIOP::send_message (CDR &stream,
writelen = peer.send ((char _FAR *) buf, buflen);
#ifdef DEBUG
- dmsg_filter (6, "wrote %d bytes to connection %d",
- writelen, connection);
+ // dmsg_filter (6, "wrote %d bytes to connection %d",
+ // writelen, connection);
+ dmsg_filter (6, "wrote %d bytes", writelen);
#endif // DEBUG
assert ((writelen >= 0
@@ -707,7 +707,7 @@ GIOP::Invocation::start (CORBA_Environment &env)
static CORBA_Principal_ptr anybody = 0;
static ServiceContextList svc_ctx; // all zeroes
- if (CDR::encoder (&TC_ServiceContextList, 0, &svc_ctx, &stream, env)
+ if (stream.encode (&TC_ServiceContextList, 0, &svc_ctx, env)
!= CORBA_TypeCode::TRAVERSE_CONTINUE)
return;
@@ -718,15 +718,15 @@ GIOP::Invocation::start (CORBA_Environment &env)
return;
}
- if (CDR::encoder (&TC_opaque,
+ if (stream.encode (&TC_opaque,
key, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_String,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_String,
&opname, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
- || CDR::encoder (_tc_CORBA_Principal,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || stream.encode (_tc_CORBA_Principal,
&anybody, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
return; // right after fault
else
return; // no fault reported
@@ -879,7 +879,7 @@ GIOP::Invocation::invoke (CORBA_ExceptionList &exceptions,
CORBA_ULong request_id;
CORBA_ULong reply_status; // GIOP::ReplyStatusType
- if (CDR::decoder (&TC_ServiceContextList, &reply_ctx, 0, &stream, env)
+ if (stream.decode (&TC_ServiceContextList, &reply_ctx, 0, env)
!= CORBA_TypeCode::TRAVERSE_CONTINUE)
{
send_error (handler_->peer());
@@ -993,7 +993,7 @@ GIOP::Invocation::invoke (CORBA_ExceptionList &exceptions,
exception = new (new char [size]) CORBA_Exception (*tcp);
- if (CDR::decoder (*tcp, exception, 0, &stream, env)
+ if (stream.decode (*tcp, exception, 0, env)
!= CORBA_TypeCode::TRAVERSE_CONTINUE)
{
delete exception;
@@ -1035,9 +1035,9 @@ GIOP::Invocation::invoke (CORBA_ExceptionList &exceptions,
// one of the facets of this object will be an IIOP invocation
// profile.
- if (CDR::decoder (_tc_CORBA_Object,
+ if (stream.decode (_tc_CORBA_Object,
&obj, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
|| obj->QueryInterface (IID_IIOP_Object,
(void **)&obj2) != NOERROR)
{
@@ -1156,30 +1156,26 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
// security environment. It may be required even when using
// IPSEC security infrastructure.
- hdr_status = CDR::decoder (&TC_ServiceContextList,
+ hdr_status = msg.decode (&TC_ServiceContextList,
&req.service_info,
0,
- &msg,
env);
// Get the rest of the request header ...
hdr_status = hdr_status && msg.get_ulong (req.request_id);
hdr_status = hdr_status && msg.get_boolean (req.response_expected);
- hdr_status = hdr_status && CDR::decoder (&TC_opaque,
+ hdr_status = hdr_status && msg.decode (&TC_opaque,
&req.object_key,
0,
- &msg,
env);
- hdr_status = hdr_status && CDR::decoder (_tc_CORBA_String,
+ hdr_status = hdr_status && msg.decode (_tc_CORBA_String,
&req.operation,
0,
- &msg,
env);
- hdr_status = hdr_status && CDR::decoder (_tc_CORBA_Principal,
+ hdr_status = hdr_status && msg.decode (_tc_CORBA_Principal,
&req.requesting_principal,
0,
- &msg,
env);
// XXX check whether hdr_status identifies a header
@@ -1226,10 +1222,9 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
start_message (Reply, response);
resp_ctx.length = 0;
- CDR::encoder (&TC_ServiceContextList,
+ response.encode (&TC_ServiceContextList,
&resp_ctx,
0,
- &response,
env);
response.put_ulong (req.request_id);
@@ -1248,10 +1243,9 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
{
ACE_DEBUG((LM_DEBUG, "(%P|%t) forwarding Request message\n"));
response.put_ulong (LOCATION_FORWARD);
- CDR::encoder (_tc_CORBA_Object,
+ response.encode (_tc_CORBA_Object,
&fwd_ref,
0,
- &response,
env);
CORBA_release (fwd_ref);
(void) send_message (response, peer);
@@ -1264,10 +1258,9 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
response.put_ulong (SYSTEM_EXCEPTION);
- (void) CDR::encoder (_tc_CORBA_OBJECT_NOT_EXIST,
+ (void) response.encode (_tc_CORBA_OBJECT_NOT_EXIST,
&exc,
0,
- &response,
env);
(void) send_message (response, peer);
@@ -1290,10 +1283,9 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
start_message (Reply, response);
resp_ctx.length = 0;
- CDR::encoder (&TC_ServiceContextList,
+ response.encode (&TC_ServiceContextList,
&resp_ctx,
0,
- &response,
env);
response.put_ulong (req.request_id);
@@ -1320,7 +1312,7 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
opaque key;
msg.get_ulong (request_id);
- CDR::decoder (&TC_opaque, &key, 0, &msg, env);
+ msg.decode (&TC_opaque, &key, 0, env);
// we've read the request header; send a LocateReply
@@ -1346,8 +1338,7 @@ GIOP::incoming_message (ACE_SOCK_Stream &peer,
if (status == OBJECT_FORWARD)
{
ACE_DEBUG((LM_DEBUG, "LocateRequest response: forward requests\n"));
- CDR::encoder (_tc_CORBA_Object, &fwd_ref, 0,
- &response, env);
+ response.encode (_tc_CORBA_Object, &fwd_ref, 0, env);
}
else if (status == OBJECT_HERE)
ACE_DEBUG((LM_DEBUG, "LocateRequest response: object is here!\n"));
diff --git a/TAO/IIOP/lib/giop.h b/TAO/IIOP/lib/giop.h
index fec7f0b086d..b3d14501528 100644
--- a/TAO/IIOP/lib/giop.h
+++ b/TAO/IIOP/lib/giop.h
@@ -248,7 +248,7 @@ public:
void *value,
CORBA_Environment &env)
{
- (void) CDR::encoder (tc, value, 0, &stream, env);
+ (void) stream.encode(tc, value, 0, env);
}
ReplyStatusType invoke (CORBA_ExceptionList &exceptions,
@@ -258,7 +258,7 @@ public:
void *value,
CORBA_Environment &env)
{
- (void) CDR::decoder (tc, value, 0, &stream, env);
+ (void) stream.decode (tc, value, 0, env);
}
// No CORBA_Context support (deprecated).
diff --git a/TAO/IIOP/lib/iioporb.cpp b/TAO/IIOP/lib/iioporb.cpp
index d54d30da4b0..2b67378bb70 100644
--- a/TAO/IIOP/lib/iioporb.cpp
+++ b/TAO/IIOP/lib/iioporb.cpp
@@ -78,9 +78,9 @@ IIOP_ORB::object_to_string (CORBA_Object_ptr obj,
// Marshal the objref into an encapsulation bytestream.
(void) cdr.put_char (MY_BYTE_SEX);
- if (CDR::encoder (_tc_CORBA_Object,
+ if (cdr.encode (_tc_CORBA_Object,
&obj, 0,
- &cdr, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
return 0;
// Now hexify the encapsulated CDR data into a string, and
@@ -215,9 +215,9 @@ ior_string_to_object (CORBA_String str,
CORBA_Object_ptr objref;
stream.setup_encapsulation (buffer, len);
- if (CDR::decoder (_tc_CORBA_Object,
+ if (stream.decode (_tc_CORBA_Object,
&objref, 0,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
objref = 0;
delete [] buffer;
diff --git a/TAO/IIOP/lib/interp.cpp b/TAO/IIOP/lib/interp.cpp
index 2bfeb77d337..c38a3550ff9 100644
--- a/TAO/IIOP/lib/interp.cpp
+++ b/TAO/IIOP/lib/interp.cpp
@@ -69,9 +69,8 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
-#include <orb.h>
-#include "debug.h"
+#include "orb.h"
#include "cdr.h"
// Utility routines are used to manipulate CDR-encapsulated TypeCode
@@ -612,7 +611,7 @@ calc_exception_attributes (CDR *stream,
// over the typecode: the inter-element padding changes depending on
// the strictest alignment required by _any_ arm of the union.
-static size_t
+size_t
calc_key_union_attributes (CDR *stream,
size_t &overall_alignment,
size_t &discrim_size_with_pad,
@@ -1382,7 +1381,7 @@ CORBA_TypeCode::traverse (const void *value1,
// this typecode ... typically used to allocate memory.
size_t
-CORBA_TypeCode::size (CORBA_Environment &env)
+CORBA_TypeCode::prv_size (CORBA_Environment &env)
{
if (_kind >= TC_KIND_COUNT)
{
@@ -1407,7 +1406,7 @@ CORBA_TypeCode::size (CORBA_Environment &env)
// completeness.
size_t
-CORBA_TypeCode::alignment (CORBA_Environment &env)
+CORBA_TypeCode::prv_alignment (CORBA_Environment &env)
{
if (_kind >= TC_KIND_COUNT)
{
diff --git a/TAO/IIOP/lib/invoke.cpp b/TAO/IIOP/lib/invoke.cpp
index b803f491f25..b0824d84c64 100644
--- a/TAO/IIOP/lib/invoke.cpp
+++ b/TAO/IIOP/lib/invoke.cpp
@@ -32,10 +32,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-#include <orb.h>
+#include "orb.h"
#include "cdr.h"
-#include "debug.h"
#include "giop.h"
class ACE_Synchronous_Cancellation_Required
diff --git a/TAO/IIOP/lib/marshal.cpp b/TAO/IIOP/lib/marshal.cpp
index f37af656c17..64931e8ba78 100644
--- a/TAO/IIOP/lib/marshal.cpp
+++ b/TAO/IIOP/lib/marshal.cpp
@@ -1,56 +1,32 @@
-// @(#)marshal.cpp 1.7 95/11/04
-// Copyright 1994-1995 by Sun Microsystems Inc.
-// All Rights Reserved
+// ============================================================================
//
-// CDR: Marshaling interpreter
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// marshal.cpp
//
-// This marshaling interpreter is driven by the typecode interpreter.
-// The typecode interpreter understands each compiler environment's
-// rules for data structure layout; this understands CDR's rules for
-// on-the-wire data structure layout.
+// = DESCRIPTION
+// Implements the MarshalObject class and the factory
//
-// Apart from some high level rules related to construction of complex
-// data types, the marshaling interpreter just knows how to encode
-// primitive data types and allocate memory on decode.
+// The original encoder and decoder code now appears in files encode.cpp and
+// decode.cpp
//
-// NOTE: to reduce the amount of compiled code, this "knows" facts
-// like native float/long/ulong being in legal CDR format, and that
-// "char" is native in ISO Latin/1 (so no transformation is needed,
-// and octet/char marshaling code is identical). On exotic platforms
-// where this is not true, some of the merged "switch" branches will
-// need to be split.
-//
-// REMEMBER: goal is to have the typecode interpreter plus one side of
-// the marshaling interpreter reside in a CPU's code cache; or at
-// least to have as litle as possible _outside_ cache when marshaling.
-// Compiled marshaling code will have a few less instructions, but
-// most will of them will be outside the instruction cache; access
-// time to get at them will be high.
-//
-// NOTE: One interesting optimization is inlining the primitive
-// put/get calls ... it'd typically save at least 40% in terms of
-// instruction count on each of these critical paths by eliminating
-// subroutine call overhead. Since it would increase code size, such
-// changes might not be desirable on machines with small caches.
-// Also, with network I/O being today's most significant bottleneck,
-// such optimizations haven't been well explored.
-//
-// THREADING NOTE: The only threading concern is as always, that data
-// structures being manipulated by any given thread must be reserved
-// to it by some mechanism (e.g. mutex). This uses no mutable data
-// outside of the thread stack, so the onus is entirely on the caller.
-//
-
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-#include <orb.h>
-
-#include "debug.h"
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "orb.h"
+#include "align.h"
#include "cdr.h"
-#include "giop.h"
-
#if defined (HAVE_WIDEC_H)
# include <widec.h>
#else
@@ -61,1012 +37,89 @@ extern "C"
}
#endif
-extern CORBA_TypeCode TC_opaque;
-
-// Encode instances of arbitrary data types based only on typecode.
-// "data" points to the data type; if it's not a primitve data type,
-// the TypeCode interpreter is used to recursively encode its
-// components. "context" is the marshaling stream on which to encode
-// the data value.
-//
-// This is a fairly typical TypeCode interpreter visit() routine; it
-// works on a single data value in conjunction with context
-// information, and must handle all IDL data types.
-
-CORBA_TypeCode::traverse_status
-CDR::encoder (CORBA_TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA_Environment &env)
+// cosntructor for the factory
+TAO_MarshalFactory::TAO_MarshalFactory()
+ : m_primitive_(TAO_MARSHAL_PRIMITIVE::instance()),
+ m_any_(TAO_MARSHAL_ANY::instance()),
+ m_typecode_(TAO_MARSHAL_TYPECODE::instance()),
+ m_principal_(TAO_MARSHAL_PRINCIPAL::instance()),
+ m_objref_(TAO_MARSHAL_OBJREF::instance()),
+ m_struct_(TAO_MARSHAL_STRUCT::instance()),
+ m_union_(TAO_MARSHAL_UNION::instance()),
+ m_string_(TAO_MARSHAL_STRING::instance()),
+ m_sequence_(TAO_MARSHAL_SEQUENCE::instance()),
+ m_array_(TAO_MARSHAL_ARRAY::instance()),
+ m_alias_(TAO_MARSHAL_ALIAS::instance()),
+ m_except_(TAO_MARSHAL_EXCEPT::instance()),
+ m_wstring_(TAO_MARSHAL_WSTRING::instance())
{
- CORBA_Boolean continue_encoding = CORBA_B_TRUE;
- CDR *stream = (CDR *) context;
-
- switch (tc->_kind)
- {
- case tk_null:
- case tk_void:
- // nothing to encode!
- break;
-
- case tk_char:
- case tk_octet:
- continue_encoding = stream->put_char (*(char *) data);
- break;
-
- case tk_short:
- case tk_ushort:
- continue_encoding = stream->put_short (*(short *) data);
- break;
-
- case tk_long:
- case tk_ulong:
- case tk_float:
- continue_encoding = stream->put_long (*(CORBA_Long *) data);
- break;
-
- case tk_double:
- case tk_longlong:
- case tk_ulonglong:
- continue_encoding = stream->put_longlong (*(CORBA_LongLong *) data);
- break;
-
- case tk_boolean:
- continue_encoding = stream->put_boolean (*(CORBA_Boolean *) data);
- break;
-
- case tk_enum:
- {
- // NOTE assumption that this is in-range.
- //
- // XXX should check this, it's a hard-to-recover error for the
- // other side
-
- u_int value = *(u_int *) data;
- continue_encoding = stream->put_ulong (value);
- }
- break;
-
- case tk_any:
- {
- CORBA_Any *any = (CORBA_Any *) data;
-
- tc = any->type ();
- if (encoder (_tc_CORBA_TypeCode, &tc, 0, context, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- data = any->value ();
- return encoder (tc, data, 0, context, env);
- }
- // NOTREACHED
-
- case tk_TypeCode:
- {
- CORBA_TypeCode_ptr tc2;
-
- tc2 = *(CORBA_TypeCode_ptr *) data;
-
- continue_encoding = stream->put_ulong ((CORBA_ULong) tc2->_kind);
- if (continue_encoding == CORBA_B_FALSE)
- break;
-
- switch (tc2->_kind)
- {
- // Most TypeCodes have empty parameter lists
- default:
- break;
-
- // A few have "simple" parameter lists
- case tk_string:
- case tk_wstring:
- continue_encoding = stream->put_ulong (tc2->_length);
- break;
-
- // Indirected typecodes can't occur at "top level" like
- // this, only nested inside others!
- case ~0:
- dmsg ("indirected typecode at top level!");
- continue_encoding = CORBA_B_FALSE;
- break;
-
- // The rest have "complex" parameter lists that are
- // already encoded as bulk octets ... put length, then
- // octets.
- case tk_objref:
- case tk_struct:
- case tk_union:
- case tk_enum:
- case tk_sequence:
- case tk_array:
- case tk_alias:
- case tk_except:
- {
- continue_encoding = stream->put_ulong (tc2->_length);
-
- for (u_int i = 0; i < tc2->_length && continue_encoding; i++)
- continue_encoding = stream->put_octet (tc2->_buffer [i]);
- }
- }
- }
- break;
-
- case tk_Principal:
- {
- CORBA_Principal_ptr p = *(CORBA_Principal_ptr *) data;
-
- if (p != 0)
- {
- continue_encoding = stream->put_long (p->id.length);
-
- for (u_int i = 0; continue_encoding && i < p->id.length; i++)
- continue_encoding = stream->put_octet (p->id.buffer [i]);
- }
- else
- continue_encoding = stream->put_long (0);
- }
- break;
-
- case tk_objref:
-
- // Current version: objref is really an IIOP_Object.
- //
- // This will change in the future; STUB_Object knows how to
- // marshal itself, that will be used.
- //
- // XXX this doesn't actually verify that the stuff got written
- // OK to the "wire" ...
- {
- CORBA_Object_ptr obj = *(CORBA_Object_ptr *) data;
-
- // NIL objrefs ... marshal as empty type hint, no elements.
-
- if (CORBA_is_nil (obj))
- {
- continue_encoding =
- stream->put_ulong (1) // strlen
- && stream->put_char (0) // NUL
- && stream->put_ulong (0); // no profiles
- break;
- }
-
- // All other objrefs ... narrow to a "real type" that we
- // recognize, then marshal.
- //
- // XXX this will be changed so it narrows to STUB_Object and
- // then asks that surrogate/proxy to marshal itself.
- //
- // For now, the original code is minimally changed.
-
- IIOP_Object *objdata;
- IIOP::ProfileBody *profile;
-
- if (obj->QueryInterface (IID_IIOP_Object,
- (void **) &objdata) != NOERROR)
- {
- env.exception (new CORBA_MARSHAL (COMPLETED_NO));
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- obj->Release ();
- profile = &objdata->profile;
-
- // STRING, a type ID hint
- encoder (_tc_CORBA_String, &objdata->type_id, 0, context, env);
-
- // UNSIGNED LONG, value one, count of the sequence of
- // encapsulated protocol profiles;
- stream->put_ulong (1);
-
- // UNSIGNED LONG, tag for this protocol profile;
- stream->put_ulong (IOP::TAG_INTERNET_IOP);
-
- // UNSIGNED LONG, number of succeeding bytes in the
- // encapsulation. We don't actually need to make the
- // encapsulation, as nothing needs stronger alignment than
- // this longword; it guarantees the rest is aligned for us.
- u_int hostlen;
-
- hostlen = ACE_OS::strlen ((char *) profile->host);
- stream->put_ulong (1 // byte order
- + 3 // version + pad byte
- + 4 // sizeof (strlen)
- + hostlen + 1 // strlen + null
- + (~hostlen & 01) // optional pad byte
- + 2 // port
- + (hostlen & 02) // optional pad short
- + 4 // sizeof (key length)
- + profile->object_key.length); // key length
-
- // CHAR describing byte order, starting the encapsulation
-
- stream->put_char (MY_BYTE_SEX);
-
- // IIOP::Version, two characters (version 1.0) padding
- stream->put_char (profile->iiop_version.major);
- stream->put_char (profile->iiop_version.minor);
-
- // STRING hostname from profile
- encoder (_tc_CORBA_String, &profile->host, 0, context, env);
-
- // UNSIGNED SHORT port number
- stream->put_ushort (profile->port);
-
- // OCTET SEQUENCE for object key
- encoder (&TC_opaque, &profile->object_key, 0, context, env);
- }
- break;
-
- case tk_sequence:
- {
- // First marshal the sequence length, verifying that it's
- // within the sequence bounds ...
- CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data;
- CORBA_ULong len = seq ? seq->length : 0;
-
- if (len > 0)
- {
- CORBA_ULong bounds;
-
- bounds = tc->ulong_param (1, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- if (bounds != 0 && len > bounds)
- {
- env.exception (new CORBA_BAD_PARAM (COMPLETED_MAYBE));
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- }
- continue_encoding = stream->put_ulong (len);
-
- // Fast exit on error or empty sequence
- if (!continue_encoding || len == 0)
- break;
- }
- // FALLTHROUGH
-
- case tk_struct:
- case tk_union:
- case tk_array:
- case tk_alias:
- // Marshal each member in order.
- return tc->traverse (data, 0, encoder, context, env);
-
- case tk_except:
- // Convert the the "hidden" TypeCode at the beginning of the
- // exception into an on-the-wire ID, then marshal the members in
- // order (traversal skips that hidden typecode, and more).
- //
- // NOTE: This is asymmetric with respect to decoding the
- // exception, since whoever decodes must pull off the ID and map
- // it to the typecode to be used to unmarshal it (search among
- // legal choices).
- {
- CORBA_String id = tc->id (env);
-
- if (env.exception () == 0)
- {
- continue_encoding =
- encoder (_tc_CORBA_String, &id, 0, context, env)
- == CORBA_TypeCode::TRAVERSE_CONTINUE
- && tc->traverse (data, 0, encoder, context, env);
- }
- else
- continue_encoding = CORBA_B_FALSE;
- }
- break;
-
- case tk_string:
- {
- CORBA_String str = *(CORBA_String *) data;
- CORBA_ULong len;
- CORBA_ULong bounds;
-
- // Be nice to programmers: treat nulls as empty strings not
- // errors. (OMG-IDL supports languages that don't use the
- // C/C++ notion of null v. empty strings; nulls aren't part of
- // the OMG-IDL string model.)
- if (str == 0)
- {
- stream->put_ulong (1);
- stream->put_char (0);
- break;
- }
-
- // Verify string satisfies bounds requirements. We're not so
- // permissive as to send messages violating the interface spec
- // by having excessively long strings!
- bounds = tc->ulong_param (0, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
- len = ACE_OS::strlen ((char *) str);
-
- if (bounds != 0 && len > bounds)
- {
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- // Encode the string, followed by a NUL character.
-
- for (continue_encoding = stream->put_ulong (len + 1);
- continue_encoding != CORBA_B_FALSE && *str;
- continue_encoding = stream->put_char (*str++))
- continue;
-
- stream->put_char (0);
- }
- break;
-
- case tk_wstring:
- {
- CORBA_WChar *str = *(CORBA_WChar **) data;
- CORBA_ULong len;
- CORBA_ULong bounds;
-
- // Be nice to programmers: treat nulls as empty strings not
- // errors. (OMG-IDL supports languages that don't use the
- // C/C++ notion of null v. empty strings; nulls aren't part of
- // the OMG-IDL string model.)
-
- if (str == 0)
- {
- stream->put_ulong (1);
- stream->put_wchar (0);
- break;
- }
-
- // Verify wide string satisfies bounds requirements. We're
- // not so permissive as to send messages violating the
- // interface spec by having excessively long strings!
-
- bounds = tc->ulong_param (0, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
- len = wslen (str);
- if (bounds != 0 && len > bounds)
- {
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- // Encode the wide string, followed by a NUL character.
-
- for (continue_encoding = stream->put_ulong (wslen (str) + 1);
- continue_encoding != CORBA_B_FALSE && *str;
- continue_encoding = stream->put_wchar (*str++))
- continue;
-
- stream->put_wchar (0);
- }
- break;
-
- case tk_longdouble:
- continue_encoding = stream->put_longdouble (*(CORBA_LongDouble *) data);
- break;
-
- case tk_wchar:
- continue_encoding = stream->put_wchar (*(CORBA_WChar *) data);
- break;
-
- // case ~0:
- default:
- dmsg ("encoder default case ?");
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- if (continue_encoding == CORBA_B_FALSE)
- {
- env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE));
- dmsg ("marshaling encoder detected error");
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- return CORBA_TypeCode::TRAVERSE_CONTINUE;
}
-// This table of TypeCode constants lets us unmarshal most typecodes
-// using the predefined constants, rather than constantly reallocating
-// them.
-//
-// XXX CFRONT-based compilers can't cope with this table
-// initialization, and need some kind of init function. Luckily,
-// they're increasingly rare in any "production" environment.
-
-#if THE_COMPILER_CAN_FIND_THIS_PROPERLY
-// The extern reference in onc/xdr.cpp doesn't seem to be able to find
-// this decl with as long as the const is part of it. I even tried
-// changing the ref decl to have 'const' in it, to no avail. --cjc
-const
-#endif
-CORBA_TypeCode_ptr __tc_consts [TC_KIND_COUNT] =
+TAO_MarshalFactory::~TAO_MarshalFactory()
{
- _tc_CORBA_Null
- , _tc_CORBA_Void
- , _tc_CORBA_Short
- , _tc_CORBA_Long
- , _tc_CORBA_UShort
-
- , _tc_CORBA_ULong
- , _tc_CORBA_Float
- , _tc_CORBA_Double
- , _tc_CORBA_Boolean
- , _tc_CORBA_Char
-
- , _tc_CORBA_Octet
- , _tc_CORBA_Any
- , _tc_CORBA_TypeCode
- , _tc_CORBA_Principal
- , 0 // _tc_CORBA_Object ... type ID is CORBA::Object
-
- , 0 // tk_struct
- , 0 // tk_union
- , 0 // tk_enum
- , 0 // _tc_CORBA_String ... unbounded
- , 0 // tk_sequence
-
- , 0 // tk_array
-
- , 0 // tk_alias
- , 0 // tk_except
-
- , _tc_CORBA_LongLong
- , _tc_CORBA_ULongLong
- , _tc_CORBA_LongDouble
- , _tc_CORBA_WChar
- , 0 // _tc_CORBA_WString ... unbounded
-};
+}
-// 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.
+// factory method
//
-// * The decoder is used when retrieving typecode parameters from
-// encapsulations. This means it must deal with "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::traverse_status
-CDR::decoder (CORBA_TypeCode_ptr tc,
- const void *data,
- const void *parent_typecode,
- void *context,
- CORBA_Environment &env)
+// Based on the kind of the typecode, return the appropriate marshal object
+TAO_MarshalObject* TAO_MarshalFactory::make_marshal_object(CORBA_TypeCode_ptr tc)
{
- CORBA_Boolean continue_decoding = CORBA_B_TRUE;
- CDR *stream = (CDR *) context;
-
- switch (tc->_kind)
+ if (tc)
{
- case tk_null:
- case tk_void:
- // nothing to decode!
- break;
-
- case tk_char:
- case tk_octet:
- continue_decoding = stream->get_char (*(CORBA_Char *) data);
- break;
-
- case tk_short:
- case tk_ushort:
- continue_decoding = stream->get_short (*(short *) data);
- break;
-
- case tk_long:
- case tk_ulong:
- case tk_float:
- continue_decoding = stream->get_long (*(CORBA_Long *) data);
- break;
-
- case tk_longlong:
- case tk_ulonglong:
- case tk_double:
- continue_decoding = stream->get_longlong (*(CORBA_LongLong *) data);
- break;
-
- case tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA_Boolean *) data);
- break;
-
- case tk_enum:
- {
- CORBA_ULong val;
-
- // NOTE assumption that this is in-range.
- //
- // XXX should check this, it's rather hard to recover from
- // such errors since they "do not occur" and are essentially
- // never tested for.
- continue_decoding = stream->get_ulong (val);
- *(u_int *) data = (u_int) val;
- }
- break;
-
- case tk_any:
- {
- CORBA_Any *any = (CORBA_Any *) data;
- CORBA_TypeCode_ptr tc2;
- void *value;
-
- if (decoder (_tc_CORBA_TypeCode,
- &tc2, 0,
- context, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- value = new CORBA_Octet[tc2->size (env)];
-
- if (decoder (tc2,
- value, 0,
- context, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
- {
- delete value;
- CORBA_release (tc2);
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- (void) new (any) CORBA_Any (tc2, value, CORBA_B_TRUE);
- }
- break;
-
- case tk_TypeCode:
- {
- CORBA_ULong kind;
- CORBA_TypeCode_ptr *tcp;
-
- continue_decoding = stream->get_ulong (kind);
- if (continue_decoding == CORBA_B_FALSE)
- break;
- if (kind >= TC_KIND_COUNT)
- {
- continue_decoding = CORBA_B_FALSE;
- break;
- }
-
- tcp = (CORBA_TypeCode_ptr *) data;
-
- // 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 (((*tcp) = __tc_consts [(u_int) kind]) != 0)
- {
- *tcp = __tc_consts [(u_int) kind];
- break;
- }
- else
- 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 (COMPLETED_MAYBE));
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- // Some have "simple" parameter lists ... some of these also
- // have preallocated constants that could be used.
- case tk_string:
- case tk_wstring:
- {
- CORBA_ULong bound;
-
- continue_decoding = stream->get_ulong (bound);
- if (continue_decoding) {
- if (bound == 0) {
- if (kind == tk_string)
- *tcp = _tc_CORBA_String;
- else
- *tcp = _tc_CORBA_WString;
- } else {
- *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind,
- bound, 0, CORBA_B_TRUE);
- }
- }
- }
- 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:
- {
- CORBA_TypeCode_ptr parent;
-
- if (parent_typecode == 0)
- {
- env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE));
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- parent = (CORBA_TypeCode_ptr) parent_typecode;
-
- // 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)
- continue_decoding = (offset < 0);
- if (continue_decoding)
- {
- indir_stream.buffer = indir_stream.next
- = stream->next + offset;
- indir_stream.remaining = indir_stream.length = 8;
-
- // Reject indirections outside parent's scope.
- if (indir_stream.next < 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;
-
- if (continue_decoding)
- continue_decoding = stream->get_ulong (indir_kind);
- if (continue_decoding
- && indir_kind >= TC_KIND_COUNT)
- continue_decoding = CORBA_B_FALSE;
- if (continue_decoding)
- continue_decoding = 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.next,
- CORBA_B_FALSE);
- (*tcp)->_parent = parent;
- parent->AddRef ();
- }
- }
- break;
-
- // The rest have "complex" parameter lists that are
- // encoded as bulk octets ...
- case tk_objref:
- case tk_struct:
- case tk_union:
- case tk_enum:
- case tk_sequence:
- case tk_array:
- case tk_alias:
- case tk_except:
- {
- u_int len;
- u_int i;
- CORBA_ULong length;
- CORBA_Octet *buffer;
-
- continue_decoding = stream->get_ulong (length);
- if (!continue_decoding)
- break;
-
- // if length > MAXUNSIGNED, error ...
- len = (u_int) length;
-
- buffer = new CORBA_Octet [len];
-
- for (i = 0; i < len && continue_decoding; i++)
- continue_decoding = stream->get_octet (buffer [i]);
-
- if (!continue_decoding) {
- delete buffer;
- break;
- }
- *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind,
- len,
- buffer,
- CORBA_B_TRUE);
- }
- }
- }
- break;
-
- case tk_Principal:
- {
- CORBA_Principal_ptr *pp = (CORBA_Principal_ptr *) data;
- CORBA_ULong len;
-
- continue_decoding = stream->get_ulong (len);
- if (len == 0)
- *pp = 0;
- else
- {
- *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]);
- }
- }
- break;
-
- case tk_objref:
- {
- // First, read the type hint.
-
- CORBA_String type_hint;
-
- decoder (_tc_CORBA_String, &type_hint, 0, context, 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;
-
- stream->get_ulong (profiles);
-
- // No profiles means a NIL objref.
-
- if (profiles == 0)
- {
- *(CORBA_Object_ptr *) data = CORBA_Object::_nil ();
- delete type_hint;
- break;
- }
-
- while (profiles-- != 0 && continue_decoding)
- {
- CORBA_ULong tmp;
-
- stream->get_ulong (tmp);
-
- if (tmp != 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.
-
- continue_decoding = stream->get_ulong (tmp);
- assert (stream->remaining >= tmp);
-
- // Create the decoding stream from the encapsulation in
- // the buffer, and skip the encapsulation.
- CDR str;
-
- str.setup_encapsulation (stream->next, (size_t) tmp);
-
- stream->next += (u_int) tmp;
- stream->remaining -= (u_int) tmp;
-
- objdata = new IIOP_Object (type_hint);
-
- IIOP::ProfileBody *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 = 0;
- objdata->Release ();
- objdata = 0;
- continue;
- }
-
- // Get host and port
- if (decoder (_tc_CORBA_String, &profile->host, 0, &str, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE
- || !str.get_ushort (profile->port))
- {
- env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE));
- dmsg ("error decoding IIOP host/port");
- objdata->Release ();
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
-
- // ... and object key
-
- continue_decoding = decoder (&TC_opaque,
- &profile->object_key,
- 0,
- &str,
- env) == CORBA_TypeCode::TRAVERSE_CONTINUE;
-
- if (str.remaining != 0)
- {
- env.exception (new CORBA_MARSHAL (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 (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
- {
- if (objdata->QueryInterface (IID_CORBA_Object,
- (void **) data) != NOERROR)
- continue_decoding = CORBA_B_FALSE;
- objdata->Release ();
- }
- }
- break;
-
- case tk_sequence:
- {
- // 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_OctetSeq *seq = (CORBA_OctetSeq *) data;
-
- continue_decoding = stream->get_ulong (seq->length);
- seq->maximum = seq->length;
- seq->buffer = 0;
-
- // Fast exit on empty sequences or errors
- if (!continue_decoding || seq->length == 0)
- break;
-
- // ... then allocate the memory into which we'll unmarshal
- CORBA_TypeCode_ptr tc2;
- size_t size;
-
- tc2 = tc->typecode_param (0, env);
- if (env.exception ())
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- size = tc2->size (env);
- if (env.exception ())
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- tc2->Release ();
-
- seq->buffer = new CORBA_Octet [size * (size_t) seq->maximum];
- }
- // FALLTHROUGH
-
- case tk_struct:
- case tk_union:
- case tk_array:
- case tk_alias:
- // Unmarshal all the individual elements using the per-member
- // description held in the "parent" TypeCode.
-
- // FALLTHROUGH
-
- case tk_except:
- // 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.
- return tc->traverse (data, 0, decoder, context, env);
-
- case tk_string:
- {
- CORBA_String str;
- CORBA_ULong len = 0;
-
- // 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);
- *((CORBA_String*) data) = str = new CORBA_Char [(size_t) (len)];
-
- if (len != 0)
- while (continue_decoding != CORBA_B_FALSE && len-- != 0)
- {
- continue_decoding = stream->get_char (*(CORBA_Char *) str);
- str++;
- }
- break;
- }
-
- case tk_wstring:
- {
- CORBA_WChar *str;
- CORBA_ULong len = 0;
-
- // 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++;
- }
- }
- break;
-
- case tk_longdouble:
- continue_decoding = stream->get_longdouble (*(CORBA_LongDouble *) data);
- break;
-
- case tk_wchar:
- continue_decoding = stream->get_wchar (*(CORBA_WChar *) data);
- break;
-
- // case ~0:
- default:
- continue_decoding = CORBA_B_FALSE;
- dmsg ("decode, default case?");
- break;
+ switch(tc->_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_enum:
+ case tk_double:
+ case tk_longlong:
+ case tk_ulonglong:
+ case tk_boolean:
+ case tk_char:
+ case tk_octet:
+ case tk_longdouble:
+ case tk_wchar:
+ return m_primitive_;
+ case tk_any:
+ return m_any_;
+ case tk_TypeCode:
+ return m_typecode_;
+ case tk_Principal:
+ return m_principal_;
+ case tk_objref:
+ return m_objref_;
+ case tk_struct:
+ return m_struct_;
+ case tk_union:
+ return m_union_;
+ case tk_string:
+ return m_string_;
+ case tk_sequence:
+ return m_sequence_;
+ case tk_array:
+ return m_array_;
+ case tk_alias:
+ return m_alias_;
+ case tk_except:
+ return m_except_;
+ case tk_wstring:
+ return m_wstring_;
+ default:
+ // anything else is an error
+ return (TAO_MarshalObject *)0;
+ }
}
-
- if (continue_decoding == CORBA_B_FALSE)
+ else
{
- env.exception (new CORBA_MARSHAL (COMPLETED_NO));
- dmsg ("marshaling decoder detected error");
- return CORBA_TypeCode::TRAVERSE_STOP;
+ return (TAO_MarshalObject *)0;
}
- return CORBA_TypeCode::TRAVERSE_CONTINUE;
}
+
+// define a default factory
+TAO_MarshalFactory *TAO_DEFAULT_MARSHAL_FACTORY = TAO_MARSHAL_FACTORY::instance();
diff --git a/TAO/IIOP/lib/marshal.h b/TAO/IIOP/lib/marshal.h
new file mode 100644
index 00000000000..8c1714488eb
--- /dev/null
+++ b/TAO/IIOP/lib/marshal.h
@@ -0,0 +1,520 @@
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// marshal.h
+//
+// = DESCRIPTION
+// Classes that marshal various IDL data types.
+//
+// = AUTHOR
+// Aniruddha S. Gokhale
+//
+// ============================================================================
+
+#if !defined (TAO_MARSHAL_H)
+#define TAO_MARSHAL_H
+
+#include <assert.h>
+#include "ace/OS.h"
+#include "ace/Synch.h"
+#include "ace/Singleton.h"
+
+class TAO_MarshalObject;
+class TAO_Marshal_Primitive;
+class TAO_Marshal_Any;
+class TAO_Marshal_TypeCode;
+class TAO_Marshal_Principal;
+class TAO_Marshal_ObjRef;
+class TAO_Marshal_Struct;
+class TAO_Marshal_Union;
+class TAO_Marshal_String;
+class TAO_Marshal_Sequence;
+class TAO_Marshal_Array;
+class TAO_Marshal_Alias;
+class TAO_Marshal_Except;
+class TAO_Marshal_WString;
+
+class TAO_MarshalFactory
+{
+ // = TITLE
+ // A Factory for generating specialized marshaling objects
+ //
+ // = DESCRIPTION
+ //
+public:
+ TAO_MarshalFactory(void);
+ // constructor
+
+ ~TAO_MarshalFactory();
+ // destructor
+
+ virtual TAO_MarshalObject *make_marshal_object(CORBA_TypeCode_ptr tc);
+ // factory method that returns the appropriate marshal object
+private:
+ // define data members that are instances of various MarshalObject classes
+ TAO_Marshal_Primitive *m_primitive_;
+ TAO_Marshal_Any *m_any_;
+ TAO_Marshal_TypeCode *m_typecode_;
+ TAO_Marshal_Principal *m_principal_;
+ TAO_Marshal_ObjRef *m_objref_;
+ TAO_Marshal_Struct *m_struct_;
+ TAO_Marshal_Union *m_union_;
+ TAO_Marshal_String *m_string_;
+ TAO_Marshal_Sequence *m_sequence_;
+ TAO_Marshal_Array *m_array_;
+ TAO_Marshal_Alias *m_alias_;
+ TAO_Marshal_Except *m_except_;
+ TAO_Marshal_WString *m_wstring_;
+};
+
+// Create a type for the singleton factory
+typedef ACE_Singleton<TAO_MarshalFactory, ACE_Thread_Mutex> TAO_MARSHAL_FACTORY;
+
+// define a default marshal factory to be used by the interpretive marshaling
+// engine
+extern TAO_MarshalFactory *TAO_DEFAULT_MARSHAL_FACTORY;
+
+class TAO_MarshalObject
+{
+ // = TITLE
+ // The Marshaling object that provides a common interface to the CDR object
+ // for marshaling different IDL data types
+ // = DESCRIPTION
+ // Provides a set of virtual methods for encoding, decoding,
+ // deep_copying, and deep_freeing.
+public:
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env) = 0;
+ // encoding operation
+
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env) = 0;
+ // decoding operation
+
+ TAO_MarshalObject(void);
+ // constructor
+
+ virtual ~TAO_MarshalObject();
+ // destructor
+};
+
+class TAO_Marshal_Primitive: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Primitive(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Primitive, ACE_Thread_Mutex> TAO_MARSHAL_PRIMITIVE;
+
+class TAO_Marshal_Any: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Any(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Any, ACE_Thread_Mutex> TAO_MARSHAL_ANY;
+
+class TAO_Marshal_TypeCode: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_TypeCode(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_TypeCode, ACE_Thread_Mutex> TAO_MARSHAL_TYPECODE;
+
+class TAO_Marshal_Principal: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Principal(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Principal, ACE_Thread_Mutex> TAO_MARSHAL_PRINCIPAL;
+
+class TAO_Marshal_ObjRef: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_ObjRef(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_ObjRef, ACE_Thread_Mutex> TAO_MARSHAL_OBJREF;
+
+class TAO_Marshal_Struct: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Struct(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Struct, ACE_Thread_Mutex> TAO_MARSHAL_STRUCT;
+
+class TAO_Marshal_Union: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Union(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Union, ACE_Thread_Mutex> TAO_MARSHAL_UNION;
+
+class TAO_Marshal_String: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_String(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_String, ACE_Thread_Mutex> TAO_MARSHAL_STRING;
+
+class TAO_Marshal_Sequence: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Sequence(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Sequence, ACE_Thread_Mutex> TAO_MARSHAL_SEQUENCE;
+
+class TAO_Marshal_Array: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Array(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Array, ACE_Thread_Mutex> TAO_MARSHAL_ARRAY;
+
+class TAO_Marshal_Alias: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Alias(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Alias, ACE_Thread_Mutex> TAO_MARSHAL_ALIAS;
+
+class TAO_Marshal_Except: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_Except(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_Except, ACE_Thread_Mutex> TAO_MARSHAL_EXCEPT;
+
+class TAO_Marshal_WString: public TAO_MarshalObject
+{
+ // = TITLE
+ // = DESCRIPTION
+public:
+ TAO_Marshal_WString(void);
+
+ virtual CORBA_TypeCode::traverse_status encode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ void *context,
+ CORBA_Environment &env);
+ virtual CORBA_TypeCode::traverse_status decode (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *parent_typecode,
+ void *context,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_copy (CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env);
+ static CORBA_TypeCode::traverse_status deep_free (CORBA_TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA_Environment &env);
+};
+
+// Create a type for the singleton
+typedef ACE_Singleton<TAO_Marshal_WString, ACE_Thread_Mutex> TAO_MARSHAL_WSTRING;
+
+// In this case, we make a substantial exception to how inline
+// files are included. Normally, we would conditionally include the
+// inline file iff __ACE_INLINE__ is defined. But, in the original,
+// highly optimized Sun IIOP code, much of what is in the inline file
+// was here ready to be inlined at a moments notice and ALWAYS. So,
+// in this ONE file, we defer to David Brownell's considerable prowess
+// at creating typecode interpreters as well as to the ACE convention
+// of placing inline functions into separate files.
+# if !defined(__ACE_INLINE__)
+# undef ACE_INLINE
+# define ACE_INLINE inline
+# define do_undef_on_ACE_INLINE
+# endif
+# include "marshal.i"
+# if defined(do_undef_on_ACE_INLINE)
+# undef do_undef_on_ACE_INLINE
+# undef ACE_INLINE
+# define ACE_INLINE
+# endif
+
+#endif
diff --git a/TAO/IIOP/lib/marshal.i b/TAO/IIOP/lib/marshal.i
new file mode 100644
index 00000000000..346dbfaf479
--- /dev/null
+++ b/TAO/IIOP/lib/marshal.i
@@ -0,0 +1,216 @@
+// constructor for the various MarshalObject classes
+ACE_INLINE TAO_MarshalObject::TAO_MarshalObject()
+{
+}
+
+ACE_INLINE TAO_Marshal_Primitive::TAO_Marshal_Primitive()
+{
+}
+
+ACE_INLINE TAO_Marshal_Any::TAO_Marshal_Any()
+{
+}
+
+ACE_INLINE TAO_Marshal_Principal::TAO_Marshal_Principal()
+{
+}
+
+ACE_INLINE TAO_Marshal_TypeCode::TAO_Marshal_TypeCode()
+{
+}
+
+ACE_INLINE TAO_Marshal_ObjRef::TAO_Marshal_ObjRef()
+{
+}
+
+ACE_INLINE TAO_Marshal_Struct::TAO_Marshal_Struct()
+{
+}
+
+ACE_INLINE TAO_Marshal_Union::TAO_Marshal_Union()
+{
+}
+
+ACE_INLINE TAO_Marshal_String::TAO_Marshal_String()
+{
+}
+
+ACE_INLINE TAO_Marshal_Sequence::TAO_Marshal_Sequence()
+{
+}
+
+ACE_INLINE TAO_Marshal_Array::TAO_Marshal_Array()
+{
+}
+
+ACE_INLINE TAO_Marshal_Alias::TAO_Marshal_Alias()
+{
+}
+
+ACE_INLINE TAO_Marshal_Except::TAO_Marshal_Except()
+{
+}
+
+ACE_INLINE TAO_Marshal_WString::TAO_Marshal_WString()
+{
+}
+
+//destructor for the MarshalObject class
+ACE_INLINE TAO_MarshalObject::~TAO_MarshalObject()
+{
+}
+
+// the deep_copy methods
+
+// deep_copy for any
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_Any::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ (void) new (dest) CORBA_Any (*(CORBA_Any*) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_copy for TypeCode
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_TypeCode::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ if ((*(CORBA_TypeCode_ptr *) source) != 0)
+ dest = source;
+ else
+ dest = _tc_CORBA_Null;
+
+ ((CORBA_TypeCode_ptr) dest)->AddRef ();
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_copy for ObjRef
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_ObjRef::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ *(CORBA_Object_ptr *) dest = CORBA_Object::_duplicate (*(CORBA_Object_ptr *)
+ source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_copy for string
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_String::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ *(CORBA_String *) dest = CORBA_string_copy (*(CORBA_String *) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_copy for wstring
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_WString::deep_copy(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ *(CORBA_WString *) dest = CORBA_wstring_copy (*(CORBA_WString *) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// *************** deep_free methods ******************
+
+// deep_free for Any
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_Any::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ ((CORBA_Any *) source)->~CORBA_Any ();
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_free for TypeCode
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_TypeCode::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ if ((*(CORBA_TypeCode_ptr *) source) != 0)
+ (*(CORBA_TypeCode_ptr *) source)->Release ();
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_free for Principal
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_Principal::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *value,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_release (*(CORBA_Principal_ptr *) value);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_free for ObjRef
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_ObjRef::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_release (*(CORBA_Object_ptr *) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_free for string
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_String::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_string_free (*(CORBA_String *) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
+// deep_free for wstring
+ACE_INLINE CORBA_TypeCode::traverse_status
+TAO_Marshal_WString::deep_free(
+ CORBA_TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ CORBA_Environment &env
+ )
+{
+ CORBA_wstring_free (*(CORBA_WString *) source);
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+}
+
diff --git a/TAO/IIOP/lib/nvlist.cpp b/TAO/IIOP/lib/nvlist.cpp
index f9fe2742640..52eb8c6379c 100644
--- a/TAO/IIOP/lib/nvlist.cpp
+++ b/TAO/IIOP/lib/nvlist.cpp
@@ -8,12 +8,10 @@
#if !defined (VXWORKS)
#include <memory.h>
#endif
-#include <orb.h>
+#include "orb.h"
#include <initguid.h>
-#include "debug.h"
-
// COM's IUnknown support
// {77420087-F276-11ce-9598-0000C07CA898}
diff --git a/TAO/IIOP/lib/object.cpp b/TAO/IIOP/lib/object.cpp
index 8c561584ddf..4feb6ec201d 100644
--- a/TAO/IIOP/lib/object.cpp
+++ b/TAO/IIOP/lib/object.cpp
@@ -8,12 +8,11 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
+
#include "orb.h"
#include "object.h"
#include "optable.h"
-
-#include <stub.h>
-#include "debug.h"
+#include "stub.h"
#include <initguid.h>
diff --git a/TAO/IIOP/lib/object.h b/TAO/IIOP/lib/object.h
index 2e586d32fb7..19403020dbd 100644
--- a/TAO/IIOP/lib/object.h
+++ b/TAO/IIOP/lib/object.h
@@ -138,8 +138,24 @@ private:
// XXX need CORBA_Object_var class typedef
-#if defined(__ACE_INLINE__)
+// In this case, we make a substantial exception to how inline
+// files are included. Normally, we would conditionally include the
+// inline file iff __ACE_INLINE__ is defined. But, in the original,
+// highly optimized Sun IIOP code, much of what is in the inline file
+// was here ready to be inlined at a moments notice and ALWAYS. So,
+// in this ONE file, we defer to David Brownell's considerable prowess
+// at creating typecode interpreters as well as to the ACE convention
+// of placing inline functions into separate files.
+# if !defined(__ACE_INLINE__)
+# undef ACE_INLINE
+# define ACE_INLINE inline
+# define do_undef_on_ACE_INLINE
+# endif
# include "object.i"
-#endif
+# if defined(do_undef_on_ACE_INLINE)
+# undef do_undef_on_ACE_INLINE
+# undef ACE_INLINE
+# define ACE_INLINE
+# endif
#endif /* CORBA_OBJECT_H */
diff --git a/TAO/IIOP/lib/orb.h b/TAO/IIOP/lib/orb.h
index 2d2be34bb92..5047e71227f 100644
--- a/TAO/IIOP/lib/orb.h
+++ b/TAO/IIOP/lib/orb.h
@@ -111,8 +111,9 @@ typedef void (*TAO_Skeleton)(CORBA_ServerRequest &,
#include "any.h"
#include "nvlist.h"
#include "request.h"
-#include "svrrqst.h"
#include "object.h"
+#include "svrrqst.h"
+#include "debug.h" // gets included only if the DEBUG flag is set
#if !defined(__IIOP_BUILD)
# include "boa.h"
diff --git a/TAO/IIOP/lib/orbobj.cpp b/TAO/IIOP/lib/orbobj.cpp
index c99a417f169..4f77c2cff18 100644
--- a/TAO/IIOP/lib/orbobj.cpp
+++ b/TAO/IIOP/lib/orbobj.cpp
@@ -16,7 +16,6 @@
#include "orb.h"
#include "stub.h"
-#include "debug.h"
#include "iioporb.h" // XXX
#include "params.h"
diff --git a/TAO/IIOP/lib/request.cpp b/TAO/IIOP/lib/request.cpp
index 73d96e1d111..520193508a6 100644
--- a/TAO/IIOP/lib/request.cpp
+++ b/TAO/IIOP/lib/request.cpp
@@ -4,12 +4,10 @@
//
// Implementation of Dynamic Invocation Interface
//
-#include <orb.h>
-#include <stub.h>
-
+#include "orb.h"
+#include "stub.h"
#include <initguid.h>
-#include "debug.h"
#include "cdr.h"
// {77420085-F276-11ce-9598-0000C07CA898}
diff --git a/TAO/IIOP/lib/roa.cpp b/TAO/IIOP/lib/roa.cpp
index d57a246bfda..e0f4e4ca483 100644
--- a/TAO/IIOP/lib/roa.cpp
+++ b/TAO/IIOP/lib/roa.cpp
@@ -1,7 +1,6 @@
// $Id$
#include "orb.h"
-#include "debug.h"
#include "roa.h"
#include "boa.h"
#include "cdr.h"
@@ -579,7 +578,7 @@ request_dispatcher (GIOP::RequestHeader &req,
CORBA_TypeCode_ptr except_tc = x->type ();
reply->put_ulong (GIOP::SYSTEM_EXCEPTION);
- (void) CDR::encoder (except_tc, x, 0, reply, env2);
+ (void) reply->encode (except_tc, x, 0, env2);
}
else if (svr_req._exception)
{ // any exception at all
@@ -597,7 +596,7 @@ request_dispatcher (GIOP::RequestHeader &req,
else
reply->put_ulong (GIOP::USER_EXCEPTION);
- (void) CDR::encoder (except_tc, x, 0, reply, env);
+ (void) reply->encode (except_tc, x, 0, env);
}
else
{ // normal reply
@@ -609,7 +608,7 @@ request_dispatcher (GIOP::RequestHeader &req,
{
tc = svr_req._retval->type ();
value = svr_req._retval->value ();
- (void) CDR::encoder (tc, value, 0, reply, env);
+ (void) reply->encode (tc, value, 0, env);
}
// ... followed by "inout" and "out" parameters, left to right
@@ -624,7 +623,7 @@ request_dispatcher (GIOP::RequestHeader &req,
any = nv->value ();
tc = any->type ();
value = any->value ();
- (void) CDR::encoder (tc, value, 0, reply, env);
+ (void) reply->encode (tc, value, 0, env);
}
}
}
diff --git a/TAO/IIOP/lib/svrrqst.cpp b/TAO/IIOP/lib/svrrqst.cpp
index 4dc7c3cbdba..a259739c65c 100644
--- a/TAO/IIOP/lib/svrrqst.cpp
+++ b/TAO/IIOP/lib/svrrqst.cpp
@@ -4,13 +4,9 @@
//
// Implementation of the Dynamic Server Skeleton Interface
-#include <orb.h>
-
+#include "orb.h"
#include <initguid.h>
-
-#include "debug.h"
#include "cdr.h"
-
#include "svrrqst.h"
// {77420086-F276-11ce-9598-0000C07CA898}
@@ -132,7 +128,7 @@ IIOP_ServerRequest::params (CORBA_NVList_ptr list,
tc->Release ();
// Then just unmarshal the value.
- (void) CDR::decoder (tc, value, 0, _incoming, env);
+ (void) _incoming->decode (tc, value, 0, env);
}
// If any data is left over, it'd be context values ... else error.
diff --git a/TAO/IIOP/lib/t-xdr.cpp b/TAO/IIOP/lib/t-xdr.cpp
index 4729082975e..8a4d82132bd 100644
--- a/TAO/IIOP/lib/t-xdr.cpp
+++ b/TAO/IIOP/lib/t-xdr.cpp
@@ -168,12 +168,12 @@ do_test (int use_XDR,
;
if (status)
- status = CDR::encoder (&TC_opaque, &key, 0, &stream, env)
+ status = stream.encode (&TC_opaque, &key, 0, env)
== CORBA_TypeCode::TRAVERSE_CONTINUE;
if (status)
- status = CDR::encoder (_tc_CORBA_String, &opname,
- 0, &stream, env)
+ status = stream.encode (_tc_CORBA_String, &opname,
+ 0, env)
== CORBA_TypeCode::TRAVERSE_CONTINUE;
/*
@@ -188,12 +188,12 @@ do_test (int use_XDR,
&& stream.put_long (99)
&& stream.put_long (-3455);
if (status)
- status = CDR::encoder (_tc_CORBA_String, &opname,
- 0, &stream, env)
+ status = stream.encode (_tc_CORBA_String, &opname,
+ 0, env)
== CORBA_TypeCode::TRAVERSE_CONTINUE;
// Gratuitous extra "interesting" data
- status = CDR::encoder (tc, data, 0, &stream, env)
+ status = stream.encode (tc, data, 0, env)
== CORBA_TypeCode::TRAVERSE_CONTINUE;
diff --git a/TAO/IIOP/lib/tc_const.cpp b/TAO/IIOP/lib/tc_const.cpp
index 20b22c79508..d398044a5ce 100644
--- a/TAO/IIOP/lib/tc_const.cpp
+++ b/TAO/IIOP/lib/tc_const.cpp
@@ -83,10 +83,27 @@ const CORBA_TypeCode_ptr _tc_CORBA_Char = &tc_char;
static CORBA_TypeCode tc_wchar (tk_wchar);
const CORBA_TypeCode_ptr _tc_CORBA_WChar = &tc_wchar;
-static CORBA_TypeCode tc_string (tk_string);
+// a string/wstring have a simple parameter list that indicates the length
+static const CORBA_Long _oc_string [] =
+{ // CDR typecode octets
+ 1, // native endian + padding; "tricky"
+ 0 // ... unbounded string
+};
+static CORBA_TypeCode tc_string (tk_string,
+ sizeof _oc_string,
+ (u_char *) &_oc_string,
+ CORBA_B_FALSE);
const CORBA_TypeCode_ptr _tc_CORBA_String = &tc_string;
-static CORBA_TypeCode tc_wstring (tk_wstring);
+static const CORBA_Long _oc_wstring [] =
+{ // CDR typecode octets
+ 1, // native endian + padding; "tricky"
+ 0 // ... unbounded string
+};
+static CORBA_TypeCode tc_wstring (tk_wstring,
+ sizeof _oc_wstring,
+ (u_char *) &_oc_wstring,
+ CORBA_B_FALSE);
const CORBA_TypeCode_ptr _tc_CORBA_WString = &tc_wstring;
//
diff --git a/TAO/IIOP/lib/typecode.cpp b/TAO/IIOP/lib/typecode.cpp
index a8a7d7624c8..92ad1cdd3c0 100644
--- a/TAO/IIOP/lib/typecode.cpp
+++ b/TAO/IIOP/lib/typecode.cpp
@@ -19,42 +19,48 @@
#include <assert.h>
#include <limits.h>
#include <string.h>
-#include <orb.h>
-
-#include "debug.h"
-#include "cdr.h"
#if !defined (VXWORKS)
#include <memory.h>
#endif
#include <sys/types.h>
+#include "orb.h"
+#include "cdr.h"
#include <initguid.h>
-
-void
-CORBA_release (CORBA_TypeCode_ptr tc)
-{
- if (tc)
- tc->Release ();
-}
-
-CORBA_Boolean
-CORBA_is_nil (CORBA_TypeCode_ptr tc)
-{
- return (CORBA_Boolean) tc == 0;
-}
-
-// Constructor for CONSTANT typecodes with empty parameter lists.
-// These are only created once, and those constants are shared.
-
-CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind)
- : _length (0),
- _buffer (0),
- _kind (kind),
- _parent (0),
- _refcount (1),
- _orb_owns (CORBA_B_FALSE)
+size_t calc_key_union_attributes(CDR *stream,
+ size_t &alignment,
+ size_t &size_with_pad,
+ CORBA_Environment &env);
+
+
+// constructor for the private state
+TC_PRV_State::TC_PRV_State()
+ : tc_id_known_(CORBA_B_FALSE),
+ tc_name_known_(CORBA_B_FALSE),
+ tc_member_count_known_(CORBA_B_FALSE),
+ tc_member_type_list_known_(CORBA_B_FALSE),
+ tc_member_label_list_known_(CORBA_B_FALSE),
+ tc_discriminator_type_known_(CORBA_B_FALSE),
+ tc_default_index_used_known_(CORBA_B_FALSE),
+ tc_length_known_(CORBA_B_FALSE),
+ tc_content_type_known_(CORBA_B_FALSE),
+ tc_size_known_(CORBA_B_FALSE),
+ tc_alignment_known_(CORBA_B_FALSE),
+ tc_discrim_pad_size_known_(CORBA_B_FALSE),
+ tc_id_(0),
+ tc_name_(0),
+ tc_member_count_(0),
+ tc_member_type_list_(0),
+ tc_member_label_list_(0),
+ tc_discriminator_type_(0),
+ tc_default_index_used_ (0),
+ tc_length_(0),
+ tc_content_type_(0),
+ tc_size_(0),
+ tc_alignment_(0),
+ tc_discrim_pad_size_(0)
{
}
@@ -70,7 +76,8 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind,
_kind (kind),
_parent (0),
_refcount (1),
- _orb_owns (orb_owns_tc)
+ _orb_owns (orb_owns_tc),
+ _prv_state (new TC_PRV_State)
{
// The CDR code used to interpret TypeCodes requires in-memory
// alignments to match the "on-the-wire" alignments, simplifying
@@ -95,21 +102,22 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind,
temp &= ~0x03;
_buffer = (CORBA_Octet *) temp;
- (void) ACE_OS::memcpy (_buffer, buffer, (size_t) length);
+ (void) ACE_OS::memcpy (_buffer, buffer, (size_t) length);
_orb_owns = CORBA_B_FALSE; // XXX may leak
}
}
-// Destructor. For "indirected" typecodes, the typecode reuses the
-// buffer owned by its parent, and so rather than deleting the buffer
-// it just drops the parent's refcount.
+// decreases the refcount and deletes when refcount reaches 0
+void CORBA_release (CORBA_TypeCode_ptr tc)
+{
+ if (tc)
+ tc->Release ();
+}
-CORBA_TypeCode::~CORBA_TypeCode (void)
+// returns true if the typecode is NULL
+CORBA_Boolean CORBA_is_nil (CORBA_TypeCode_ptr tc)
{
- if (_parent)
- _parent->Release ();
- else if (_orb_owns)
- delete _buffer;
+ return (CORBA_Boolean) tc == 0;
}
// COM's IUnknown support
@@ -118,6 +126,7 @@ CORBA_TypeCode::~CORBA_TypeCode (void)
DEFINE_GUID (IID_CORBA_TypeCode,
0xa201e4c1, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98);
+// COM stuff
ULONG __stdcall
CORBA_TypeCode::AddRef (void)
{
@@ -126,6 +135,7 @@ CORBA_TypeCode::AddRef (void)
return _refcount++;
}
+// COM stuff
ULONG __stdcall
CORBA_TypeCode::Release (void)
{
@@ -140,6 +150,7 @@ CORBA_TypeCode::Release (void)
return 0;
}
+// COM stuff
HRESULT __stdcall
CORBA_TypeCode::QueryInterface (REFIID riid,
void **ppv)
@@ -156,134 +167,640 @@ CORBA_TypeCode::QueryInterface (REFIID riid,
return NOERROR;
}
-// just fetch the 'kind' field out of the typecode
-
-CORBA_TCKind
-CORBA_TypeCode::kind (CORBA_Environment &env) const
+CORBA_Boolean
+CORBA_TypeCode::prv_equal(CORBA_TypeCode_ptr tc, CORBA_Environment &env) const
{
- env.clear ();
- return _kind;
+ // We come in here only if the typecode kinds of both are same
+ // Handle each complex typecode separately
+ switch (_kind)
+ {
+ case tk_null:
+ case tk_void:
+ case tk_short:
+ case tk_ushort:
+ case tk_long:
+ case tk_ulong:
+ case tk_float:
+ case tk_double:
+ case tk_longlong:
+ case tk_longdouble:
+ case tk_boolean:
+ case tk_octet:
+ case tk_char:
+ case tk_wchar:
+ case tk_TypeCode:
+ case tk_Principal:
+ // all these are simple typecodes and the comparison is based solely on
+ // the _kind field
+ return CORBA_B_TRUE;
+ case tk_objref:
+ // return prv_equal_objref(tc, env);
+ case tk_struct:
+ // return prv_equal_struct(tc, env);
+ case tk_union:
+ // return prv_equal_union(tc, env);
+ case tk_enum:
+ // return prv_equal_enum(tc, env);
+ case tk_string:
+ // return prv_equal_string(tc, env);
+ case tk_wstring:
+ // return prv_equal_string(tc, env);
+ case tk_sequence:
+ // return prv_equal_sequence(tc, env);
+ case tk_array:
+ // return prv_equal_array(tc, env);
+ case tk_alias:
+ // return prv_equal_alias(tc, env);
+ case tk_except:
+ // return prv_equal_except(tc, env);
+ // Not implemented yet
+ return CORBA_B_FALSE;
+ }
}
-// skip a typecode encoding in a given CDR stream
-
-static CORBA_Boolean
-skip_typecode (CDR &stream)
+// Return the type ID (RepositoryId) for the TypeCode; it may be empty.
+//
+// NOTE the string returned here is owned by the typecode!!
+//
+// Valid only for objref, struct, union, enum, alias, and except. Raises
+// BadKind exception for the rest of the cases.
+const CORBA_String
+CORBA_TypeCode::prv_id (CORBA_Environment &env) const
{
- CORBA_ULong kind;
- CORBA_ULong temp;
-
- if (!stream.get_ulong (kind) || kind >= TC_KIND_COUNT)
- return CORBA_B_FALSE;
+ env.clear ();
- switch (kind)
+ switch (_kind)
{
- // Most TypeCodes have empty parameter lists, nothing to skip
+ // These are all complex typecodes, which have as their first
+ // parameter (number zero) a repository/type ID string encoded
+ // per CDR rules. That means we can just return a pointer to
+ // that string directly!
+
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_enum:
+ case tk_alias:
+ case tk_except:
+ _prv_state->tc_id_known_ = CORBA_B_TRUE;
+ _prv_state->tc_id_ = (CORBA_String) (_buffer
+ + 4 // skip byte order flag and padding
+ + 4 // skip (strlen + 1)
+ );
+ return _prv_state->tc_id_;
+ // No other typecodes ever have type IDs
default:
- break;
+ env.exception (new CORBA_BadKind ());
+ return 0;
+ }
+}
- // Some have single integer parameters, easy to skip. Some have
- // preallocated constants that could be used.
- case tk_string:
- case tk_wstring:
- case ~0:
- return stream.get_ulong (temp);
+// return the name. The string is owned by the typecode
+const CORBA_String
+CORBA_TypeCode::prv_name (CORBA_Environment &env) const
+{
+ env.clear ();
+
+ switch (_kind)
+ {
+ // These are all complex typecodes, which have as their second
+ // parameter (number one) a name string encoded
+ // per CDR rules. That means we can just return a pointer to
+ // that string directly!
- // The rest have "complex" parameter lists that are
- // encoded as bulk octets ... just skip them.
case tk_objref:
case tk_struct:
case tk_union:
case tk_enum:
- case tk_sequence:
- case tk_array:
case tk_alias:
case tk_except:
- return stream.get_ulong (temp) != CORBA_B_FALSE
- && stream.skip_bytes (temp) != CORBA_B_FALSE;
+ {
+ CORBA_ULong len;
+ CDR stream;
+
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+
+ // skip the typecode ID
+ if (stream.skip_string ()) // ID
+ {
+ _prv_state->tc_name_known_ = CORBA_B_TRUE;
+ _prv_state->tc_name_ = (CORBA_String)(stream.next
+ +
+ CDR::LONG_SIZE); // skip past the length field
+ return _prv_state->tc_name_;
+ }
+ else
+ {
+ env.exception(new CORBA_INTERNAL(COMPLETED_NO));
+ return (CORBA_String)0;
+ }
+ // No other typecodes ever have type IDs
+ }
+ break;
+ default:
+ env.exception (new CORBA_BadKind ());
+ return 0;
}
+}
+
+// Return the number of members defined by this typecode
+//
+// Applicable to struct, union, enum, alias, and except
+// For the rest of the cases, raises the BadKind exception.
+
+CORBA_ULong
+CORBA_TypeCode::prv_member_count (CORBA_Environment &env) const
+{
+ env.clear ();
+
+ switch (_kind)
+ {
+ case tk_alias:
+ // tc_member_count_known_ = CORBA_B_TRUE;
+ //tc_member_count_ = 1;
+ return 1;
+
+ case tk_enum:
+ case tk_except:
+ case tk_struct:
+ {
+ CORBA_ULong members;
+ CDR stream;
+
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+
+ // skip rest of header (type ID and name) and collect the
+ // number of struct members
+ if (!stream.skip_string () // ID
+ || !stream.skip_string () // struct name
+ || !stream.get_ulong (members))
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+
+ _prv_state->tc_member_count_known_ = CORBA_B_TRUE;
+ _prv_state->tc_member_count_ = members;
+ return _prv_state->tc_member_count_;
+ }
+ case tk_union:
+ {
+ CORBA_ULong members;
+ CDR stream;
+
+ stream.setup_encapsulation (_buffer, (size_t) _length);
+
+ // skip rest of header (type ID, name, etc...) and collect the
+ // number of struct members
+ if (!stream.skip_string () // ID
+ || !stream.skip_string () // struct name
+ || !skip_typecode (stream) // discriminant TC
+ || !stream.get_ulong (members) // default used
+ || !stream.get_ulong (members)) // real member count
+ {
+ // this is a system exception indicating something is wrong with
+ // the typecode itself.
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
- return CORBA_B_TRUE;
+ _prv_state->tc_member_count_known_ = CORBA_B_TRUE;
+ _prv_state->tc_member_count_ = members;
+ return _prv_state->tc_member_count_;
+ }
+ default:
+ env.exception(new CORBA_BadKind());
+ return 0;
+ }
}
+// Return the name for the nth member
+// Applicable only to tk_struct, tk_union, and tk_except
+const CORBA_String
+CORBA_TypeCode::member_name(CORBA_ULong index, CORBA_Environment &env) const
+{
+ return 0;
+}
-// Return member labels for tk_union typecodes.
+// NOTE special calling convention for stream.decode () when we're
+// potentially deencapsulating an indirected typecode: the "data2"
+// value indicates that this typecode is the parent. See comments at
+// stream.decode () for further details.
+//
+// Applicable only to struct, union, and except
+//
-CORBA_Any_ptr
-CORBA_TypeCode::member_label (CORBA_ULong n,
- CORBA_Environment &env) const
+CORBA_TypeCode_ptr
+CORBA_TypeCode::prv_member_type (CORBA_ULong index, CORBA_Environment &env) const
{
- env.clear ();
+ CORBA_ULong temp, mcount;
+ // Build the de-encapsulating CDR stream, bypassing the stringent
+ // alignment tests (we're a bit looser in what we need here, and we
+ // _know_ we're OK). Then skip the byte order code.
CDR stream;
+ CORBA_TypeCode_ptr tc = 0;
stream.setup_encapsulation (_buffer, (size_t)_length);
+ switch (_kind)
+ {
+ case tk_except:
+ case tk_struct: // index from 0
+ mcount = member_count (env); // clears env
+ if (env.exception () == 0)
+ {
+ // the first time in. Precompute and store types of all members
+ _prv_state->tc_member_type_list_ = new CORBA_TypeCode_ptr [mcount];
+ if (_prv_state->tc_member_type_list_)
+ {
+ // skip the id, name, and member_count part
+ if (!stream.skip_string () // type ID, hidden
+ || !stream.skip_string () // typedef name
+ || !stream.get_ulong (temp))
+ { // member count
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return (CORBA_TypeCode_ptr)0;
+ }
+ else
+ {
+ CORBA_ULong i;
+
+ // compute the typecodes for all the members and return the
+ // required one
+ for (i = 0; i < mcount; i++)
+ {
+ // the ith entry will have the typecode of the ith guy
+ if (!stream.skip_string () // skip the name
+ || stream.decode (_tc_CORBA_TypeCode,
+ &_prv_state->tc_member_type_list_[i],
+ this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+ }
+ _prv_state->tc_member_type_list_known_ = CORBA_B_TRUE;
+ if (index >= 0 && index < mcount)
+ {
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_member_type_list_[index]);
+ }
+ else
+ {
+ env.exception(new CORBA_Bounds());
+ return (CORBA_TypeCode_ptr)0;
+ }
+ }
+ }
+ else // no memory for the member_list
+ {
+ env.exception(new CORBA_NO_MEMORY(COMPLETED_NO));
+ return (CORBA_TypeCode_ptr)0;
+ }
+ }
+ else // out of bounds
+ {
+ env.exception (new CORBA_Bounds());
+ return (CORBA_TypeCode_ptr)0;
+ }
+ case tk_union: // index from 0
+ mcount = member_count (env); // clears env
+ if (env.exception () == 0)
+ {
+ // the first time in. Precompute and store types of all members
+ _prv_state->tc_member_type_list_ = new CORBA_TypeCode_ptr [mcount];
+ if (_prv_state->tc_member_type_list_)
+ {
+ // skip the id, name, and discrimant type part
+ if (!stream.skip_string () // type ID, hidden
+ || !stream.skip_string () // typedef name
+ || stream.decode (_tc_CORBA_TypeCode,
+ &tc, this,
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE) // TC
+ { // member count
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return (CORBA_TypeCode_ptr)0;
+ }
+ else if (!stream.get_ulong (temp) // default used
+ || !stream.get_ulong (temp)) // member count
+ {
+ tc->Release ();
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+ else
+ {
+ CORBA_ULong i;
+ CORBA_Long scratch; // always big enough
+ // compute the typecodes for all the members and return the
+ // required one
+ for (i = 0; i < temp; i++)
+ {
+ // the ith entry will have the typecode of the ith guy
+ if (stream.decode (tc, &scratch, this, env) // member label
+ != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || !stream.skip_string () // skip the name
+ || stream.decode (_tc_CORBA_TypeCode, // get the typecode
+ &_prv_state->tc_member_type_list_[i],
+ this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+ }
+ _prv_state->tc_member_type_list_known_ = CORBA_B_TRUE;
+ if (index >= 0 && index < mcount)
+ {
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_member_type_list_[index]);
+ }
+ else
+ {
+ env.exception(new CORBA_Bounds());
+ return (CORBA_TypeCode_ptr)0;
+ }
+ }
+ }
+ else // no memory for the member_list
+ {
+ env.exception(new CORBA_NO_MEMORY(COMPLETED_NO));
+ return (CORBA_TypeCode_ptr)0;
+ }
+ }
+ else // out of bounds
+ {
+ env.exception (new CORBA_Bounds());
+ return (CORBA_TypeCode_ptr)0;
+ }
+
+ default:
+ // bad kind
+ env.exception(new CORBA_BadKind());
+ return (CORBA_TypeCode_ptr)0;
+ }
+}
+
+// Return member labels for tk_union typecodes.
+CORBA_Any_ptr
+CORBA_TypeCode::prv_member_label (CORBA_ULong n,
+ CORBA_Environment &env) const
+{
+ env.clear ();
+
// this function is only applicable to the tk_union TC
- if (_kind != tk_union)
+ if (_kind == tk_union)
{
- env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ CDR stream;
+
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+
+ // skip ID and name, and then get the discriminant TC
+ CORBA_TypeCode_ptr tc = 0;
+
+ if (!stream.skip_string () // type ID, hidden
+ || !stream.skip_string () // typedef name
+ || stream.decode (_tc_CORBA_TypeCode, &tc, this, env)
+ != CORBA_TypeCode::TRAVERSE_CONTINUE) {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+
+ // skip default used, and get member count
+ CORBA_ULong member_count;
+
+ if (!stream.get_ulong (member_count) // default used
+ || !stream.get_ulong (member_count))
+ {
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ dmsg ("TypeCode::prv_member_label -- error reading from stream");
+ return 0;
+ }
+
+ _prv_state->tc_member_label_list_ = new CORBA_Any_ptr [member_count];
+ if (_prv_state->tc_member_label_list_)
+ {
+ for (CORBA_ULong i = 0; i < member_count; i++)
+ {
+ // allocate buffer to hold the member label value
+ void *buf = new CORBA_Octet [tc->size (env)];
+ if (stream.decode (tc, buf, this, env)
+ != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || !stream.skip_string () // member name
+ || !skip_typecode (stream)) // member type
+ { // member TC
+ dmsg1("TypeCode::prv_member_label -- error getting typecode\
+for member %d",i);
+ delete [] buf;
+ // XXX-Andy: free this list on error
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
+ return 0;
+ }
+ else
+ {
+ _prv_state->tc_member_label_list_[i] = new CORBA_Any (tc, buf, CORBA_B_TRUE);
+ }
+ }
+ }
+ else
+ {
+ env.exception(new CORBA_NO_MEMORY(COMPLETED_NO));
+ return 0;
+ }
+
+ _prv_state->tc_member_label_list_known_ = CORBA_B_TRUE;
+ tc->Release ();
+
+ // If caller asked for the label for a nonexistent member, they get
+ // an error report!
+ if (n >= member_count)
+ {
+ env.exception (new CORBA_Bounds ());
+ return 0;
+ }
+ else
+ {
+ return _prv_state->tc_member_label_list_[n];
+ }
+ }
+ else // wrong typecode
+ {
+ env.exception(new CORBA_BadKind());
return 0;
}
+}
- // skip ID and name, and then get the discriminant TC
- CORBA_TypeCode_ptr tc = 0;
+CORBA_TypeCode_ptr
+CORBA_TypeCode::prv_discriminator_type(CORBA_Environment &env) const
+{
+ CDR stream;
+
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+ // skip ID and name, and then get the discriminant TC
+
if (!stream.skip_string () // type ID, hidden
- || !stream.skip_string () // typedef name
- || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE) {
- env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
- return 0;
- }
-
- // skip default used, and get member count
- CORBA_ULong member_count;
-
- if (!stream.get_ulong (member_count) // default used
- || !stream.get_ulong (member_count))
+ || !stream.skip_string () // typedef name
+ || stream.decode (_tc_CORBA_TypeCode,
+ &_prv_state->tc_discriminator_type_, this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE)
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
return 0;
}
+ else
+ {
+ _prv_state->tc_discriminator_type_known_ = CORBA_B_TRUE;
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_discriminator_type_);
+ }
+}
+
+CORBA_Long
+CORBA_TypeCode::prv_default_index (CORBA_Environment &env) const
+{
+ CDR stream;
+ CORBA_TypeCode_ptr tc = 0;
+
+ stream.setup_encapsulation (_buffer, (size_t)_length);
- // If caller asked for the label for a nonexistent member, they get
- // an error report!
- if (n >= member_count)
+ // skip ID and name, and then get the discriminant TC
+
+ if (!stream.skip_string () // type ID, hidden
+ || !stream.skip_string () // typedef name
+ || stream.decode (_tc_CORBA_TypeCode,
+ &tc, this, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ || !stream.get_long(_prv_state->tc_default_index_used_))
+
{
- env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
+ env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
return 0;
}
+ else
+ {
+ _prv_state->tc_default_index_used_known_ = CORBA_B_TRUE;
+ return _prv_state->tc_default_index_used_;
+ }
+}
- // Get the n-th member label; they're all the same size and have no
- // nested pointers, so we just overwrite each one with the enxt
- // parameter.
+CORBA_Long
+CORBA_TypeCode::prv_length (CORBA_Environment &env) const
+{
+ CDR stream;
+ CORBA_TypeCode_ptr tc = 0;
- void *buf = new CORBA_Octet [tc->size (env)];
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+ switch (_kind)
+ {
+ case tk_sequence:
+ case tk_array:
+ {
+ // skip the typecode of the element and get the bounds
+ if (stream.decode (_tc_CORBA_TypeCode, &tc, this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE // skip typecode
+ || !stream.get_ulong(_prv_state->tc_length_))
+ {
+ env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
+ return 0;
+ }
+ else
+ {
+ _prv_state->tc_length_known_ = CORBA_B_TRUE;
+ return _prv_state->tc_length_;
+ }
+ break;
+ case tk_string:
+ case tk_wstring:
+ {
+ if (stream.get_ulong(_prv_state->tc_length_))
+ {
+ _prv_state->tc_length_known_ = CORBA_B_TRUE;
+ return _prv_state->tc_length_;
+ }
+ else
+ {
+ env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
+ return 0;
+ }
+ }
+ default:
+ env.exception (new CORBA_BadKind);
+ return 0;
+ }
+ }
+}
- if (env.exception () != 0)
- return 0;
+CORBA_TypeCode_ptr
+CORBA_TypeCode::prv_content_type (CORBA_Environment &env) const
+{
+ CDR stream;
+ CORBA_TypeCode_ptr tc = 0;
- for (CORBA_ULong i = 0; i <= n; i++)
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+ switch (_kind)
{
- if (CDR::decoder (tc, buf, this, &stream, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE
- || !stream.skip_string () // member name
- || !skip_typecode (stream))
- { // member TC
- delete [] buf;
- env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
- return 0;
+ case tk_sequence:
+ case tk_array:
+ {
+ // skip the typecode of the element and get the bounds
+ if (stream.decode (_tc_CORBA_TypeCode, &_prv_state->tc_content_type_,
+ this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE) // element type
+ {
+ env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
+ return 0;
+ }
+ else
+ {
+ _prv_state->tc_content_type_known_ = CORBA_B_TRUE;
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_content_type_);
+ }
+ break;
+ case tk_alias:
+ {
+ if (!stream.skip_string() // typeID
+ || !stream.skip_string() // name
+ || stream.decode (_tc_CORBA_TypeCode,
+ &_prv_state->tc_content_type_, this, env) !=
+ CORBA_TypeCode::TRAVERSE_CONTINUE)
+ {
+ env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
+ return 0;
+ }
+ else
+ {
+ _prv_state->tc_content_type_known_ = CORBA_B_TRUE;
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_content_type_);
+ }
}
+ default:
+ env.exception (new CORBA_BadKind);
+ return 0;
+ }
}
+}
- // return the member label as an any
- CORBA_Any *retval;
+CORBA_ULong
+CORBA_TypeCode::prv_discrim_pad_size (CORBA_Environment &env)
+{
+ CDR stream;
+ size_t discrim_size,
+ overall_align;
- retval = new CORBA_Any (tc, buf, CORBA_B_TRUE);
- tc->Release ();
- return retval;
+ stream.setup_encapsulation (_buffer, (size_t)_length);
+
+ (void) calc_key_union_attributes (&stream, overall_align, discrim_size, env);
+ if (env. exception () == 0)
+ {
+ _prv_state->tc_discrim_pad_size_known_ = CORBA_B_TRUE;
+ _prv_state->tc_discrim_pad_size_ = discrim_size;
+ return discrim_size;
+ }
+ else
+ {
+ return 0;
+ }
}
+// ************ The following are deprecated ****************
// say how many parameters this typecode has; normally a fixed number,
// some are variable length.
@@ -445,10 +962,10 @@ CORBA_TypeCode::ulong_param (CORBA_ULong n,
// Internal hack, used until member_type (), discriminator_type (),
// and content_type () are implemented.
//
-// NOTE special calling convention for CDR::decoder () when we're
+// NOTE special calling convention for stream.decode () when we're
// potentially deencapsulating an indirected typecode: the "data2"
// value indicates that this typecode is the parent. See comments at
-// CDR::decoder () for further details.
+// stream.decode () for further details.
CORBA_TypeCode_ptr
CORBA_TypeCode::typecode_param (CORBA_ULong n,
@@ -484,9 +1001,9 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
case tk_array:
if (n != 0)
break;
- if (CDR::decoder (_tc_CORBA_TypeCode,
+ if (stream.decode (_tc_CORBA_TypeCode,
&tc, this,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
return 0;
@@ -498,7 +1015,7 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
break;
if (!stream.skip_string () // type ID, hidden
|| !stream.skip_string () // typedef name
- || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env)
+ || stream.decode (_tc_CORBA_TypeCode, &tc, this, env)
!= CORBA_TypeCode::TRAVERSE_CONTINUE)
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
@@ -538,7 +1055,7 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
}
if (!stream.skip_string ()
- || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream,
+ || stream.decode (_tc_CORBA_TypeCode, &tc, this,
env)!= CORBA_TypeCode::TRAVERSE_CONTINUE)
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
@@ -556,9 +1073,9 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
if (!stream.skip_string () // type ID, hidden
|| !stream.skip_string () // typedef name
- || CDR::decoder (_tc_CORBA_TypeCode,
+ || stream.decode (_tc_CORBA_TypeCode,
&tc, this,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) // TC
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE) // TC
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
return 0;
@@ -583,7 +1100,7 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
for (i = 0; i < temp; i++)
{
- if (CDR::decoder (tc, &scratch, this, &stream, env) // member label
+ if (stream.decode (tc, &scratch, this, env) // member label
!= CORBA_TypeCode::TRAVERSE_CONTINUE
|| !stream.skip_string () // member name
|| !skip_typecode (stream))
@@ -595,9 +1112,9 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
}
// member label
- if (CDR::decoder (tc,
+ if (stream.decode (tc,
&scratch, this,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE
|| !stream.skip_string ()) // member name
{
tc->Release ();
@@ -606,9 +1123,9 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
}
tc->Release ();
- if (CDR::decoder (_tc_CORBA_TypeCode,
+ if (stream.decode (_tc_CORBA_TypeCode,
&tc, this,
- &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
+ env) != CORBA_TypeCode::TRAVERSE_CONTINUE)
{
env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO));
return 0;
@@ -620,37 +1137,50 @@ CORBA_TypeCode::typecode_param (CORBA_ULong n,
return 0;
}
-// Return the type ID (RepositoryId) for the TypeCode; it may be empty.
-//
-// NOTE the string returned here is owned by the typecode!!
-
-CORBA_String
-CORBA_TypeCode::id (CORBA_Environment &env) const
+// skip a typecode encoding in a given CDR stream
+// This is just a helper function
+CORBA_Boolean
+CORBA_TypeCode::skip_typecode (CDR &stream)
{
- env.clear ();
+ CORBA_ULong kind;
+ CORBA_ULong temp;
- switch (_kind)
+ if (stream.get_ulong (kind) && (kind < TC_KIND_COUNT || kind == ~0))
{
- // These are all complex typecodes, which have as their first
- // parameter (number zero) a repository/type ID string encoded
- // per CDR rules. That means we can just return a pointer to
- // that string directly!
- case tk_objref:
- case tk_struct:
- case tk_union:
- case tk_enum:
- case tk_alias:
- case tk_except:
- return (CORBA_String) (_buffer
- + 4 // skip byte order flag and padding
- + 4 // skip (strlen + 1)
- );
+ switch (kind)
+ {
+ // Most TypeCodes have empty parameter lists, nothing to skip
+ default:
+ break;
- // No other typecodes ever have type IDs
- default:
- env.exception (new CORBA_BAD_PARAM (COMPLETED_NO));
- return 0;
+ // Some have single integer parameters, easy to skip. Some have
+ // preallocated constants that could be used.
+ case tk_string:
+ case tk_wstring:
+ case ~0:
+ return stream.get_ulong (temp);
+
+ // The rest have "complex" parameter lists that are
+ // encoded as bulk octets ... just skip them.
+ case tk_objref:
+ case tk_struct:
+ case tk_union:
+ case tk_enum:
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ case tk_except:
+ return stream.get_ulong (temp) != CORBA_B_FALSE
+ && stream.skip_bytes (temp) != CORBA_B_FALSE;
+ }
+
+ return CORBA_B_TRUE;
+ }
+ else
+ {
+ return CORBA_B_FALSE;
}
}
+
diff --git a/TAO/IIOP/lib/typecode.h b/TAO/IIOP/lib/typecode.h
index 726c4a1e783..f7128bbcccd 100644
--- a/TAO/IIOP/lib/typecode.h
+++ b/TAO/IIOP/lib/typecode.h
@@ -29,6 +29,9 @@
# define TAO_TYPECODE_H
# include "ace/OS.h"
+# include "any.h"
+
+class CDR;
enum CORBA_TCKind
{
@@ -100,35 +103,81 @@ void CORBA_release (CORBA_TypeCode_ptr);
CORBA_Boolean CORBA_is_nil (CORBA_TypeCode_ptr obj);
extern const IID IID_CORBA_TypeCode;
+class TC_PRV_State;
class ACE_Svc_Export CORBA_TypeCode : public IUnknown
{
+ // = TITLE
+ // The CORBA TypeCode class. It maintains the in-memory representation of any
+ // OMG CORBA IDL data type.
+ //
+ // = DESCRIPTION
+ // Implements the CORBA::TypeCode interface specified by CORBA 2.0 spec
public:
+ // Special Note:
+ // Many of the methods on this class should have been "const"
+ // methods. However, we are not able to do so due to our precompute
+ // optimizations that change the state of the object whenever a quantify is
+ // not yet precomputed
+
+ static CORBA_TypeCode_ptr _duplicate(CORBA_TypeCode_ptr tc);
+ static CORBA_TypeCode_ptr _nil();
+
+ CORBA_Boolean equal (const CORBA_TypeCode_ptr, CORBA_Environment &env) const;
+ // compares two typecodes
+
CORBA_TCKind kind (CORBA_Environment &) const;
- // For all TypeCode kinds
+ // For all TypeCode kinds, returns the "kind" of the typecode
- CORBA_ULong param_count (CORBA_Environment &) const;
- // Deprecated, CORBA 1.2, not fully usable
+ const CORBA_String id (CORBA_Environment &) const;
+ // For tk_{objref,struct,union,enum,alias,except}. Returns the repository ID,
+ // raises BadKind.
- CORBA_String id (CORBA_Environment &) const;
- // For tk_{objref,struct,union,enum,alias,except}
+ const CORBA_String name (CORBA_Environment &) const;
+ // returns name (), raises (BadKind)
+
+ CORBA_ULong member_count (CORBA_Environment &) const;
+ // returns member_count (), raises (BadKind). Useful for tk_struct, tk_union,
+ // tk_enum, tk_alias, and tk_except.
+
+ const CORBA_String member_name (CORBA_ULong index, CORBA_Environment &) const;
+ // returns member_name (...), raises (BadKind, Bounds); Useful for tk_struct, tk_union,
+ // tk_enum, tk_alias, and tk_except.
+
+ CORBA_TypeCode_ptr member_type (CORBA_ULong index, CORBA_Environment &) const;
+ // returns member_type (...), raises (BadKind, Bounds); Useful for tk_struct,
+ // tk_union, and tk_except
CORBA_Any_ptr member_label (CORBA_ULong n, CORBA_Environment&) const;
- // Other CORBA 2.0 IFR updates -- not yet implemented/needed
- //
- // String name () raises (BadKind);
- // ULong member_count () raises (BadKind);
- // String member_name (...) raises (BadKind, Bounds);
- // TypeCode_ptr member_type (...) raises (BadKind, Bounds);
+ // For tk_union. Returns the label. Raises BadKind, Bounds.
+
+ CORBA_TypeCode_ptr discriminator_type (CORBA_Environment &) const;
+ // returns the discriminator type for tk_union. raises (BadKind);
- // TypeCode_ptr discriminator_type () raises (BadKind);
- // Long default_index () raises (BadKind);
+ CORBA_Long default_index (CORBA_Environment &) const;
+ // returns the default index for the tk_union. Raises (BadKind);
- // Long length () raises (BadKind);
- // TypeCode_ptr content_type () raises (BadKind);
+ CORBA_ULong length (CORBA_Environment &) const;
+ // returns length, raises (BadKind). Used for tk_string, tk_sequence, and
+ // tk_array
+
+ CORBA_TypeCode_ptr content_type (CORBA_Environment &) const;
+ // returns the content type (element type). Raises (BadKind); Useful for
+ // tk_sequence, tk_array, and tk_alias
+
+ CORBA_ULong TAO_discrim_pad_size(CORBA_Environment &);
+ // Calculates the padded size of discriminant type
+ // TAO Extension
+
+ // Following three are deprecated
+
+ CORBA_ULong param_count (CORBA_Environment &) const;
+ // Deprecated, CORBA 1.2, not fully usable. Returns the number of parameters
+ // that the typecode takes.
CORBA_ULong ulong_param (CORBA_ULong n,
CORBA_Environment &) const;
+
CORBA_TypeCode_ptr typecode_param (CORBA_ULong n,
CORBA_Environment &) const;
// Internal utilities, pending CORBA 2.0 IFR APIs; just enough
@@ -208,12 +257,13 @@ public:
// recursion.
size_t size (CORBA_Environment &env);
- size_t alignment (CORBA_Environment &env);
+ // returns the size. Used by the IIOP marshaling engine.
- static CORBA_TypeCode_ptr _nil (void);
+ size_t alignment (CORBA_Environment &env);
+ // returns the alignment requirements for this typecode. used by the IIOP
+ // marshaling engine.
// Stuff required for COM IUnknown support
-
ULONG __stdcall AddRef (void);
ULONG __stdcall Release (void);
HRESULT __stdcall QueryInterface (REFIID riid,
@@ -234,9 +284,68 @@ public:
// reference to that parent to ensure its memory is not freed
// inappropriately.
+ static CORBA_Boolean CORBA_TypeCode::skip_typecode (CDR &stream);
+ // skip a typecode encoding in a given CDR stream
+ // This is just a helper function
+
private:
+ // All the private/helper methods
+
+ CORBA_Boolean prv_equal (CORBA_TypeCode_ptr tc, CORBA_Environment &env) const;
+ // compares the typecodes
+
+ const CORBA_String prv_id (CORBA_Environment &) const;
+ // For tk_{objref,struct,union,enum,alias,except}. Returns the repository ID,
+ // raises BadKind.
+
+ const CORBA_String prv_name (CORBA_Environment &) const;
+ // returns name (), raises (BadKind)
+
+ CORBA_ULong prv_member_count (CORBA_Environment &) const;
+ // returns member_count (), raises (BadKind). Useful for tk_struct, tk_union,
+ // tk_enum, tk_alias, and tk_except.
+
+ CORBA_TypeCode_ptr prv_member_type (CORBA_ULong index,
+ CORBA_Environment &) const;
+ // returns member_type (...), raises (BadKind, Bounds); Useful for tk_struct,
+ // tk_union, and tk_except
+
+ // CORBA_TypeCode_ptr prv_member_label (CORBA_ULong index,
+ // CORBA_Environment &) const;
+ // returns member_label (...), raises (BadKind, Bounds); Useful for tk_union
+
+ CORBA_Any_ptr prv_member_label (CORBA_ULong n, CORBA_Environment&) const;
+ // For tk_union. Returns the label. Raises BadKind, Bounds.
+
+ CORBA_TypeCode_ptr prv_discriminator_type (CORBA_Environment &) const;
+ // returns the discriminator type for tk_union. raises (BadKind);
+
+ CORBA_Long prv_default_index (CORBA_Environment &) const;
+ // returns the default index for the tk_union. Raises (BadKind);
+
+ CORBA_Long prv_length (CORBA_Environment &) const;
+ // returns length, raises (BadKind). Used for tk_string, tk_sequence, and
+ // tk_array
+
+ CORBA_TypeCode_ptr prv_content_type (CORBA_Environment &) const;
+ // returns the content type (element type). Raises (BadKind); Useful for
+ // tk_sequence, tk_array, and tk_alias
+
+ size_t prv_size (CORBA_Environment &env);
+ // returns the size. Used by the IIOP marshaling engine.
+
+ size_t prv_alignment (CORBA_Environment &env);
+ // returns the alignment requirements for this typecode. used by the IIOP
+ // marshaling engine.
+
+ CORBA_ULong prv_discrim_pad_size(CORBA_Environment &);
+ // Calculates the padded size of discriminant type
+ // TAO Extension
+
ACE_Thread_Mutex lock_;
+
u_int _refcount;
+ // if refcount reaches 0, free this typecode
CORBA_Boolean _orb_owns;
// If "orb_owns" is false, the value is a constant typecode with
@@ -246,6 +355,15 @@ private:
//
// "orb owns" is always set, except for TypeCode constants.
+ TC_PRV_State *_prv_state;
+ // maintains precomputed state. We need a separate class that maintains the
+ // precomputed state since most of the TypeCode class operations keep the
+ // state of the object constant. However, for the purpose of precomputation,
+ // we need to update the state. We cannot update state directly in the
+ // TypeCode class as that defeats the constness. However, we can keep an
+ // object in our typecode class that remains constant, but we can update its
+ // state.
+
// = No copy constructor or assignment operator supported;
// Use TypeCode_ptr values, duplicate(), release().
@@ -253,6 +371,41 @@ private:
CORBA_TypeCode &operator = (const CORBA_TypeCode &src);
};
+// private state of the TypeCode. Used to store precomputed values
+class TC_PRV_State
+{
+public:
+ TC_PRV_State();
+
+ // data members that indicate if the desired quantify was precomputed or not.
+ CORBA_Boolean tc_id_known_;
+ CORBA_Boolean tc_name_known_;
+ CORBA_Boolean tc_member_count_known_;
+ CORBA_Boolean tc_member_type_list_known_;
+ CORBA_Boolean tc_member_label_list_known_;
+ CORBA_Boolean tc_discriminator_type_known_;
+ CORBA_Boolean tc_default_index_used_known_;
+ CORBA_Boolean tc_length_known_;
+ CORBA_Boolean tc_content_type_known_;
+ CORBA_Boolean tc_size_known_;
+ CORBA_Boolean tc_alignment_known_;
+ CORBA_Boolean tc_discrim_pad_size_known_;
+
+ // These data members store the precomputed values
+ CORBA_String tc_id_;
+ CORBA_String tc_name_;
+ CORBA_ULong tc_member_count_;
+ CORBA_TypeCode_ptr *tc_member_type_list_;
+ CORBA_Any_ptr *tc_member_label_list_;
+ CORBA_TypeCode_ptr tc_discriminator_type_;
+ CORBA_Long tc_default_index_used_;
+ CORBA_ULong tc_length_;
+ CORBA_TypeCode_ptr tc_content_type_;
+ CORBA_ULong tc_size_;
+ CORBA_ULong tc_alignment_;
+ CORBA_ULong tc_discrim_pad_size_;
+};
+
// TypeCode constants, which are always accessible in all ORB runtimes.
extern const CORBA_TypeCode_ptr _tc_CORBA_Null;
@@ -282,4 +435,25 @@ extern const CORBA_TypeCode_ptr _tc_CORBA_Principal;
extern const CORBA_TypeCode_ptr _tc_CORBA_Object;
+// In this case, we make a substantial exception to how inline
+// files are included. Normally, we would conditionally include the
+// inline file iff __ACE_INLINE__ is defined. But, in the original,
+// highly optimized Sun IIOP code, much of what is in the inline file
+// was here ready to be inlined at a moments notice and ALWAYS. So,
+// in this ONE file, we defer to David Brownell's considerable prowess
+// at creating typecode interpreters as well as to the ACE convention
+// of placing inline functions into separate files.
+
+# if !defined(__ACE_INLINE__)
+# undef ACE_INLINE
+# define ACE_INLINE inline
+# define do_undef_on_ACE_INLINE
+# endif
+# include "typecode.i"
+# if defined(do_undef_on_ACE_INLINE)
+# undef do_undef_on_ACE_INLINE
+# undef ACE_INLINE
+# define ACE_INLINE
+# endif
+
#endif /* TAO_TYPECODE_H */
diff --git a/TAO/IIOP/lib/typecode.i b/TAO/IIOP/lib/typecode.i
new file mode 100644
index 00000000000..007c170ec44
--- /dev/null
+++ b/TAO/IIOP/lib/typecode.i
@@ -0,0 +1,309 @@
+ACE_INLINE CORBA_TypeCode_ptr
+CORBA_TypeCode::_duplicate(CORBA_TypeCode_ptr tc)
+{
+ if (tc)
+ {
+ tc->AddRef();
+ }
+ return tc;
+}
+
+// Constructor for CONSTANT typecodes with empty parameter lists.
+// These are only created once, and those constants are shared.
+
+ACE_INLINE CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind)
+ : _length (0),
+ _buffer (0),
+ _kind (kind),
+ _parent (0),
+ _refcount (1),
+ _orb_owns (CORBA_B_FALSE),
+ _prv_state (new TC_PRV_State)
+{
+}
+
+// Destructor. For "indirected" typecodes, the typecode reuses the
+// buffer owned by its parent, and so rather than deleting the buffer
+// it just drops the parent's refcount.
+
+ACE_INLINE CORBA_TypeCode::~CORBA_TypeCode (void)
+{
+ delete _prv_state;
+
+ if (_parent)
+ _parent->Release ();
+ else if (_orb_owns)
+ delete _buffer;
+}
+
+// Returns true if the two typecodes are identical
+ACE_INLINE CORBA_Boolean
+CORBA_TypeCode::equal(const CORBA_TypeCode_ptr tc,
+ CORBA_Environment &env) const
+{
+ if (this->_kind != tc->kind(env))
+ {
+ // simple case
+ return CORBA_B_FALSE;
+ }
+ else
+ {
+ return this->prv_equal(tc, env);
+ }
+}
+
+// just fetch the 'kind' field out of the typecode
+ACE_INLINE CORBA_TCKind
+CORBA_TypeCode::kind (CORBA_Environment &env) const
+{
+ env.clear ();
+ return _kind;
+}
+
+// returns the Repository ID
+ACE_INLINE const CORBA_String
+CORBA_TypeCode::id(CORBA_Environment &env) const
+{
+ env.clear();
+
+ // if already precomputed
+ if (_prv_state->tc_id_known_)
+ {
+ return _prv_state->tc_id_;
+ }
+ else
+ {
+ return prv_id(env);
+ }
+}
+
+// returns the string name
+ACE_INLINE const CORBA_String
+CORBA_TypeCode::name(CORBA_Environment &env) const
+{
+ env.clear();
+
+ // if already precomputed
+ if (_prv_state->tc_name_known_)
+ {
+ return _prv_state->tc_name_;
+ }
+ else
+ {
+ return prv_name(env);
+ }
+}
+
+// Return the number of members defined by this typecode
+//
+// Applicable to struct, union, enum, alias, and except
+// For the rest of the cases, raises the BadKind exception.
+
+ACE_INLINE CORBA_ULong
+CORBA_TypeCode::member_count (CORBA_Environment &env) const
+{
+ env.clear ();
+
+ // if already precomputed
+ if (_prv_state->tc_member_count_known_)
+ {
+ return _prv_state->tc_member_count_;
+ }
+ else
+ {
+ return prv_member_count(env);
+ }
+}
+
+// Return the i-th member typecode if it exists, else raise an
+// exception. Possible exceptions are BadKind and Bounds.
+//
+// Applicable only to struct, union, and except
+//
+
+ACE_INLINE CORBA_TypeCode_ptr
+CORBA_TypeCode::member_type (CORBA_ULong index, CORBA_Environment &env) const
+{
+ if (_prv_state->tc_member_count_known_ && _prv_state->tc_member_type_list_known_)
+ {
+ if (index >= 0 && index < _prv_state->tc_member_count_)
+ {
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_member_type_list_[index]);
+ }
+ else
+ {
+ env.exception(new CORBA_Bounds());
+ return 0;
+ }
+ }
+ else
+ {
+ return prv_member_type(index, env);
+ }
+}
+
+
+// Return the label of the i-th member.
+// Applicable only to tk_union
+ACE_INLINE CORBA_Any_ptr
+CORBA_TypeCode::member_label (CORBA_ULong index, CORBA_Environment &env) const
+{
+ if (_prv_state->tc_member_count_known_ && _prv_state->tc_member_label_list_known_)
+ {
+ if (index >= 0 && index < _prv_state->tc_member_count_)
+ {
+ (void)_prv_state->tc_member_label_list_[index]->AddRef();
+ return _prv_state->tc_member_label_list_[index];
+ }
+ else
+ {
+ env.exception(new CORBA_Bounds());
+ return 0;
+ }
+ }
+ else
+ {
+ return prv_member_label(index, env);
+ }
+}
+
+// only applicable to tk_unions
+ACE_INLINE CORBA_TypeCode_ptr
+CORBA_TypeCode::discriminator_type (CORBA_Environment &env) const
+{
+ if (_kind == tk_union)
+ {
+ if (_prv_state->tc_discriminator_type_known_)
+ {
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_discriminator_type_);
+ }
+ else
+ {
+ return prv_discriminator_type(env);
+ }
+ }
+ else
+ {
+ env.exception( new CORBA_BadKind());
+ return (CORBA_TypeCode_ptr)0;
+ }
+}
+
+// only applicable to tk_unions
+ACE_INLINE CORBA_Long
+CORBA_TypeCode::default_index (CORBA_Environment &env) const
+{
+ if (_kind == tk_union)
+ {
+ if (_prv_state->tc_default_index_used_known_)
+ {
+ return _prv_state->tc_default_index_used_;
+ }
+ else
+ {
+ return prv_default_index (env);
+ }
+ }
+ else
+ {
+ env.exception( new CORBA_BadKind());
+ return 0;
+ }
+}
+
+// returns the length. Applicable only to string, sequence, and arrays
+ACE_INLINE CORBA_ULong
+CORBA_TypeCode::length (CORBA_Environment &env) const
+{
+ switch (_kind)
+ {
+ case tk_sequence:
+ case tk_array:
+ case tk_string:
+ case tk_wstring:
+ if (_prv_state->tc_length_known_)
+ {
+ return _prv_state->tc_length_;
+ }
+ else
+ {
+ return prv_length(env);
+ }
+ default:
+ env.exception( new CORBA_BadKind());
+ return 0;
+ }
+}
+
+// returns the length. Applicable only to string, sequence, and arrays
+ACE_INLINE CORBA_TypeCode_ptr
+CORBA_TypeCode::content_type (CORBA_Environment &env) const
+{
+ switch (_kind)
+ {
+ case tk_sequence:
+ case tk_array:
+ case tk_alias:
+ if (_prv_state->tc_content_type_known_)
+ {
+ return CORBA_TypeCode::_duplicate(_prv_state->tc_content_type_);
+ }
+ else
+ {
+ return prv_content_type(env);
+ }
+ default:
+ env.exception( new CORBA_BadKind());
+ return 0;
+ }
+}
+
+// calculate size of the typecode
+ACE_INLINE size_t
+CORBA_TypeCode::size (CORBA_Environment &env)
+{
+ if (_prv_state->tc_size_known_)
+ {
+ return _prv_state->tc_size_;
+ }
+ else
+ {
+ return prv_size (env);
+ }
+}
+
+// calculate alignment requirements of the typecode
+ACE_INLINE size_t
+CORBA_TypeCode::alignment (CORBA_Environment &env)
+{
+ if (_prv_state->tc_alignment_known_)
+ {
+ return _prv_state->tc_alignment_;
+ }
+ else
+ {
+ return prv_alignment (env);
+ }
+}
+
+// compute the padded size of the discriminant
+ACE_INLINE CORBA_ULong
+CORBA_TypeCode::TAO_discrim_pad_size (CORBA_Environment &env)
+{
+ if (_kind == tk_union)
+ {
+ if (_prv_state->tc_discrim_pad_size_known_)
+ {
+ return _prv_state->tc_discrim_pad_size_;
+ }
+ else
+ {
+ return prv_discrim_pad_size (env);
+ }
+ }
+ else
+ {
+ env.exception (new CORBA_BadKind());
+ return 0;
+ }
+}