summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog-98c32
-rw-r--r--TAO/tao/Any.cpp790
-rw-r--r--TAO/tao/Any.h362
-rw-r--r--TAO/tao/Any.i293
-rw-r--r--TAO/tao/Arg_Shifter.cpp117
-rw-r--r--TAO/tao/Arg_Shifter.h97
-rw-r--r--TAO/tao/CDR.cpp547
-rw-r--r--TAO/tao/CDR.h379
-rw-r--r--TAO/tao/CDR.i394
-rw-r--r--TAO/tao/NVList.cpp275
-rw-r--r--TAO/tao/NVList.h160
-rw-r--r--TAO/tao/NVList.i63
-rw-r--r--TAO/tao/ORB_Strategies_T.cpp46
-rw-r--r--TAO/tao/ORB_Strategies_T.h45
-rw-r--r--TAO/tao/ORB_Strategies_T.i10
-rw-r--r--TAO/tao/Principal.cpp50
-rw-r--r--TAO/tao/Principal.h60
-rw-r--r--TAO/tao/tao.bld58
18 files changed, 3738 insertions, 40 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c
index d901b80ae3e..12eed9a942e 100644
--- a/TAO/ChangeLog-98c
+++ b/TAO/ChangeLog-98c
@@ -1,16 +1,13 @@
-Sat Mar 21 20:34:39 1998 Sergio Flores <sergio@lambada.cs.wustl.edu>
+Sat Mar 21 11:00:40 1998 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu>
- * tao/connect.cpp (open): fixed a bug due to wrong parens
- location.
- * tests/Cubit/TAO/MT_Cubit/server.cpp:
- * tests/Cubit/TAO/MT_Cubit/Util_Thread.cpp:
- * tests/Cubit/TAO/MT_Cubit/Task_Client.h:
- * tests/Cubit/TAO/MT_Cubit/Task_Client.cpp: added option to
- disable use of the name service. hacked the code for platforms
- that don't support floating point math. Added Quantify start/stop
- primitives around CORBA calls.
+ * tao: Renamed a bunch of files so that the names and
+ capitalization matches precisely.
-Sat Mar 21 11:00:40 1998 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu>
+ * tao/Request.i: Created this file and moved a bunch of inline
+ methods into here.
+
+ * tao: Renamed the corbacom.* files (since we don't support COM
+ anyhow) into CORBA.h and the new CORBA.i and CORBA.cpp files.
* tao/corbacom.h: Moved the CORBA_SEQUENCE stuff back into the
header file since it wasn't linking correctly...
@@ -56,6 +53,19 @@ Sat Mar 21 11:00:40 1998 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu>
* tao/sequence_T.i (replace): Fixed some typos in the template
code. Thanks to Ben Eng <ben@jetpen.com> for reporting these.
+Sat Mar 21 20:34:39 1998 Sergio Flores <sergio@lambada.cs.wustl.edu>
+
+ * tao/connect.cpp (open): fixed a bug due to wrong parens
+ location.
+
+ * tests/Cubit/TAO/MT_Cubit/server.cpp:
+ * tests/Cubit/TAO/MT_Cubit/Util_Thread.cpp:
+ * tests/Cubit/TAO/MT_Cubit/Task_Client.h:
+ * tests/Cubit/TAO/MT_Cubit/Task_Client.cpp: added option to
+ disable use of the name service. hacked the code for platforms
+ that don't support floating point math. Added Quantify start/stop
+ primitives around CORBA calls.
+
Sat Mar 21 17:55:40 1998 Michael Kircher <mk1@cs.wustl.edu>
* orbsvcs/test/Simulator/NavWeap.idl: removed typo
diff --git a/TAO/tao/Any.cpp b/TAO/tao/Any.cpp
new file mode 100644
index 00000000000..eb7ab852c57
--- /dev/null
+++ b/TAO/tao/Any.cpp
@@ -0,0 +1,790 @@
+// @ (#) $Id$
+
+#include "tao/corba.h"
+
+CORBA::TypeCode_ptr
+CORBA_Any::type (void) const
+{
+ return this->type_;
+}
+
+const void *
+CORBA_Any::value (void) const
+{
+ return this->value_;
+}
+
+// Default "Any" constructor -- initializes to nulls per the
+// OMG C++ mapping.
+
+// NOTE: null (zero) typecode pointers are also treated as the null
+// typecode ...
+
+CORBA_Any::CORBA_Any (void)
+ : type_ (CORBA::_tc_null),
+ value_ (0),
+ orb_owns_data_ (CORBA::B_FALSE),
+ refcount_ (1)
+{
+}
+
+// The more common "Any" constructor has its own copy of a typecode,
+// and either holds or "consumes" an arbitrary data value satisfying
+// the normal binary interface rules.
+
+CORBA_Any::CORBA_Any (CORBA::TypeCode_ptr tc,
+ void *value,
+ CORBA::Boolean orb_owns_data)
+ : type_ (tc),
+ value_ (value),
+ orb_owns_data_ (orb_owns_data),
+ refcount_ (1)
+{
+ tc->AddRef ();
+}
+
+// Helper routine for "Any" copy constructor ...
+//
+// "Deep Copy" from source to dest. Memory is always there to be
+// copied to ... if this calls itself recursively, it ensures that
+// this remains true (only really an issue for sequences) .
+//
+// This shows the main reason to pass two values to the "visit"
+// function used by the TypeCode interpreter: it allows the copy to be
+// made without using any additional temporary memory. Most other
+// such "visit" routines use only a single value. This is also
+// slightly atypical in that it doesn't use the "context".
+
+static CORBA::TypeCode::traverse_status
+deep_copy (CORBA::TypeCode_ptr tc,
+ const void *source,
+ const void *dest,
+ void *, // no context
+ CORBA::Environment &env)
+{
+ CORBA::TypeCode::traverse_status retval;
+ CORBA::TCKind my_kind;
+
+ if (!tc)
+ {
+ env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO) );
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ my_kind = tc->kind (env);
+
+ if (env.exception_type () != CORBA::NO_EXCEPTION)
+ return CORBA::TypeCode::TRAVERSE_STOP;
+
+ // 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.
+ //
+ // See the TypeCode interpreter code for more details about the
+ // representational assumptions here.
+
+ retval = CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ switch (my_kind)
+ {
+ case CORBA::tk_null:
+ case CORBA::tk_void:
+ break;
+
+ case CORBA::tk_char:
+ case CORBA::tk_octet:
+ *(CORBA::Octet *) dest = *(CORBA::Octet *) source;
+ break;
+
+ case CORBA::tk_short:
+ case CORBA::tk_ushort:
+ *(CORBA::Short *) dest = *(CORBA::Short *) source;
+ break;
+
+ case CORBA::tk_wchar:
+ *(CORBA::WChar *) dest = *(CORBA::WChar *) source;
+ break;
+
+ case CORBA::tk_long:
+ case CORBA::tk_ulong:
+ case CORBA::tk_float:
+ *(CORBA::Long *) dest = *(CORBA::Long *) source;
+ break;
+
+ case CORBA::tk_longlong:
+ case CORBA::tk_ulonglong:
+ case CORBA::tk_double:
+ *(CORBA::LongLong *) dest = *(CORBA::LongLong *) source;
+ break;
+
+ case CORBA::tk_longdouble:
+ *(CORBA::LongDouble *) dest = *(CORBA::LongDouble *) source;
+ break;
+
+ case CORBA::tk_boolean:
+ *(CORBA::Boolean *) dest = *(CORBA::Boolean *) source;
+ break;
+
+ case CORBA::tk_any:
+ (void) new (dest) CORBA_Any (*(CORBA_Any*) source);
+ break;
+
+ case CORBA::tk_TypeCode:
+ if ((*(CORBA::TypeCode_ptr *) source) != 0)
+ dest = source;
+ else
+ dest = CORBA::_tc_null;
+ ((CORBA::TypeCode_ptr) dest)->AddRef ();
+ break;
+
+ case CORBA::tk_Principal:
+ {
+ CORBA::Principal_ptr src, dst;
+
+ src = *(CORBA::Principal_ptr *) source;
+ // @@ Andy, please make sure to check for memory failure.
+ dst = *(CORBA::Principal_ptr *) dest = new CORBA::Principal;
+
+ // 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)
+ {
+ // @@ Andy, please make sure to check for memory failure.
+ dst->id.buffer = new CORBA::Octet [(unsigned) dst->id.length];
+ ACE_OS::memcpy (dst->id.buffer, src->id.buffer,
+ (size_t) dst->id.length);
+ }
+ else
+ dst->id.buffer = 0;
+ }
+ break;
+
+ case CORBA::tk_objref:
+ *(CORBA::Object_ptr *) dest =
+ CORBA::Object::_duplicate (*(CORBA::Object_ptr *) source);
+ break;
+
+ case CORBA::tk_sequence:
+ {
+ CORBA::OctetSeq *src, *dst;
+ CORBA::TypeCode_ptr tcp;
+ size_t size;
+
+ // Rely on binary format of sequences -- all are the same
+ // except for the type pointed to by "buffer"
+
+ src = (CORBA::OctetSeq *) source;
+ dst = (CORBA::OctetSeq *) dest;
+
+ assert (src->length <= UINT_MAX);
+ dst->length = dst->maximum = src->length;
+
+ // Get the size of each "buffer" element
+
+ tcp = tc->typecode_param (0, env);
+
+ if (env.exception () != 0)
+ {
+ retval = CORBA::TypeCode::TRAVERSE_STOP;
+ break;
+ }
+
+ size = tcp->size (env);
+
+ if (env.exception () != 0)
+ {
+ retval = CORBA::TypeCode::TRAVERSE_STOP;
+ break;
+ }
+ tcp->Release ();
+
+ // Now allocate a new (uninitialized) buffer of the right size
+ // to hold that many elements ... fall through and let a
+ // general traverse fill in those buffer elements.
+
+ size *= (size_t) src->length;
+ dst->buffer = new CORBA::Octet[size];
+ }
+ // FALLTHROUGH
+
+ case CORBA::tk_struct:
+ case CORBA::tk_union:
+ case CORBA::tk_array:
+ case CORBA::tk_alias:
+ return tc->traverse (source,
+ dest,
+ (CORBA::TypeCode::VisitRoutine) deep_copy,
+ 0,
+ env);
+
+ case CORBA::tk_except:
+ // 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, the traverse code
+ // ignores it completely.
+
+ *(CORBA::TypeCode_ptr *) dest = *(CORBA::TypeCode_ptr *) source;
+ (void) (*(CORBA::TypeCode_ptr *) dest)->AddRef ();
+
+ return tc->traverse (source,
+ dest,
+ (CORBA::TypeCode::VisitRoutine) deep_copy,
+ 0,
+ env);
+
+ case CORBA::tk_enum:
+ *(int *) dest = *(int *) source;
+ break;
+
+ case CORBA::tk_string:
+ *(CORBA::String *) dest =
+ CORBA::string_copy (*(CORBA::String *) source);
+ break;
+
+ case CORBA::tk_wstring:
+ *(CORBA::WString *) dest =
+ CORBA::wstring_copy (*(CORBA::WString *) source);
+ break;
+
+ default:
+ dmsg ("deep copy default case ?");
+ env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO) );
+ retval = CORBA::TypeCode::TRAVERSE_STOP;
+ break;
+ }
+ return retval;
+}
+
+// Copy constructor for "Any".
+
+CORBA_Any::CORBA_Any (const CORBA_Any &src)
+ : type_ (src.type_ != 0 ? src.type_ : CORBA::_tc_null),
+ orb_owns_data_ (CORBA::B_TRUE),
+ refcount_ (1)
+{
+ CORBA::Environment env;
+ size_t size;
+
+ this->type_->AddRef ();
+
+ size = this->type_->size (env); // XXX check error status
+ this->value_ = (char *) calloc (1, size);
+
+#if 0
+ // @@ Andy, can we remove this code if its not needed?
+ (void) this->type_->traverse (src.value_,
+ value_,
+ (CORBA::TypeCode::VisitRoutine) deep_copy,
+ 0,
+ env);
+#endif /* replaced by our optimizations */
+
+ (void) DEEP_COPY (this->type_, src.value_, this->value_, env);
+}
+
+//a&a : Added on 14 feb 1998
+
+CORBA_Any &
+CORBA_Any::operator= (const CORBA_Any &src)
+{
+ CORBA::Environment env;
+ size_t size;
+
+ if (this == &src)
+ {
+ this->AddRef ();
+ return *this;
+ }
+
+ if (this->orb_owns_data_)
+ DEEP_FREE (this->type_, this->value_, 0, env);
+
+ // @@ Andy, can we remove this code if it's not needed?
+ // this->Release (); // release any value + typecode we may have
+
+ // Now copy the contents of the source to ourselves.
+ this->type_ = (src.type_) != 0 ? src.type_ : CORBA::_tc_null;
+
+ this->orb_owns_data_ = CORBA::B_TRUE;
+ this->refcount_ = 1;
+
+ this->type_->AddRef ();
+
+ size = this->type_->size (env); // XXX check error status
+ this->value_ = (char *) calloc (1, size);
+ (void) DEEP_COPY (this->type_, src.value_, this->value_, env);
+ return *this;
+}
+
+// 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 recurses.
+//
+// This is one of the simplest typecode interpreter callbacks, since
+// in most cases it does nothing. Also, it uses neither the second
+// value nor the context parameter.
+
+static CORBA::TypeCode::traverse_status
+deep_free (CORBA::TypeCode_ptr tc,
+ const void *value,
+ const void *, // value2 unused
+ void *, // context unused
+ CORBA::Environment &env)
+{
+ // Don't do anything if the value is a null pointer.
+
+ if (!value)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ CORBA::TypeCode::traverse_status retval;
+ CORBA::TCKind my_kind;
+
+ if (!tc)
+ {
+ env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO) );
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ my_kind = tc->kind (env);
+
+ if (env.exception_type () != CORBA::NO_EXCEPTION)
+ return CORBA::TypeCode::TRAVERSE_STOP;
+
+ // Free only embedded pointers ... which don't exist in most
+ // primitive types.
+
+ retval = CORBA::TypeCode::TRAVERSE_CONTINUE;
+ switch (my_kind)
+ {
+ case CORBA::tk_struct:
+ case CORBA::tk_union:
+ case CORBA::tk_array:
+ case CORBA::tk_alias:
+ return tc->traverse (value,
+ 0,
+ (CORBA::TypeCode::VisitRoutine) deep_free,
+ 0,
+ env);
+
+ // 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.
+ //
+ case CORBA::tk_except:
+ return retval;
+
+ case CORBA::tk_sequence:
+ retval = tc->traverse (value,
+ 0,
+ (CORBA::TypeCode::VisitRoutine) deep_free,
+ 0,
+ env);
+ // @@ This better be allocated via new[].
+ //
+ // @@ (ANDY) I'm not sure what to do here...should I delete the
+ // value? It seems that the DTOR for the sequence will insure
+ // that this buffer goes away.
+ delete [] ((CORBA::OctetSeq *) value)->buffer;
+ break;
+
+ case CORBA::tk_TypeCode:
+ if ((*(CORBA::TypeCode_ptr *) value) != 0)
+ (*(CORBA::TypeCode_ptr *) value)->Release ();
+ break;
+
+ case CORBA::tk_Principal:
+ CORBA::release (*(CORBA::Principal_ptr *) value);
+ break;
+
+ case CORBA::tk_objref:
+ CORBA::release (*(CORBA::Object_ptr *) value);
+ break;
+
+ case CORBA::tk_string:
+ CORBA::string_free (*(CORBA::String *) value);
+ *(CORBA::String *)value = 0;
+ break;
+
+ case CORBA::tk_wstring:
+ CORBA::wstring_free (*(CORBA::WString *) value);
+ *(CORBA::WString *)value = 0;
+ break;
+
+ case CORBA::tk_any:
+#ifdef __BORLANDC__
+ // XXX BC++ doesn't yet accept explicit calls to destructors
+ // with this syntax. A simple workaround must exist, though;
+ // other explicit destructor calls work.
+
+ dmsg ("Delete Any-in-Any ... memory leak with BC++ 4.5");
+#else
+ ((CORBA_Any *) value)->~CORBA_Any ();
+#endif /* __BORLANDC__ */
+ break;
+
+ default:
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+ }
+
+ if (env.exception_type () != CORBA::NO_EXCEPTION)
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ else
+ return retval;
+}
+
+// Destructor for an "Any" deep-frees memory if needed.
+//
+// NOTE that the assertion below will fire on application programmer
+// errors, such as using AddRef/Release out of sync with the true
+// lifetime of an Any value allocated on the stack. BUT it involves
+// changing the refcounting policy so that it's initialized to zero,
+// not one ... which policy affects the whole source base, and not
+// just this data type. Get to this later.
+
+CORBA_Any::~CORBA_Any (void)
+{
+ CORBA::Environment env;
+
+ // assert (this->refcount_ == 0);
+
+ if (this->orb_owns_data_)
+ // @@ Andy, do we still need the deep_free() function call? If
+ // not, can we remove it?
+ // (void) deep_free (type_, value_, 0, 0, env);
+ DEEP_FREE (this->type_, this->value_, 0, env);
+ // @@ Andy, is the following comment still true? If not, can we remove it?
+
+ // TODO: This crashes the server on NT, apparently the previous
+ // DEEP_FREE does the job and make the delete operator uneeded.
+ // delete value_;
+
+ if (this->type_)
+ this->type_->Release ();
+}
+
+// All-at-once replacement of the contents of an "Any."
+
+void
+CORBA_Any::replace (CORBA::TypeCode_ptr tc,
+ const void *v,
+ CORBA::Boolean orb_owns_data,
+ CORBA::Environment &env)
+{
+ if (this->orb_owns_data_)
+ {
+ // @@ Andy, do we still need the deep_free() function call? If
+ // not, can we remove it?
+ // (void) deep_free (type_, value_, 0, 0, env);
+ if (value_)
+ DEEP_FREE (this->type_, this->value_, 0, env);
+ // @@ Andy, is this delete ok? The one in the destructor is
+ // commented out...
+ delete this->value_;
+ }
+
+ if (this->type_ != 0)
+ this->type_->Release ();
+
+ env.clear ();
+
+ this->type_ = tc;
+ tc->AddRef ();
+ this->value_ = (void *) v;
+ this->orb_owns_data_ = orb_owns_data;
+}
+
+// insertion of from_string
+void
+CORBA_Any::operator<<= (from_string s)
+{
+ // If the inserted string is bounded, we create a typecode.
+ static CORBA::Long _oc_string [] =
+ { // CDR typecode octets
+ TAO_ENCAP_BYTE_ORDER, // native endian + padding; "tricky"
+ 0 // ... unbounded string to start with
+ };
+
+ CORBA::TypeCode_ptr tc = 0;
+ if (s.bound_ > 0)
+ {
+ // Bounded string.
+ _oc_string [1] = s.bound_;
+ ACE_NEW (tc, CORBA::TypeCode (CORBA::tk_string,
+ sizeof _oc_string,
+ (char *) &_oc_string,
+ CORBA::B_TRUE));
+ }
+ else
+ tc = CORBA::_tc_string; // unbounded.
+
+ if (s.nocopy_)
+ this->replace (tc, new char* (s.val_), CORBA::B_TRUE);
+ else // copying
+ this->replace (tc, new char* (CORBA::string_dup (s.val_)),
+ CORBA::B_TRUE);
+}
+
+// Extraction: these are safe and hence we have to check that the
+// typecode of the Any is equal to the one we are trying to extract
+// into
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::Short &s) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_short, env))
+ {
+ s = *(CORBA::Short *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::UShort &s) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_ushort, env))
+ {
+ s = *(CORBA::UShort *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::Long &l) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_long, env))
+ {
+ l = *(CORBA::Long *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::ULong &l) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_ulong, env))
+ {
+ l = *(CORBA::ULong *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::Float &f) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_float, env))
+ {
+ f = *(CORBA::Float *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::Double &d) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_double, env))
+ {
+ d = *(CORBA::Double *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (CORBA::Any &a) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_any, env))
+ {
+ a = *(CORBA::Any *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (char *&s) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_string, env))
+ {
+ s = *(char **) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+// = extraction into the special types
+
+CORBA::Boolean
+CORBA_Any::operator>>= (to_boolean b) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_boolean, env))
+ {
+ b.ref_ = *(CORBA::Boolean *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (to_octet o) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_octet, env))
+ {
+ o.ref_ = *(CORBA::Octet *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (to_char c) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_char, env))
+ {
+ c.ref_ = *(CORBA::Char *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (to_string s) const
+{
+ CORBA::Environment env;
+
+ // The typecode must be equal. Since we do not readily have access
+ // to the typecode of the string into which we want to retrieve, we
+ // emulate the behavior of "equal"
+ if (this->type_->kind (env) == CORBA::tk_string)
+ {
+ CORBA::ULong bound = this->type_->length (env);
+ if (s.bound_ == bound) // bounds are same
+ {
+ s.val_ = *(char **) this->value_;
+ return CORBA::B_TRUE;
+ }
+ }
+
+ // Otherwise.
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CORBA_Any::operator>>= (to_object obj) const
+{
+ CORBA::Environment env;
+
+ if (this->type_->equal (CORBA::_tc_Object, env))
+ {
+ obj.ref_ = *(CORBA::Object_ptr *) this->value_;
+ return CORBA::B_TRUE;
+ }
+ else
+ return CORBA::B_FALSE;
+}
+
+CORBA::ULong
+CORBA_Any::AddRef (void)
+{
+ return ++refcount_;
+}
+
+CORBA::ULong
+CORBA_Any::Release (void)
+{
+ {
+ ACE_ASSERT (this != 0);
+
+ if (--refcount_ != 0)
+ return refcount_;
+ }
+
+ delete this;
+ return 0;
+}
+
+// ----------------------------------------------------------------------
+// Any_var type
+// ----------------------------------------------------------------------
+
+CORBA::Any_var &
+CORBA_Any_var::operator= (CORBA::Any *p)
+{
+ if (this->ptr_ != p)
+ {
+ if (this->ptr_ != 0)
+ delete (this->ptr_);
+
+ this->ptr_ = p;
+ }
+ return *this;
+}
+
+CORBA::Any_var &
+CORBA_Any_var::operator= (const CORBA::Any_var& r)
+{
+ if (this->ptr_ != 0)
+ delete (this->ptr_);
+
+ this->ptr_ = new CORBA::Any (*r.ptr_);
+ return *this;
+}
diff --git a/TAO/tao/Any.h b/TAO/tao/Any.h
new file mode 100644
index 00000000000..1f9b47b57bd
--- /dev/null
+++ b/TAO/tao/Any.h
@@ -0,0 +1,362 @@
+// This may look like C, but it's really -*- C++ -*-
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// Any.h
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems, Inc.
+// and Aniruddha Gokhale.
+//
+// ============================================================================
+
+#if !defined (TAO_ANY_H)
+#define TAO_ANY_H
+
+class TAO_Export CORBA_Any
+{
+ // = TITLE
+ // Class "Any" can wrap values of any type, with the assistance
+ // of a TypeCode to describe that type.
+ //
+ // = DESCRIPTION
+ // This includes three constructors, a destructor, and a "replace"
+ // method for the "Any" data type. "Any" values pair a pointer to
+ // a data structure in the native binary representation (e.g. C
+ // struct) with a TypeCode that describes that data structure.
+ //
+ // The copy constructor and the destructor each use the TypeCode
+ // interpreter with specialized "visit" callback routines. The
+ // "visit" routines are used respectively to make "deep copies"
+ // and perform "deep frees" of the aritrary values as described by
+ // the "Any" value's typecode.
+ //
+ // Note that these "visit" routines are called directly, and they
+ // choose whether or not to use the TypeCode interpreter to
+ // examine constituents. In the simple cases, the "visit"
+ // routines can do their work without any further calls; only for
+ // constructed types is the interpreter's knowledge really
+ // required.
+ //
+ // THREADING NOTE: "Any" is a data structure which must be
+ // protected by external critical sections. Like simpler numeric
+ // types, "Any" instances are accessed and modified atomically.
+ // This implementation is reentrant, so that independent "Any"
+ // values may be manipulated concurrently when the underlying
+ // programming environment is itself reentrant.
+public:
+
+ // = Minor codes for exceptional returns
+ enum
+ {
+ UNINITIALIZED_type = 0xf000,
+ VALUE_WITHOUT_TYPE,
+ UNSUPPORTED_OPERATION
+ };
+
+ // = Initialization and termination operations.
+ CORBA_Any (void);
+ // Default constructor.
+
+ CORBA_Any (CORBA::TypeCode_ptr type,
+ void *value = 0,
+ CORBA::Boolean orb_owns_data = CORBA::B_FALSE);
+ // Constructor.
+
+ CORBA_Any (const CORBA_Any &a);
+ // Copy constructor.
+
+ ~CORBA_Any (void);
+ // Destructor.
+
+ CORBA_Any &operator= (const CORBA_Any &);
+ // assignment operator
+
+ // = NOTE: 94-9-14 has assignment operator plus many insertion, as
+ // specified below.
+
+ // =type safe insertion
+
+ void operator<<= (CORBA::Short);
+ // insert a short
+
+ void operator<<= (CORBA::UShort);
+ // insert an unsigned short
+
+ void operator<<= (CORBA::Long);
+ // insert a long
+
+ void operator<<= (CORBA::ULong);
+ // insert an unsigned long
+
+ void operator<<= (CORBA::Float);
+ // insert a float
+
+ void operator<<= (CORBA::Double);
+ // insert a double
+
+ void operator<<= (const CORBA_Any&);
+ // insert an Any
+
+ void operator<<= (const char*);
+ // insert unbounded strings
+
+ // =type safe extraction
+
+ CORBA::Boolean operator>>= (CORBA::Short&) const;
+ // extract a short
+
+ CORBA::Boolean operator>>= (CORBA::UShort&) const;
+ // extract an unsigned short
+
+ CORBA::Boolean operator>>= (CORBA::Long&) const;
+ // extract a long
+
+ CORBA::Boolean operator>>= (CORBA::ULong&) const;
+ // extract an unsigned long
+
+ CORBA::Boolean operator>>= (CORBA::Float&) const;
+ // extract a float
+
+ CORBA::Boolean operator>>= (CORBA::Double&) const;
+ // extract a double
+
+ CORBA::Boolean operator>>= (CORBA_Any&) const;
+ // extract an Any
+
+ CORBA::Boolean operator>>= (char*&) const;
+ // extract an unbounded string
+
+ // = Special types.
+
+ // These are needed for insertion and extraction of booleans,
+ // octets, chars, and bounded strings.
+
+ struct from_boolean
+ {
+ from_boolean (CORBA::Boolean b);
+ CORBA::Boolean val_;
+ };
+
+ struct from_octet
+ {
+ from_octet (CORBA::Octet o);
+ CORBA::Octet val_;
+ };
+
+ struct from_char
+ {
+ from_char (CORBA::Char c);
+ CORBA::Char val_;
+ };
+
+ struct from_string
+ {
+ from_string (char* s, CORBA::ULong b,
+ CORBA::Boolean nocopy = CORBA::B_FALSE);
+ char *val_;
+ CORBA::ULong bound_;
+ CORBA::Boolean nocopy_;
+ };
+
+ void operator<<= (from_boolean);
+ // insert a boolean
+
+ void operator<<= (from_char);
+ // insert a char
+
+ void operator<<= (from_octet);
+ // insert an octet
+
+ void operator<<= (from_string);
+ // insert a bounded string
+
+ // = Special types.
+
+ // These extract octets, chars, booleans, bounded strings, and
+ // object references
+
+ struct to_boolean
+ {
+ to_boolean (CORBA::Boolean &b);
+ CORBA::Boolean &ref_;
+ };
+
+ struct to_char
+ {
+ to_char (CORBA::Char &c);
+ CORBA::Char &ref_;
+ };
+
+ struct to_octet
+ {
+ to_octet (CORBA::Octet &o);
+ CORBA::Octet &ref_;
+ };
+
+ struct to_string
+ {
+ to_string (char *&s, CORBA::ULong b);
+ char *&val_;
+ CORBA::ULong bound_;
+ };
+
+ struct to_object
+ {
+ to_object (CORBA::Object_ptr &obj);
+ CORBA::Object_ptr &ref_;
+ };
+
+ // extraction of the special types
+ CORBA::Boolean operator>>= (to_boolean) const;
+ CORBA::Boolean operator>>= (to_octet) const;
+ CORBA::Boolean operator>>= (to_char) const;
+ CORBA::Boolean operator>>= (to_string) const;
+ CORBA::Boolean operator>>= (to_object) const;
+
+ // = ALLOCATION
+ void *operator new (size_t, const void *p);
+ // Placement new.
+ void *operator new (size_t s);
+ // Default new.
+ void operator delete (void *p);
+ // Default delete
+
+ void replace (CORBA::TypeCode_ptr type,
+ const void *value,
+ CORBA::Boolean orb_owns_data,
+ CORBA::Environment &env);
+ // Replace the current typecode and data with the specified one -
+ // unsafe.
+
+ CORBA::TypeCode_ptr type (void) const;
+ // Return TypeCode of the element stored in the Any.
+
+ const void *value (void) const;
+ // Returns 0 if the Any has not been assigned a value, following the
+ // CORBA spec (TODO: give a reference) it returns a non-zero value
+ // otherwise. TAO does *not* guarantee that this value may be casted
+ // to the contained type safely.
+
+ // = Memory management methods.
+ CORBA::ULong AddRef (void);
+ CORBA::ULong Release (void);
+
+private:
+ CORBA::TypeCode_ptr type_;
+ // Typecode for the <Any>.
+
+ void *value_;
+ // Value for the <Any>.
+
+ CORBA::Boolean orb_owns_data_;
+ // Flag that indicates the ORB is responsible for deleting the data.
+
+ CORBA::ULong refcount_;
+ // Reference count the <Any> to reduce copying costs.
+
+ void replace (CORBA::TypeCode_ptr type,
+ const void *value,
+ CORBA::Boolean orb_owns_data);
+ // Helper for extraction operators that don't pass an environment
+ // parameter.
+
+ // 94-9-14 hides unsigned char insert/extract
+ void operator<<= (unsigned char);
+ CORBA::Boolean operator>>= (unsigned char&) const;
+};
+
+class TAO_Export CORBA_Any_var
+{
+ // = TITLE
+ // Provide for automatic storage deallocation on going out of
+ // scope.
+public:
+ CORBA_Any_var (void);
+ // default constructor
+
+ CORBA_Any_var (CORBA_Any *a);
+ // construct from an Any pointer
+
+ CORBA_Any_var (const CORBA_Any_var &a);
+ // copy constructor
+
+ ~CORBA_Any_var (void);
+ // destructor
+
+ CORBA_Any_var &operator= (CORBA_Any *a);
+ // assignment from a pointer to Any
+
+ CORBA_Any_var &operator= (const CORBA_Any_var &a);
+ // assignment from an Any_var
+
+ CORBA_Any *operator-> (void);
+ // arrow operator (smart pointer)
+
+ operator const CORBA_Any *() const;
+ // cast
+
+ operator CORBA_Any *&();
+ // cast
+
+ const CORBA_Any &in (void) const;
+ // for in Any parameter
+
+ CORBA_Any &inout (void);
+ // for inout Any parameter
+
+ CORBA_Any *&out (void);
+ // for out Any parameter
+
+ CORBA_Any *_retn (void);
+ // for Any return types
+
+private:
+ CORBA_Any *ptr_;
+ // Holds the Any.
+};
+
+class TAO_Export CORBA_Any_out
+ // = TITLE
+ // @@ (ANDY) Please document me.
+{
+public:
+ // = operations.
+
+ CORBA_Any_out (CORBA_Any *&p);
+ // construction from a reference to a CORBA_Any
+
+ CORBA_Any_out (CORBA_Any_var &p);
+ // construction from a var
+
+ CORBA_Any_out (CORBA_Any_out &s);
+ // copy constructor
+
+ CORBA_Any_out &operator= (CORBA_Any_out &s);
+ // assignment from a CORBA_Any_out
+
+ CORBA_Any_out &operator= (CORBA_Any *p);
+ // assignment from a CORBA_Any
+
+ CORBA_Any_out &operator= (const CORBA_Any *p);
+ // assignment from a const CORBA_Any
+
+ operator CORBA_Any *&();
+ // cast
+
+ CORBA_Any *& ptr (void);
+ // return underlying instance
+
+private:
+ CORBA_Any *&ptr_;
+ // Instance
+
+ void operator= (const CORBA_Any_var &);
+ // assignment from _var disallowed
+};
+
+#endif /* TAO_ANY_H */
diff --git a/TAO/tao/Any.i b/TAO/tao/Any.i
new file mode 100644
index 00000000000..2b4e36a6afd
--- /dev/null
+++ b/TAO/tao/Any.i
@@ -0,0 +1,293 @@
+// This may look like C, but it's really -*- C++ -*-
+
+ACE_INLINE void *
+CORBA_Any::operator new (size_t, const void *p)
+{
+ return (void *) p;
+}
+
+ACE_INLINE void *
+CORBA_Any::operator new (size_t s)
+{
+ return ::operator new (s);
+}
+
+ACE_INLINE void
+CORBA_Any::operator delete (void *p)
+{
+ ::operator delete (p);
+}
+
+// Insertion from special types.
+
+// @@ Andy, please take a look at this method and make sure it's what
+// you intended. I couldn't find it defined anywhere. --cjc
+ACE_INLINE void
+CORBA_Any::replace (CORBA::TypeCode_ptr type,
+ const void *value,
+ CORBA::Boolean orb_owns_data)
+{
+ CORBA_Environment e;
+ this->replace (type, value, orb_owns_data, e);
+}
+
+// insertion operators
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::Short s)
+{
+ this->replace (CORBA::_tc_short, new CORBA::Short (s), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::UShort s)
+{
+ this->replace (CORBA::_tc_ushort, new CORBA::UShort (s), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::Long l)
+{
+ this->replace (CORBA::_tc_long, new CORBA::Long (l), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::ULong l)
+{
+ this->replace (CORBA::_tc_ulong, new CORBA::ULong (l), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::Float f)
+{
+ this->replace (CORBA::_tc_float, new CORBA::Float (f), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (CORBA::Double d)
+{
+ this->replace (CORBA::_tc_double, new CORBA::Double (d), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (const CORBA_Any& a)
+{
+ this->replace (CORBA::_tc_any, new CORBA_Any (a), CORBA::B_TRUE);
+}
+
+// this is a copying version for unbounded strings
+ACE_INLINE void
+CORBA_Any::operator<<= (const char* s)
+{
+ this->replace (CORBA::_tc_string, new char* (CORBA::string_dup (s)),
+ CORBA::B_TRUE);
+}
+
+// implementing the special types
+ACE_INLINE
+CORBA_Any::from_boolean::from_boolean (CORBA::Boolean b)
+ : val_ (b)
+{
+}
+
+ACE_INLINE
+CORBA_Any::to_boolean::to_boolean (CORBA::Boolean &b)
+ : ref_ (b)
+{
+}
+
+ACE_INLINE
+CORBA_Any::from_octet::from_octet (CORBA::Octet o)
+ : val_ (o)
+{
+}
+
+ACE_INLINE
+CORBA_Any::to_octet::to_octet (CORBA::Octet &o)
+ : ref_ (o)
+{
+}
+
+ACE_INLINE
+CORBA_Any::from_char::from_char (CORBA::Char c)
+ : val_ (c)
+{
+}
+
+ACE_INLINE
+CORBA_Any::to_char::to_char (CORBA::Char &c)
+ : ref_ (c)
+{
+}
+
+ACE_INLINE
+CORBA_Any::from_string::from_string (char *s,
+ CORBA::ULong b,
+ CORBA::Boolean nocopy)
+ : val_ (s),
+ bound_ (b),
+ nocopy_ (nocopy)
+{
+}
+
+ACE_INLINE
+CORBA_Any::to_string::to_string (char *&s,
+ CORBA::ULong b)
+ : val_ (s),
+ bound_ (b)
+{
+}
+
+ACE_INLINE
+CORBA_Any::to_object::to_object (CORBA::Object_ptr &obj)
+ : ref_ (obj)
+{
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (from_boolean b)
+{
+ this->replace (CORBA::_tc_boolean, new CORBA::Boolean (b.val_), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (from_octet o)
+{
+ this->replace (CORBA::_tc_octet, new CORBA::Octet (o.val_), CORBA::B_TRUE);
+}
+
+ACE_INLINE void
+CORBA_Any::operator<<= (from_char c)
+{
+ this->replace (CORBA::_tc_char, new CORBA::Char (c.val_), CORBA::B_TRUE);
+}
+
+// ----------------------------------------------------------------------
+// CORBA_Any_var type
+// ----------------------------------------------------------------------
+
+ACE_INLINE
+CORBA_Any_var::CORBA_Any_var (void)
+ : ptr_ (0)
+{
+}
+
+ACE_INLINE
+CORBA_Any_var::CORBA_Any_var (CORBA_Any *p)
+ : ptr_ (p)
+{
+}
+
+ACE_INLINE
+CORBA_Any_var::CORBA_Any_var (const CORBA_Any_var& r)
+ : ptr_ (new CORBA::Any (*r.ptr_))
+{
+}
+
+ACE_INLINE
+CORBA_Any_var::~CORBA_Any_var (void)
+{
+ delete this->ptr_;
+}
+
+ACE_INLINE
+CORBA_Any_var::operator CORBA_Any *&()
+{
+ return this->ptr_;
+}
+
+ACE_INLINE
+CORBA_Any_var::operator const CORBA_Any *() const
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA::Any *
+CORBA_Any_var::operator-> (void)
+{
+ return this->ptr_;
+}
+
+ACE_INLINE const CORBA_Any &
+CORBA_Any_var::in (void) const
+{
+ return *this->ptr_;
+}
+
+ACE_INLINE CORBA_Any &
+CORBA_Any_var::inout (void)
+{
+ return *this->ptr_;
+}
+
+ACE_INLINE CORBA_Any *&
+CORBA_Any_var::out (void)
+{
+ delete this->ptr_;
+ this->ptr_ = 0;
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA_Any *
+CORBA_Any_var::_retn (void)
+{
+ CORBA_Any *temp = this->ptr_;
+ this->ptr_ = 0;
+ return temp;
+}
+
+// ----------------------------------------------------------------------
+// CORBA_Any_out type
+// ----------------------------------------------------------------------
+
+ACE_INLINE
+CORBA_Any_out::CORBA_Any_out (CORBA_Any *&s)
+ : ptr_ (s)
+{
+ this->ptr_ = 0;
+}
+
+ACE_INLINE
+CORBA_Any_out::CORBA_Any_out (CORBA_Any_var &s)
+ : ptr_ (s.out ())
+{
+}
+
+ACE_INLINE
+CORBA_Any_out::CORBA_Any_out (CORBA_Any_out &s)
+ : ptr_ (s.ptr_)
+{
+}
+
+ACE_INLINE CORBA_Any_out &
+CORBA_Any_out::operator= (CORBA_Any_out &s)
+{
+ this->ptr_ = s.ptr_;
+ return *this;
+}
+
+ACE_INLINE CORBA_Any_out &
+CORBA_Any_out::operator= (CORBA_Any *s)
+{
+ this->ptr_ = s;
+ return *this;
+}
+
+ACE_INLINE CORBA_Any_out &
+CORBA_Any_out::operator= (const CORBA_Any *s)
+{
+ this->ptr_ = new CORBA::Any (*s);
+ return *this;
+}
+
+ACE_INLINE
+CORBA_Any_out::operator CORBA_Any *&()
+{
+ return this->ptr_;
+}
+
+ACE_INLINE CORBA_Any *&
+CORBA_Any_out::ptr (void)
+{
+ return this->ptr_;
+}
diff --git a/TAO/tao/Arg_Shifter.cpp b/TAO/tao/Arg_Shifter.cpp
new file mode 100644
index 00000000000..8e8dc51aa34
--- /dev/null
+++ b/TAO/tao/Arg_Shifter.cpp
@@ -0,0 +1,117 @@
+// $Id$
+
+#include "Arg_Shifter.h"
+
+Arg_Shifter::Arg_Shifter (int &argc, char **argv, char **temp)
+ : argc_ (argc),
+ total_size_ (argc),
+ temp_ (temp),
+ argv_ (argv),
+ current_index_ (0),
+ back_ (argc - 1),
+ front_ (0)
+{
+ // If not provided with one, allocate a temporary array.
+ if (this->temp_ == 0)
+ this->temp_ = new char *[this->total_size_];
+
+ if (this->temp_ != 0)
+ {
+ // Fill the temporary array.
+ this->argc_ = 0;
+ for (int i = 0; i < this->total_size_; i++)
+ {
+ this->temp_[i] = this->argv_[i];
+ this->argv_[i] = 0;
+ }
+ }
+ else
+ {
+ // Allocation failed, prohibit iteration.
+ this->current_index_ = this->argc_;
+ this->front_ = this->argc_;
+ }
+}
+
+Arg_Shifter::~Arg_Shifter (void)
+{
+ // Delete the temporary vector.
+ delete [] temp_;
+}
+
+char *
+Arg_Shifter::get_current (void) const
+{
+ char *return_value = 0;
+
+ if (this->is_anything_left ())
+ return_value = this->temp_[current_index_];
+
+ return return_value;
+}
+
+int
+Arg_Shifter::consume_arg (int number)
+{
+ int return_value = 0;
+
+ // Stick knowns at the end of the vector (consumed).
+ if (this->is_anything_left() >= number)
+ {
+ for (int i = 0, j = this->back_ - (number - 1);
+ i < number;
+ i++, j++, this->current_index_++)
+ this->argv_[j] = this->temp_[this->current_index_];
+
+ this->back_ -= number;
+ return_value = 1;
+ }
+
+ return return_value;
+}
+
+int
+Arg_Shifter::ignore_arg (int number)
+{
+ int return_value = 0;
+
+ // Keep unknowns at the head of the vector.
+ if (this->is_anything_left () >= number)
+ {
+ for (int i = 0;
+ i < number;
+ i++, this->current_index_++, this->front_++)
+ this->argv_[this->front_] = this->temp_[this->current_index_];
+
+ return_value = 1;
+ this->argc_ += number;
+ }
+
+ return return_value;
+}
+
+int
+Arg_Shifter::is_anything_left (void) const
+{
+ return this->total_size_ - this->current_index_;
+}
+
+int
+Arg_Shifter::is_option_next (void) const
+{
+ return this->is_anything_left () &&
+ this->temp_[this->current_index_][0] == '-';
+}
+
+int
+Arg_Shifter::is_parameter_next (void) const
+{
+ return this->is_anything_left ()
+ && this->temp_[this->current_index_][0] != '-';
+}
+
+int
+Arg_Shifter::num_ignored_args (void) const
+{
+ return this->front_;
+}
diff --git a/TAO/tao/Arg_Shifter.h b/TAO/tao/Arg_Shifter.h
new file mode 100644
index 00000000000..d0952b48e01
--- /dev/null
+++ b/TAO/tao/Arg_Shifter.h
@@ -0,0 +1,97 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// ========================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// Arg_Shifter.h
+//
+// = AUTHOR
+// Seth Widoff
+//
+// ========================================================================
+
+#if !defined (TAO_ARG_SHIFTER_H)
+#define TAO_ARG_SHIFTER_H
+
+class Arg_Shifter
+{
+ // = TITLE
+ // This ADT shifts known args to the back of the argv vector, so
+ // deeper levels of argument parsing can locate the yet
+ // unprocessed arguments at the beginning of the vector.
+ //
+ // = DESCRIPTION
+ // The Arg_Shifter copies the pointers of the argv vector into a
+ // temporary array. As the Arg_Shifter iterates over the temp, is
+ // places known arguments in the rear of the argv and unknown
+ // ones in the beginning. So, after having visited all the
+ // arguments in the temp vector, Arg_Shifter has placed all the
+ // unknown arguments in their original order at the front of
+ // argv.
+public:
+ Arg_Shifter (int &argc, char **argv, char **temp = 0);
+ // Initialize the Arg_Shifter to the vector over which to iterate,
+ // also providing the temporary array if the client doesn't want the
+ // arg_shifter to dynamically allocate its own. If internal dynamic
+ // allocation fails, the Arg_Shifter will set all the indices to the
+ // end of the vector, forbidding iteration. Following iteration over
+ // argv, the argc value will contain the number of unconsumed
+ // arguments.
+
+ ~Arg_Shifter (void);
+
+ char *get_current (void) const;
+ // Get the current head of the vector.
+
+ int consume_arg (int number = 1);
+ // Consume <number> argument(s) by sticking them/it on the end of
+ // the vector.
+
+ int ignore_arg (int number = 1);
+ // Place <number> arguments in the same relative order ahead of the
+ // known arguemnts in the vector.
+
+ int is_anything_left (void) const;
+ // Returns the number of args left to see in the vector.
+
+ int is_option_next (void) const;
+ // Returns 1 if there's a next item in the vector and it begins with
+ // '-'.
+
+ int is_parameter_next (void) const;
+ // Returns 1 if there's a next item in the vector and it doesn't
+ // begin with '-'.
+
+ int num_ignored_args (void) const;
+ // Returns the number of irrelevant args seen.
+
+private:
+ int &argc_;
+ // The size of the argument vector.
+
+ int total_size_;
+ // The size of argv_.
+
+ char **temp_;
+ // The temporary array over which we traverse.
+
+ char **argv_;
+ // The array in which the arguments are reordered.
+
+ int current_index_;
+ // The element in <temp_> we're currently examining.
+
+ int back_;
+ // The index of <argv_> in which we'll stick the next unknown
+ // argument.
+
+ int front_;
+ // The index of <argv_> in which we'll stick the next known
+ // argument.
+};
+
+#endif /* TAO_ARG_SHIFTER_H */
diff --git a/TAO/tao/CDR.cpp b/TAO/tao/CDR.cpp
new file mode 100644
index 00000000000..8aadd881f13
--- /dev/null
+++ b/TAO/tao/CDR.cpp
@@ -0,0 +1,547 @@
+// $Id$
+
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// All Rights Reserved
+
+// CDR: Encode/Decode basic machine data types
+//
+// Implementation of OMG "Common Data Representation" (CDR) ... there
+// are one routine each for byte/halfword/word/doubleword put/get,
+// which adjust to establish "natural" alignment (the bulk of the
+// code) and then put or get with byteswapping as needed.
+//
+// The implementation knows that native data formats are conformant
+// with OMG-IDL's (and hence CDR's) size requirements, and relies on
+// the fact that (for example) CORBA_Long is always four bytes long
+// even if the environment's "int" is a different size.
+//
+// char, octet 8 bits (1 byte)
+// short, unsigned short 16 bits (2 bytes)
+// long, unsigned long, float 32 bits (4 bytes)
+// double, (unsigned) long long 64 bits (8 bytes)
+// long double 128 bits (16 bytes)
+//
+// Moreover, this "knows" that the native 'char' represents ISO
+// Latin/1 characters (an ASCII superset addressing Western European
+// characters) and that "double" and "float" comply with the IEEE
+// standards. (The "long double" may not be a native data type,
+// though.)
+//
+// THREADING NOTE: "CDR" is a data structure which must be protected
+// by external critical sections. Like simpler numeric types, "CDR"
+// instances are accessed and modified atomically. This
+// implementation is reentrant, so that independent "CDR" values may
+// be manipulated concurrently when the underlying programming
+// environment is itself reentrant.
+
+#include "tao/corba.h"
+
+// This functions are private, so it is safe to declare them inline in
+// the .cpp file, we still use the ACE_INLINE macro to support
+// compilations without any inline code.
+
+ACE_INLINE
+void CDR::swap_long(char *orig, CORBA::Long &target)
+{
+ register char *lp = ACE_reinterpret_cast(char *,&target);
+
+ lp [3] = *orig++;
+ lp [2] = *orig++;
+ lp [1] = *orig++;
+ lp [0] = *orig++;
+}
+
+ACE_INLINE
+void CDR::swap_ulonglong(char *orig, CORBA::ULongLong &target)
+{
+ register char *llp = ACE_reinterpret_cast(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++;
+}
+
+ACE_INLINE
+void CDR::swap_longdouble(char *orig, CORBA::LongDouble &target)
+{
+ register char *ldp = ACE_reinterpret_cast(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++;
+}
+
+ACE_INLINE void
+CDR::mb_align (ACE_Message_Block* mb)
+{
+ ptr_arith_t temp = (ptr_arith_t) mb->base ();
+
+ temp += MAX_ALIGNMENT - 1;
+ temp &= ~ ((ptr_arith_t) MAX_ALIGNMENT - 1);
+ char* start = ACE_reinterpret_cast(char*,temp);
+ mb->rd_ptr (start);
+ mb->wr_ptr (start);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::adjust_to_put (size_t size, char*& buf)
+{
+ buf = ACE_reinterpret_cast (char *,
+ ptr_align_binary (this->mb_->wr_ptr (),
+ size));
+ char *end = buf + size;
+
+ if (end <= this->mb_->end ())
+ {
+ this->mb_->wr_ptr (end);
+ return CORBA::B_TRUE;
+ }
+ else if (this->grow (0))
+ {
+ // grow(0) may change the value of wr_ptr() so we have to
+ // recompute the position....
+ buf = ACE_reinterpret_cast (char *,
+ ptr_align_binary (this->mb_->wr_ptr (),
+ size));
+ this->mb_->wr_ptr (buf + size);
+ return CORBA::B_TRUE;
+ }
+
+ return CORBA::B_FALSE;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::adjust_to_get (size_t size,
+ char*& buf)
+{
+ buf = ACE_reinterpret_cast (char *,
+ ptr_align_binary (this->mb_->rd_ptr(),
+ size));
+ char *end = buf + size;
+ if (end <= this->mb_->end ())
+ {
+ this->mb_->rd_ptr (end);
+ return CORBA::B_TRUE;
+ }
+
+ return CORBA::B_FALSE;
+}
+
+CDR::CDR (char *buf,
+ size_t len,
+ int byte_order,
+ int consume_buf,
+ TAO_Marshal_Factory *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]. Yes, that
+ // complicates the grow () primitive.
+ : do_byteswap (byte_order != TAO_ENCAP_BYTE_ORDER),
+ factory_ (f),
+ mobj_ (0),
+ good_bit_ (1)
+{
+ if (buf != 0)
+ {
+ ACE_Message_Block::Message_Flags flags =
+ consume_buf ? 0 : ACE_Message_Block::DONT_DELETE;
+ ACE_NEW (this->mb_,
+ ACE_Message_Block
+ (new ACE_Data_Block (len,
+ ACE_Message_Block::MB_DATA,
+ (char *) buf,
+ 0,
+ 0,
+ flags)));
+ // We cannot trust the buffer to be properly aligned.
+ CDR::mb_align (this->mb_);
+ }
+ else
+ {
+ if (len == 0)
+ len = CDR::DEFAULT_BUFSIZE + CDR::MAX_ALIGNMENT;
+ ACE_NEW (this->mb_, ACE_Message_Block (len));
+ CDR::mb_align (this->mb_);
+ }
+
+#if defined(ACE_PURIFY)
+ if (this->mb_->base () != 0)
+ (void) ACE_OS::memset (this->mb_->base (), 0, len);
+#endif
+}
+
+CDR::CDR (const CDR& rhs)
+ : do_byteswap (rhs.do_byteswap),
+ factory_ (rhs.factory_),
+ mobj_ (rhs.mobj_),
+ good_bit_ (rhs.good_bit_)
+{
+ this->mb_ = ACE_Message_Block::duplicate (rhs.mb_);
+ this->mb_->wr_ptr (rhs.mb_->wr_ptr ());
+ this->mb_->rd_ptr (rhs.mb_->rd_ptr ());
+}
+
+CDR::~CDR (void)
+{
+ ACE_Message_Block::release (this->mb_);
+ this->mb_ = 0;
+}
+
+CORBA::Boolean
+CDR::get_string (char*& buf)
+{
+ CORBA::ULong len;
+ return this->get_encapsulation (buf, len);
+}
+
+CORBA::Boolean
+CDR::get_encapsulation (char *&buf, CORBA::ULong& size)
+{
+ // TODO in some platforms this may not be safe.....
+ // @@ Carlos, can you please address this?
+ if (this->get_ulong (size))
+ {
+ buf = this->mb_->rd_ptr ();
+ this->mb_->rd_ptr (size);
+ return CORBA::B_TRUE;
+ }
+
+ return CORBA::B_FALSE;
+}
+
+void
+CDR::setup_encapsulation (char *buf, u_int len)
+{
+ // Also used when interpreting typecodes, but more generally when
+ // getting ready to read from encapsulations. In such cases the
+ // buffer alignment guarantees must be provided by the caller, this
+ // code doesn't verify them. These streams are "read only".
+ ACE_Message_Block::release (this->mb_);
+ this->mb_ = 0;
+ ACE_NEW (this->mb_,
+ ACE_Message_Block (buf + 1, len - 1));
+ do_byteswap = (buf[0] != TAO_ENCAP_BYTE_ORDER);
+
+ this->mb_->wr_ptr (buf + len);
+
+#if 0
+ // @@ TODO This test should be activated in debug version, but it
+ // seems a bit too conservative, checking for 4 byte boudaries
+ // should be OK for most cases.
+
+ ptr_arith_t temp = (ptr_arith_t) buf + 1;
+
+ temp += MAX_ALIGNMENT - 1;
+ temp &= ~ ((ptr_arith_t) MAX_ALIGNMENT - 1);
+ char* start = ACE_reinterpret_cast(char*,temp);
+
+ if (start != buf + 1)
+ {
+ ACE_ERROR ((LM_WARNING,
+ "unproperly aligned buffer in "
+ "CDR::setup_encapsulation\n"));
+ }
+#endif /* 0 */
+}
+
+void
+CDR::setup_indirection (CDR& cdr, CORBA::Long offset)
+{
+ ACE_Message_Block::release (this->mb_);
+ this->do_byteswap = cdr.do_byteswap;
+ this->factory_ = cdr.factory_;
+ this->mobj_ = cdr.mobj_;
+ this->good_bit_ = 1;
+
+ this->mb_ = ACE_Message_Block::duplicate (cdr.mb_);
+ this->mb_->wr_ptr (cdr.mb_->wr_ptr ());
+ this->mb_->rd_ptr (cdr.mb_->rd_ptr () + offset);
+
+ if (this->mb_->rd_ptr () < this->mb_->base ()
+ || this->mb_->rd_ptr () > this->mb_->wr_ptr () )
+ this->good_bit_ = 0;
+}
+
+void
+CDR::reset (void)
+{
+ CDR::mb_align (this->mb_);
+}
+
+// Grow the CDR buffer, either to a known size (incoming message) or
+// by a standard increment (creating outgoing message).
+//
+// We can't use realloc () because of a constraint that the part of the
+// buffer into which we marshal be aligned according to MAX_ALIGNMENT,
+// which can be a stronger requirement than malloc/realloc places on
+// buffer. This makes growing a buffer on the encode side costly,
+// since it can need to be done repetitively and copies more data each
+// time.
+//
+// NOTE: this code knows about what's involved in the constructor and
+// destructor, as it needs to invoke the constructor and do what the
+// destructor would do (and not in the normal order). It also knows
+// all other state that's significant. Change with care!
+//
+// NOTE: arguably this is a good place to ensure that the memory's
+// zeroed out to comply with Orange Book C2 "object reuse" (meaning
+// data, like I/O buffers) policy. IIOP doesn't mandate such policies
+// though.
+
+CORBA::Boolean
+CDR::grow (size_t newsize)
+{
+ // Calculate the new buffer's length; if growing for encode, we
+ // don't grow in "small" chunks because of the cost.
+
+ size_t new_len;
+
+ size_t size = this->mb_->size();
+ if (newsize == 0)
+ {
+ // TODO We should the growth strategy should be controlled using
+ // the ORB parameters....
+ if (size < CDR::EXP_GROWTH_MAX)
+ new_len = size * 2;
+ else
+ new_len = size + CDR::LINEAR_GROWTH_CHUNK;
+ }
+ else if (newsize <= size)
+ return CORBA::B_TRUE;
+ else
+ new_len = newsize;
+
+ new_len += MAX_ALIGNMENT - 1;
+
+ ACE_Message_Block *mb;
+ ACE_NEW_RETURN (mb,
+ ACE_Message_Block (new_len),
+ CORBA::B_FALSE);
+
+ CDR::mb_align (mb);
+
+ mb->copy (this->mb_->rd_ptr (),
+ this->mb_->length());
+ ACE_Message_Block::release (this->mb_);
+ this->mb_ = mb;
+
+ return CORBA::B_TRUE;
+}
+
+// ****************************************************************
+// put_ methods
+
+CORBA::Boolean
+CDR::put_short (CORBA::Short s)
+{
+ char *buf;
+
+ if (this->adjust_to_put (SHORT_SIZE, buf))
+ {
+ // copy the half word, native byte order
+ *(CORBA::Short *)buf = s;
+ return CORBA::B_TRUE;
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::put_long (CORBA::Long l)
+{
+ char *buf;
+
+ if (this->adjust_to_put (LONG_SIZE, buf))
+ {
+ // copy the word, native byte order
+ *(CORBA::Long *)buf = l;
+ return CORBA::B_TRUE;
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::put_ulonglong (const CORBA::ULongLong &ull)
+{
+ char *buf;
+
+ if (this->adjust_to_put (LONGLONG_SIZE, buf))
+ {
+ *(CORBA::ULongLong *)buf = ull;
+ return CORBA::B_TRUE;
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::put_longdouble (CORBA::LongDouble &ld)
+{
+ char *buf;
+
+ if (this->adjust_to_put (LONGDOUBLE_SIZE, buf))
+ {
+ // copy the longdouble in native byte order
+ *(CORBA::LongDouble *)buf = ld;
+ return CORBA::B_TRUE;
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::put_string (const char *str, CORBA::ULong len)
+{
+ // Assuming that length is the length of the string. We insert len+1
+ // for the additional NUL character.
+ if (this->put_long (len + 1))
+ {
+ char *buf = this->mb_->wr_ptr ();
+ char *end = buf + len + 1;
+
+ if (end <= this->mb_->end ()
+ || this->grow (this->size () + len + 1))
+ this->mb_->copy (str, len + 1);
+
+ return CORBA::B_TRUE;
+ }
+ return CORBA::B_FALSE;
+}
+
+// ****************************************************************
+// get_
+
+CORBA::Boolean
+CDR::get_short (CORBA::Short &s)
+{
+ char *buf;
+ if (this->adjust_to_get (SHORT_SIZE, buf))
+ {
+ // decode halfword, swapping as needed
+ if (!do_byteswap)
+ {
+ s = *(CORBA::Short *)buf;
+ return CORBA::B_TRUE; // put a return here to avoid a jump
+ }
+ else
+ {
+ // do swapping
+ register char *sp = ACE_reinterpret_cast(char *, &s);
+
+ sp [1] = buf[0];
+ sp [0] = buf[1];
+ return CORBA::B_TRUE;
+ }
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::get_long (CORBA::Long &l)
+{
+ char *buf;
+ if (this->adjust_to_get (LONG_SIZE, buf))
+ {
+ if (!do_byteswap)
+ {
+ l = *(CORBA::Long *)buf;
+ 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 (buf, l);
+ return CORBA::B_TRUE;
+ }
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::get_ulonglong (CORBA::ULongLong &ull)
+{
+ char *buf;
+
+ if (this->adjust_to_get (LONGLONG_SIZE, buf))
+ {
+ if (!do_byteswap)
+ {
+ ull = *(CORBA::ULongLong *)buf;
+ return CORBA::B_TRUE;
+ }
+ else
+ {
+ swap_ulonglong (buf, ull);
+ return CORBA::B_TRUE;
+ }
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::get_longdouble (CORBA::LongDouble &ld)
+{
+ char *buf;
+
+ if (this->adjust_to_get (LONGDOUBLE_SIZE, buf))
+ {
+ if (!do_byteswap)
+ {
+ ld = *(CORBA::LongDouble *)buf;
+ return CORBA::B_TRUE;
+ }
+ else
+ {
+ swap_longdouble (buf, ld);
+ return CORBA::B_TRUE;
+ }
+ }
+
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+CORBA::Boolean
+CDR::get_string (char *&str, CORBA::ULong len)
+{
+ // len includes the terminating 0
+ char *end = this->mb_->rd_ptr () + len;
+
+ if (end <= this->mb_->end ())
+ {
+ ACE_OS::memcpy (str, this->mb_->rd_ptr (), len);
+ this->mb_->rd_ptr (end);
+ return CORBA::B_TRUE;
+ }
+
+ return CORBA::B_FALSE;
+}
diff --git a/TAO/tao/CDR.h b/TAO/tao/CDR.h
new file mode 100644
index 00000000000..b8812720e5f
--- /dev/null
+++ b/TAO/tao/CDR.h
@@ -0,0 +1,379 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// cdr.h
+//
+// = DESCRIPTION
+// Common Data Representation (CDR) marshaling streams.
+//
+// This implementation assumes that the native numeric
+// representation is two's complement for integers, IEEE
+// single/double for floats. Also that characters are in ISO
+// Latin/1.
+//
+// Note that CDR itself makes no such assumptions, but this
+// implementation makes such assumptions for reasons of
+// efficiency. Careful enhancements could preserve that
+// efficiency where the assumptions are true, yet still allow the
+// code to work when they aren't true.
+//
+// The implementation expects that buffers are aligned according
+// to the strongest CDR alignment restriction.
+//
+// NOTE: this does everything "CDR 1.1" does ... that is, it
+// supports the five extended OMG-IDL data types in UNO Appendix
+// A, which provide richer arithmetic types (64 bit integers,
+// "quad precision" FP) and UNICODE-based characters and strings.
+// Those types are not standard parts of OMG-IDL at this time.
+//
+// THREADING NOTE: CDR data structures must be protected against
+// concurrent access by their owning thread.
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems, Inc.
+// Many enhancements added by Andy Gokhake and Carlos O'Ryan.
+//
+// ============================================================================
+
+#if !defined (TAO_CDR_H)
+#define TAO_CDR_H
+
+class TAO_Export CDR
+{
+ // = TITLE
+ // The core marshaling primitive: a memory buffer, into which all
+ // the basic OMG-IDL datatypes can be placed ... or from which
+ // they can be retreived.
+ //
+ // = DESCRIPTION
+ // A particularly useful static member function for this buffer is
+ // an interpretive encoding routine, usable as a typecode
+ // interpreter callback. Ditto for decoding. These are used to
+ // support all OMG-IDL datatypes, even those not supported
+ // directly by put/get primitives.
+ //
+ // Struct members are intentionally exposed; the functionality of
+ // this class, and hence the appropriate abstactions for them,
+ // hasn't quite settled down enough to settle on fast abstractions
+ // that let data be hidden without pointlessly sacrificing speed.
+public:
+ // = Constants defined by the CDR protocol.
+
+ // By defining these constants as enums we ensure they get inlined
+ // and avoid pointless static memory allocations.
+
+ enum
+ {
+ // Note that some of these get reused as part of the standard
+ // binary format: unsigned is the same size as its signed cousin,
+ // float is CDR_LONG_SIZE, and double is CDR_LONGLONG_SIZE.
+
+ SHORT_SIZE = 2,
+ LONG_SIZE = 4,
+ LONGLONG_SIZE = 8,
+ LONGDOUBLE_SIZE = 16,
+
+ MAX_ALIGNMENT = 16,
+ // Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "long
+ // double", size as above).
+
+ DEFAULT_BUFSIZE = 1430,
+ // Ethernet MTU, less headers. Default buffer size for
+ // request/response messages. These are normally stack-allocated,
+ // and tuning may cause you to want to change this value. The
+ // best value depends on your particular application mix; you can
+ // also change how buffers grow(). Most remote invocations
+ // (statistically) are "small", and the default used here is
+ // perhaps larger than most such messages.
+ //
+ // If this size is "too small" you need to heap-allocate buffers too
+ // often. "Too large" is mostly a waste of stackspace, but stack
+ // frames as large as the system page size (often 4Kb) can easily
+ // overrun the "redzone" at the bottom of most VM-based stacks.
+
+ EXP_GROWTH_MAX = 4096,
+ // The buffer size grows exponentially until it reaches this size;
+ // afterwards it grows linearly using the next constant
+
+ LINEAR_GROWTH_CHUNK = 4096
+ // Once exponential growth is ruled out the buffer size increases
+ // in chunks of this size, note that this constants have the same
+ // value right now, but it does not need to be so.
+ };
+ // = ENCODING SUPPORT
+
+ // = Adjust pointers as needed, then store in the native byte order.
+ //
+ // There exist only routines to put byte, halfword (2 bytes), word
+ // (4 bytes), doubleword (8 bytes) and quadword (16 byte) entities,
+ // 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 (CORBA::Float f);
+ // encode a float into the CDR stream
+
+ CORBA::Boolean put_double (const CORBA::Double &d);
+ // encode a double into the CDR stream
+
+ CORBA::Boolean put_longdouble (CORBA::LongDouble &ld);
+ // encode a longdouble into the CDR stream
+
+ CORBA::Boolean put_string (const char *str, CORBA::ULong len);
+ // encode a string of length len
+
+ CORBA::TypeCode::traverse_status encode (CORBA::TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA::Environment &env);
+ // Marshaling. ... <context> really points to a <CDR>.
+
+ // = DECODING SUPPORT
+
+ // Same assumptions are made as above, but a flag is tested to
+ // determine whether decode should byteswap or not. It's cheaper to
+ // 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 (CORBA::ULongLong &ull);
+ // decode an unsigned longlong from the CDR stream
+
+ CORBA::Boolean get_float (CORBA::Float &f);
+ // decode a float from the CDR stream
+
+ CORBA::Boolean get_double (CORBA::Double &d);
+ // decode a double from the CDR stream
+
+ CORBA::Boolean get_longdouble (CORBA::LongDouble &ld);
+ // decode a longdouble from the CDR stream
+
+ CORBA::Boolean get_string (char *&str, CORBA::ULong len);
+ // decode a string. Length includes the terminating 0
+
+ CORBA::TypeCode::traverse_status decode (CORBA::TypeCode_ptr tc,
+ const void *data,
+ const void *,
+ CORBA::Environment &env);
+ // Unmarshaling interpreter ... <context> really points to a <CDR>.
+
+ CDR (char *buf = 0,
+ size_t len = 0,
+ int byte_order = TAO_ENCAP_BYTE_ORDER,
+ int consume_buf = 0,
+ TAO_Marshal_Factory *f = TAO_Marshal::DEFAULT_MARSHAL_FACTORY);
+ // constructor
+
+ CDR (const CDR& rhs);
+ // Copy constructor, build a new stream that points to the same data
+ // as <rhs>.
+ // Using this new stream for writing results in undefined behavior.
+
+ ~CDR (void);
+ // destructor
+
+ // = Used mostly when interpreting typecodes.
+
+ // These may change the state of a CDR buffer even when errors are
+ // reported.
+
+ CORBA::Boolean skip_string (void);
+ // skip a string field in a typecode
+
+ // TODO: This methods should be private and the classes that need it
+ // (TypeCode, Exception, etc.) would be declared friend.
+
+ CORBA::Boolean get_encapsulation (char*& buf, CORBA::ULong& len);
+ // Returns an encapsulated buffer (such as a string) stored inside
+ // the CDR.
+ // TODO: This method should be private and the classes that need it
+ // (TypeCode, Exception, etc.) would be declared friend.
+
+ CORBA::Boolean get_string (char*& buf);
+ // Returns an encapsulated string stored inside the CDR; but without
+ // any copying.
+
+ CORBA::Boolean rd_ptr (size_t n);
+ // Move the read pointer <n> bytes ahead, it is used to skip
+ // portions of the stream, specially in typecodes.
+
+ CORBA::Boolean wr_ptr (size_t n);
+ // Move the write pointer <n> bytes ahead, it is used to when the
+ // CDR is read from a socket to set the end of the message.
+
+ void setup_encapsulation (char *buf, u_int len);
+ // Also used when interpreting typecodes, but more generally when
+ // getting ready to read from encapsulations. In such cases the
+ // buffer alignment guarantees must be provided by the caller, this
+ // code doesn't verify them. These streams are "read only".
+
+ void setup_indirection (CDR& cdr, CORBA::Long offset);
+ // Set the CDR to point to the stream in <cdr>.
+ // The stream is read-only from then on.
+
+ CORBA::Boolean grow (size_t newlength);
+ // Grow the buffer to the identified size ... if it's zero, just
+ // grow it by a standard quantum (e.g. when encoding we can't know
+ // in advance how big it will need to become).
+
+ size_t bytes_remaining (void);
+ // Some code needs to know how much is left on encode or decode.
+
+ int good_bit (void) const;
+ // If zero then some error has ocurred.
+
+ char *buffer (void) const;
+ // Return the internal buffer.
+
+ size_t length (void) const;
+ // Return the internal buffer length (how many bytes in the buffer
+ // contain useful data).
+
+ size_t size (void) const;
+ // Return the internal buffer capacity.
+
+ void reset (void);
+ // Reset the read and write pointers to the start of the buffer.
+
+ int do_byteswap;
+ // for decoding only.
+ // TODO: It could be used for encoding also, for instance, if all
+ // the machines in a network but one are little endian it makes
+ // sense to make that machine swap the bytes on write. At least
+ // some people would like such a feature.
+
+private:
+ static void swap_long (char *orig, CORBA::Long &target);
+ // do byte swapping for longs
+
+ static void swap_ulonglong (char *orig, CORBA::ULongLong &target);
+ // do byte swapping for longlongs
+
+ static void swap_longdouble (char *orig, CORBA::LongDouble &target);
+ // do byte swapping for longdoubles
+
+ static void mb_align (ACE_Message_Block* mb);
+
+ CORBA::Boolean adjust_to_put (size_t size,
+ char*& buf);
+ // Returns (in <buf>) the next position in the buffer aligned to
+ // <size>, it advances the Message_Block wr_ptr past the data
+ // (i.e. <buf> + <size>). If necessary it grows the Message_Block
+ // buffer. Returns B_FALSE on failure.
+
+ CORBA::Boolean adjust_to_get (size_t size,
+ char*& buf);
+ // Returns (in <buf>) the next position in the buffer aligned to
+ // <size>, it sets the Message_Block rd_ptr past the data
+ // (i.e. <buf> + <size>). Returns B_FALSE on failure.
+
+private:
+ ACE_Message_Block *mb_;
+ // The buffer is stored in a Message_Block, future implementations
+ // will take advantage of the chaining features of it to provide
+ // minimal copying encapsulation.
+
+ TAO_Marshal_Factory *factory_;
+ // Maintain a factory that can make specialized marshaling objects.
+
+ TAO_Marshal_Object *mobj_;
+ // Maintain an instance of a marshaling object. The CDR stream
+ // delegates the marshaling activity to mobj_.
+
+ int good_bit_;
+ // Set to 0 when an error ocurrs.
+};
+
+#if !defined(__ACE_INLINE__)
+extern CDR &operator<< (CDR &cdr, CORBA::Boolean x);
+extern CDR &operator<< (CDR &cdr, CORBA::Octet x);
+extern CDR &operator<< (CDR &cdr, CORBA::Short x);
+extern CDR &operator<< (CDR &cdr, CORBA::UShort x);
+extern CDR &operator<< (CDR &cdr, CORBA::Long x);
+extern CDR &operator<< (CDR &cdr, CORBA::ULong x);
+extern CDR &operator<< (CDR &cdr, CORBA::LongLong x);
+extern CDR &operator<< (CDR &cdr, CORBA::ULongLong x);
+extern CDR &operator<< (CDR &cdr, CORBA::Float x);
+extern CDR &operator<< (CDR &cdr, CORBA::Double x);
+extern CDR &operator<< (CDR &cdr, CORBA::Char x);
+extern CDR &operator<< (CDR &cdr, CORBA::WChar x);
+extern CDR &operator>> (CDR &cdr, CORBA::Boolean &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Octet &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Short &x);
+extern CDR &operator>> (CDR &cdr, CORBA::UShort &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Long &x);
+extern CDR &operator>> (CDR &cdr, CORBA::ULong &x);
+extern CDR &operator>> (CDR &cdr, CORBA::LongLong &x);
+extern CDR &operator>> (CDR &cdr, CORBA::ULongLong &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Float &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Double &x);
+extern CDR &operator>> (CDR &cdr, CORBA::Char &x);
+extern CDR &operator>> (CDR &cdr, CORBA::WChar &x);
+#endif /* __ACE_INLINE */
+
+#endif /* TAO_CDR_H */
diff --git a/TAO/tao/CDR.i b/TAO/tao/CDR.i
new file mode 100644
index 00000000000..475ba9eaf5b
--- /dev/null
+++ b/TAO/tao/CDR.i
@@ -0,0 +1,394 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// 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, env);
+
+ if (this->mobj_)
+ return this->mobj_->decode (tc, data, data2, this, env);
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+}
+
+// Encode data into CDR stream.
+
+ACE_INLINE CORBA::Boolean
+CDR::skip_string (void)
+{
+ char *dummy0;
+ CORBA::ULong dummy1;
+ return this->get_encapsulation (dummy0, dummy1);
+}
+
+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, env);
+
+ if (this->mobj_)
+ return this->mobj_->encode (tc, data, data2, this, env);
+ else
+ return CORBA::TypeCode::TRAVERSE_STOP;
+}
+
+ACE_INLINE size_t
+CDR::bytes_remaining (void)
+{
+ return this->mb_->length();
+}
+
+ACE_INLINE int
+CDR::good_bit (void) const
+{
+ return this->good_bit_;
+}
+
+ACE_INLINE char*
+CDR::buffer (void) const
+{
+ return this->mb_->rd_ptr();
+}
+
+ACE_INLINE size_t
+CDR::length (void) const
+{
+ return this->mb_->length ();
+}
+
+ACE_INLINE size_t
+CDR::size (void) const
+{
+ return this->mb_->size ();
+}
+
+// ****************************************************************
+// put_ routines
+
+ACE_INLINE CORBA::Boolean
+CDR::put_byte (char c)
+{
+ if (this->mb_->wr_ptr () + 1 <= this->mb_->end ()
+ || grow (0) == CORBA::B_TRUE)
+ {
+ this->mb_->copy (&c, 1);
+ return CORBA::B_TRUE;
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_char (CORBA::Char c)
+{
+ return put_byte ((char) c);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_wchar (CORBA::WChar wc)
+{
+ // "wchar_t" isn't always 2 bytes, such systems might need further
+ // conversion (e.g. hosts with multibyte characters native, rather
+ // than UNICODE)
+
+ return put_short ((short) wc);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_boolean (CORBA::Boolean b)
+{
+ return put_byte ((char) (b != CORBA::B_FALSE));
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_octet (CORBA::Octet o)
+{
+ return put_byte ((char) o);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_ushort (CORBA::UShort s)
+{
+ return put_short ((CORBA::Short) s);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_ulong (CORBA::ULong l)
+{
+ return put_long ((CORBA::Long) l);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_longlong (const CORBA::LongLong &ll)
+{
+ return put_ulonglong ((CORBA::ULongLong &) ll);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_float (CORBA::Float f)
+{
+ return put_long (*(CORBA::Long *) &f);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::put_double (const CORBA::Double &d)
+{
+ return put_ulonglong (*(CORBA::ULongLong *) &d);
+}
+
+// ****************************************************************
+// DECODING routines ... adjust pointer, then byteswap as needed.
+
+ACE_INLINE CORBA::Boolean
+CDR::get_byte (char &c)
+{
+ if (this->mb_->rd_ptr () + 1 <= this->mb_->end ())
+ {
+ c = (char) *this->mb_->rd_ptr ();
+ this->mb_->rd_ptr (1);
+ return CORBA::B_TRUE;
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_char (CORBA::Char &o)
+{
+ return this->get_byte ((char &) o);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_wchar (CORBA::WChar &wc)
+{
+ short s;
+
+ // wchar_t isn't always "short"
+
+ CORBA::Boolean retval = this->get_short (s);
+ wc = s;
+ return retval;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_boolean (CORBA::Boolean &b)
+{
+ CORBA::Char c;
+
+ // CORBA::Boolean is rarely 'char'
+ CORBA::Boolean retval = this->get_char (c);
+ b = (c == 1);
+ return retval;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_octet (CORBA::Octet &o)
+{
+ return this->get_byte ((char &) o);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_ushort (CORBA::UShort &s)
+{
+ return this->get_short ((short&) s);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_ulong (CORBA::ULong &l)
+{
+ return this->get_long ((CORBA::Long &) l);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_longlong (CORBA::LongLong &ll)
+{
+ return this->get_ulonglong ((CORBA::ULongLong &) ll);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_float (float &f)
+{
+ return this->get_long ((CORBA::Long &) f);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::get_double (double &d)
+{
+ return this->get_ulonglong ((CORBA::ULongLong &) d);
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::rd_ptr (size_t n)
+{
+ if (this->mb_->rd_ptr () + n <= this->mb_->end ())
+ {
+ this->mb_->rd_ptr (n);
+ return CORBA::B_TRUE;
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+ACE_INLINE CORBA::Boolean
+CDR::wr_ptr (size_t n)
+{
+ if (this->mb_->wr_ptr () + n <= this->mb_->end ())
+ {
+ this->mb_->wr_ptr (n);
+ return CORBA::B_TRUE;
+ }
+ this->good_bit_ = 0;
+ return CORBA::B_FALSE;
+}
+
+// ****************************************************************
+// TODO: Use the CORBA_* types when they become available.
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Octet x)
+{
+ cdr.put_octet (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Short x)
+{
+ cdr.put_short (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::UShort x)
+{
+ cdr.put_short (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Long x)
+{
+ cdr.put_long (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::ULong x)
+{
+ cdr.put_long (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::LongLong x)
+{
+ cdr.put_longlong (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::ULongLong x)
+{
+ cdr.put_ulonglong (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Float x)
+{
+ cdr.put_float (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Double x)
+{
+ cdr.put_double (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator<< (CDR &cdr, CORBA::Char x)
+{
+ cdr.put_char (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Octet &x)
+{
+ cdr.get_octet (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Short &x)
+{
+ cdr.get_short (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::UShort &x)
+{
+ cdr.get_ushort (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Long &x)
+{
+ cdr.get_long (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::ULong &x)
+{
+ cdr.get_ulong (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::LongLong &x)
+{
+ cdr.get_longlong (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::ULongLong &x)
+{
+ cdr.get_ulonglong (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Float &x)
+{
+ cdr.get_float (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Double &x)
+{
+ cdr.get_double (x);
+ return cdr;
+}
+
+ACE_INLINE CDR &
+operator>> (CDR &cdr, CORBA::Char &x)
+{
+ cdr.get_char (x);
+ return cdr;
+}
diff --git a/TAO/tao/NVList.cpp b/TAO/tao/NVList.cpp
new file mode 100644
index 00000000000..313c2fa764f
--- /dev/null
+++ b/TAO/tao/NVList.cpp
@@ -0,0 +1,275 @@
+// This may look like C, but it's really -*- C++ -*-
+
+// Implementation of Named Value List and NamedValue classes
+
+#include "tao/corba.h"
+
+CORBA::ULong
+CORBA_NamedValue::AddRef (void)
+{
+ return refcount_++;
+}
+
+CORBA::ULong
+CORBA_NamedValue::Release (void)
+{
+ {
+ ACE_ASSERT (this != 0);
+
+ if (--this->refcount_ != 0)
+ return this->refcount_;
+ }
+
+ // delete this;
+ // this is causing free mismatched memory error
+ this->~CORBA_NamedValue ();
+ ACE_OS::free (this);
+ return 0;
+}
+
+// Reference counting for DII Request object
+
+void
+CORBA::release (CORBA::NamedValue_ptr nv)
+{
+ if (nv)
+ nv->Release ();
+}
+
+CORBA::Boolean
+CORBA::is_nil (CORBA::NamedValue_ptr nv)
+{
+ return (CORBA::Boolean) (nv == 0);
+}
+
+CORBA_NamedValue::~CORBA_NamedValue (void)
+{
+ if (this->name_)
+ {
+ CORBA::string_free (this->name_);
+ this->name_ = 0;
+ }
+ // the Any will be destroyed on its own as we hold an instance and not a
+ // pointer to Any
+}
+
+
+// =Methods on class NVList
+
+CORBA::ULong
+CORBA_NVList::AddRef (void)
+{
+ return this->refcount_++;
+}
+
+CORBA::ULong
+CORBA_NVList::Release (void)
+{
+ {
+ ACE_ASSERT (this != 0);
+
+ if (--this->refcount_ != 0)
+ return this->refcount_;
+ }
+
+ delete this;
+ return 0;
+}
+
+// Reference counting for DII Request object
+
+void
+CORBA::release (CORBA::NVList_ptr nvl)
+{
+ if (nvl)
+ nvl->Release ();
+}
+
+CORBA::Boolean
+CORBA::is_nil (CORBA::NVList_ptr nvl)
+{
+ return (CORBA::Boolean) (nvl == 0);
+}
+
+CORBA_NVList::~CORBA_NVList (void)
+{
+ // destroy each NamedValue element
+ for (CORBA::ULong i = 0; i < this->max_; i++)
+ (&this->values_[i])->~CORBA_NamedValue ();
+
+ if (this->values_)
+ ACE_OS::free ((char *)values_);
+
+ this->values_ = 0;
+ this->len_ = this->max_ = 0;
+}
+
+// add an element and just initialize its flags
+CORBA::NamedValue_ptr
+CORBA_NVList::add (CORBA::Flags flags,
+ CORBA::Environment &env)
+{
+ CORBA::ULong len = this->len_; // next slot
+
+ // call the helper to allocate a NamedValue element (if necessary)
+ if (!this->add_element (flags, env))
+ return 0;
+
+ // now initialize the fields
+ this->values_[len].flags_ = flags;
+ return &this->values_[len];
+}
+
+// add an element and just initialize its flags and name
+CORBA::NamedValue_ptr
+CORBA_NVList::add_item (const char *name,
+ CORBA::Flags flags,
+ CORBA::Environment &env)
+{
+ CORBA::ULong len = this->len_; // next slot
+
+ // call the helper to allocate a NamedValue element (if necessary)
+ if (!this->add_element (flags, env))
+ return 0;
+
+ // now initialize the fields
+ this->values_[len].flags_ = flags;
+ this->values_[len].name_ = CORBA::string_dup (name);
+ return &this->values_[len];
+}
+
+// add a value. If necessary, increment the list
+CORBA::NamedValue_ptr
+CORBA_NVList::add_value (const char *name,
+ const CORBA::Any &value,
+ CORBA::Flags flags,
+ CORBA::Environment &env)
+{
+ CORBA::ULong len = this->len_; // next slot
+
+ // call the helper to allocate a NamedValue element (if necessary)
+ if (!this->add_element (flags, env))
+ return 0;
+
+ // now initialize the fields
+ this->values_[len].flags_ = flags;
+ this->values_[len].name_ = CORBA::string_dup (name); // make a copy
+
+ if (ACE_BIT_ENABLED (flags, CORBA::IN_COPY_VALUE))
+ // IN_COPY_VALUE means that the parameter is not "borrowed" by
+ // the ORB, but rather that the ORB copies its value.
+ //
+ // Initialize the newly allocated memory using a copy
+ // constructor that places the new "Any" value at just the right
+ // place, and makes a "deep copy" of the data.
+ (void) new (&this->values_[len].any_) CORBA::Any (value);
+ else
+
+ // The normal behaviour for parameters is that the ORB "borrows"
+ // their memory for the duration of calls.
+ //
+ // Initialize the newly allocated "Any" using a normal
+ // constructor that places the new "Any" value at just the right
+ // place, yet doesn't copy the memory (except for duplicating
+ // the typecode).
+ //
+ // NOTE: DSI has yet to be updated so that it's OK to use such
+ // application-allocated memory. It needs at least a "send the
+ // response now" call.
+ //
+ (void) new (&this->values_[len].any_) CORBA::Any (value.type (),
+ (void *)value.value (),
+ CORBA::B_FALSE); // does
+ // not
+ // own
+
+ // return pointer to the newly inserted member
+ return &this->values_[len];
+}
+
+// add an element and just initialize its flags and name
+CORBA::NamedValue_ptr
+CORBA_NVList::add_item_consume (char *name,
+ CORBA::Flags flags,
+ CORBA::Environment &env)
+{
+ CORBA::ULong len = this->len_; // next slot
+
+ // call the helper to allocate a NamedValue element (if necessary)
+ if (!this->add_element (flags, env))
+ return 0;
+
+ // now initialize the fields
+ this->values_[len].flags_ = flags;
+ this->values_[len].name_ = name; // we consume it
+ return &this->values_[len];
+}
+
+// add a value. If necessary, increment the list
+CORBA::NamedValue_ptr
+CORBA_NVList::add_value_consume (char * /*name*/,
+ CORBA::Any * /*value*/,
+ CORBA::Flags /*flags*/,
+ CORBA::Environment &/*env*/)
+{
+ // not implemented because we need to see how we can consume the value
+ // One soln is to make the any_ member of NamedValue to be a Any_ptr or
+ // Any_var
+ // XXXASG- TODO
+ return 0;
+}
+
+//CORBA::Status
+void
+CORBA_NVList::remove (CORBA::ULong /*n*/, CORBA::Environment &/*env*/)
+{
+ // not implemented
+ // XXXASG - TODO
+
+}
+
+// Helper method
+CORBA::Boolean
+CORBA_NVList::add_element (CORBA::Flags flags, CORBA::Environment &env)
+{
+ env.clear ();
+ if (ACE_BIT_DISABLED (flags, CORBA::ARG_IN | CORBA::ARG_OUT | CORBA::ARG_INOUT))
+ {
+ env.exception (new CORBA::BAD_PARAM (CORBA::COMPLETED_NO));
+ return 0;
+ }
+
+ // We track "len_" and "max_" like sequences do; mixing the
+ // "add_arg" and nvlist[i] style accessors produces undefined
+ // behaviour.
+ CORBA::ULong len = this->len_++; // len_ points to the next available
+ // slot. Access is by zero based indexing
+
+ // Extend the array with an _initialized_ element ... relying on
+ // zeroed memory to be sufficiently initialized.
+ //
+
+ if (this->values_ == 0) // list was created as an empty list
+ {
+ this->values_ = (CORBA::NamedValue_ptr)
+ ACE_OS::calloc (this->len_, sizeof (CORBA::NamedValue));
+ this->max_ = this->len_;
+ }
+ else if (len >= max_) // need reallocation
+ {
+ // reallocate a larger buffer
+ this->values_ = (CORBA::NamedValue_ptr) ACE_OS::realloc
+ ((char *)this->values_, sizeof (CORBA::NamedValue) * this->len_);
+ // now zero the elements that have been newly allocated
+ (void) ACE_OS::memset (&this->values_[this->max_], 0,
+ sizeof (values_[this->max_]) * (this->len_ - this->max_));
+ this->max_ = this->len_; // set the new maximum size
+ }
+ if (!this->values_)
+ {
+ env.exception (new CORBA::NO_MEMORY (CORBA::COMPLETED_NO));
+ return 0;
+ }
+
+ return 1; // success
+}
diff --git a/TAO/tao/NVList.h b/TAO/tao/NVList.h
new file mode 100644
index 00000000000..5dff27b1220
--- /dev/null
+++ b/TAO/tao/NVList.h
@@ -0,0 +1,160 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// NVList.h
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// and
+// Aniruddha Gokhale (additions, missing operations)
+//
+// ============================================================================
+
+#if !defined (TAO_NVLIST_H)
+# define TAO_NVLIST_H
+
+class TAO_Export CORBA_NamedValue
+{
+ // = TITLE
+ // NamedValue ... these occur only in "NVList" (named value list) data
+ // structures. The binary form of the data structure is frozen and
+ // visible to programs using it (e.g. from C). The C++ class supports
+ // some programming discipline, e.g. to avoid memory leaks.
+ //
+ // They just represent parameters to calls. The name is optional, and
+ // the value is packaged as an Any. The flags indicate parameter
+ // mode, and some ownership rules for "top level" memory.
+public:
+ const char *name (void) const;
+ // optional name
+
+ CORBA::Any_ptr value (void) const;
+ // return the value
+
+ CORBA::Flags flags (void) const;
+ // return the parameter mode flag
+
+ ~CORBA_NamedValue (void);
+ // destructor - manages the name and value
+
+ // = Methods required for COM IUnknown support.
+
+ CORBA::ULong AddRef (void);
+ CORBA::ULong Release (void);
+
+private:
+ u_int refcount_;
+ // refcount used in release
+
+ CORBA::Any any_;
+ // holds the value
+
+ CORBA::Flags flags_;
+ // parameter mode flags
+
+ char *name_;
+ // optional IDL name of the parameter
+
+ CORBA_NamedValue (void);
+ // private constructor. Cannot be directly instantiated other than by its
+ // friends.
+
+ friend class CORBA_ORB;
+ friend class CORBA_NVList;
+ friend class CORBA_Request;
+};
+
+class TAO_Export CORBA_NVList
+{
+ // = TITLE
+ // NVList ... this is used in the (client side) DII (Dynamic
+ // Invocation Interface) to hold parameters, except for the return
+ // parameter. It's used in the same role in the (server side) DSI
+ // (Dynamic Skeleton Interface).
+ //
+ // = DESCRIPTION
+ // Each user (client, server) provides the typecode and memory for
+ // each parameter using an NVList, then talks to the ORB using a
+ // Request or ServerRequest pseudo-object. The ORB copies data
+ // to/from the IPC messages (e.g. IIOP::Request, IIOP::Response)
+ // as appropriate.
+public:
+ ~CORBA_NVList (void);
+ // destructor
+
+ CORBA::ULong count (void) const;
+ // return the current number of elements in the list
+
+ CORBA::NamedValue_ptr add (CORBA::Flags,
+ CORBA::Environment &);
+ // add an element and just initialize the flags
+
+ CORBA::NamedValue_ptr add_item (const char *,
+ CORBA::Flags,
+ CORBA::Environment &);
+ // add an element and initialize its name and flags
+
+ CORBA::NamedValue_ptr add_value (const char *,
+ const CORBA::Any &,
+ CORBA::Flags,
+ CORBA::Environment &);
+ // initializes a value, name, and flags
+
+ CORBA::NamedValue_ptr add_item_consume (char *,
+ CORBA::Flags,
+ CORBA::Environment &);
+ // just like add_item. In addition, memory management of char * name is taken
+ // over by the NVList
+
+ CORBA::NamedValue_ptr add_value_consume (char *,
+ CORBA::Any_ptr,
+ CORBA::Flags,
+ CORBA::Environment &);
+ // just like add_value. In addition, the NVList controls the memory
+ // management of the char *name and Any *value parameter
+
+ CORBA::NamedValue_ptr item (CORBA::ULong n, CORBA::Environment &env);
+ // retrieve the item at the nth location. Raises Bounds
+
+
+ // CORBA::Status
+ void remove (CORBA::ULong n, CORBA::Environment &env);
+ // remove element at index n. Raises Bounds
+
+ // = Methods required for COM IUnknown support
+
+ CORBA::ULong AddRef (void);
+ CORBA::ULong Release (void);
+
+private:
+ CORBA_NVList (void);
+ // constructor - cannot be instantiated directly other than through the
+ // ORB::create_list method
+
+ CORBA::Boolean add_element (CORBA::Flags, CORBA::Environment &);
+ // helper to increase the list size. This is used by all the add_ methods of
+ // the NVList class
+
+ CORBA::NamedValue *values_;
+ // list of parameters stored as NamedValues
+
+ CORBA::ULong max_;
+ // maximum length of list
+
+ CORBA::ULong len_;
+ // current length of list
+
+ CORBA::ULong refcount_;
+ // maintains how many references exist to this object
+
+ friend class CORBA_ORB;
+ friend class CORBA_Request;
+};
+
+#endif /* TAO_NVLIST_H */
diff --git a/TAO/tao/NVList.i b/TAO/tao/NVList.i
new file mode 100644
index 00000000000..9cf97b1efcb
--- /dev/null
+++ b/TAO/tao/NVList.i
@@ -0,0 +1,63 @@
+// This may look like C, but it's really -*- C++ -*-
+
+// constructor
+ACE_INLINE
+CORBA_NamedValue::CORBA_NamedValue (void)
+ : refcount_ (1),
+ flags_ (0),
+ name_ (0)
+{
+}
+
+// return the name
+ACE_INLINE const char*
+CORBA_NamedValue::name (void) const
+{
+ return this->name_;
+}
+
+// return the value
+ACE_INLINE CORBA::Any_ptr
+CORBA_NamedValue::value (void) const
+{
+ return ACE_const_cast(CORBA::Any_ptr,&this->any_);
+}
+
+// return the flags
+ACE_INLINE CORBA::Flags
+CORBA_NamedValue::flags (void) const
+{
+ return this->flags_;
+}
+
+
+// = methods for the NVList class
+
+// constructor
+ACE_INLINE
+CORBA_NVList::CORBA_NVList (void)
+ : values_ (0),
+ max_ (0),
+ len_ (0),
+ refcount_ (1)
+{
+}
+
+ACE_INLINE CORBA::ULong
+CORBA_NVList::count (void) const
+{
+ return this->max_;
+}
+
+ACE_INLINE CORBA::NamedValue_ptr
+CORBA_NVList::item (CORBA::ULong n, CORBA::Environment &env)
+{
+ env.clear ();
+ if (n >= this->max_) // 0 based indexing
+ {
+ env.exception (new CORBA::TypeCode::Bounds ());
+ return 0;
+ }
+ else
+ return &this->values_ [n];
+}
diff --git a/TAO/tao/ORB_Strategies_T.cpp b/TAO/tao/ORB_Strategies_T.cpp
new file mode 100644
index 00000000000..4e236326a95
--- /dev/null
+++ b/TAO/tao/ORB_Strategies_T.cpp
@@ -0,0 +1,46 @@
+// $Id$
+
+#include "tao/ORB_Strategies_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/ORB_Strategies_T.i"
+#endif /* __ACE_INLINE__ */
+
+template <class SH> int
+TAO_Reactive_Strategy<SH>::activate_svc_handler (SH *svc_handler, void *arg)
+{
+ ACE_TRACE ("ACE_Reactive_Strategy<SVC_HANDLER>::activate_svc_handler");
+
+ ACE_Reactor *r = TAO_ORB_Core_instance ()->reactor ();
+
+ int result = 0;
+
+ if (r == 0)
+ result = -1;
+
+ // Register with the Reactor with the appropriate <mask>.
+ else if (r->register_handler (svc_handler, this->mask_) == -1)
+ result = -1;
+
+ // If the implementation of the reactor uses event associations
+ else if (r->uses_event_associations ())
+ {
+ // If we don't have non-block on, it won't work with
+ // WFMO_Reactor
+ // This maybe too harsh
+ // if (!ACE_BIT_ENABLED (this->flags_, ACE_NONBLOCK))
+ // goto failure;
+ if (svc_handler->open ((void *) this) != -1)
+ return 0;
+ else
+ result = -1;
+ }
+ else
+ // Call up to our parent to do the SVC_HANDLER initialization.
+ return this->inherited::activate_svc_handler (svc_handler, arg);
+
+ if (result == -1)
+ svc_handler->close (0);
+
+ return result;
+}
diff --git a/TAO/tao/ORB_Strategies_T.h b/TAO/tao/ORB_Strategies_T.h
new file mode 100644
index 00000000000..9f7dde2000a
--- /dev/null
+++ b/TAO/tao/ORB_Strategies_T.h
@@ -0,0 +1,45 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// ORB_Strategies_T.h
+//
+// = AUTHOR
+// Chris Cleeland
+//
+// ============================================================================
+
+#if !defined (TAO_ORB_STRATEGIES_T_H)
+# define TAO_ORB_STRATEGIES_T_H
+
+#include "ace/Strategies_T.h"
+
+template <class SH>
+class TAO_Reactive_Strategy : public ACE_Reactive_Strategy<SH>
+{
+ // @@ Please document me.
+public:
+ TAO_Reactive_Strategy (void);
+ ~TAO_Reactive_Strategy (void);
+
+ virtual int activate_svc_handler (SH *sh, void *arg);
+};
+
+#if defined (__ACE_INLINE__)
+#include "tao/ORB_Strategies_T.i"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "tao/ORB_Strategies_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ORB_Strategies_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* TAO_ORB_STRATEGIES_T_H */
diff --git a/TAO/tao/ORB_Strategies_T.i b/TAO/tao/ORB_Strategies_T.i
new file mode 100644
index 00000000000..9655ecf55a0
--- /dev/null
+++ b/TAO/tao/ORB_Strategies_T.i
@@ -0,0 +1,10 @@
+template <class SH> ACE_INLINE
+TAO_Reactive_Strategy<SH>::TAO_Reactive_Strategy (void)
+{
+}
+
+template <class SH> ACE_INLINE
+TAO_Reactive_Strategy<SH>::~TAO_Reactive_Strategy (void)
+{
+}
+
diff --git a/TAO/tao/Principal.cpp b/TAO/tao/Principal.cpp
new file mode 100644
index 00000000000..877c01ddacb
--- /dev/null
+++ b/TAO/tao/Principal.cpp
@@ -0,0 +1,50 @@
+// $Id$
+
+// Copyright 1994-1995 by Sun Microsystems Inc.
+// All Rights Reserved
+// ORB: Principal identifier pseudo-objref
+
+#include "tao/corba.h"
+
+void
+CORBA::release (CORBA::Principal_ptr principal)
+{
+ if (principal)
+ principal->Release ();
+}
+
+CORBA::Boolean
+CORBA::is_nil (CORBA::Principal_ptr principal)
+{
+ return (CORBA::Boolean) (principal == 0);
+}
+
+CORBA_Principal::CORBA_Principal (void)
+{
+}
+
+CORBA_Principal::~CORBA_Principal (void)
+{
+ assert (refcount_ == 0);
+
+ if (id.buffer)
+ delete [] id.buffer;
+}
+
+CORBA::ULong
+CORBA_Principal::AddRef (void)
+{
+ return ++refcount_;
+}
+
+CORBA::ULong
+CORBA_Principal::Release (void)
+{
+ {
+ if (--refcount_ != 0)
+ return refcount_;
+ }
+
+ delete this;
+ return 0;
+}
diff --git a/TAO/tao/Principal.h b/TAO/tao/Principal.h
new file mode 100644
index 00000000000..0de5dde1404
--- /dev/null
+++ b/TAO/tao/Principal.h
@@ -0,0 +1,60 @@
+// This may look like C, but it's really -*- C++ -*-
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO
+//
+// = FILENAME
+// principal.h
+//
+// = DESCRIPTION
+// The CORBA_Principal pseudo-object implementation.
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems Inc.
+//
+// ============================================================================
+
+#if !defined (TAO_PRINCIPAL_H)
+# define TAO_PRINCIPAL_H
+
+class TAO_Export CORBA_Principal
+{
+ // = TITLE
+ // A "Principal" identifies an authenticated entity in the
+ // network administration framework. Identities are used to
+ // control acccess (authorization) as well as in audit trails
+ // (accountability).
+public:
+ // To applications, the identifier is an opaque ID.
+
+ // CORBA::SEQUENCE <CORBA::Octet> id;
+ CORBA::OctetSeq id;
+
+ // @@ add "==", "<", ">" operators
+
+ // = Stuff required for memory management.
+ CORBA::ULong AddRef (void);
+ CORBA::ULong Release (void);
+
+ CORBA_Principal (void);
+
+private:
+ CORBA::ULong refcount_;
+
+ ~CORBA_Principal (void);
+
+ // = these are not provided
+ CORBA_Principal &operator = (const CORBA::Principal_ptr &);
+ CORBA_Principal (const CORBA::Principal_ptr &);
+
+#if defined (__GNUG__)
+ // G++ (even 2.6.3) stupidly thinks instances can't be created.
+ // This de-warns.
+ friend class everyone_needs_a_friend;
+#endif /* __GNUG__ */
+};
+
+#endif /* TAO_PRINCIPAL_H */
diff --git a/TAO/tao/tao.bld b/TAO/tao/tao.bld
index d9f475cfde4..d54ad9f554e 100644
--- a/TAO/tao/tao.bld
+++ b/TAO/tao/tao.bld
@@ -2,17 +2,17 @@
default:
library
:defines=DEBUG
-any.cpp
+Any.cpp
C++
-arg_shifter.cpp
+Arg_Shifter.cpp
C++
-cdr.cpp
+CDR.cpp
C++
-client_factory.cpp
+Client_Strategy_Factory.cpp
C++
-connect.cpp
+Connect.cpp
C++
-corbacom.cpp
+CORBA.cpp
C++
debug.cpp
C++
@@ -28,55 +28,55 @@ default_server.cpp
C++
encode.cpp
C++
-except.cpp
+Exception.cpp
C++
-giop.cpp
+GIOP.cpp
C++
-iiopobj.cpp
+IIOP_Object.cpp
C++
-iioporb.cpp
+IIOP_ORB.cpp
C++
interp.cpp
C++
-marshal.cpp
+Marshal.cpp
C++
-nvlist.cpp
+NVList.cpp
C++
-object.cpp
+Object.cpp
C++
-objkeyC.cpp
+Object_KeyC.cpp
C++
-objtable.cpp
+Object_Table.cpp
C++
-optable.cpp
+Operation_Table.cpp
C++
-orbobj.cpp
+ORB.cpp
C++
-orb_core.cpp
+ORB_Core.cpp
C++
params.cpp
C++
-poa.cpp
+POA.cpp
C++
-poaC.cpp
+POAC.cpp
C++
-poaS.cpp
+POAS.cpp
C++
-principa.cpp
+Principal.cpp
C++
-request.cpp
+Request.cpp
C++
-sequence.cpp
+Sequence.cpp
C++
-servant_base.cpp
+Servant_Base.cpp
C++
server_factory.cpp
C++
-svrrqst.cpp
+Server_Request.cpp
C++
-tao_internals.cpp
+Tao_Internal.cpp
C++
-tc_const.cpp
+Typecode_Constants.cpp
C++
-typecode.cpp
+Typecode.cpp
C++