summaryrefslogtreecommitdiff
path: root/TAO/tao/any.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/any.cpp')
-rw-r--r--TAO/tao/any.cpp679
1 files changed, 0 insertions, 679 deletions
diff --git a/TAO/tao/any.cpp b/TAO/tao/any.cpp
deleted file mode 100644
index a3aa868446b..00000000000
--- a/TAO/tao/any.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-// @ (#) $Id$
-//
-// Copyright 1994-1995 by Sun Microsystems Inc.
-// All Rights Reserved
-//
-// ORB: Implementation of CORBA_Any
-//
-// 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.
-//
-// COM NOTE: Yes, this is a utility data type whose implementation is
-// fully exposed. Factories for these are not normally used in C++.
-
-#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;
-
- type_->AddRef ();
-
- size = type_->size (env); // XXX check error status
- value_ = (char *) calloc (1, size);
-
-#if 0
- (void) type_->traverse (src.value_,
- value_,
- (CORBA::TypeCode::VisitRoutine) deep_copy,
- 0,
- env);
-#endif /* replaced by our optimizations */
-
- (void) DEEP_COPY (type_, src.value_, value_, env);
-}
-
-// 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[].
- 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);
- break;
-
- case CORBA::tk_wstring:
- CORBA::wstring_free (*(CORBA::WString *) value);
- 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 (refcount_ == 0);
-
- if (this->orb_owns_data_)
- {
- // (void) deep_free (type_, value_, 0, 0, env);
- DEEP_FREE (this->type_, this->value_, 0, env);
- // 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 (orb_owns_data_)
- {
- // (void) deep_free (type_, value_, 0, 0, env);
- if (value_)
- DEEP_FREE (type_, value_, 0, env);
- delete value_;
- }
-
- if (type_ != 0)
- type_->Release ();
-
- env.clear ();
-
- type_ = tc;
- tc->AddRef ();
- value_ = (void *) v;
- orb_owns_data_ = orb_owns_data;
-}
-
-// For COM -- IUnKnown operations
-
-// {A201E4C8-F258-11ce-9598-0000C07CA898}
-DEFINE_GUID (IID_CORBA_Any,
-0xa201e4c8, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98);
-
-ULONG
-__stdcall
-CORBA_Any::AddRef (void)
-{
- ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, lock_, 0));
-
- return ++refcount_;
-}
-
-ULONG __stdcall
-CORBA_Any::Release (void)
-{
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->lock_, 0));
-
- ACE_ASSERT (this != 0);
-
- if (--refcount_ != 0)
- return refcount_;
- }
-
- delete this;
- return 0;
-}
-
-HRESULT __stdcall
-CORBA_Any::QueryInterface (REFIID riid,
- void **ppv)
-{
- *ppv = 0;
-
- if (IID_CORBA_Any == riid || IID_IUnknown == riid)
- *ppv = this;
-
- if (*ppv == 0)
- return ResultFromScode (E_NOINTERFACE);
-
- (void) AddRef ();
- return NOERROR;
-}
-
-// VARIANT conversions
-
-// copy constructor
-
-CORBA_Any::CORBA_Any (const VARIANT &src)
-{
- orb_owns_data_ = CORBA::B_TRUE;
- refcount_ = 1;
- type_ = CORBA::_tc_void;
- value_ = 0;
-
- *this = src;
-}
-
-// assignment operator
-CORBA_Any &
-CORBA_Any::operator = (const VARIANT &src)
-{
- this->~CORBA_Any ();
-
- // XXX better, report exception
- assert (ACE_BIT_DISABLED (src.vt, 0xB000));
-
- switch (src.vt & 0x0fff)
- {
- case VT_EMPTY:
- type_ = CORBA::_tc_void;
- value_ = 0;
- break;
-
- case VT_NULL:
- type_ = CORBA::_tc_null;
- value_ = 0;
- break;
-
- case VT_I2:
- type_ = CORBA::_tc_short;
- value_ =
- new CORBA::Short ((src.vt & VT_BYREF) ? (*src.piVal) : src.iVal);
- break;
-
- case VT_I4:
- type_ = CORBA::_tc_long;
- value_ =
- new CORBA::Long ((src.vt & VT_BYREF) ? (*src.plVal) : src.lVal);
- break;
-
- case VT_R4:
- type_ = CORBA::_tc_float;
- value_ =
- new CORBA::Float ((src.vt & VT_BYREF) ? (*src.pfltVal) : src.fltVal);
- break;
-
- case VT_R8:
- type_ = CORBA::_tc_double;
- value_ =
- new CORBA::Double ((src.vt & VT_BYREF) ? (*src.pdblVal) : src.dblVal);
- break;
-
- // case VT_CY:
- // case VT_DATE:
- // XXX convert currency and date to TBD CORBA conventions
-
- // case VT_BSTR:
- // XXX convert to CORBA string
-
- // case VT_DISPATCH:
- // case VT_UNKNOWN:
- // case VT_VARIANT:
- // XXX convert to CORBA objref or appropriate pseudo-objref
-
- // case VT_BOOL:
- // XXX convert to CORBA boolean
-
- // case VT_ERROR:
- // XXX what to do?
-
- case VT_UI1:
- type_ = CORBA::_tc_octet;
- value_ =
- new CORBA::Octet ((src.vt & VT_BYREF) ? (*src.pbVal) : src.bVal);
- break;
-
- default:
- // XXX report some exception ... throw it?
- type_ = CORBA::_tc_void;
- value_ = 0;
- break;
- }
-
- return *this;
-}
-
-CORBA_Any::operator VARIANT (void)
-{
- VARIANT retval;
-
- // XXX convert it ... or report exception somehow!
-
- retval.vt = VT_EMPTY;
- return retval;
-}
-
-// ----------------------------------------------------------------------
-// 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;
-}
-