diff options
author | Ossama Othman <ossama-othman@users.noreply.github.com> | 2005-03-25 04:25:29 +0000 |
---|---|---|
committer | Ossama Othman <ossama-othman@users.noreply.github.com> | 2005-03-25 04:25:29 +0000 |
commit | ed4e2bf808e370e3c7b640933b8bc512afc3401b (patch) | |
tree | 97feb494342a1d7b82cf4488e99daf3704842fd6 | |
parent | 298ad64391ac7bad7bbd0309ce9850958eacebe6 (diff) | |
download | ATCD-ed4e2bf808e370e3c7b640933b8bc512afc3401b.tar.gz |
*** empty log message ***
86 files changed, 7451 insertions, 96 deletions
diff --git a/TAO/tao/Alias_TypeCode.cpp b/TAO/tao/Alias_TypeCode.cpp new file mode 100644 index 00000000000..9e5ce9ad484 --- /dev/null +++ b/TAO/tao/Alias_TypeCode.cpp @@ -0,0 +1,175 @@ +// $Id$ + +#ifndef TAO_ALIAS_TYPECODE_CPP +#define TAO_ALIAS_TYPECODE_CPP + +#include "tao/Alias_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/Alias_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <typename StringType, class RefCountPolicy> +TAO::TypeCode::Alias<StringType, RefCountPolicy>::~Alias (void) +{ + if (this->content_type_) + CORBA::release (*this->content_type_); +} + +template <typename StringType, class RefCountPolicy> +bool +TAO::TypeCode::Alias<StringType, RefCountPolicy>::tao_marshal ( + TAO_OutputCDR &) const +{ + // A tk_alias TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + return + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->attributes_.id ()) + && (cdr << this->attributes_.name ()) + && (cdr << *(this->content_type_.in ())); +} + +template <typename StringType, class RefCountPolicy> +void +TAO::TypeCode::Alias<StringType, RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, class RefCountPolicy> +void +TAO::TypeCode::Alias<StringType, RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Alias<StringType, RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL_NOT_USED) const +{ + // The CORBA::TypeCode base class already verified equality of the + // base attributes (id and name). Perform an equality comparison of + // the members. + + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return this->content_type_->equal (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <typename StringType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Alias<StringType, RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != CORBA::tk_alias) + return (0); + + char const * const this_id = this->attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return *(this->content_type_)->equivalent (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Alias<StringType, RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::tk_alias; +} + +template <typename StringType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Alias<StringType, RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + TAO_TypeCodeFactory_Adapter * adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name () + ); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TypeCode_var compact_content_type = + *(this->content_type_)->get_compact_typecode ( + ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + return adapter->create_alias_tc (this->attributes_.id (), + "" /* empty name */ + compact_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <typename StringType, class RefCountPolicy> +char const * +TAO::TypeCode::Alias<StringType, RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.id (); +} + +template <typename StringType, class RefCountPolicy> +char const * +TAO::TypeCode::Alias<StringType, RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.name (); +} + +template <typename StringType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Alias<StringType, RefCountPolicy>::content_type_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::TypeCode::_duplicate (*this->content_type_); +} + +#endif /* TAO_ALIAS_TYPECODE_CPP */ diff --git a/TAO/tao/Alias_TypeCode.h b/TAO/tao/Alias_TypeCode.h new file mode 100644 index 00000000000..c87afb00f09 --- /dev/null +++ b/TAO/tao/Alias_TypeCode.h @@ -0,0 +1,130 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Alias_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_alias CORBA::TypeCode. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_ALIAS_TYPECODE_H +#define TAO_ALIAS_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Alias + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c typedef. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c typedef. + */ + template <typename StringType, class RefCountPolicy> + class Alias + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + Alias (char const * id, + char const * name, + CORBA::TypeCode_ptr * tc); + + /// Destructor. + ~Alias (void); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_alias @c CORBA::TypeCode -specific template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual TypeCode_ptr content_type_i (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// Base attributes for this @c TypeCode containing the + /// repository ID and name of the @c typedef. + Base_Attributes<StringType> attributes_; + + /// The @c TypeCode corresponding to the original type upon + /// which the IDL @c typedef was made. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the @c + * CORBA::TypeCode_ptr when creating this @c Field statically at + * compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c TypeCode::Alias. + */ + CORBA::TypeCode_ptr * content_type_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Alias_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Alias_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Alias_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_ALIAS_TYPECODE_H */ diff --git a/TAO/tao/Alias_TypeCode.inl b/TAO/tao/Alias_TypeCode.inl new file mode 100644 index 00000000000..e955b596fd7 --- /dev/null +++ b/TAO/tao/Alias_TypeCode.inl @@ -0,0 +1,16 @@ +// -*- C++ -*- +// +// $Id$ + + +template <class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Alias<StringType, RefCountPolicy>::Alias ( + char const * id, + char const * name, + CORBA::TypeCode_ptr * tc) + : RefCountPolicy (), + attributes_ (id, name), + content_type_ (tc) +{ +} diff --git a/TAO/tao/Any.cpp b/TAO/tao/Any.cpp index c688e1b4cb6..e881c609647 100644 --- a/TAO/tao/Any.cpp +++ b/TAO/tao/Any.cpp @@ -7,7 +7,8 @@ #include "tao/Any_Dual_Impl_T.h" #include "tao/Any_Unknown_IDL_Type.h" #include "tao/Object.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" +#include "tao/TypeCode_Constants.h" #include "tao/SystemException.h" #include "tao/CDR.h" diff --git a/TAO/tao/Any_Basic_Impl.cpp b/TAO/tao/Any_Basic_Impl.cpp index 9afe23ce010..a5d4b950f26 100644 --- a/TAO/tao/Any_Basic_Impl.cpp +++ b/TAO/tao/Any_Basic_Impl.cpp @@ -1,7 +1,7 @@ // $Id$ #include "tao/Any_Basic_Impl.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "tao/Any_Unknown_IDL_Type.h" #include "tao/CDR.h" #include "tao/SystemException.h" @@ -18,8 +18,15 @@ namespace TAO Any_Basic_Impl::Any_Basic_Impl (CORBA::TypeCode_ptr tc, void *value) : Any_Impl (0, tc), - kind_ (tc ? tc->kind_ : CORBA::tk_null) + kind_ (CORBA::tk_null) { + if (!CORBA::is_nil (tc)) + { + ACE_DECLARE_NEW_CORBA_ENV; + this->kind_ = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + CORBA::TCKind const tckind = static_cast<CORBA::TCKind> (this->kind_); switch (tckind) @@ -137,7 +144,7 @@ namespace TAO // Get the kind of the type where we are extracting in ie. the // aliased type if there are any. Passing the aliased kind // will not help. - CORBA::TCKind tck = tc->kind (); + CORBA::TCKind const tck = tc->kind (); // We don't want the rd_ptr of unk to move, in case it is // shared by another Any. This copies the state, not the buffer. @@ -151,7 +158,7 @@ namespace TAO { Any_Basic_Impl::assign_value (_tao_elem, replacement, - tck); + tck); const_cast<CORBA::Any &> (any).replace (replacement); replacement_safety.release (); return 1; @@ -268,7 +275,10 @@ namespace TAO Any_Basic_Impl * Any_Basic_Impl::create_empty (CORBA::TypeCode_ptr tc) { - CORBA::TCKind const kind = static_cast<CORBA::TCKind> (tc->kind_); + ACE_DECLARE_NEW_CORBA_ENV; + CORBA::TCKind const kind = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + TAO::Any_Basic_Impl * retval = 0; switch (kind) diff --git a/TAO/tao/Any_Dual_Impl_T.cpp b/TAO/tao/Any_Dual_Impl_T.cpp index be0ac30c674..e9b2442d874 100644 --- a/TAO/tao/Any_Dual_Impl_T.cpp +++ b/TAO/tao/Any_Dual_Impl_T.cpp @@ -10,7 +10,7 @@ #include "tao/Environment.h" #include "tao/SystemException.h" #include "tao/CDR.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "ace/CORBA_macros.h" #include "ace/Auto_Ptr.h" diff --git a/TAO/tao/Any_Impl.cpp b/TAO/tao/Any_Impl.cpp index 8a81a18a9df..90315638c32 100644 --- a/TAO/tao/Any_Impl.cpp +++ b/TAO/tao/Any_Impl.cpp @@ -4,7 +4,7 @@ #include "Marshal.h" #include "CORBA_String.h" #include "SystemException.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ace/Guard_T.h" diff --git a/TAO/tao/Any_Impl_T.cpp b/TAO/tao/Any_Impl_T.cpp index dce88148265..5a06163cfa5 100644 --- a/TAO/tao/Any_Impl_T.cpp +++ b/TAO/tao/Any_Impl_T.cpp @@ -9,7 +9,7 @@ #include "tao/CDR.h" #include "tao/Environment.h" #include "tao/SystemException.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "ace/CORBA_macros.h" #include "ace/Auto_Ptr.h" diff --git a/TAO/tao/Any_Special_Impl_T.cpp b/TAO/tao/Any_Special_Impl_T.cpp index 00d2766e517..e9745d7eb26 100644 --- a/TAO/tao/Any_Special_Impl_T.cpp +++ b/TAO/tao/Any_Special_Impl_T.cpp @@ -7,7 +7,7 @@ #include "tao/Any_Unknown_IDL_Type.h" #include "tao/Marshal.h" #include "tao/Environment.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "ace/CORBA_macros.h" @@ -47,36 +47,36 @@ TAO::Any_Special_Impl_T<T, from_T, to_T>::insert (CORBA::Any & any, CORBA::ULong bound ) { - CORBA::TypeCode_ptr bounded_tc = CORBA::TypeCode::_nil (); - - if (bound > 0) - { - CORBA::TCKind kind = static_cast<CORBA::TCKind> (tc->kind_); - CORBA::Long _oc_buffer [] = - { - TAO_ENCAP_BYTE_ORDER, - static_cast<CORBA::Long> (bound) - }; - - ACE_NEW (bounded_tc, - CORBA::TypeCode (kind, - sizeof _oc_buffer, - (char *) &_oc_buffer, - 1, - 0)); - } - else - { - bounded_tc = CORBA::TypeCode::_duplicate (tc); - } - - Any_Special_Impl_T<T, from_T, to_T> *new_impl = 0; +// CORBA::TypeCode_ptr bounded_tc = CORBA::TypeCode::_nil (); + +// if (bound > 0) +// { +// CORBA::TCKind kind = static_cast<CORBA::TCKind> (tc->kind_); +// static CORBA::Long _oc_buffer [] = +// { +// TAO_ENCAP_BYTE_ORDER, +// static_cast<CORBA::Long> (bound) +// }; + +// ACE_NEW (bounded_tc, +// CORBA::TypeCode (kind, +// sizeof _oc_buffer, +// (char *) &_oc_buffer, +// 1, +// 0)); +// } +// else +// { +// bounded_tc = CORBA::TypeCode::_duplicate (tc); +// } + + Any_Special_Impl_T<T, from_T, to_T> * new_impl = 0; ACE_NEW (new_impl, Any_Special_Impl_T (destructor, - bounded_tc, + /* bounded_ */ tc, value, bound)); - CORBA::release (bounded_tc); +// CORBA::release (bounded_tc); any.replace (new_impl); } @@ -95,7 +95,8 @@ TAO::Any_Special_Impl_T<T, from_T, to_T>::extract (const CORBA::Any & any, { CORBA::TypeCode_ptr any_type = any._tao_get_typecode (); CORBA::TypeCode_var unaliased_any_type = - any_type->unalias (ACE_ENV_SINGLE_ARG_PARAMETER); + TAO::unaliased_typecode (any_type + ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; CORBA::TCKind any_kind = diff --git a/TAO/tao/Any_SystemException.cpp b/TAO/tao/Any_SystemException.cpp index ea168a4f405..7c3860c4751 100644 --- a/TAO/tao/Any_SystemException.cpp +++ b/TAO/tao/Any_SystemException.cpp @@ -8,7 +8,7 @@ #include "Marshal.h" #include "CORBA_String.h" #include "SystemException.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ace/Auto_Ptr.h" #include "ace/CORBA_macros.h" diff --git a/TAO/tao/Any_Unknown_IDL_Type.cpp b/TAO/tao/Any_Unknown_IDL_Type.cpp index 1154674fe69..1f80c2fc3b3 100644 --- a/TAO/tao/Any_Unknown_IDL_Type.cpp +++ b/TAO/tao/Any_Unknown_IDL_Type.cpp @@ -5,15 +5,18 @@ #include "tao/ORB_Core.h" #include "tao/SystemException.h" #include "tao/Marshal.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" +#include "tao/CDR.h" #include "ace/Dynamic_Service.h" #include "ace/OS_NS_string.h" + ACE_RCSID (tao, Any_Unknown_IDL_Type, "$Id$") + TAO::Unknown_IDL_Type::Unknown_IDL_Type ( CORBA::TypeCode_ptr tc, TAO_InputCDR &cdr diff --git a/TAO/tao/CDR_Encaps_Codec.cpp b/TAO/tao/CDR_Encaps_Codec.cpp index a01f912d1b2..706f516ae67 100644 --- a/TAO/tao/CDR_Encaps_Codec.cpp +++ b/TAO/tao/CDR_Encaps_Codec.cpp @@ -8,7 +8,7 @@ #include "OctetSeqC.h" #include "Any.h" #include "Any_Impl.h" -#include "Typecode.h" +#include "TypeCode.h" #include "Marshal.h" #include "Any_Unknown_IDL_Type.h" #include "SystemException.h" diff --git a/TAO/tao/Empty_Param_TypeCode.cpp b/TAO/tao/Empty_Param_TypeCode.cpp new file mode 100644 index 00000000000..b15fa95f4ff --- /dev/null +++ b/TAO/tao/Empty_Param_TypeCode.cpp @@ -0,0 +1,88 @@ +// $Id$ + +#include "Empty_Param_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "Empty_Param_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +ACE_RCSID (tao, + Empty_Param_TypeCode, + "$Id$") + + +bool +TAO::TypeCode::Empty_Param::tao_marshal (TAO_OutputCDR &) const +{ + // Empty parameter list. Nothing to marshal. + + return true; +} + +void +TAO::TypeCode::Empty_Param::tao_duplicate (void) +{ + // No-op since empty parameter TypeCodes are never created + // dynamically, meaning there is no need to implement reference + // counting. +} + +void +TAO::TypeCode::Empty_Param::tao_release (void) +{ + // No-op since empty parameter TypeCodes are never created + // dynamically, meaning there is no need to implement reference + // counting. +} + +CORBA::Boolean +TAO::TypeCode::Empty_Param::equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // Equality has already been established in the + // CORBA::TypeCode base class. + + return 1; +} + +CORBA::Boolean +TAO::TypeCode::Empty_Param::equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this->kind_) + return 0; + + return 1; +} + +CORBA::TCKind +TAO::TypeCode::Empty_Param::kind_i (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->kind_; +} + +CORBA::TypeCode_ptr +TAO::TypeCode::Empty_Param::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Already compact since parameter list is empty. + + // Since empty parameter TypeCodes are never created + // dynamically, there is no need to manipulate a reference count. + + static TAO::TypeCode::Empty_Param compact_typecode (this->kind_); + + return &compact_typecode; +} diff --git a/TAO/tao/Empty_Param_TypeCode.h b/TAO/tao/Empty_Param_TypeCode.h new file mode 100644 index 00000000000..7416d9d6161 --- /dev/null +++ b/TAO/tao/Empty_Param_TypeCode.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Empty_Param_TypeCode.h + * + * $Id$ + * + * Header file for @c CORBA::TypeCodes with empty parameter lists. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_EMPTY_PARAM_TYPECODE_H +#define TAO_EMPTY_PARAM_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Empty_Param + * + * @brief @c CORBA::TypeCode implementation for OMG IDL types with + * empty parameter lists. + * + * This class implements a @c CORBA::TypeCode for OMG IDL types + * with empty parameter lists. + * + * @note @c Empty_Param @c TypeCodes are not reference counted in + * TAO since they are static, exist as constants for the + * length of a given OS process, and cannot be created + * through the @c CORBA::ORB or @c CORBA::TypeCodeFactory + * interfaces. + */ + class Empty_Param : public CORBA::TypeCode + { + public: + + /// Constructor. + Empty_Param (CORBA::TCKind k); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c CORBA::TypeCode template methods specific to @c TypeCodes + * with empty parameter lists. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// Kind of this @c TypeCode. + CORBA::TCKind const kind_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Empty_Param_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_EMPTY_PARAM_TYPECODE_H */ diff --git a/TAO/tao/Empty_Param_TypeCode.inl b/TAO/tao/Empty_Param_TypeCode.inl new file mode 100644 index 00000000000..81a5d13e0d1 --- /dev/null +++ b/TAO/tao/Empty_Param_TypeCode.inl @@ -0,0 +1,10 @@ +// -*- C++ -*- +// +// $Id$ + + +ACE_INLINE +TAO::TypeCode::Empty_Param::Empty_Param (CORBA::TCKind k) + : kind_ (k) +{ +} diff --git a/TAO/tao/Enum_TypeCode.cpp b/TAO/tao/Enum_TypeCode.cpp new file mode 100644 index 00000000000..976e39a28dd --- /dev/null +++ b/TAO/tao/Enum_TypeCode.cpp @@ -0,0 +1,272 @@ +// $Id$ + +#ifndef TAO_ENUM_TYPECODE_CPP +#define TAO_ENUM_TYPECODE_CPP + +#include "tao/Enum_TypeCode.h" +#include "tao/TypeCode_Enumerators.h" + +#ifndef __ACE_INLINE__ +# include "tao/Enum_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +bool +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::tao_marshal ( + TAO_OutputCDR & cdr) const +{ + // A tk_enum TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + bool const success = + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->base_attributes_.id ()) + && (cdr << this->base_attributes_.name ()) + && (cdr << this->nenumerators_); + + if (!success) + return false; + + Enumerator<StringType> const * const begin = this->enumerators (); + Enumerator<StringType> const * const end = begin + this->nenumerators_; + + for (Enumerator<StringType> const * i = begin; i != end; ++i) + { + Enumerator<StringType> const & enumerator = *i; + + if (!(cdr << enumerator.get_name ())) + return false; + } + + return true; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +void +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +void +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // This call shouldn't throw since CORBA::TypeCode::equal() verified + // that the TCKind is the same as our's prior to invoking this + // method, meaning that member_count() is supported. + + CORBA::ULong const tc_nenumerators = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nenumerators != this->nenumerators_) + return 0; + + for (CORBA::ULong i = 0; i < this->nenumerators_; ++i) + { + Enumerator<StringType> const & lhs_enumerator = this->enumerators_[i]; + + char const * const lhs_name = lhs_enumerator.get_name (); + char const * const rhs_name = tc->member_name (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strcmp (lhs_name, rhs_name) != 0) + return 0; + } + + return 1; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // Call kind_i() instead of using CORBA::tk_enum directly since a + // subclass, such as Except_TypeCode, can use this equivalent_i() + // implementation. + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this_kind) + return 0; + + char const * const this_id = this->base_attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + // Perform a enumural comparison, excluding the name() and + // member_name() operations. + + CORBA::ULong const tc_nenumerators = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nenumerators != this->nenumerators_) + return 0; + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Enum<StringType, EnumeratorArrayType, RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::tk_enum; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + Enumerator<StringType> * tc_enumerators = 0; + + ACE_Auto_Array_Ptr<Enumerator<StringType> > safe_enumerators; + + if (this->nenumerators_ > 0) + { + // Dynamically construct a new array of enumerators stripped of + // member names. + + ACE_NEW_THROW_EX (tc_enumerators, + Enumerator<StringType> [this->nenumerators_], + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + safe_enumerators.reset (enumerators); + + static char const * empty_name = ""; + + for (CORBA::ULong i = 0; i < this->nenumerators_; ++i) + { + // Member names will be stripped, i.e. not embedded within + // the compact TypeCode. + + tc_enumerators[i].name = empty_name; + } + } + + TAO_TypeCodeFactory_Adapter * adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name ()); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + tc = adapter->_tao_create_enum_tc (this_kind, + this->base_attributes_.id (), + "" /* empty name */, + tc_enumerators, + this->nenumerators_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + (void) safe_enumerators.release (); + + return tc; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Enum<StringType, EnumeratorArrayType, RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.id (); +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Enum<StringType, EnumeratorArrayType, RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.name (); +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +CORBA::ULong +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::member_count_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->nenumerators_; +} + +template <typename StringType, class EnumeratorArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Enum<StringType, + EnumeratorArrayType, + RefCountPolicy>::member_name_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + if (index >= this->nenumerators_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); + + return this->enumerators_[index].get_name (); +} + +#endif /* TAO_ENUM_TYPECODE_CPP */ diff --git a/TAO/tao/Enum_TypeCode.h b/TAO/tao/Enum_TypeCode.h new file mode 100644 index 00000000000..753d1d8aa91 --- /dev/null +++ b/TAO/tao/Enum_TypeCode.h @@ -0,0 +1,147 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Enum_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_enum CORBA::TypeCode. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_ENUM_TYPECODE_H +#define TAO_ENUM_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Base_Attributes.h" + + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Enum + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c enum. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c enum. + */ + template <typename StringType, + class EnumeratorArrayType, + class RefCountPolicy> + class Enum + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Conenumor. + Enum (char const * id, + char const * name, + Enumerator<StringType> const * enumerators, + CORBA::ULong nenumerators); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_enum @c CORBA::TypeCode -specific template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong member_count_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * member_name_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + //@} + + private: + + /// Get pointer to the underlying @c Enumerator array. + Enumerator<StringType> const * enumerators (void) const; + + private: + + /** + * @c Enum Attributes + * + * Attributes representing the structure of an OMG IDL + * @c enum. + * + * @note These attributes are declared in the order in which + * they are marshaled into a CDR stream in order to + * increase cache hits by improving spatial locality. + */ + //@{ + + /// Base attributes containing repository ID and name of + /// structure type. + Base_Attributes base_attributes_; + + /// The number of enumerators in the OMG IDL enumeration. + CORBA::ULong const nenumerators_; + + /// Array of @c TAO::TypeCode enumerators representing + /// enumerators in the OMG IDL defined @c enum. + EnumeratorArrayType const enumerators_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Enum_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Enum_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Enum_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_ENUM_TYPECODE_H */ diff --git a/TAO/tao/Enum_TypeCode.inl b/TAO/tao/Enum_TypeCode.inl new file mode 100644 index 00000000000..a55f91dbada --- /dev/null +++ b/TAO/tao/Enum_TypeCode.inl @@ -0,0 +1,16 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename StringType, class AttrType, class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Enum<StringType, AttrType, RefCountPolicy>::Enum ( + char const * id, + char const * name, + Enumerator<StringType> const * enumerators, + CORBA::ULong nenumerators) + : base_attributes_ (id, name) + , nenumerators_ (nenumerators) + , enumerators_ (enumerators) +{ +} diff --git a/TAO/tao/Exception.cpp b/TAO/tao/Exception.cpp index e8711f28f66..92e4d7df62e 100644 --- a/TAO/tao/Exception.cpp +++ b/TAO/tao/Exception.cpp @@ -5,9 +5,9 @@ #include "Environment.h" #include "Any_SystemException.h" #include "Any_Dual_Impl_T.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ORB_Constants.h" -#include "TC_Constants_Forward.h" +#include "TypeCode_Constants.h" #include "CORBA_String.h" #include "CDR.h" #include "debug.h" diff --git a/TAO/tao/Fixed_TypeCode.cpp b/TAO/tao/Fixed_TypeCode.cpp new file mode 100644 index 00000000000..177b7602d0f --- /dev/null +++ b/TAO/tao/Fixed_TypeCode.cpp @@ -0,0 +1,127 @@ +// $Id$ + +#ifndef TAO_FIXED_TYPECODE_CPP +#define TAO_FIXED_TYPECODE_CPP + +#include "Fixed_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/Fixed_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <class RefCountPolicy> +bool +TAO::TypeCode::Fixed<RefCountPolicy>::tao_marshal (TAO_OutputCDR & cdr) const +{ + // A tk_fixed TypeCode has a "simple" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that its parameter(s) must be + // marshaled immediately following the TCKind. No CDR encapsulation + // is to be created. + + return (cdr << this->digits_) && (cdr << this->scale_); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::Fixed<RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::Fixed<RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Fixed<RefCountPolicy>::equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // The following call won't throw since CORBA::TypeCode::equal() has + // already established the kind of tc is the same as our kind. + CORBA::UShort const tc_digits = + tc->fixed_digits (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::UShort const tc_scale = + tc->fixed_scale (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return (this->digits_ == tc_digits + && this->scale_ == tc_scale); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Fixed<RefCountPolicy>::equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // Call kind_i() instead of using CORBA::tk_fixed directly since a + // subclass, such as WFixed_TypeCode, can use this equivalent_i() + // implementation. + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this_kind) + return 0; + + // Since TCKind comparisons must be performed before equal_i() is + // called, we can also call it to determine equivalence of + // tk_fixed TypeCodes. + return this->equal_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +template <class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Fixed<RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::tk_fixed; +} + +template <class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Fixed<RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Already compact since tk_fixed TypeCodes have no name or member + // names, meaning that we can simply call _duplicate() on this + // TypeCode. + return CORBA::TypeCode::_duplicate (this); +} + +template <class RefCountPolicy> +CORBA::UShort +TAO::TypeCode::Fixed<RefCountPolicy>::fixed_digits_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->digits_; +} + +template <class RefCountPolicy> +CORBA::UShort +TAO::TypeCode::Fixed<RefCountPolicy>::fixed_scale_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->scale_; +} + + +#endif /* TAO_FIXED_TYPECODE_CPP */ diff --git a/TAO/tao/Fixed_TypeCode.h b/TAO/tao/Fixed_TypeCode.h new file mode 100644 index 00000000000..aff9cc46dba --- /dev/null +++ b/TAO/tao/Fixed_TypeCode.h @@ -0,0 +1,104 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Fixed_TypeCode.h + * + * $Id$ + * + * Header file for @c CORBA::tk_fixed @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_FIXED_TYPECODE_H +#define TAO_FIXED_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Fixed + * + * @brief @c CORBA::TypeCode implementation for the OMG IDL @fixed + * types. + * + * This class implements a @c CORBA::TypeCode for the OMG IDL @c + * fixed types. + */ + template <class RefCountPolicy> + class Fixed : public CORBA::TypeCode + : private RefCountPolicy + { + public: + + /// Constructor. + Fixed (CORBA::UShort digits, CORBA::UShort scale); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c CORBA::TypeCode template methods specific to @c tk_fixed + * @c TypeCodes. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual UShort fixed_digits_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual UShort fixed_scale_i (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// The number of significant digits. + CORBA::UShort const digits_; + + /// The scale factor. + CORBA::UShort const scale_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Fixed_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_FIXED_TYPECODE_H */ diff --git a/TAO/tao/Fixed_TypeCode.inl b/TAO/tao/Fixed_TypeCode.inl new file mode 100644 index 00000000000..16217258126 --- /dev/null +++ b/TAO/tao/Fixed_TypeCode.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id$ + +template <class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Fixed<RefCountPolicy::Fixed (CORBA::UShort digits, + CORBA::UShort scale) + : digits_ (digits), + scale_ (scale) +{ +} diff --git a/TAO/tao/Invocation_Base.cpp b/TAO/tao/Invocation_Base.cpp index 08b0253c9fe..46caafc77e9 100644 --- a/TAO/tao/Invocation_Base.cpp +++ b/TAO/tao/Invocation_Base.cpp @@ -2,7 +2,7 @@ #include "Stub.h" #include "operation_details.h" #include "ORB_Core.h" -#include "Typecode.h" +#include "TypeCode.h" #include "DynamicC.h" #include "SystemException.h" diff --git a/TAO/tao/Marshal.cpp b/TAO/tao/Marshal.cpp index 16826a284ca..b63181880a5 100644 --- a/TAO/tao/Marshal.cpp +++ b/TAO/tao/Marshal.cpp @@ -22,7 +22,7 @@ // ============================================================================ #include "tao/Marshal.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #if !defined (__ACE_INLINE__) # include "tao/Marshal.i" diff --git a/TAO/tao/NVList.cpp b/TAO/tao/NVList.cpp index fdfb2213e16..9049d4434b0 100644 --- a/TAO/tao/NVList.cpp +++ b/TAO/tao/NVList.cpp @@ -7,7 +7,7 @@ #include "tao/SystemException.h" #include "tao/BoundsC.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "tao/Marshal.h" #include "tao/CORBA_String.h" #include "tao/Any_Impl.h" diff --git a/TAO/tao/Null_RefCount_Policy.h b/TAO/tao/Null_RefCount_Policy.h new file mode 100644 index 00000000000..fd4ea8e2f57 --- /dev/null +++ b/TAO/tao/Null_RefCount_Policy.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Null_RefCount_Policy.h + * + * $Id$ + * + * Header file for TAO's reference count policy (unrelated to CORBA + * policies). + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_NULL_REFCOUNT_POLICY_H +#define TAO_NULL_REFCOUNT_POLICY_H + +#include /**/ "ace/pre.h" + +#include "tao/TAO_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + /** + * @class Null_RefCount_Policy + * + * @brief No-op reference counting policy. + * + * This class is intended to be used as a "policy" argument to a + * host class template that implements no-op reference counting. + * That class would then inherit privately from it like so: + * + * @code + * template <class RefCountPolicy> + * class MyHostClass : private RefCountPolicy + * { + * public: + * void my_add_ref (void) { this->RefCountPolicy::add_ref (); } + * void my_remove_ref (void) { this->RefCountPolicy::remove_ref (); } + * }; + * @endcode + * + * and use it like so: + * + * @code + * typedef MyHostClass<TAO::Null_RefCount_Policy> MyNonRefCountedClass; + * MyNonRefCountedClass m; + * ... + * @endcode + * + * @note In order to incur no size overhead on the host class due to + * virtual tables, no base class defining an interface is + * defined. This allows C++ compilers to apply the Empty Base + * Class Optimization. + */ + class TAO_Export Null_RefCount_Policy + { + public: + + /// No-op reference increment. + void add_ref (void) { } + + /// No-op reference decrement. + void remove_ref (void) { } + + }; + +} // End namespace TAO + +#include /**/ "ace/post.h" + +#endif /* TAO_NULL_REFCOUNT_POLICY_H */ diff --git a/TAO/tao/ORB.h b/TAO/tao/ORB.h index 7bd410a275d..dcdea3771f3 100644 --- a/TAO/tao/ORB.h +++ b/TAO/tao/ORB.h @@ -8,8 +8,9 @@ * * Header file for CORBA's ORB type. * - * @author Copyright 1994-1995 by Sun Microsystems Inc. - * @author Douglas C. Schmidt <schmidt@dre.vanderbilt.edu.edu> + * @author DOC Center - Washington University at St. Louis + * @author DOC Group - Vanderbilt University + * @author DOC Laboratory - University of California at Irvine */ //============================================================================= @@ -154,22 +155,22 @@ namespace CORBA virtual void _raise (void) const; virtual void _tao_encode (TAO_OutputCDR & - ACE_ENV_ARG_DECL_NOT_USED) const; + ACE_ENV_ARG_DECL) const; virtual void _tao_decode (TAO_InputCDR & - ACE_ENV_ARG_DECL_NOT_USED); + ACE_ENV_ARG_DECL); }; typedef char *ObjectId; typedef CORBA::String_var ObjectId_var; typedef CORBA::String_out ObjectId_out; - static CORBA::TypeCode_ptr _tc_ObjectId; + static CORBA::TypeCode_ptr const _tc_ObjectId; typedef CORBA::ORB_ObjectIdList ObjectIdList; typedef CORBA::ORB_ObjectIdList_var ObjectIdList_var; typedef CORBA::ORB_ObjectIdList_out ObjectIdList_out; typedef CORBA::ORB_ObjectIdList *ObjectIdList_ptr; - static CORBA::TypeCode_ptr _tc_ObjectIdList; + static CORBA::TypeCode_ptr const _tc_ObjectIdList; /// Return a duplicate of @c orb. /** @@ -377,7 +378,7 @@ namespace CORBA CORBA::TypeCode_ptr create_local_interface_tc ( const char *id, - const char *ame + const char *name ACE_ENV_ARG_DECL_WITH_DEFAULTS); CORBA::TypeCode_ptr create_component_tc ( @@ -581,7 +582,8 @@ namespace CORBA ACE_Time_Value *get_timeout (void); protected: - // We must be created via the @c ORB_init() call. + + // We must be created via the @c CORBA::ORB_init() function. ORB (TAO_ORB_Core *orb_core); /// Destructor @@ -596,12 +598,12 @@ namespace CORBA /// Resolve the Policy Manager for this ORB. CORBA::Object_ptr resolve_policy_manager ( - ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ACE_ENV_SINGLE_ARG_DECL ); /// Resolve the Policy Current for this thread. CORBA::Object_ptr resolve_policy_current ( - ACE_ENV_SINGLE_ARG_DECL_NOT_USED + ACE_ENV_SINGLE_ARG_DECL ); private: @@ -623,7 +625,7 @@ namespace CORBA void check_shutdown (ACE_ENV_SINGLE_ARG_DECL); /// Set the timeout value - void set_timeout (ACE_Time_Value *timeout); + void set_timeout (ACE_Time_Value * timeout); private: @@ -645,7 +647,7 @@ namespace CORBA ORB &operator= (const ORB &); /// Timeout value - ACE_Time_Value *timeout_; + ACE_Time_Value * timeout_; }; } // End namespace CORBA diff --git a/TAO/tao/Objref_TypeCode.cpp b/TAO/tao/Objref_TypeCode.cpp new file mode 100644 index 00000000000..26a5b7bcd25 --- /dev/null +++ b/TAO/tao/Objref_TypeCode.cpp @@ -0,0 +1,146 @@ +// $Id$ + +#ifndef TAO_OBJREF_TYPECODE_CPP +#define TAO_OBJREF_TYPECODE_CPP + +#include "tao/Objref_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/Objref_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + +#include "tao/ORB_Core.h" +#include "tao/CDR.h" + +#include "ace/Dynamic_Service.h" + + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +bool +TAO::TypeCode::Objref<StringType, + Kind, + RefCountPolicy>::tao_marshal (TAO_OutputCDR & cdr) const +{ + // A tk_objref TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + return + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << TAO_OutputCDR::from_string (this->attributes_.id (), 0)) + && (cdr << TAO_OutputCDR::from_string (this->attributes_.name (), 0)); +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +void +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +void +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr /* tc */ + ACE_ENV_ARG_DECL_NOT_USED) const +{ + // Equality has already been established in the + // CORBA::TypeCode base class. + + return 1; +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != Kind) + return 0; + + char const * const this_id = this->attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strcmp (this_id, tc_id) != 0) + return 0; + + return 1; +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return Kind; +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Objref<StringType, + Kind, + RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + TAO_TypeCodeFactory_Adapter * const adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name () + ); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + return + Objref_Traits<Kind>::create_compact_typecode (adapter, + this->attributes_.id () + ACE_ENV_ARG_PARAMETER); +} + + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +char const * +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.id (); +} + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +char const * +TAO::TypeCode::Objref<StringType, Kind, RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.name (); +} + + +#endif /* TAO_OBJREF_TYPECODE_CPP */ diff --git a/TAO/tao/Objref_TypeCode.h b/TAO/tao/Objref_TypeCode.h new file mode 100644 index 00000000000..cd8629b2fb7 --- /dev/null +++ b/TAO/tao/Objref_TypeCode.h @@ -0,0 +1,215 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Objref_TypeCode.h + * + * $Id$ + * + * Header file for + * @c tk_abstract_interface, + * @c tk_component, + * @c tk_local_interface, + * @c tk_native and + * @c tk_objref + * @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_OBJREF_TYPECODE_H +#define TAO_OBJREF_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCodeFactory_Adapter.h" + +#include "tao/TypeCode_Base_Attributes.h" + + +namespace TAO +{ + namespace TypeCode + { + template <CORBA::TCKind KIND> struct Objref_Traits; + + template <> + struct Objref_Traits<CORBA::tk_abstract_interface> + { + static + CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_abstract_interface_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + template <> + struct Objref_Traits<CORBA::tk_component> + { + static + CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_component_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + + template <> + struct Objref_Traits<CORBA::tk_home> + { + static + CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_home_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + template <> + struct Objref_Traits<CORBA::tk_local_interface> + { + static + CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_local_interface_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + template <> + struct Objref_Traits<CORBA::tk_native> + { + static CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_native_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + template <> + struct Objref_Traits<CORBA::tk_objref> + { + static + CORBA::TypeCode_ptr + create_compact_typecode (TAO_TypeCodeFactory_Adapter * factory, + char const * id + ACE_ENV_ARG_DECL) + { + return factory->create_interface_tc (id, + "" /* empty name */ + ACE_ENV_ARG_PARAMETER); + } + }; + + /** + * @class Objref + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c object and object-like types + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c object (interface) and object-like types (abstract + * interface, component, local interface and native). + */ + template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> + class Objref + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + Objref (char const * id, + char const * name); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_abstract_interface, @c tk_component, @c + * tk_local_interface, @c tk_native and @c tk_objref + * @c CORBA::TypeCode -specific template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// Base attributes (@c id and @c name). + Base_Attributes<StringType> attributes_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Objref_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Objref_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Objref_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_OBJREF_TYPECODE_H */ diff --git a/TAO/tao/Objref_TypeCode.inl b/TAO/tao/Objref_TypeCode.inl new file mode 100644 index 00000000000..3a1e735c3f0 --- /dev/null +++ b/TAO/tao/Objref_TypeCode.inl @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// $Id$ + + +template <typename StringType, CORBA::TCKind Kind, class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Objref<StringType, + Kind, + RefCountPolicy>::Objref (char const * id, + char const * name) + : RefCountPolicy (), + attributes_ (id, name) +{ +} diff --git a/TAO/tao/PredefinedType_Seq_Tmplinst.cpp b/TAO/tao/PredefinedType_Seq_Tmplinst.cpp index c50c111c7a2..d9a421dc56f 100644 --- a/TAO/tao/PredefinedType_Seq_Tmplinst.cpp +++ b/TAO/tao/PredefinedType_Seq_Tmplinst.cpp @@ -29,7 +29,7 @@ ACE_RCSID (tao, # include "Sequence_T.h" # include "Any.h" # include "Object.h" -# include "Typecode.h" +# include "TypeCode.h" #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION || ACE_HAS_TEMPLATE_INSTANTIATION_PRAGM */ diff --git a/TAO/tao/RequestInfo_Util.cpp b/TAO/tao/RequestInfo_Util.cpp index 7db5fe67980..f4ba3e2fedc 100644 --- a/TAO/tao/RequestInfo_Util.cpp +++ b/TAO/tao/RequestInfo_Util.cpp @@ -3,7 +3,7 @@ // $Id$ #include "RequestInfo_Util.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ORB_Constants.h" #include "StringSeqC.h" #include "DynamicC.h" diff --git a/TAO/tao/Sequence_TypeCode.cpp b/TAO/tao/Sequence_TypeCode.cpp new file mode 100644 index 00000000000..93362f34243 --- /dev/null +++ b/TAO/tao/Sequence_TypeCode.cpp @@ -0,0 +1,126 @@ +// $Id$ + +#ifndef TAO_SEQUENCE_TYPECODE_CPP +#define TAO_SEQUENCE_TYPECODE_CPP + +#include "Sequence_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/Sequence_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + +template <class RefCountPolicy> +TAO::TypeCode::Sequence<RefCountPolicy>::~Sequence (void) +{ + if (this->content_type_) + CORBA::release (*this->content_type_); +} + +template <class RefCountPolicy> +bool +TAO::TypeCode::Sequence<RefCountPolicy>::tao_marshal ( + TAO_OutputCDR & cdr) const +{ + // A tk_array or tk_sequence TypeCode has a "complex" parameter list + // type (see Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR + // section of the CORBA specification), meaning that it must be + // marshaled into a CDR encapsulation. + + // Create a CDR encapsulation. + return + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << *(this->content_type_)) + && (cdr << this->length_); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::Sequence<RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::Sequence<RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Sequence<RefCountPolicy>::equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // The following calls won't throw since CORBA::TypeCode::equal() + // has already established the kind of tc is the same as our kind. + CORBA::ULong const tc_length = tc->length (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (this->length_ != tc_length) + return 0; + + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return *(this->content_type_)->equal (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Sequence<RefCountPolicy>::equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this->kind_) + return 0; + + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return *(this->content_type_)->equivalent (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Sequence<RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->kind_; +} + +template <class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Sequence<RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Already compact since tk_sequence and tk_array TypeCodes have no + // name or member names, meaning that we can simply call + // _duplicate() on this TypeCode. + return CORBA::TypeCode::_duplicate (this); +} + +template <class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Sequence<RefCountPolicy>::length_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->length_; +} + + +#endif /* TAO_SEQUENCE_TYPECODE_CPP */ diff --git a/TAO/tao/Sequence_TypeCode.h b/TAO/tao/Sequence_TypeCode.h new file mode 100644 index 00000000000..b1c2efebbdc --- /dev/null +++ b/TAO/tao/Sequence_TypeCode.h @@ -0,0 +1,127 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Sequence_TypeCode.h + * + * $Id$ + * + * Header file for @c tk_sequence and @c tk_array @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_SEQUENCE_TYPECODE_H +#define TAO_SEQUENCE_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Sequence + * + * @brief @c CORBA::TypeCode implementation for OMG IDL + * @c sequence and @c array types. + * + * This class implements a @c CORBA::TypeCode for OMG IDL + * @c sequence and array types. + */ + template <class RefCountPolicy> + class Sequence : public CORBA::TypeCode + : private RefCountPolicy + { + public: + + /// Constructor. + Sequence (CORBA::TCKind kind, + CORBA::TypeCode_ptr * content_type, + CORBA::ULong length); + + /// Destructor. + ~Sequence (void); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c CORBA::TypeCode template methods specific to @c tk_sequence + * @c TypeCodes. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong length_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr content_type (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// The kind of this @c TypeCode. + /** + * @c kind_ is either @c CORBA::tk_sequence or + * @c CORBA::tk_array. + */ + CORBA::TCKind const kind_; + + /// Element type of the sequence. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the @c + * CORBA::TypeCode_ptr when creating this @c Field statically at + * compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c TypeCode::Sequence. + */ + CORBA::TypeCode_ptr * content_type_; + + /// Length of the @c sequence or array. A length of zero + /// indicates an unbounded @c sequence. + CORBA::ULong const length_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Sequence_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_SEQUENCE_TYPECODE_H */ diff --git a/TAO/tao/Sequence_TypeCode.inl b/TAO/tao/Sequence_TypeCode.inl new file mode 100644 index 00000000000..2c0edb2e190 --- /dev/null +++ b/TAO/tao/Sequence_TypeCode.inl @@ -0,0 +1,16 @@ +// -*- C++ -*- +// +// $Id$ + +template <class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Sequence<RefCountPolicy>::Sequence ( + CORBA::TCKind kind, + CORBA::TypeCode_ptr * content_type, + CORBA::ULong length) + : kind_ (kind) + , content_type_ (content_type) + , length_ (length) +{ + // ACE_ASSERT (kind == CORBA::tk_array || kind == CORBA::tk_sequence); +} diff --git a/TAO/tao/String_TypeCode.cpp b/TAO/tao/String_TypeCode.cpp new file mode 100644 index 00000000000..c74a102d463 --- /dev/null +++ b/TAO/tao/String_TypeCode.cpp @@ -0,0 +1,113 @@ +// $Id$ + +#ifndef TAO_STRING_TYPECODE_CPP +#define TAO_STRING_TYPECODE_CPP + +#include "String_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/String_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <class RefCountPolicy> +bool +TAO::TypeCode::String<RefCountPolicy>::tao_marshal (TAO_OutputCDR & cdr) const +{ + // A tk_string TypeCode has a "simple" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that its parameter(s) must be + // marshaled immediately following the TCKind. No CDR encapsulation + // is to be created. + + return (cdr << this->length_); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::String<RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <class RefCountPolicy> +void +TAO::TypeCode::String<RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::String<RefCountPolicy>::equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // The following call won't throw since CORBA::TypeCode::equal() has + // already established the kind of tc is the same as our kind. + CORBA::ULong const tc_length = tc->length (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return (this->length_ == tc_length); +} + +template <class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::String<RefCountPolicy>::equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // Call kind_i() instead of using CORBA::tk_string directly since a + // subclass, such as WString_TypeCode, can use this equivalent_i() + // implementation. + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this_kind) + return 0; + + // Since TCKind comparisons must be performed before equal_i() is + // called, we can also call it to determine equivalence of + // tk_string-based TypeCodes. + return this->equal_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +template <class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::String<RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->kind_; +} + +template <class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::String<RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Already compact since tk_string TypeCodes have no name or member + // names, meaning that we can simply call _duplicate() on this + // TypeCode. + return CORBA::TypeCode::_duplicate (this); +} + +template <class RefCountPolicy> +CORBA::ULong +TAO::TypeCode::String<RefCountPolicy>::length_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->length_; +} + + +#endif /* TAO_STRING_TYPECODE_CPP */ diff --git a/TAO/tao/String_TypeCode.h b/TAO/tao/String_TypeCode.h new file mode 100644 index 00000000000..0a95958921a --- /dev/null +++ b/TAO/tao/String_TypeCode.h @@ -0,0 +1,110 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file String_TypeCode.h + * + * $Id$ + * + * Header file for @c CORBA::tk_string or @c CORBA::tk_wstring + * @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_STRING_TYPECODE_H +#define TAO_STRING_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class String + * + * @brief @c CORBA::TypeCode implementation for OMG IDL string + * types. + * + * This class implements a @c CORBA::TypeCode for OMG IDL string + * types, including @c wstring. + */ + template <class RefCountPolicy> + class String + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + String (CORBA::TCKind kind, CORBA::ULong length); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c CORBA::TypeCode template methods specific to @c tk_string + * @c TypeCodes. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong length_i (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// The kind of this @c TypeCode. + /** + * @c kind_ is either @c CORBA::tk_string or + * @c CORBA::tk_wstring. + */ + CORBA::TCKind const kind_; + + /// Length of the @c string. A length of zero indicates an + /// unbounded @c string. + CORBA::ULong const length_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/String_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_STRING_TYPECODE_H */ diff --git a/TAO/tao/String_TypeCode.inl b/TAO/tao/String_TypeCode.inl new file mode 100644 index 00000000000..781f9f30061 --- /dev/null +++ b/TAO/tao/String_TypeCode.inl @@ -0,0 +1,13 @@ +// -*- C++ -*- +// +// $Id$ + +template <class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::String<RefCountPolicy>::String (CORBA::TCKind kind, + CORBA::ULong length) + : kind_ (kind), + length_ (length) +{ + // ACE_ASSERT (kind == CORBA::tk_string || kind == CORBA::tk_wstring); +} diff --git a/TAO/tao/Struct_TypeCode.cpp b/TAO/tao/Struct_TypeCode.cpp new file mode 100644 index 00000000000..5008b0abc69 --- /dev/null +++ b/TAO/tao/Struct_TypeCode.cpp @@ -0,0 +1,371 @@ +// $Id$ + +#ifndef TAO_STRUCT_TYPECODE_CPP +#define TAO_STRUCT_TYPECODE_CPP + +#include "tao/Struct_TypeCode.h" +#include "tao/TypeCode_Struct_Field.h" +#include "tao/ORB_Core.h" +#include "tao/TypeCodeFactory_Adapter.h" + + +#ifndef __ACE_INLINE__ +# include "tao/Struct_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + +#include "ace/Dynamic_Service.h" + + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +bool +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_marshal (TAO_OutputCDR & cdr) const +{ + // A tk_struct TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + bool const success = + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->base_attributes_.id ()) + && (cdr << this->base_attributes_.name ()) + && (cdr << this->nfields_); + + if (!success) + return false; + + Struct_Field<StringType> const * const begin = this->fields (); + Struct_Field<StringType> const * const end = begin + this->nfields_; + + for (Struct_Field<StringType> const * i = begin; i != end; ++i) + { + Struct_Field<StringType> const & field = *i; + + if (!(cdr << field.get_name ()) + || !(cdr << *(field.type))) + return false; + } + + return true; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +void +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +void +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // This call shouldn't throw since CORBA::TypeCode::equal() verified + // that the TCKind is the same as our's prior to invoking this + // method, meaning that member_count() is supported. + + CORBA::ULong const tc_nfields = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nfields != this->nfields_) + return 0; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + Struct_Field<StringType> const & lhs_field = this->fields_[i]; + + char const * const lhs_name = lhs_field.get_name (); + char const * const rhs_name = tc->member_name (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strcmp (lhs_name, rhs_name) != 0) + return 0; + + CORBA::TypeCode_ptr const lhs_tc = *(lhs_field.type); + CORBA::TypeCode_var const rhs_tc = + tc->member_type (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equal_members = + lhs_tc->equal (rhs_tc.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_members) + return 0; + } + + return 1; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != Kind) + return 0; + + char const * const this_id = this->base_attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + // Perform a structural comparison, excluding the name() and + // member_name() operations. + + CORBA::ULong const tc_nfields = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nfields != this->nfields_) + return 0; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + CORBA::TypeCode_ptr const lhs = *(this->fields_[i].type); + CORBA::TypeCode_var const rhs = + tc->member_type (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equiv_members = + lhs->equivalent (rhs.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equiv_members) + return 0; + } + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return Kind; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + Struct_Field<StringType> * tc_fields = 0; + + ACE_Auto_Array_Ptr<Struct_Field<StringType> > safe_fields; + + if (this->nfields_ > 0) + { + // Dynamically construct a new array of fields stripped of + // member names. + + ACE_NEW_THROW_EX (tc_fields, + Struct_Field<StringType> [this->nfields_], + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + safe_fields.reset (tc_fields); + + static char const empty_name[] = ""; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + // Member names will be stripped, i.e. not embedded within + // the compact TypeCode. + + tc_fields[i].name = empty_name; + tc_fields[i].type = 0; // FIX ME! +// &(*this->fields_[i].type)->get_compact_typecode ( +// ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + } + } + + TAO_TypeCodeFactory_Adapter * const adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name ()); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TypeCode_var tc = + adapter->_tao_create_struct_except_tc (Kind, + this->base_attributes_.id (), + "" /* empty name */, + tc_fields, + this->nfields_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + (void) safe_fields.release (); + + return tc._retn (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.id (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.name (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::ULong +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_count_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->nfields_; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_name_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + if (index >= this->nfields_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); + + return this->fields_[index].get_name (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_type_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + if (index >= this->nfields_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), + CORBA::TypeCode::_nil ()); + + return CORBA::TypeCode::_duplicate (*(this->fields_[index].type)); +} + +#endif /* TAO_STRUCT_TYPECODE_CPP */ diff --git a/TAO/tao/Struct_TypeCode.h b/TAO/tao/Struct_TypeCode.h new file mode 100644 index 00000000000..9951b3babec --- /dev/null +++ b/TAO/tao/Struct_TypeCode.h @@ -0,0 +1,156 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Struct_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_struct and @c tk_except + * @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + * @author Carlos O'Ryan + */ +//============================================================================= + +#ifndef TAO_STRUCT_TYPECODE_H +#define TAO_STRUCT_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Base_Attributes.h" + + +namespace TAO +{ + namespace TypeCode + { + template<typename StringType> struct Struct_Field; + + /** + * @class Struct + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c struct or @c exception. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c struct or @c exception. + */ + template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> + class Struct + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + Struct (char const * id, + char const * name, + Struct_Field<StringType> const * fields, + CORBA::ULong nfields); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_struct or @c tk_except @c CORBA::TypeCode -specific + * template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong member_count_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * member_name_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::TypeCode_ptr member_type_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + //@} + + private: + + /// Get pointer to the underlying @c Field array. + Struct_Field<StringType> const * fields (void) const; + + private: + + /** + * @c Struct Attributes + * + * Attributes representing the structure of an OMG IDL + * @c struct or @c exception. + * + * @note These attributes are declared in the order in which + * they are marshaled into a CDR stream in order to + * increase cache hits by improving spatial locality. + */ + //@{ + + /// Base attributes containing repository ID and name of + /// structure type. + Base_Attributes<StringType> const base_attributes_; + + /// The number of fields in the OMG IDL structure. + CORBA::ULong const nfields_; + + /// Array of @c TAO::TypeCode fields representing structure of the + /// OMG IDL defined @c struct. + FieldArrayType const fields_; + + //@} + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Struct_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Struct_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Struct_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_STRUCT_TYPECODE_H */ diff --git a/TAO/tao/Struct_TypeCode.inl b/TAO/tao/Struct_TypeCode.inl new file mode 100644 index 00000000000..63825f49350 --- /dev/null +++ b/TAO/tao/Struct_TypeCode.inl @@ -0,0 +1,65 @@ +// -*- C++ -*- +// +// $Id$ + +#include "tao/TypeCode_Struct_Field.h" +#include "tao/True_RefCount_Policy.h" + +#include "ace/Auto_Ptr.h" + + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::Struct ( + char const * id, + char const * name, + Struct_Field<StringType> const * fields, + CORBA::ULong nfields) + : base_attributes_ (id, name) + , nfields_ (nfields) + , fields_ (fields) +{ +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +ACE_INLINE TAO::TypeCode::Struct_Field<StringType> const * +TAO::TypeCode::Struct<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::fields (void) const +{ + return this->fields_; +} + +// ------------------------------------------------------------- +// Member specializations +// ------------------------------------------------------------- + +ACE_INLINE TAO::TypeCode::Struct_Field<CORBA::String_var> const * +TAO::TypeCode::Struct< + CORBA::String_var, + ACE_Auto_Array_Ptr<TAO::TypeCode::Struct_Field<CORBA::String_var> const>, + CORBA::tk_struct, + TAO::True_RefCount_Policy>::fields (void) const +{ + return this->fields_.get (); +} + +ACE_INLINE TAO::TypeCode::Struct_Field<CORBA::String_var> const * +TAO::TypeCode::Struct< + CORBA::String_var, + ACE_Auto_Array_Ptr<TAO::TypeCode::Struct_Field<CORBA::String_var> const>, + CORBA::tk_except, + TAO::True_RefCount_Policy>::fields (void) const +{ + return this->fields_.get (); +} diff --git a/TAO/tao/SystemException.cpp b/TAO/tao/SystemException.cpp index 85ee1231b57..44cb9836e29 100644 --- a/TAO/tao/SystemException.cpp +++ b/TAO/tao/SystemException.cpp @@ -4,9 +4,9 @@ #include "Environment.h" #include "Any_SystemException.h" #include "Any_Dual_Impl_T.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ORB_Constants.h" -#include "TC_Constants_Forward.h" +#include "TypeCode_Constants.h" #include "CORBA_String.h" #include "CDR.h" #include "debug.h" @@ -1145,10 +1145,9 @@ STANDARD_EXCEPTION_LIST #define TAO_SYSTEM_EXCEPTION(name) \ void \ -CORBA::name ::_tao_any_destructor (void *x) \ +CORBA::name ::_tao_any_destructor (void * x) \ { \ - CORBA::name *tmp = static_cast<CORBA::name *> (x); \ - delete tmp; \ + delete static_cast<CORBA::name *> (x); \ } STANDARD_EXCEPTION_LIST @@ -1158,7 +1157,7 @@ STANDARD_EXCEPTION_LIST CORBA::Exception * \ CORBA::name ::_tao_duplicate (void) const \ { \ - CORBA::Exception *result; \ + CORBA::Exception * result; \ ACE_NEW_RETURN (result, CORBA::name (*this), 0); \ return result; \ } diff --git a/TAO/tao/TC_Constants_Forward.h b/TAO/tao/TC_Constants_Forward.h index 93df81213df..72c27451a1c 100644 --- a/TAO/tao/TC_Constants_Forward.h +++ b/TAO/tao/TC_Constants_Forward.h @@ -27,27 +27,27 @@ namespace CORBA * All the TypeCode constants */ //@{ - extern TAO_Export TypeCode_ptr _tc_null; - extern TAO_Export TypeCode_ptr _tc_void; - extern TAO_Export TypeCode_ptr _tc_short; - extern TAO_Export TypeCode_ptr _tc_long; - extern TAO_Export TypeCode_ptr _tc_ushort; - extern TAO_Export TypeCode_ptr _tc_ulong; - extern TAO_Export TypeCode_ptr _tc_float; - extern TAO_Export TypeCode_ptr _tc_double; - extern TAO_Export TypeCode_ptr _tc_boolean; - extern TAO_Export TypeCode_ptr _tc_char; - extern TAO_Export TypeCode_ptr _tc_octet; - extern TAO_Export TypeCode_ptr _tc_any; - extern TAO_Export TypeCode_ptr _tc_TypeCode; - extern TAO_Export TypeCode_ptr _tc_Principal; - extern TAO_Export TypeCode_ptr _tc_Object; - extern TAO_Export TypeCode_ptr _tc_string; - extern TAO_Export TypeCode_ptr _tc_longlong; - extern TAO_Export TypeCode_ptr _tc_ulonglong; - extern TAO_Export TypeCode_ptr _tc_longdouble; - extern TAO_Export TypeCode_ptr _tc_wchar; - extern TAO_Export TypeCode_ptr _tc_wstring; + extern TAO_Export TypeCode_ptr const _tc_null; + extern TAO_Export TypeCode_ptr const _tc_void; + extern TAO_Export TypeCode_ptr const _tc_short; + extern TAO_Export TypeCode_ptr const _tc_long; + extern TAO_Export TypeCode_ptr const _tc_ushort; + extern TAO_Export TypeCode_ptr const _tc_ulong; + extern TAO_Export TypeCode_ptr const _tc_float; + extern TAO_Export TypeCode_ptr const _tc_double; + extern TAO_Export TypeCode_ptr const _tc_boolean; + extern TAO_Export TypeCode_ptr const _tc_char; + extern TAO_Export TypeCode_ptr const _tc_octet; + extern TAO_Export TypeCode_ptr const _tc_any; + extern TAO_Export TypeCode_ptr const _tc_TypeCode; + extern TAO_Export TypeCode_ptr const _tc_Principal; + extern TAO_Export TypeCode_ptr const _tc_Object; + extern TAO_Export TypeCode_ptr const _tc_string; + extern TAO_Export TypeCode_ptr const _tc_longlong; + extern TAO_Export TypeCode_ptr const _tc_ulonglong; + extern TAO_Export TypeCode_ptr const _tc_longdouble; + extern TAO_Export TypeCode_ptr const _tc_wchar; + extern TAO_Export TypeCode_ptr const _tc_wstring; #define TAO_SYSTEM_EXCEPTION_LIST \ TAO_SYSTEM_EXCEPTION(UNKNOWN); \ @@ -93,16 +93,16 @@ namespace CORBA // = Typecode constants for system exceptions. #define TAO_SYSTEM_EXCEPTION(name) \ - extern TAO_Export TypeCode_ptr _tc_ ## name + extern TAO_Export TypeCode_ptr const _tc_ ## name TAO_SYSTEM_EXCEPTION_LIST #undef TAO_SYSTEM_EXCEPTION //@} - extern TAO_Export TypeCode_ptr _tc_UnknownUserException; + extern TAO_Export TypeCode_ptr const _tc_UnknownUserException; extern TAO_Export TypeCode_ptr const _tc_Current; - extern TAO_Export TypeCode_ptr _tc_NamedValue; + extern TAO_Export TypeCode_ptr const _tc_NamedValue; } #include /**/ "ace/post.h" diff --git a/TAO/tao/True_RefCount_Policy.cpp b/TAO/tao/True_RefCount_Policy.cpp new file mode 100644 index 00000000000..3b5b3fab354 --- /dev/null +++ b/TAO/tao/True_RefCount_Policy.cpp @@ -0,0 +1,17 @@ +// $Id$ + +#include "True_RefCount_Policy.h" + +#ifndef __ACE_INLINE__ +# include "True_RefCount_Policy.inl" +#endif /* !__ACE_INLINE__ */ + + +ACE_RCSID (tao, + True_RefCount_Policy, + "$Id$") + + +TAO::True_RefCount_Policy::~True_RefCount_Policy (void) +{ +} diff --git a/TAO/tao/True_RefCount_Policy.h b/TAO/tao/True_RefCount_Policy.h new file mode 100644 index 00000000000..64efa5220f5 --- /dev/null +++ b/TAO/tao/True_RefCount_Policy.h @@ -0,0 +1,121 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file True_RefCount_Policy.h + * + * $Id$ + * + * Header file for TAO's true reference count policy (unrelated to + * CORBA policies). + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_TRUE_REFCOUNT_POLICY_H +#define TAO_TRUE_REFCOUNT_POLICY_H + +#include /**/ "ace/pre.h" + +#include "tao/TAO_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/orbconf.h" + +#include "ace/Thread_Mutex.h" + + +namespace TAO +{ + /** + * @class True_RefCount_Policy + * + * @brief True reference counting policy. + * + * This class is intended to be used as a "policy" argument to a + * host class template that requires true/functional reference + * counting. That class would then inherit privately from it like + * so: + * + * @code + * template <class RefCountPolicy> + * class MyHostClass : private RefCountPolicy + * { + * public: + * void my_add_ref (void) { this->RefCountPolicy::add_ref (); } + * void my_remove_ref (void) { this->RefCountPolicy::remove_ref (); } + * }; + * @endcode + * + * and use it like so: + * + * @code + * typedef MyHostClass<TAO::True_RefCount_Policy> MyRefCountedClass; + * MyRefCountedClass * p = new MyRefCountedClass; + * ... + * p->my_remove_ref (); + * @endcode + * + * @note Ideally, the host class should declare a protected + * destructor to enforce proper memory management through the + * reference counting mechanism, i.e. to prevent clients from + * calling @c operator @c delete() directly on the host class + * object. + */ + class TAO_Export True_RefCount_Policy + { + public: + + /// Increase the reference count on this object. + void add_ref (void); + + /// Decrease the reference count on this object. + /** + * Decrease the reference count on this object. Once the + * reference count drops to zero, call @c operator @c delete() + * on this object. + */ + void remove_ref (void); + + protected: + + /// Constructor. + /** + * @note This constructor is protected since it not meant to be + * instantiated/used as a standalone object. + */ + True_RefCount_Policy (void); + + /// Destructor. + /** + * @note The destructor must be virtual to ensure that subclass + * destructors are called when the reference count drops to + * zero, i.e. when @c remove_ref() calls @c operator + * @c delete @c this. + */ + virtual ~True_RefCount_Policy (void); + + private: + + /// Lock used to synchronize reference count. + TAO_SYNCH_MUTEX lock_; + + /// Reference count. + unsigned int refcount_; + + }; + +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/True_RefCount_Policy.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TRUE_REFCOUNT_POLICY_H */ diff --git a/TAO/tao/True_RefCount_Policy.inl b/TAO/tao/True_RefCount_Policy.inl new file mode 100644 index 00000000000..a6db939e129 --- /dev/null +++ b/TAO/tao/True_RefCount_Policy.inl @@ -0,0 +1,37 @@ +// -*- C++ -*- +// +// $Id$ + + +#include "ace/Guard_T.h" + + +ACE_INLINE +TAO::True_RefCount_Policy::True_RefCount_Policy (void) + : lock_ (), + refcount_ (1) +{ +} + +ACE_INLINE void +TAO::True_RefCount_Policy::add_ref (void) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_); + + ++this->refcount_; +} + +ACE_INLINE void +TAO::True_RefCount_Policy::remove_ref (void) +{ + { + ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_); + + --this->refcount_; + + if (this->refcount_ != 0) + return; + } + + delete this; +} diff --git a/TAO/tao/TypeCode.cpp b/TAO/tao/TypeCode.cpp new file mode 100644 index 00000000000..9e175252565 --- /dev/null +++ b/TAO/tao/TypeCode.cpp @@ -0,0 +1,279 @@ +// $Id$ + +#include "TypeCode.h" + + +ACE_RCSID (tao, + TypeCode, + "$Id$") + + +#if !defined (__ACE_INLINE__) +# include "TypeCode.inl" +#endif /* ! __ACE_INLINE__ */ + +#include "SystemException.h" +#include "CDR.h" +#include "ORB_Constants.h" +#include "Struct_TypeCode.h" +#include "Null_RefCount_Policy.h" + +#include "ace/OS_NS_string.h" + + +CORBA::Boolean +CORBA::TypeCode::equal (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + if (this == tc) + return 1; + + CORBA::TCKind const tc_kind = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::TCKind const this_kind = this->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this_kind) + return 0; + + ACE_TRY + { + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + char const * const this_id = this->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (ACE_OS::strcmp (this_id, tc_id) != 0) + return 0; + + char const * const tc_name = tc->name (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + char const * const this_name = this->name (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (ACE_OS::strcmp (this_name, tc_name) != 0) + return 0; + } + ACE_CATCH (CORBA::TypeCode::BadKind, ex) + { + // Some TypeCodes do not support the id() and name() + // operations. Ignore the failure, and continue equality + // verification using TypeCode subclass-specific techniques + // below. + } + ACE_ENDTRY; + ACE_CHECK_RETURN (0); + + return this->equal_i (tc + ACE_ENV_ARG_PARAMETER); +} + + +char const * +CORBA::TypeCode::id_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +char const * +CORBA::TypeCode::name_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::ULong +CORBA::TypeCode::member_count_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +char const * +CORBA::TypeCode::member_name_i (CORBA::ULong /* index */ + ACE_ENV_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::TypeCode_ptr +CORBA::TypeCode::member_type_i (CORBA::ULong /* index */ + ACE_ENV_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::TypeCode::_nil ()); +} + +CORBA::Any * +CORBA::TypeCode::member_label_i (CORBA::ULong /* index */ + ACE_ENV_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::TypeCode_ptr +CORBA::TypeCode::discriminator_type_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::TypeCode::_nil ()); +} + +CORBA::Long +CORBA::TypeCode::default_index_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::ULong +CORBA::TypeCode::length_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::TypeCode_ptr +CORBA::TypeCode::content_type_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::TypeCode::_nil ()); +} + +CORBA::UShort +CORBA::TypeCode::fixed_digits_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::UShort +CORBA::TypeCode::fixed_scale_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0); +} + +CORBA::Visibility +CORBA::TypeCode::member_visibility_i (CORBA::ULong /* index */ + ACE_ENV_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::PRIVATE_MEMBER); +} + +CORBA::ValueModifier +CORBA::TypeCode::type_modifier_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::VM_NONE); +} + +CORBA::TypeCode_ptr +CORBA::TypeCode::concrete_base_type_i (ACE_ENV_SINGLE_ARG_DECL) const +{ + ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), + CORBA::TypeCode::_nil ()); +} + +// --------------------------------------------------------------- + +bool +TAO::operator<< (TAO_OutputCDR & cdr, + CORBA::TypeCode const * tc) +{ + ACE_DECLARE_NEW_CORBA_ENV; + + if (tc == 0) + { + ACE_THROW_RETURN (CORBA::MARSHAL (0, + CORBA::COMPLETED_MAYBE), + false); + } + + CORBA::ULong const kind = + static_cast<CORBA::ULong> (tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK_RETURN (false); + + return (cdr << kind) && tc->tao_marshal (cdr); +} + +CORBA::TypeCode_ptr +TAO::unaliased_typecode (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) +{ + if (CORBA::is_nil (tc)) + { + ACE_THROW_RETURN (CORBA::BAD_PARAM (CORBA::OMGVMCID | 13, + CORBA::COMPLETED_NO), + tc); + } + + CORBA::TCKind tc_kind = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (tc); + + if (tc_kind == CORBA::tk_alias) + { + CORBA::TypeCode_var tc_content; + + // Iterate until we get to the actual unaliased type. + do + { + tc_content = + tc_content->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (tc); + + tc_kind = tc_content->kind (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (tc); + } + while (tc_kind == CORBA::tk_alias); + + return tc_content._retn (); + } + + return CORBA::TypeCode::_duplicate (tc); +} + +// -------------------------------------------------------------- + +namespace TAO +{ + namespace TypeCode + { + // Notice that these are all statically instantiated and not + // exported. + + char const tc_bounds_id[] = "IDL:omg.org/CORBA/TypeCode/Bounds:1.0"; + char const tc_bounds_name[] = "Bounds"; + Struct<char const *, + Struct_Field<char const *> const *, + CORBA::tk_except, + TAO::Null_RefCount_Policy> tc_Bounds (tc_bounds_id, + tc_bounds_name, + 0, + 0); + + char const tc_bad_kind_id[] = "IDL:omg.org/CORBA/TypeCode/BadKind:1.0"; + char const tc_bad_kind_name[] = "BadKind"; + Struct<char const *, + Struct_Field<char const *> const *, + CORBA::tk_except, + TAO::Null_RefCount_Policy> tc_BadKind (tc_bad_kind_id, + tc_bad_kind_name, + 0, + 0); + } +} + + +// ------------------------------------------------------------------ +// OMG defined TypeCode constants +// ------------------------------------------------------------------ + +namespace CORBA +{ + + // Notice that these are constant TypeCode references/pointers, not + // constant TypeCodes. TypeCodes are effectively read-only since + // all non-static TypeCode operations are const. + + TypeCode_ptr const TypeCode::_tc_Bounds = &TAO::TypeCode::tc_Bounds; + TypeCode_ptr const TypeCode::_tc_BadKind = &TAO::TypeCode::tc_BadKind; + +} diff --git a/TAO/tao/TypeCode.h b/TAO/tao/TypeCode.h new file mode 100644 index 00000000000..69108479539 --- /dev/null +++ b/TAO/tao/TypeCode.h @@ -0,0 +1,575 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode.h + * + * $Id$ + * + * Header file the @c CORBA::TypeCode class. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + * @author DOC group at Vanderbilt University, Washington University + * and the University of California at Irvine. + */ +//============================================================================= + +#ifndef TAO_TYPECODE_H +#define TAO_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TAO_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/UserException.h" +#include "tao/Basic_Types.h" +#include "tao/OBV_Constants.h" +#include "tao/CORBA_methods.h" +#include "tao/Pseudo_VarOut_T.h" + +namespace CORBA +{ + typedef TAO_Pseudo_Var_T<TypeCode> TypeCode_var; + typedef TAO_Pseudo_Out_T<TypeCode, TypeCode_var> TypeCode_out; + + /** + * @enum TCKind + * + * Kinds of @c TypeCodes in the CORBA namespace, as defined by the + * OMG. + */ + enum TCKind + { + // = Kinds of typecodes. + + // Do not change these enum values, or duplicate them if you need + // to add values. They are used to index tables, and if you + // change the values you'll need to find and update all of those + // tables. The values are also part of the Common Data + // Representation, and hence are part of IIOP and other ORB + // protocols. + + tk_null = 0, + tk_void = 1, + tk_short = 2, + tk_long = 3, + tk_ushort = 4, + tk_ulong = 5, + tk_float = 6, + tk_double = 7, + tk_boolean = 8, + tk_char = 9, + tk_octet = 10, + tk_any = 11, + tk_TypeCode = 12, + tk_Principal = 13, + tk_objref = 14, + tk_struct = 15, + tk_union = 16, + tk_enum = 17, + tk_string = 18, + tk_sequence = 19, + tk_array = 20, + tk_alias = 21, + tk_except = 22, + + tk_longlong = 23, + tk_ulonglong = 24, + tk_longdouble = 25, + tk_wchar = 26, + tk_wstring = 27, + tk_fixed = 28, + tk_value = 29, + tk_value_box = 30, + tk_native = 31, + tk_abstract_interface = 32, + tk_local_interface = 33, + tk_component = 34, + tk_home = 35, + tk_event = 36, + + // This symbol is not defined by CORBA 3.0. It's used to speed up + // dispatch based on TCKind values, and lets many important ones + // just be table lookups. It must always be the last enum value!! + + TAO_TC_KIND_COUNT + }; + + typedef TCKind & TCKind_out; + + /** + * @class TypeCode + * + * @brief A representation of the structure of a given OMG + * IDL-declared type. + * + * @c TypeCodes are primarily used by @c CORBA::Anys, the CORBA + * Interface Repository and the CORBA Dynamic Invocation Interface. + */ + class TAO_Export TypeCode + { + public: + + /** + * @class Bounds + * + * @brief Out-of-bounds member index exception. + * + * Exception thrown when attempting to pass an out-of-bounds index + * value to a @c TypeCode operation that accepts a member index + * argument. + */ + class TAO_Export Bounds : public UserException + { + public: + + /// Constructor. + Bounds (void); + + static Bounds * _downcast (CORBA::Exception * ex); + static CORBA::Exception * _alloc (void); + + virtual CORBA::Exception * _tao_duplicate (void) const; + + virtual void _raise (void) const; + + virtual void _tao_encode (TAO_OutputCDR & cdr + ACE_ENV_ARG_DECL) const; + virtual void _tao_decode (TAO_InputCDR & cdr + ACE_ENV_ARG_DECL); + + }; + + /** + * @class BadKind + * + * @brief Invalid @c TypeCode operation exception. + * + * Exception thrown when attempting to invoke a @c TypeCode + * operation that is not valid for the type represented by the + * @c TypeCode. + */ + class TAO_Export BadKind : public CORBA::UserException + { + public: + + BadKind (void); + + static BadKind * _downcast (CORBA::Exception * ex); + static CORBA::Exception * _alloc (void); + + virtual CORBA::Exception * _tao_duplicate (void) const; + + virtual void _raise (void) const; + + virtual void _tao_encode (TAO_OutputCDR & cdr + ACE_ENV_ARG_DECL) const; + virtual void _tao_decode (TAO_InputCDR & cdr + ACE_ENV_ARG_DECL); + + }; + + static CORBA::TypeCode_ptr const _tc_Bounds; + static CORBA::TypeCode_ptr const _tc_BadKind; + + /// Duplicate this @c TypeCode. + /** + * Statically instantiated @c TypeCodes incur no reference count + * manipulation, i.e. reference counting is a no-op. + * + * Dynamically instantiated @c TypeCodes will have their reference + * count incremented by one each time this function is called. + */ + static CORBA::TypeCode_ptr _duplicate (CORBA::TypeCode_ptr tc); + + /// Returns a NULL typecode. + static CORBA::TypeCode_ptr _nil (void); + + /** + * @name @c CORBA::TypeCode Methods + * + * These methods are part of the public interface of @c + * CORBA::TypeCode class, as defined by the OMG CORBA + * specification and C++ mapping. + * + * The C++ mapping does not declare the methods in the public + * @c CORBA::TypeCode API as @c virtual, so work around that by + * making these methods inlined to forward all calls to the + * corresponding protected template method (i.e. the design + * pattern, not the C++ feature) listed below in the @c protected + * block. + */ + //@{ + /// Equality of two @c TypeCodes. + /** + * @return @c true if and only if the set of legal operations is + * the same and invoking any operation on the this + * @c TypeCode and @a tc returns identical results. + */ + Boolean equal (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + + /// Equivalence of two @c TypeCodes. + /** + * Equivalence of two @c TypeCodes satisfies a subset of the + * requirements necessary for equality. + * + * @see equal + */ + Boolean equivalent (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + + /// The kind of @c TypeCode. + TCKind kind (ACE_ENV_SINGLE_ARG_DECL) const; + + /// Return @c TypeCode stripped of optional @c name and + /// @c member_name fields. + /** + * @note Calling this method will incur additional run-time memory + * consumption since TAO's implementation relies on the + * TypeCodeFactory to dynamically create a compact @c + * TypeCode; the exception being @c TypeCodes with empty + * parameter lists. Those @c TypeCodes are already compact, + * meaning that call this method on such @c TypeCodes incurs + * no additional run-time memory requirements. + * + * Unless you need to send compact @c TypeCodes + * "over-the-wire" or your @c TypeCode corresponds to a + * type with a large number of members, try to stick with + * the existing potentially non-compact @c TypeCode. + * + * @note Compact @c TypeCodes may also be generated statically by + * the TAO_IDL compiler by invoking it with its "-Gt" + * (i.e. enable optimized TypeCodes) command line option. + */ + TypeCode_ptr get_compact_typecode (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The @c RepositoryId globally identifying the type. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_objref + * @li @c tk_struct + * @li @c tk_union + * @li @c tk_enum + * @li @c tk_alias + * @li @c tk_value + * @li @c tk_value_box + * @li @c tk_native + * @li @c tk_abstract_interface + * @li @c tk_local_interface + * @li @c tk_except + * @li @c tk_component + * @li @c tk_home + * @li @c tk_event + * + * @note CORBA::TypeCode::id() does not follow the usual parameter + * passing rules defined by the C++ mapping. This behavior + * is required by the C++ mapping. In particular, ownership + * is maintained by the @c TypeCode. + */ + char const * id (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The simple name identifying the type within its enclosing + /// scope. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_objref + * @li @c tk_struct + * @li @c tk_union + * @li @c tk_enum + * @li @c tk_alias + * @li @c tk_value + * @li @c tk_value_box + * @li @c tk_native + * @li @c tk_abstract_interface + * @li @c tk_local_interface + * @li @c tk_except + * @li @c tk_component + * @li @c tk_home + * @li @c tk_event + * + * @note CORBA::TypeCode::name() does not follow the usual + * parameter passing rules defined by the C++ mapping. This + * behavior is required by the C++ mapping. In particular, + * ownership is maintained by the @c TypeCode. + */ + char const * name (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The type member count. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_struct + * @li @c tk_union + * @li @c tk_enum + * @li @c tk_value + * @li @c tk_except + * @li @c tk_event + */ + ULong member_count (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The type member name. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_struct + * @li @c tk_union + * @li @c tk_enum + * @li @c tk_value + * @li @c tk_except + * @li @c tk_event + * + * @note CORBA::TypeCode::member_name() does not follow the usual + * parameter passing rules defined by the C++ mapping. This + * behavior is required by the C++ mapping. In particular, + * ownership is maintained by the @c TypeCode. + */ + char const * member_name (ULong index + ACE_ENV_ARG_DECL) const; + + /// The type member @c TypeCode. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_struct + * @li @c tk_union + * @li @c tk_value + * @li @c tk_except + * @li @c tk_event + */ + TypeCode_ptr member_type (ULong index + ACE_ENV_ARG_DECL) const; + + /// The union member label. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_union + */ + Any * member_label (ULong index + ACE_ENV_ARG_DECL) const; + + /// The type of all non-default union member labels. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_union + */ + TypeCode_ptr discriminator_type (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The index of the default union member. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_union + */ + Long default_index (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The length of the type. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_string + * @li @c tk_wstring + * @li @c tk_sequence + * @li @c tk_array + */ + ULong length (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The underlying content type. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_sequence + * @li @c tk_array + * @li @c tk_value_box + * @li @c tk_alias + */ + TypeCode_ptr content_type (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The number of significant digits. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_fixed + */ + UShort fixed_digits (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The scale factor. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_fixed + */ + UShort fixed_scale (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The @c Visibility of the @c valuetype or @c eventtype member + /// corresponding to index @a index. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_value + * @li @c tk_event + */ + Visibility member_visibility (ULong index + ACE_ENV_ARG_DECL) const; + + /// The @c ValueModifier of the @c valuetype of @c eventtype + /// represented by this @c TypeCode. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_value + * @li @c tk_event + */ + ValueModifier type_modifier (ACE_ENV_SINGLE_ARG_DECL) const; + + /// The @c TypeCode corresponding to the concrete base + /// @c valuetype or @c eventtype. + /** + * This method is valid for the following kinds of @c TypeCodes: + * + * @li @c tk_value + * @li @c tk_event + * + * @return @c TypeCode corresponding to the concrete base + * @c valuetype or @c eventtype. + * @c CORBA::TypeCode::_nil() if no concrete base exists. + */ + TypeCode_ptr concrete_base_type (ACE_ENV_SINGLE_ARG_DECL) const; + //@} + + /// Marshal this @c TypeCode into a CDR output stream. + /** + * Marshal this @c TypeCode into the @a cdr output CDR stream, + * excluding the @c TypeCode kind. Existing @a cdr contents will + * not be altered. The marshaled @c TypeCode will be appended to + * the given @a cdr CDR output stream. + * + * @return @c true if marshaling was successful. + * + * @note This is a TAO-specific method that is not part of the + * standard @c CORBA::TypeCode interface. + * + * @note If this method returns @false, the contents of the @a cdr + * output CDR stream are undefined. + */ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const = 0; + + /// Increase the reference count on this @c TypeCode. + virtual void tao_duplicate (void) = 0; + + /// Decrease the reference count on this object. + virtual void tao_release (void) = 0; + + /// Destruction callback for Anys. + static void CORBA::TypeCode::_tao_any_destructor (void * x); + + protected: + + /// Constructor. + TypeCode (void); + + /// Destructor. + /** + * Protected destructor to enforce proper memory management + * through the reference counting mechanism. + */ + virtual ~TypeCode (void); + + /** + * @name @c TypeCode Template Methods + * + * Methods that must be implemented by @c CORBA::TypeCode + * subclasses if valid for those subclasses. + * + * The default implementations of the non-pure virtual methods + * throw the @c CORBA::TypeCode::BadKind exception since many of + * these methods are @c TypeCode type-specific. This reduces code + * duplication and bloat. + * + * The @c TypeCode @c equal(), @c equivalent(), @c kind() and + * @c get_compact_typecode() methods are valid for all + * @c TypeCodes which is why their template method "@c _i" + * counterparts are pure virtual. + */ + //@{ + virtual Boolean equal_i (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const = 0; + virtual Boolean equivalent_i (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const = 0; + virtual TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const = 0; + virtual TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const = 0; + + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual ULong member_count_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * member_name_i (ULong index + ACE_ENV_ARG_DECL) const; + virtual TypeCode_ptr member_type_i (ULong index + ACE_ENV_ARG_DECL) const; + virtual Any * member_label_i (ULong index + ACE_ENV_ARG_DECL) const; + virtual TypeCode_ptr discriminator_type_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual Long default_index_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual ULong length_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual TypeCode_ptr content_type_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual UShort fixed_digits_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual UShort fixed_scale_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual Visibility member_visibility_i (ULong index + ACE_ENV_ARG_DECL) const; + virtual ValueModifier type_modifier_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual TypeCode_ptr concrete_base_type_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + //@} + + private: + + // Prevent copying and assignment. + TypeCode (TypeCode const &); + void operator= (TypeCode const &); + + }; + +} // End namespace CORBA + + +namespace TAO +{ + extern TAO_Export bool operator<< (TAO_OutputCDR & cdr, + CORBA::TypeCode const * x); + extern TAO_Export bool operator>> (TAO_InputCDR& cdr, + CORBA::TypeCode *&x); + + /// Return the unaliased content @c TypeCode of the given + /// @c TypeCode. + CORBA::TypeCode_ptr unaliased_typecode (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL); + + /// Return the unaliased @c TCKind of the given @c TypeCode. + /** + * @note This is a convenience function that simply calls @c kind() + * on the unaliased @c TypeCode returned from + * @c unaliased_typecode(). + */ + CORBA::TCKind unaliased_kind (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL); + +} + + +#if defined (__ACE_INLINE__) +# include "tao/TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_H */ diff --git a/TAO/tao/TypeCode.inl b/TAO/tao/TypeCode.inl new file mode 100644 index 00000000000..273b02f76cd --- /dev/null +++ b/TAO/tao/TypeCode.inl @@ -0,0 +1,189 @@ +// -*- C++ -*- +// +// $Id$ + + +#include "tao/CORBA_methods.h" +#include "tao/Environment.h" + + +ACE_INLINE CORBA::Boolean +CORBA::is_nil (CORBA::TypeCode_ptr obj) +{ + return obj == 0; +} + +ACE_INLINE void +CORBA::release (CORBA::TypeCode_ptr obj) +{ + if (obj) + obj->tao_release (); +} + +// -------------------------------------------------------------- + +ACE_INLINE +CORBA::TypeCode::TypeCode (void) +{ +} + +ACE_INLINE +CORBA::TypeCode::~TypeCode (void) +{ +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::_duplicate (CORBA::TypeCode_ptr tc) +{ + if (!CORBA::is_nil (tc)) + tc->tao_duplicate (); + + return tc; +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::_nil (void) +{ + return static_cast<CORBA::TypeCode_ptr> (0); +} + +ACE_INLINE CORBA::Boolean +CORBA::TypeCode::equivalent (TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + if (this == tc) + return 1; + else + return this->equivalent_i (tc + ACE_ENV_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TCKind +CORBA::TypeCode::kind (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::get_compact_typecode (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->get_compact_typecode_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE char const * +CORBA::TypeCode::id (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->id_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE char const * +CORBA::TypeCode::name (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->name_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::ULong +CORBA::TypeCode::member_count (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->member_count_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE char const * +CORBA::TypeCode::member_name (ULong index + ACE_ENV_ARG_DECL) const +{ + return this->member_name_i (index + ACE_ENV_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::member_type (ULong index + ACE_ENV_ARG_DECL) const +{ + return this->member_type_i (index + ACE_ENV_ARG_PARAMETER); +} + +ACE_INLINE CORBA::Any * +CORBA::TypeCode::member_label (ULong index + ACE_ENV_ARG_DECL) const +{ + return this->member_label_i (index + ACE_ENV_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::discriminator_type (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->discriminator_type_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::Long +CORBA::TypeCode::default_index (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->default_index_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::ULong +CORBA::TypeCode::length (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->length_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::content_type (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->content_type_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::UShort +CORBA::TypeCode::fixed_digits (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->fixed_digits_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::UShort +CORBA::TypeCode::fixed_scale (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->fixed_scale_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::Visibility +CORBA::TypeCode::member_visibility (ULong index + ACE_ENV_ARG_DECL) const +{ + return this->member_visibility_i (index + ACE_ENV_ARG_PARAMETER); +} + +ACE_INLINE CORBA::ValueModifier +CORBA::TypeCode::type_modifier (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->type_modifier_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE CORBA::TypeCode_ptr +CORBA::TypeCode::concrete_base_type (ACE_ENV_SINGLE_ARG_DECL) const +{ + return this->concrete_base_type_i (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +ACE_INLINE void +CORBA::TypeCode::_tao_any_destructor (void * x) +{ + CORBA::release (static_cast <CORBA::TypeCode_ptr> (x)); +} + +// -------------------------------------------------------------- + +ACE_INLINE CORBA::TCKind +TAO::unaliased_kind (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) +{ + CORBA::TypeCode_var unaliased_tc = + TAO::unaliased_typecode (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TAO_TC_KIND_COUNT); + + return unaliased_tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER); +} diff --git a/TAO/tao/TypeCodeFactory_Adapter.h b/TAO/tao/TypeCodeFactory_Adapter.h index 776521743d9..820293c8553 100644 --- a/TAO/tao/TypeCodeFactory_Adapter.h +++ b/TAO/tao/TypeCodeFactory_Adapter.h @@ -1,4 +1,4 @@ -// This may look like C, but it's really -*- C++ -*- +// -*- C++ -*- //============================================================================= /** @@ -32,6 +32,16 @@ namespace CORBA class ValueMemberSeq; } +namespace TAO +{ + namespace TypeCode + { + template<typename STRING_TYPE> class Struct_Field; + template<typename STRING_TYPE> class Value_Field; + } +} + + /** * @class TAO_TypeCodeFactory_Adapter * @@ -195,6 +205,31 @@ public: ACE_ENV_ARG_DECL_WITH_DEFAULTS ) ACE_THROW_SPEC ((CORBA::SystemException)) = 0; + + // -- + + // Factory methods that has no corresponding TypeCodeFactory IDL, + // i.e. it is TAO-specific. + + virtual CORBA::TypeCode_ptr _tao_create_struct_except_tc ( + CORBA::TCKind, + char const * id, + char const * name, + TAO::TypeCode::Struct_Field<char const *> const * fields, + CORBA::ULong nfields + ACE_ENV_ARG_DECL) = 0; + + + virtual CORBA::TypeCode_ptr _tao_create_value_event_tc ( + CORBA::TCKind, + char const * id, + char const * name, + CORBA::ValueModifier modifier, + CORBA::TypeCode_ptr const * concrete_base, + TAO::TypeCode::Value_Field<char const *> const * fields, + CORBA::ULong nfields + ACE_ENV_ARG_DECL) = 0; + }; #include /**/ "ace/post.h" diff --git a/TAO/tao/TypeCode_Base_Attributes.cpp b/TAO/tao/TypeCode_Base_Attributes.cpp new file mode 100644 index 00000000000..b73f35b914a --- /dev/null +++ b/TAO/tao/TypeCode_Base_Attributes.cpp @@ -0,0 +1,10 @@ +// $Id$ + +#ifndef TAO_TYPECODE_BASE_ATTRIBUTES_CPP +#define TAO_TYPECODE_BASE_ATTRIBUTES_CPP + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Base_Attributes.inl" +#endif /* !__ACE_INLINE__ */ + +#endif /* TAO_TYPECODE_BASE_ATTRIBUTES_CPP */ diff --git a/TAO/tao/TypeCode_Base_Attributes.h b/TAO/tao/TypeCode_Base_Attributes.h new file mode 100644 index 00000000000..3f475334d6d --- /dev/null +++ b/TAO/tao/TypeCode_Base_Attributes.h @@ -0,0 +1,85 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Base_Attributes.h + * + * $Id$ + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_TYPECODE_BASE_ATTRIBUTES_H +#define TAO_TYPECODE_BASE_ATTRIBUTES_H + +#include /**/ "ace/pre.h" + +#include "tao/CORBA_String.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Base_Attributes + * + * @brief Attributes contained by most @c TypeCodes with complex + * parameter lists. + * + * Most @c TypeCodes with complex parameter lists (see Section + * 15.3.5.1 "TypeCode" in the CORBA specification) contain these + * attributes, namely a repository ID and a name. + */ + template <typename STRING_TYPE> + class Base_Attributes + { + public: + + /// Constructor. + Base_Attributes (char const * id, + char const * name); + + /// Get the @c RepositoryId globally identifying the type. + char const * id (void) const; + + /// Get the simple name identifying the type within its + /// enclosing scope. + char const * name (void) const; + + private: + + /// The @c RepositoryId globally identifying the type. + STRING_TYPE const id_; + + /// The simple name identifying the type within its enclosing + /// scope. + STRING_TYPE const name_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Base_Attributes.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Base_Attributes.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Base_Attributes.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_BASE_ATTRIBUTES_H */ diff --git a/TAO/tao/TypeCode_Base_Attributes.inl b/TAO/tao/TypeCode_Base_Attributes.inl new file mode 100644 index 00000000000..55e6dd94cb4 --- /dev/null +++ b/TAO/tao/TypeCode_Base_Attributes.inl @@ -0,0 +1,46 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename STRING_TYPE> +ACE_INLINE +TAO::TypeCode::Base_Attributes<STRING_TYPE>::Base_Attributes ( + char const * id, + char const * name) + : id_ (id), + name_ (name) +{ +} + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Base_Attributes<STRING_TYPE>::id (void) const +{ + return this->id_; +} + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Base_Attributes<STRING_TYPE>::name (void) const +{ + return this->name_; +} + +// ----------------------------------------------------------------- +// Some compilers exhibit warnings about better conversion sequence +// from a CORBA::String_var to a char const *. These member +// specializations work around them by performing explicit +// conversions. +// ----------------------------------------------------------------- + +ACE_INLINE char const * +TAO::TypeCode::Base_Attributes<CORBA::String_var>::id (void) const +{ + return this->id_.in (); +} + +ACE_INLINE char const * +TAO::TypeCode::Base_Attributes<CORBA::String_var>::name (void) const +{ + return this->name_.in (); +} diff --git a/TAO/tao/TypeCode_Case.cpp b/TAO/tao/TypeCode_Case.cpp new file mode 100644 index 00000000000..5c83263c258 --- /dev/null +++ b/TAO/tao/TypeCode_Case.cpp @@ -0,0 +1,87 @@ +// $Id$ + +#ifndef TAO_TYPECODE_CASE_CPP +#define TAO_TYPECODE_CASE_CPP + +#include "TypeCode_Case.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Case.inl" +#endif /* __ACE_INLINE__ */ + + +template <typename STRING_TYPE> +char const * +TAO::TypeCode::Case<STRING_TYPE>::~Case (void) +{ + if (this->type_) + CORBA::release (*(this->type_)); +} + +template <typename STRING_TYPE> +bool +TAO::TypeCode::Case<STRING_TYPE>::equal (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // Check case names. + char const * const lhs_name = this->name (); + char const * const rhs_name = tc->member_name (index + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strcmp (lhs_name, rhs_name) != 0) + return 0; + + // Check case TypeCodes. + CORBA::TypeCode_ptr const lhs_tc = this->type (); + CORBA::TypeCode_var const rhs_tc = + tc->member_type (index + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equal_members = + lhs_tc->equal (rhs_tc.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_members) + return 0; + + // Check case labels. + return this->equal_labels (index, + tc + ACE_ENV_ARG_PARAMETER); +} + +template <typename STRING_TYPE> +bool +TAO::TypeCode::Case<STRING_TYPE>::equivalent (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // Member names are ignore when determining equivalence. + + // Check case TypeCodes. + CORBA::TypeCode_ptr const lhs_tc = this->type (); + CORBA::TypeCode_var const rhs_tc = + tc->member_type (index + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equivalent_members = + lhs_tc->equivalent (rhs_tc.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equivalent_members) + return 0; + + // Check case labels. + // The labels must be equal when determining equivalence, too. + return this->equal_labels (index, + tc + ACE_ENV_ARG_PARAMETER); +} + +#endif /* TAO_TYPECODE_CASE_CPP */ diff --git a/TAO/tao/TypeCode_Case.h b/TAO/tao/TypeCode_Case.h new file mode 100644 index 00000000000..7b5042b6a14 --- /dev/null +++ b/TAO/tao/TypeCode_Case.h @@ -0,0 +1,159 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Case.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Case type. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_TYPECODE_CASE_H +#define TAO_TYPECODE_CASE_H + +#include /**/ "ace/pre.h" + +#include "ace/config.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace CORBA +{ + class TypeCode; + typedef TypeCode* TypeCode_ptr; + + class Any; +} + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Case + * + * @brief Abstract base class for that represents an IDL @c union + * case/member. + * + * This class hides the actual IDL @c union member label value + * from the @c TAO::TypeCode::Union class by relying on a + * CORBA::Any return value that corresponds to the @c + * CORBA::TypeCode::member_label() return type. It also allows + * the @c TAO::TypeCode::Union class to marshal the member label + * values into a CDR stream without knowledge of the underlying + * member label values. + */ + template <typename STRING_TYPE> + class Case + { + public: + + /// Constructor. + Case (char const * name, + CORBA::TypeCode_ptr * tc); + + /// Destructor. + virtual ~Case (void); + + /// Return the IDL @c union case label value embedded within a + /// @c CORBA::Any. + virtual CORBA::Any * label (ACE_ENV_SINGLE_ARG_DECL) const = 0; + + /// Get the name of the @c union case/member. + char const * name (void) const; + + /// Get the @c CORBA::TypeCode of the @c union case/member. + /** + * @note The reference count is not manipulated by this method, + * i.e., ownership is retained by this class. + */ + CORBA::TypeCode_ptr type (void) const; + + /// Marshal this IDL @c union member into the given output CDR + /// stream. + bool marshal (TAO_OutputCDR & cdr) const; + + /// Check for equality of the @c case attributes contained by this + /// class and the corresponding member attributes at index "@a + /// index" in the given @c TypeCode @a tc. + bool equal (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + + /// Check for equivalence of the @c case attributes contained by + /// this class and the corresponding member attributes at index + /// "@a index" in the given @c TypeCode @a tc. + bool equivalent (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + + protected: + + /// Marshal the IDL @c union @c case label value into the given + /// output CDR stream. + virtual bool marshal_label (TAO_OutputCDR & cdr) const = 0; + + /// Verify equality of member labels. + /** + * Performing member label equality comparisons in the @c Case + * subclass allows us to avoid performing interpretive + * extraction of the value from the @c Any returned from the + * "right hand side" operand @c TypeCode since the @c Case + * subclass already knows what type and value should be + * extracted from the @c Any. + * + * @param index Member index of given @c TypeCode @a tc being + * tested. + * @param tc The @c TypeCode whose member "@a index" label is + * being tested. + */ + virtual bool equal_label (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const = 0; + + private: + + /// The name of the case. + STRING_TYPE const name_; + + /// Pointer to the @c CORBA::TypeCode of the case. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the @c + * CORBA::TypeCode_ptr when creating this @c Case statically at + * compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c Case. + */ + CORBA::TypeCode_ptr * const type_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Case.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Case.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Case.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_CASE_H */ diff --git a/TAO/tao/TypeCode_Case.inl b/TAO/tao/TypeCode_Case.inl new file mode 100644 index 00000000000..b5e23148d6b --- /dev/null +++ b/TAO/tao/TypeCode_Case.inl @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// $Id$ + +#include "tao/CDR.h" + + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Case<STRING_TYPE>::Case ( + char const * member_name, + CORBA::TypeCode_ptr * member_type) + : name_ (member_name) + , type_ (member_type) +{ +} + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Case<STRING_TYPE>::name (void) const +{ + return this->name_; +} + +template <typename STRING_TYPE> +ACE_INLINE CORBA::TypeCode_ptr +TAO::TypeCode::Case<STRING_TYPE>::type (void) const +{ + return *this->type_; +} + +template <typename STRING_TYPE> +ACE_INLINE bool +TAO::TypeCode::Case<STRING_TYPE>::marshal ( + TAO_OutputCDR & cdr) const +{ + return + this->marshal_label () + && (cdr << this->name ()) + && (cdr << this->type ()); +} + + +// ----------------------------------------------------------------- +// Some compilers exhibit warnings about better conversion sequence +// from a CORBA::String_var to a char const *. This member +// specialization works around them by performing explicit +// conversions. +// ----------------------------------------------------------------- + +ACE_INLINE char const * +TAO::TypeCode::Case<CORBA::String_var>::name (void) const +{ + return this->name_.in (); +} diff --git a/TAO/tao/TypeCode_Constants.cpp b/TAO/tao/TypeCode_Constants.cpp new file mode 100644 index 00000000000..69771b39f6c --- /dev/null +++ b/TAO/tao/TypeCode_Constants.cpp @@ -0,0 +1,140 @@ +// $Id$ + + +#include "TypeCode_Constants.h" + + +ACE_RCSID (tao, + TypeCode_Constants, + "$Id$") + + +#include "Null_RefCount_Policy.h" +#include "Empty_Param_TypeCode.h" +#include "Objref_TypeCode.h" +#include "String_TypeCode.h" +#include "Value_TypeCode.h" + + +namespace TAO +{ + namespace TypeCode + { + // Notice that these are all statically instantiated and not + // exported. There CORBA::TypeCode_ptr counterparts are, however, + // exported. + + Empty_Param tc_null (CORBA::tk_null); + Empty_Param tc_void (CORBA::tk_void); + Empty_Param tc_boolean (CORBA::tk_boolean); + Empty_Param tc_char (CORBA::tk_char); + Empty_Param tc_wchar (CORBA::tk_wchar); + Empty_Param tc_short (CORBA::tk_short); + Empty_Param tc_ushort (CORBA::tk_ushort); + Empty_Param tc_long (CORBA::tk_long); + Empty_Param tc_ulong (CORBA::tk_ulong); + Empty_Param tc_longlong (CORBA::tk_longlong); + Empty_Param tc_ulonglong (CORBA::tk_ulonglong); + Empty_Param tc_float (CORBA::tk_float); + Empty_Param tc_double (CORBA::tk_double); + Empty_Param tc_longdouble (CORBA::tk_longdouble); + Empty_Param tc_octet (CORBA::tk_octet); + Empty_Param tc_any (CORBA::tk_any); + Empty_Param tc_TypeCode (CORBA::tk_TypeCode); + Empty_Param tc_Principal (CORBA::tk_Principal); + + // -------------- + + String<TAO::Null_RefCount_Policy> tc_string (CORBA::tk_string, 0); + String<TAO::Null_RefCount_Policy> tc_wstring (CORBA::tk_wstring, 0); + + // -------------- + + char const tc_object_id[] = "IDL:omg.org/CORBA/Object:1.0"; + char const tc_object_name[] = "Object"; + Objref<char const *, + CORBA::tk_objref, + TAO::Null_RefCount_Policy> tc_Object (tc_object_id, tc_object_name); + + char const tc_component_id[] = "IDL:omg.org/CORBA/CCMObject:1.0"; + char const tc_component_name[] = "CCMObject"; + Objref<char const *, + CORBA::tk_component, + TAO::Null_RefCount_Policy> tc_Component (tc_component_id, + tc_component_name); + + char const tc_home_id[] = "IDL:omg.org/CORBA/CCMHome:1.0"; + char const tc_home_name[] = "CCMHome"; + Objref<char const *, + CORBA::tk_home, + TAO::Null_RefCount_Policy> tc_Home (tc_home_id, tc_home_name); + + // -------------- + + char const tc_value_base_id[] = "IDL:omg.org/CORBA/ValueBase:1.0"; + char const tc_value_base_name[] = "ValueBase"; + Value<char const *, + Value_Field<char const *> const *, + CORBA::tk_value, + TAO::Null_RefCount_Policy> tc_ValueBase (tc_value_base_id, + tc_value_base_name, + CORBA::VM_NONE, + 0, // Nil TypeCode + 0, // Field array + 0); // Field count + + char const tc_event_base_id[] = "IDL:omg.org/CORBA/EventBase:1.0"; + char const tc_event_base_name[] = "EventBase"; + Value<char const *, + Value_Field<char const *> const *, + CORBA::tk_event, + TAO::Null_RefCount_Policy> tc_EventBase (tc_event_base_id, + tc_event_base_name, + CORBA::VM_NONE, + 0, // Nil TypeCode + 0, // Field array + 0); // Field count + + } // End TypeCode namespace +} // End TAO namespace + +// ------------------------------------------------------------------ +// OMG defined TypeCode constants +// ------------------------------------------------------------------ + +namespace CORBA +{ + // Notice that these are constant TypeCode references/pointers, not + // constant TypeCodes. TypeCodes are effectively read-only since + // all non-static TypeCode operations are const. + + TypeCode_ptr const _tc_null = &TAO::TypeCode::tc_null; + TypeCode_ptr const _tc_void = &TAO::TypeCode::tc_void; + TypeCode_ptr const _tc_boolean = &TAO::TypeCode::tc_boolean; + TypeCode_ptr const _tc_char = &TAO::TypeCode::tc_char; + TypeCode_ptr const _tc_wchar = &TAO::TypeCode::tc_wchar; + TypeCode_ptr const _tc_short = &TAO::TypeCode::tc_short; + TypeCode_ptr const _tc_ushort = &TAO::TypeCode::tc_ushort; + TypeCode_ptr const _tc_long = &TAO::TypeCode::tc_long; + TypeCode_ptr const _tc_ulong = &TAO::TypeCode::tc_ulong; + TypeCode_ptr const _tc_longlong = &TAO::TypeCode::tc_longlong; + TypeCode_ptr const _tc_ulonglong = &TAO::TypeCode::tc_ulonglong; + TypeCode_ptr const _tc_float = &TAO::TypeCode::tc_float; + TypeCode_ptr const _tc_double = &TAO::TypeCode::tc_double; + TypeCode_ptr const _tc_longdouble = &TAO::TypeCode::tc_longdouble; + TypeCode_ptr const _tc_octet = &TAO::TypeCode::tc_octet; + TypeCode_ptr const _tc_any = &TAO::TypeCode::tc_any; + TypeCode_ptr const _tc_TypeCode = &TAO::TypeCode::tc_TypeCode; + TypeCode_ptr const _tc_Principal = &TAO::TypeCode::tc_Principal; + + TypeCode_ptr const _tc_string = &TAO::TypeCode::tc_string; + TypeCode_ptr const _tc_wstring = &TAO::TypeCode::tc_wstring; + + TypeCode_ptr const _tc_Object = &TAO::TypeCode::tc_Object; + TypeCode_ptr const _tc_Component = &TAO::TypeCode::tc_Component; + TypeCode_ptr const _tc_Home = &TAO::TypeCode::tc_Home; + + TypeCode_ptr const _tc_ValueBase = &TAO::TypeCode::tc_ValueBase; + TypeCode_ptr const _tc_EventBase = &TAO::TypeCode::tc_EventBase; + +} diff --git a/TAO/tao/TypeCode_Constants.h b/TAO/tao/TypeCode_Constants.h new file mode 100644 index 00000000000..f3302e9071b --- /dev/null +++ b/TAO/tao/TypeCode_Constants.h @@ -0,0 +1,115 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Constants.h + * + * $Id$ + * + * Declare the @c TypeCode constants available to the ORB and user + * applications. + * + * @author Jeff Parsons + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_TYPECODE_CONSTANTS_FORWARD_H +#define TAO_TYPECODE_CONSTANTS_FORWARD_H + +#include /**/ "ace/pre.h" + +#include "tao/TAO_Export.h" + +namespace CORBA +{ + class TypeCode; + typedef TypeCode * TypeCode_ptr; + + /** + * @name TypeCode Constants + * + * All the TypeCode constants + */ + //@{ + extern TAO_Export TypeCode_ptr const _tc_null; + extern TAO_Export TypeCode_ptr const _tc_void; + extern TAO_Export TypeCode_ptr const _tc_short; + extern TAO_Export TypeCode_ptr const _tc_long; + extern TAO_Export TypeCode_ptr const _tc_ushort; + extern TAO_Export TypeCode_ptr const _tc_ulong; + extern TAO_Export TypeCode_ptr const _tc_float; + extern TAO_Export TypeCode_ptr const _tc_double; + extern TAO_Export TypeCode_ptr const _tc_boolean; + extern TAO_Export TypeCode_ptr const _tc_char; + extern TAO_Export TypeCode_ptr const _tc_octet; + extern TAO_Export TypeCode_ptr const _tc_any; + extern TAO_Export TypeCode_ptr const _tc_TypeCode; + extern TAO_Export TypeCode_ptr const _tc_Principal; + extern TAO_Export TypeCode_ptr const _tc_Object; + extern TAO_Export TypeCode_ptr const _tc_string; + extern TAO_Export TypeCode_ptr const _tc_longlong; + extern TAO_Export TypeCode_ptr const _tc_ulonglong; + extern TAO_Export TypeCode_ptr const _tc_longdouble; + extern TAO_Export TypeCode_ptr const _tc_wchar; + extern TAO_Export TypeCode_ptr const _tc_wstring; + +#define TAO_SYSTEM_EXCEPTION_LIST \ + TAO_SYSTEM_EXCEPTION(UNKNOWN); \ + TAO_SYSTEM_EXCEPTION(BAD_PARAM); \ + TAO_SYSTEM_EXCEPTION(NO_MEMORY); \ + TAO_SYSTEM_EXCEPTION(IMP_LIMIT); \ + TAO_SYSTEM_EXCEPTION(COMM_FAILURE); \ + TAO_SYSTEM_EXCEPTION(INV_OBJREF); \ + TAO_SYSTEM_EXCEPTION(OBJECT_NOT_EXIST); \ + TAO_SYSTEM_EXCEPTION(NO_PERMISSION); \ + TAO_SYSTEM_EXCEPTION(INTERNAL); \ + TAO_SYSTEM_EXCEPTION(MARSHAL); \ + TAO_SYSTEM_EXCEPTION(INITIALIZE); \ + TAO_SYSTEM_EXCEPTION(NO_IMPLEMENT); \ + TAO_SYSTEM_EXCEPTION(BAD_TYPECODE); \ + TAO_SYSTEM_EXCEPTION(BAD_OPERATION); \ + TAO_SYSTEM_EXCEPTION(NO_RESOURCES); \ + TAO_SYSTEM_EXCEPTION(NO_RESPONSE); \ + TAO_SYSTEM_EXCEPTION(PERSIST_STORE); \ + TAO_SYSTEM_EXCEPTION(BAD_INV_ORDER); \ + TAO_SYSTEM_EXCEPTION(TRANSIENT); \ + TAO_SYSTEM_EXCEPTION(FREE_MEM); \ + TAO_SYSTEM_EXCEPTION(INV_IDENT); \ + TAO_SYSTEM_EXCEPTION(INV_FLAG); \ + TAO_SYSTEM_EXCEPTION(INTF_REPOS); \ + TAO_SYSTEM_EXCEPTION(BAD_CONTEXT); \ + TAO_SYSTEM_EXCEPTION(OBJ_ADAPTER); \ + TAO_SYSTEM_EXCEPTION(DATA_CONVERSION); \ + TAO_SYSTEM_EXCEPTION(INV_POLICY); \ + TAO_SYSTEM_EXCEPTION(REBIND); \ + TAO_SYSTEM_EXCEPTION(TIMEOUT); \ + TAO_SYSTEM_EXCEPTION(TRANSACTION_UNAVAILABLE); \ + TAO_SYSTEM_EXCEPTION(TRANSACTION_MODE); \ + TAO_SYSTEM_EXCEPTION(TRANSACTION_REQUIRED); \ + TAO_SYSTEM_EXCEPTION(TRANSACTION_ROLLEDBACK); \ + TAO_SYSTEM_EXCEPTION(INVALID_TRANSACTION); \ + TAO_SYSTEM_EXCEPTION(CODESET_INCOMPATIBLE); \ + TAO_SYSTEM_EXCEPTION(BAD_QOS); \ + TAO_SYSTEM_EXCEPTION(INVALID_ACTIVITY); \ + TAO_SYSTEM_EXCEPTION(ACTIVITY_COMPLETED); \ + TAO_SYSTEM_EXCEPTION(ACTIVITY_REQUIRED); \ + TAO_SYSTEM_EXCEPTION(THREAD_CANCELLED); + + // = Typecode constants for system exceptions. +#define TAO_SYSTEM_EXCEPTION(name) \ + extern TAO_Export TypeCode_ptr const _tc_ ## name + TAO_SYSTEM_EXCEPTION_LIST +#undef TAO_SYSTEM_EXCEPTION + //@} + + extern TAO_Export TypeCode_ptr const _tc_UnknownUserException; + + extern TAO_Export TypeCode_ptr const _tc_Current; + + extern TAO_Export TypeCode_ptr const _tc_NamedValue; +} + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_CONSTANTS_H */ diff --git a/TAO/tao/TypeCode_Default_Case.cpp b/TAO/tao/TypeCode_Default_Case.cpp new file mode 100644 index 00000000000..8b5b3e450e4 --- /dev/null +++ b/TAO/tao/TypeCode_Default_Case.cpp @@ -0,0 +1,85 @@ +// $Id$ + +#ifndef TAO_TYPECODE_DEFAULT_CASE_CPP +#define TAO_TYPECODE_DEFAULT_CASE_CPP + +#include "TypeCode_Default_Case.h" + +#include "tao/CDR.h" +#include "tao/Any.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Default_Case.inl" +#endif /* __ACE_INLINE__ */ + + +namespace TAO +{ + namespace TypeCode + { + + // Default case's label is a zero octet. + static TAO_OutputCDR::from_octet const zero_octet (0); + + } // Namespace TypeCode +} // Namespace TAO + +// ------------------------------------------------------------ + +template <typename STRING_TYPE> +bool +TAO::TypeCode::Default_Case<STRING_TYPE>::marshal_label ( + TAO_OutputCDR & cdr) const +{ + // Default case's label is a zero octet. + return (cdr << TAO::TypeCode::zero_octet); +} + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +bool +TAO::TypeCode::Default_Case<DISCRIMINATOR_TYPE, + STRING_TYPE>::equal_label ( + CORBA::ULong index + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + CORBA::Any_var const any = tc->member_label (index + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + + + // Label for default case is always zero octet. + static CORBA::Octet const this_label = 0; + + CORBA::Octet tc_label; + if (any.in () >>= CORBA::Any::to_octet (tc_label) + && this_label == tc_label) + { + return true; + } + + return false; +} + +template <typename STRING_TYPE> +CORBA::Any * +TAO::TypeCode::Default_Case<STRING_TYPE>::label ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + CORBA::Any * value; + + ACE_NEW_THROW_EX (value, + CORBA::Any, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + CORBA::Any_var safe_value (value); + + *value <<= TAO::TypeCode::zero_octet; + + return safe_value._retn (); +} + + + +#endif /* TAO_TYPECODE_DEFAULT_CASE_CPP */ diff --git a/TAO/tao/TypeCode_Default_Case.h b/TAO/tao/TypeCode_Default_Case.h new file mode 100644 index 00000000000..4072da0706f --- /dev/null +++ b/TAO/tao/TypeCode_Default_Case.h @@ -0,0 +1,86 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Default_Case.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Default_Case type. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_TYPECODE_DEFAULT_CASE_H +#define TAO_TYPECODE_DEFAULT_CASE_H + +#include /**/ "ace/pre.h" + +#include "ace/config.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Case.h" + + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Default_Case + * + * @brief Representation of an OMG IDL defined @c union @c default + * @c case. + * + */ + template <typename STRING_TYPE> + class Default_Case : public Case<STRING_TYPE> + { + public: + + /// Constructor. + Default_Case (char const * member_name, + CORBA::TypeCode_ptr * member_type); + + /** + * @name @c TAO::TypeCode::Case Methods + * + * Methods required by the @c TAO::TypeCode::Case abstract base + * class. + * + * @see @c TAO::TypeCode::Case + */ + //@{ + virtual CORBA::Any * label (ACE_ENV_SINGLE_ARG_DECL) const; + virtual bool marshal_label (TAO_OutputCDR & cdr) const; + virtual bool equal_label (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + //@} + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Default_Case.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Default_Case.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Default_Case.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_DEFAULT_CASE_H */ diff --git a/TAO/tao/TypeCode_Default_Case.inl b/TAO/tao/TypeCode_Default_Case.inl new file mode 100644 index 00000000000..6be34598a97 --- /dev/null +++ b/TAO/tao/TypeCode_Default_Case.inl @@ -0,0 +1,12 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Default_Case<STRING_TYPE>::Default_Case ( + char const * member_name, + CORBA::TypeCode_ptr * member_type) + : Case<STRING_TYPE> (member_name, member_type) +{ +} diff --git a/TAO/tao/TypeCode_Enumerator.cpp b/TAO/tao/TypeCode_Enumerator.cpp new file mode 100644 index 00000000000..a17468c4d01 --- /dev/null +++ b/TAO/tao/TypeCode_Enumerator.cpp @@ -0,0 +1,12 @@ +// $Id$ + +#ifndef TAO_TYPECODE_ENUMERATOR_CPP +#define TAO_TYPECODE_ENUMERATOR_CPP + +#include "TypeCode_Enumerator.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Enumerator.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* TAO_TYPECODE_ENUMERATOR_CPP */ diff --git a/TAO/tao/TypeCode_Enumerator.h b/TAO/tao/TypeCode_Enumerator.h new file mode 100644 index 00000000000..900a622314e --- /dev/null +++ b/TAO/tao/TypeCode_Enumerator.h @@ -0,0 +1,113 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Enumerator.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Enumerator type. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_TYPECODE_ENUMERATOR_H +#define TAO_TYPECODE_ENUMERATOR_H + +#include /**/ "ace/pre.h" + +#include "tao/TAO_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/orbconf.h" + +namespace CORBA +{ + class TypeCode; + typedef TypeCode* TypeCode_ptr; +} + +namespace TAO +{ + namespace TypeCode + { + /** + * @struct Enumerator + * + * @brief Enumerator of an OMG IDL defined enumeration (@c enum). + * + * An @c Enumerator contains the name for a given OMG IDL defined + * enumeration. For example, the enumerators in following OMG IDL + * enumeration: + * + * \code + * enum Color + * { + * RED; + * BLUE; + * }; + * \endcode + * + * would be represented using the following @c + * TAO::TypeCode::Enumerator array: + * + * \code + * TAO::TypeCode::Enumerator _tao_enumerators_Color[] = + * { + * "RED", + * "BLUE", + * }; + * \endcode + */ + template <typename STRING_TYPE> + struct Enumerator + { + + /// Return the name of the @c Enumerator. + /** + * @note This method unfortunately exists so that we can + * retrieve the underlying string when the @a STRING_TYPE + * is @c CORBA::String_var rather than the + * @c CORBA::String_var itself. This is necessary to + * silence a warning about better conversion sequences + * exhibited by some C++ compilers. + */ + char const * get_name (void) const; + + /// The name of the enumerator. + STRING_TYPE name; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Enumerator.inl" +#endif /* __ACE_INLINE__ */ + +// If we didn't have to worry about better conversion sequence +// warnings, and drop the Enumerator<>::get_name() method, we could +// drop the below #include directives and remove the files contained +// within them altogether. + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Enumerator.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Enumerator.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Enumerator.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_ENUMERATOR_H */ diff --git a/TAO/tao/TypeCode_Enumerator.inl b/TAO/tao/TypeCode_Enumerator.inl new file mode 100644 index 00000000000..6f3ea4eb33e --- /dev/null +++ b/TAO/tao/TypeCode_Enumerator.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Enumerator<STRING_TYPE>::get_name (void) const +{ + return this->name; +} + +// ----------------------------------------------------------------- +// Some compilers exhibit warnings about better conversion sequence +// from a CORBA::String_var to a char const *. This member +// specialization works around them by performing explicit +// conversions. +// ----------------------------------------------------------------- + +ACE_INLINE char const * +TAO::TypeCode::Enumerator<CORBA::String_var>::get_name (void) const +{ + return this->name.in (); +} diff --git a/TAO/tao/TypeCode_Non_Default_Case.cpp b/TAO/tao/TypeCode_Non_Default_Case.cpp new file mode 100644 index 00000000000..ba451c3ad97 --- /dev/null +++ b/TAO/tao/TypeCode_Non_Default_Case.cpp @@ -0,0 +1,143 @@ +// $Id$ + +#ifndef TAO_TYPECODE_NON_DEFAULT_CASE_CPP +#define TAO_TYPECODE_NON_DEFAULT_CASE_CPP + +#include "TypeCode_Non_Default_Case.h" + +#include "tao/CDR.h" +#include "tao/Any.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Non_Default_Case.inl" +#endif /* __ACE_INLINE__ */ + +namespace TAO +{ + namespace TypeCode + { + template <typename T> + struct Case_Traits + { + inline static T any_from (T v) + { + return v; + } + + inline static T any_to (T & v) + { + return v; + } + }; + + // Specializations for types that require wrapper for Any + // insertion. Note that we only define specializations for types + // that can be used in an IDL union discriminator. + + template <> + struct Case_Traits<CORBA::Boolean> + { + inline static CORBA::Any::from_boolean any_from (CORBA::Boolean v) + { + return CORBA::Any::from_boolean (v); + } + + inline static CORBA::Any::to_boolean any_to (CORBA::Boolean & v) + { + return CORBA::Any::to_boolean (v); + } + }; + + template <> + struct Case_Traits<CORBA::Char> + { + inline static CORBA::Any::from_char any_from (CORBA::Char v) + { + return CORBA::Any::from_char (v); + } + + inline static CORBA::Any::to_char any_to (CORBA::Char & v) + { + return CORBA::Any::to_char (v); + } + }; + + template <> + struct Case_Traits<CORBA::WChar> + { + inline static CORBA::Any::from_wchar any_from (CORBA::WChar v) + { + return CORBA::Any::from_wchar (v); + } + + inline static CORBA::Any::to_wchar any_to (CORBA::WChar & v) + { + return CORBA::Any::to_wchar (v); + } + }; + + } // End TypeCode namespace +} // End TAO namespace + +// ---------------------------------------------------------------- + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +bool +TAO::TypeCode::Non_Default_Case<DISCRIMINATOR_TYPE, + STRING_TYPE>::marshal_label ( + TAO_OutputCDR & cdr) const +{ + return (cdr << this->label_); +} + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +bool +TAO::TypeCode::Non_Default_Case<DISCRIMINATOR_TYPE, + STRING_TYPE>::equal_label ( + CORBA::ULong index + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + CORBA::Any_var const any = tc->member_label (index + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + + // The equality operator==() below is guaranteed to be defined for + // the discriminator type since an IDL union discriminator type must + // be any of the following: (1) an integer, (2) a character, (3) a + // boolean, or (4) an enumeration. + + DISCRIMINATOR_TYPE tc_label; + if (any.in () + >>= TAO::TypeCode::Case_Traits<DISCRIMINATOR_TYPE>::any_to (tc_label) + && this->label_ == tc_label) + { + return true; + } + + return false; +} + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +CORBA::Any * +TAO::TypeCode::Non_Default_Case<DISCRIMINATOR_TYPE, STRING_TYPE>::label ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + CORBA::Any * value; + + ACE_NEW_THROW_EX (value, + CORBA::Any, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + CORBA::Any_var safe_value (value); + + *value <<= + TAO::TypeCode::Case_Traits<DISCRIMINATOR_TYPE>::any_from (this->label_); + + return safe_value._retn (); +} + + + +#endif /* TAO_TYPECODE_NON_DEFAULT_CASE_CPP */ diff --git a/TAO/tao/TypeCode_Non_Default_Case.h b/TAO/tao/TypeCode_Non_Default_Case.h new file mode 100644 index 00000000000..1488fdd61d0 --- /dev/null +++ b/TAO/tao/TypeCode_Non_Default_Case.h @@ -0,0 +1,136 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Non_Default_Case.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Non_Default_Case type. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_TYPECODE_NON_DEFAULT_CASE_H +#define TAO_TYPECODE_NON_DEFAULT_CASE_H + +#include /**/ "ace/pre.h" + +#include "ace/config.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Case.h" + + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Non_Default_Case + * + * @brief Representation of an OMG IDL defined @c union @c case. + * + * A @c Non_Default_Case contains the corresponding case label value, name and + * pointer to the @c CORBA::TypeCode for a given OMG IDL @c union + * @c case. For + * example, the cases in following OMG IDL @c union: + * + * \code + * union Foo switch (short) + * { + * case 0: + * case 1: short a; + * case 2: long b; + * default: octet c; + * }; + * \endcode + * + * would be represented using the following statically instantiated + * @c TAO::TypeCode::Non_Default_Case array: + * + * \code + * typedef TAO::TypeCode::Non_Default_Case<CORBA::Short, + char const *> Foo_Case; + * Foo_Case _tao_cases_Foo[] = + * { + * Foo_Case (0, "a", &CORBA::_tc_short), + * Foo_Case (1, "b", &CORBA::_tc_short), + * Foo_Case (2, "c", &CORBA::_tc_long) + * }; + * \endcode + * + * The @c default case is passed directly to the + * @c TAO::TypeCode::Union constructor. + * + * The template parameter @a DISCRIMINATOR_TYPE is the + * corresponding C++ type for the IDL defined @c union + * discriminator type. For example, a @c union with an IDL @c + * short discriminator will have a corresponding @c CORBA::Short + * C++ type. This template parameter is necessary to allow the + * actual @c case label value to be stored as its actual type, + * which is particularly important when marshaling that value into + * a CDR stream. + * + * The template parameter @a STRING_TYPE is either @c char @c + * const @c * or @c CORBA::String_var. The latter is only used + * when creating @c CORBA::tk_union @c TypeCode dynamically, such + * as through the TypeCodeFactory. + */ + template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> + class Non_Default_Case : public Case<STRING_TYPE> + { + public: + + /// Constructor. + Non_Default_Case (DISCRIMINATOR_TYPE member_label, + char const * member_name, + CORBA::TypeCode_ptr * member_type); + + /** + * @name @c TAO::TypeCode::Case Methods + * + * Methods required by the @c TAO::TypeCode::Case abstract base + * class. + * + * @see @c TAO::TypeCode::Case + */ + //@{ + virtual CORBA::Any * label (ACE_ENV_SINGLE_ARG_DECL) const; + virtual bool marshal_label (TAO_OutputCDR & cdr) const; + virtual bool equal_label (CORBA::ULong index, + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + //@} + + private: + + /// IDL @c union case/member label value. + DISCRIMINATOR_TYPE const label_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Non_Default_Case.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Non_Default_Case.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Non_Default_Case.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_NON_DEFAULT_CASE_H */ diff --git a/TAO/tao/TypeCode_Non_Default_Case.inl b/TAO/tao/TypeCode_Non_Default_Case.inl new file mode 100644 index 00000000000..7a4dd0ab343 --- /dev/null +++ b/TAO/tao/TypeCode_Non_Default_Case.inl @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Non_Default_Case<DISCRIMINATOR_TYPE, + STRING_TYPE>::Non_Default_Case ( + DISCRIMINATOR_TYPE member_label, + char const * member_name, + CORBA::TypeCode_ptr * member_type) + : Case<STRING_TYPE> (member_name, member_type) + , label_ (member_label) +{ +} diff --git a/TAO/tao/TypeCode_Struct_Field.cpp b/TAO/tao/TypeCode_Struct_Field.cpp new file mode 100644 index 00000000000..009ab6d1c4d --- /dev/null +++ b/TAO/tao/TypeCode_Struct_Field.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#ifndef TAO_TYPECODE_STRUCT_FIELD_CPP +#define TAO_TYPECODE_STRUCT_FIELD_CPP + +#include "TypeCode_Struct_Field.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Struct_Field.inl" +#endif /* __ACE_INLINE__ */ + + +template <typename STRING_TYPE> +TAO::TypeCode::Struct_Field<STRING_TYPE>::~Struct_Field (void) +{ + if (this->type) + CORBA::release (*type); +} + +#endif /* TAO_TYPECODE_STRUCT_FIELD_CPP */ diff --git a/TAO/tao/TypeCode_Struct_Field.h b/TAO/tao/TypeCode_Struct_Field.h new file mode 100644 index 00000000000..402ded3640b --- /dev/null +++ b/TAO/tao/TypeCode_Struct_Field.h @@ -0,0 +1,129 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Struct_Field.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Struct_Field type. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + * @author Carlos O'Ryan + */ +//============================================================================= + +#ifndef TAO_TYPECODE_STRUCT_FIELD_H +#define TAO_TYPECODE_STRUCT_FIELD_H + +#include /**/ "ace/pre.h" + +#include "ace/config.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace CORBA +{ + class TypeCode; + typedef TypeCode* TypeCode_ptr; +} + +namespace TAO +{ + namespace TypeCode + { + /** + * @struct Struct_Field + * + * @brief Name/type pair for fields of an OMG IDL defined + * structure or exception. + * + * A @c Struct_Field contains the corresponding name and pointer + * to the @c CORBA::TypeCode for a given OMG IDL defined type. + * For example, the fields in following OMG IDL structure: + * + * \code + * struct Foo + * { + * long the_number; + * string the_string; + * }; + * \endcode + * + * would be represented using the following statically instantiated + * @c TAO::TypeCode::Struct_Field array: + * + * \code + * TAO::TypeCode::Struct_Field<char const *> _tao_fields_Foo[] = + * { + * { "the_number", &CORBA::_tc_long }, + * { "the_string", &CORBA::_tc_string }, + * }; + * \endcode + * + * The template parameter @a STRING_TYPE is either @c char + * @c const @c * or @c CORBA::String_var. The latter is only used + * when creating @c CORBA::tk_struct or @c CORBA::tk_except + * @c TypeCodes dynamically, such as through the TypeCodeFactory. + */ + template <typename STRING_TYPE> + struct Struct_Field + { + /// Destructor. + ~Struct_Field (void); + + /// Return the name of the @c Struct_Field. + /** + * @note This method unfortunately exists so that we can + * retrieve the underlying string when the @a STRING_TYPE + * is @c CORBA::String_var rather than the + * @c CORBA::String_var itself. This is necessary to + * silence a warning about better conversion sequences + * exhibited by some C++ compilers. + */ + char const * get_name (void) const; + + /// The name of the field. + STRING_TYPE name; + + /// Pointer to the @c CORBA::TypeCode of the field. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the @c + * CORBA::TypeCode_ptr when creating this @c Struct_Field + * statically at compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c Struct_Field. + */ + CORBA::TypeCode_ptr * type; + + }; + + } // End namespace TypeCode +} // End namespace TAO + +// If we didn't have to worry about better conversion sequence +// warnings, and drop the Struct_Field<>::get_name() method, we could +// drop the below #include directives and remove the files contained +// within them altogether. + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Struct_Field.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Struct_Field.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Struct_Field.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_STRUCT_FIELD_H */ diff --git a/TAO/tao/TypeCode_Struct_Field.inl b/TAO/tao/TypeCode_Struct_Field.inl new file mode 100644 index 00000000000..70e5bafdef6 --- /dev/null +++ b/TAO/tao/TypeCode_Struct_Field.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Struct_Field<STRING_TYPE>::get_name (void) const +{ + return this->name; +} + +// ----------------------------------------------------------------- +// Some compilers exhibit warnings about better conversion sequence +// from a CORBA::String_var to a char const *. This member +// specialization works around them by performing explicit +// conversions. +// ----------------------------------------------------------------- + +ACE_INLINE char const * +TAO::TypeCode::Struct_Field<CORBA::String_var>::get_name (void) const +{ + return this->name.in (); +} diff --git a/TAO/tao/TypeCode_Value_Field.cpp b/TAO/tao/TypeCode_Value_Field.cpp new file mode 100644 index 00000000000..df8eb7720a7 --- /dev/null +++ b/TAO/tao/TypeCode_Value_Field.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#ifndef TAO_TYPECODE_VALUE_FIELD_CPP +#define TAO_TYPECODE_VALUE_FIELD_CPP + +#include "TypeCode_Value_Field.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Value_Field.inl" +#endif /* __ACE_INLINE__ */ + + +template <typename STRING_TYPE> +TAO::TypeCode::Value_Field<STRING_TYPE>::~Value_Field (void) +{ + if (this->type) + CORBA::release (*type); +} + +#endif /* TAO_TYPECODE_VALUE_FIELD_CPP */ diff --git a/TAO/tao/TypeCode_Value_Field.h b/TAO/tao/TypeCode_Value_Field.h new file mode 100644 index 00000000000..74019af73c9 --- /dev/null +++ b/TAO/tao/TypeCode_Value_Field.h @@ -0,0 +1,131 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Value_Field.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Value_Field type. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_TYPECODE_VALUE_FIELD_H +#define TAO_TYPECODE_VALUE_FIELD_H + +#include /**/ "ace/pre.h" + +#include "ace/config.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +namespace CORBA +{ + class TypeCode; + typedef TypeCode* TypeCode_ptr; +} + +namespace TAO +{ + namespace TypeCode + { + /** + * @struct Value_Field + * + * @brief Name/type/visibility tuple fields of an OMG IDL defined + * @c valuetype or @c eventtype. + * + * A @c Value_Field contains the corresponding name and pointer to the + * @c CORBA::TypeCode for a given OMG IDL defined type. For + * example, the fields in following OMG IDL structure: + * + * \code + * struct Foo + * { + * long the_number; + * string the_string; + * }; + * \endcode + * + * would be represented using the following statically instantiated + * @c TAO::TypeCode::Value_Field array: + * + * \code + * TAO::TypeCode::Value_Field<char const *> _tao_fields_Foo[] = + * { + * { "the_number", &CORBA::_tc_long }, + * { "the_string", &CORBA::_tc_string }, + * }; + * \endcode + * + * The template parameter @a STRING_TYPE is either @c char + * @c const @c * or @c CORBA::String_var. The latter is only used + * when creating @c CORBA::tk_value or @c CORBA::tk_event + * @c TypeCodes dynamically, such as through the TypeCodeFactory. + */ + template <typename STRING_TYPE> + struct Value_Field + { + /// Destructor. + ~Value_Field (void); + + /// Return the name of the @c Value_Field. + /** + * @note This method unfortunately exists so that we can + * retrieve the underlying string when the @a STRING_TYPE + * is @c CORBA::String_var rather than the + * @c CORBA::String_var itself. This is necessary to + * silence a warning about better conversion sequences + * exhibited by some C++ compilers. + */ + char const * get_name (void) const; + + /// The name of the field. + STRING_TYPE name; + + /// Pointer to the @c CORBA::TypeCode of the field. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the + * @c CORBA::TypeCode_ptr when creating this @c Value_Field + * statically at compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c Value_Field. + */ + CORBA::TypeCode_ptr * type; + + /// The visibility of the field. + CORBA::Visibility visibility; + + }; + + } // End namespace TypeCode +} // End namespace TAO + +// If we didn't have to worry about better conversion sequence +// warnings, and drop the Value_Field<>::get_name() method, we could +// drop the below #include directives and remove the files contained +// within them altogether. + +#ifdef __ACE_INLINE__ +# include "tao/TypeCode_Value_Field.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Value_Field.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Value_Field.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_VALUE_FIELD_H */ diff --git a/TAO/tao/TypeCode_Value_Field.inl b/TAO/tao/TypeCode_Value_Field.inl new file mode 100644 index 00000000000..852273c2d83 --- /dev/null +++ b/TAO/tao/TypeCode_Value_Field.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Value_Field<STRING_TYPE>::get_name (void) const +{ + return this->name; +} + +// ----------------------------------------------------------------- +// Some compilers exhibit warnings about better conversion sequence +// from a CORBA::String_var to a char const *. This member +// specialization works around them by performing explicit +// conversions. +// ----------------------------------------------------------------- + +ACE_INLINE char const * +TAO::TypeCode::Value_Field<CORBA::String_var>::get_name (void) const +{ + return this->name.in (); +} diff --git a/TAO/tao/Union_TypeCode.cpp b/TAO/tao/Union_TypeCode.cpp new file mode 100644 index 00000000000..53bf163312d --- /dev/null +++ b/TAO/tao/Union_TypeCode.cpp @@ -0,0 +1,387 @@ +// $Id$ + +#ifndef TAO_UNION_TYPECODE_CPP +#define TAO_UNION_TYPECODE_CPP + +#include "tao/Union_TypeCode.h" +#include "tao/TypeCode_Case.h" + +#ifndef __ACE_INLINE__ +# include "tao/Union_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +bool +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::tao_marshal ( + TAO_OutputCDR & cdr) const +{ + // A tk_union TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + CORBA::ULong const count = this->case_count (); + + // Create a CDR encapsulation. + bool const success = + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->base_attributes_.id ()) + && (cdr << this->base_attributes_.name ()) + && (cdr << *(this->discriminant_type_)) + && (cdr << this->default_index_) + && (cdr << count); + + if (!success) + return false; + + // Note that we handle the default case below, too. The default + // case handling is hidden behind the case_count() and case() + // methods. + + for (unsigned int i = 0; i < count; ++i) + { + case_type const & c = this->case (i); + + if (!c.marshal (cdr)) + return false; + } + + return true; +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +void +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +void +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // These calls shouldn't throw since CORBA::TypeCode::equal() + // verified that the TCKind is the same as our's prior to invoking + // this method, meaning that the CORBA::tk_union TypeCode methods + // are supported. + + CORBA::ULong const tc_count = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Long tc_def = tc->default_index (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::ULong const this_count = this->case_count (); + + if (tc_count != this_count + || tc_def != this->default_index_) + return 0; + + // Check the discriminator type. + CORBA::TypeCode_var tc_discriminator = + tc->discriminator_type (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equal_discriminators = + (*this->discriminator_type_)->equal (tc_discriminator.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_discriminators) + return 0; + + for (CORBA::ULong i = 0; i < this_count; ++i) + { + case_type const & lhs_case = this->case (i); + + bool const equal_case = + lhs_case.equal (i, + tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_case) + return 0; + } + + return 1; +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // Call kind_i() instead of using CORBA::tk_union directly since a + // subclass, such as Except_TypeCode, can use this equivalent_i() + // implementation. + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != this_kind) + return 0; + + char const * const this_id = this->base_attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + // Perform a structural comparison, excluding the name() and + // member_name() operations. + + CORBA::ULong const tc_count = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Long tc_def = tc->default_index (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::ULong const this_count = this->case_count (); + + if (tc_count != this_count + || tc_def != this->default_index_) + return 0; + + CORBA::TypeCode_var tc_discriminator = + tc->discriminator_type (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equiv_discriminators = + (*this->discriminator_type_)->equivalent (tc_discriminator.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equiv_discriminators) + return 0; + + for (CORBA::ULong i = 0; i < this_count; ++i) + { + case_type const & lhs_case = this->case (i); + + bool const equivalent_case = + lhs_case.equivalent (i, + tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equivalent_case) + return 0; + } + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Union<StringType, CaseArrayType, RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::tk_union; +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + case_type * tc_cases = 0; + + ACE_Auto_Array_Ptr<Case<CORBA::String_var> > safe_cases; + + if (this->ncases_ > 0) + { + // Dynamically construct a new array of cases stripped of + // member names. + + ACE_NEW_THROW_EX (tc_cases, + case_type[this->ncases_], + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + safe_cases.reset (tc_cases); + + static char const * empty_name = ""; + + for (CORBA::ULong i = 0; i < this->ncases_; ++i) + { + // Member names will be stripped, i.e. not embedded within + // the compact TypeCode. + tc_cases[i].name = empty_name; + tc_cases[i].type = + &(this->case (i).type ()->get_compact_typecode ( + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + } + } + + // Create the compact union TypeCode. + TAO_TypeCodeFactory_Adapter * adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name ()); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TCKind const this_kind = + this->kind_i (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + tc = adapter->_tao_create_union_tc (this->base_attributes_.id (), + "", /* empty name */ + this->discriminant_type_, + tc_cases, + this->ncases_, + this->default_index_, + "", + CORBA::TypeCode_ptr * default_member_type + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + (void) safe_cases.release (); + + return tc; +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Union<StringType, CaseArrayType, RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.id (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Union<StringType, CaseArrayType, RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.name (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::ULong +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::member_count_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->case_count (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +char const * +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::member_name_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + if (index >= this->case_count ()) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); + + return this->case (index).name (); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::member_type_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + if (index >= this->case_count ()) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), + CORBA::TypeCode::_nil ()); + + return CORBA::TypeCode::_duplicate (this->case (index).type ()); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::Any * +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::member_label_i (ULong index + ACE_ENV_ARG_DECL) const +{ + if (index >= this->case_count ()) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), + 0); + + return this->case (index).label (ACE_ENV_ARG_PARAMETER); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::discriminator_type_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + return CORBA::TypeCode::_duplicate (*this->discriminator_type_); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +CORBA::Long +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::default_index_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->default_index_; +} + + +#endif /* TAO_UNION_TYPECODE_CPP */ diff --git a/TAO/tao/Union_TypeCode.h b/TAO/tao/Union_TypeCode.h new file mode 100644 index 00000000000..98df9331715 --- /dev/null +++ b/TAO/tao/Union_TypeCode.h @@ -0,0 +1,189 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Union_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_union CORBA::TypeCode. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_UNION_TYPECODE_H +#define TAO_UNION_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Base_Attributes.h" + + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Union + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c union. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c union. + */ + template <typename StringType, class CaseArrayType, class RefCountPolicy> + class Union + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + typedef TAO::TypeCode::Case<StringType> case_type; + + /// Constructor. + Union (char const * id, + char const * name, + CORBA::TypeCode_ptr * discriminant_type, + case_type const * cases, + CORBA::ULong ncases, + CORBA::Long default_index); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_union @c CORBA::TypeCode -specific template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong member_count_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * member_name_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::TypeCode_ptr member_type_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::Any * member_label_i (ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::TypeCode_ptr discriminator_type_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::Long default_index_i (ACE_ENV_SINGLE_ARG_DECL) const; + //@} + + private: + + /// Get pointer to the underlying @c Case array. + case_type const * cases (void) const; + + /// Return the number of cases in the IDL @c union, including + /// the @c default case. + CORBA::ULong case_count (void) const; + + /// Return @c union case corresponding to given member (not + /// @c case_type array) index. + /** + * @param index The zero-based index of the @c union member, + * including the @c default case. For example, if + * the @c default case is the second @union + * case/member, the @a index would be @c 1. + * + * @return Reference to @c union case/member corresponding to + * the given member zero-based @a index value. + * + * @note This method handles the @c default case. Do not + * attempt to perform special handling for the @c default + * case by shifting the index value by one, for example. + */ + case_type const & case (CORBA::ULong index) const; + + private: + + /** + * @c Union Attributes + * + * Attributes representing the structure of an OMG IDL + * @c union. + * + * @note These attributes are declared in the order in which + * they are marshaled into a CDR stream in order to + * increase cache hits by improving spatial locality. + */ + //@{ + + /// Base attributes containing repository ID and name of + /// union type. + Base_Attributes<StringType> const base_attributes_; + + /// Type of IDL @c union discriminant. + CORBA::TypeCode_ptr * const discriminant_type_; + + /// The number of cases in the OMG IDL union, excluding the + /// @c default case. + CORBA::ULong const ncases_; + + /// Array of @c TAO::TypeCode::Case representing structure of + /// the OMG IDL defined @c union. + CaseArrayType const cases_; + + /// IDL @c union @c default case. + /** + * @note Only valid if @c this->default_index_ @c >= @c 0. + */ + Default_Case<StringType> const default_case_; + + //@} + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Union_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Union_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Union_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_UNION_TYPECODE_H */ diff --git a/TAO/tao/Union_TypeCode.inl b/TAO/tao/Union_TypeCode.inl new file mode 100644 index 00000000000..f0dbe93daab --- /dev/null +++ b/TAO/tao/Union_TypeCode.inl @@ -0,0 +1,65 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Union<StringType, CaseArrayType, RefCountPolicy>::Union ( + char const * id, + char const * name, + CORBA::TypeCode_ptr * discriminant_type, + Case const * cases, + CORBA::ULong ncases, + CORBA::Long default_index, + char const * default_member_name, + CORBA::TypeCode_ptr * default_member_type) + : base_attributes_ (id, name) + , default_index_ (default_index), + , ncases_ (ncases) + , cases_ (cases) + , default_case_ (default_member_name, + default_member_type) +{ +} + +template <typename StringType, typename CaseArrayType, class RefCountPolicy> +ACE_INLINE CORBA::ULong +TAO::TypeCode::Union<StringType, + CaseArrayType>::case_count (void) const +{ + return (this->default_index_ < 0 ? this->ncases_ : this->ncases_ + 1); +} + +template <typename StringType, typename CaseArrayType, class RefCountPolicy> +ACE_INLINE TAO::TypeCode::Union::case_type const & +TAO::TypeCode::Union<StringType, + CaseArrayType>::case (CORBA::ULong index) const +{ + if (default_index_ >= 0) + { + if (index == static_cast<CORBA::ULong> (this->default_index_)) + return this->default_case_; + + // Shift by one if default case was declared prior to + // non-default cases. + else if (index > static_cast<CORBA::ULong> (this->default_index_)) + return this->cases_[index - 1]; + + // Remaining (index < this->default_index_) case is handled + // below. + } + + return this->cases_[index]; +} + + +// ------------------------------------------------------------- +// Member specializations +// ------------------------------------------------------------- + +ACE_INLINE TAO::TypeCode::Union::Case const * +TAO::TypeCode::Union<CORBA::String_var, + ACE_Auto_Ptr_Array<Case const> >::cases (void) const +{ + return this->cases_.get (); +} diff --git a/TAO/tao/Value_Box_TypeCode.cpp b/TAO/tao/Value_Box_TypeCode.cpp new file mode 100644 index 00000000000..bd579b9a693 --- /dev/null +++ b/TAO/tao/Value_Box_TypeCode.cpp @@ -0,0 +1,175 @@ +// $Id$ + +#ifndef TAO_VALUE_BOX_TYPECODE_CPP +#define TAO_VALUE_BOX_TYPECODE_CPP + +#include "tao/Value_Box_TypeCode.h" + +#ifndef __ACE_INLINE__ +# include "tao/Value_Box_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <typename StringType, class RefCountPolicy> +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::~Value_Box (void) +{ + if (this->content_type_) + CORBA::release (*this->content_type_); +} + +template <typename StringType, class RefCountPolicy> +bool +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::tao_marshal ( + TAO_OutputCDR &) const +{ + // A tk_value_box TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + return + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->attributes_.id ()) + && (cdr << this->attributes_.name ()) + && (cdr << *(this->content_type_.in ())); +} + +template <typename StringType, class RefCountPolicy> +void +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, class RefCountPolicy> +void +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL_NOT_USED) const +{ + // The CORBA::TypeCode base class already verified equality of the + // base attributes (id and name). Perform an equality comparison of + // the members. + + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return this->content_type_->equal (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <typename StringType, class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != CORBA::tk_value_box) + return (0); + + char const * const this_id = this->attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + CORBA::TypeCode_var rhs_content_type = + tc->content_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return *(this->content_type_)->equivalent (rhs_content_type.in () + ACE_ENV_ARG_PARAMETER); + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::tk_value_box; +} + +template <typename StringType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + TAO_TypeCodeFactory_Adapter * adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name () + ); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TypeCode_var compact_content_type = + *(this->content_type_)->get_compact_typecode ( + ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + return adapter->create_value_box_tc (this->attributes_.id (), + "" /* empty name */ + compact_content_type.in () + ACE_ENV_ARG_PARAMETER); +} + +template <typename StringType, class RefCountPolicy> +char const * +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.id (); +} + +template <typename StringType, class RefCountPolicy> +char const * +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->attributes_.name (); +} + +template <typename StringType, class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Value_Box<StringType, RefCountPolicy>::content_type_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return CORBA::TypeCode::_duplicate (*this->content_type_); +} + +#endif /* TAO_VALUE_BOX_TYPECODE_CPP */ diff --git a/TAO/tao/Value_Box_TypeCode.h b/TAO/tao/Value_Box_TypeCode.h new file mode 100644 index 00000000000..fb359bf63e0 --- /dev/null +++ b/TAO/tao/Value_Box_TypeCode.h @@ -0,0 +1,130 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Value_Box_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_value_box CORBA::TypeCode. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_VALUE_BOX_TYPECODE_H +#define TAO_VALUE_BOX_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Value_Box + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * boxed @c valuetype. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * boxed @c valuetype. + */ + template <typename StringType, class RefCountPolicy> + class Value_Box + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + Value_Box (char const * id, + char const * name, + CORBA::TypeCode_ptr * tc); + + /// Destructor. + ~Value_Box (void); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_value_box @c CORBA::TypeCode -specific template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual TypeCode_ptr content_type_i (ACE_ENV_SINGLE_ARG_DECL) const; + + private: + + /// Base attributes for this @c TypeCode containing the + /// repository ID and name of the boxed @c valuetype. + Base_Attributes<StringType> attributes_; + + /// The @c TypeCode corresponding to the original type upon + /// which the IDL boxed @c valuetype was made. + /** + * A pointer to the @c CORBA::TypeCode_ptr rather than the + * @c CORBA::TypeCode_ptr itself is stored since that address is + * well-defined. We may not know the value of the @c + * CORBA::TypeCode_ptr when creating this @c Field statically at + * compile-time, hence the indirection. + * + * @note This @c TypeCode is released upon destruction of this + * @c TypeCode::Value_Box. + */ + CORBA::TypeCode_ptr * content_type_; + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Value_Box_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Value_Box_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Value_Box_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_VALUE_BOX_TYPECODE_H */ diff --git a/TAO/tao/Value_TypeCode.cpp b/TAO/tao/Value_TypeCode.cpp new file mode 100644 index 00000000000..a7c331b9ee5 --- /dev/null +++ b/TAO/tao/Value_TypeCode.cpp @@ -0,0 +1,483 @@ +// $Id$ + +#ifndef TAO_VALUE_TYPECODE_CPP +#define TAO_VALUE_TYPECODE_CPP + +#include "tao/Value_TypeCode.h" +#include "tao/TypeCode_Value_Field.h" + +#ifndef __ACE_INLINE__ +# include "tao/Value_TypeCode.inl" +#endif /* !__ACE_INLINE__ */ + + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +bool +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_marshal ( + TAO_OutputCDR & cdr) const +{ + // A tk_value TypeCode has a "complex" parameter list type (see + // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of + // the CORBA specification), meaning that it must be marshaled into + // a CDR encapsulation. + + // Create a CDR encapsulation. + bool const success = + (cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) + && (cdr << this->base_attributes_.id ()) + && (cdr << this->base_attributes_.name ()) + && (cdr << this->type_modifier_) + && (cdr << *this->concrete_base_) + && (cdr << this->nfields_); + + if (!success) + return false; + + Value_Field<StringType> const * const begin = this->fields (); + Value_Field<StringType> const * const end = begin + this->nfields_; + + for (Value_Field<StringType> const * i = begin; i != end; ++i) + { + Value_Field<StringType> const & field = *i; + + if (!(cdr << field.get_name ()) + || !(cdr << *(field.type)) + || !(cdr << field.visibility)) + return false; + } + + return true; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +void +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_duplicate (void) +{ + this->RefCountPolicy::add_ref (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +void +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::equal_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // None of these calls should throw since CORBA::TypeCode::equal() + // verified that the TCKind is the same as our's prior to invoking + // this method. + + CORBA::ValueModifier const tc_type_modifier = + tc->type_modifier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_type_modifier != this->type_modifier_) + return 0; + + CORBA::TypeCode_var rhs_concrete_base_type = + tc->concrete_base_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equal_concrete_base_types = + this->equal (rhs_concrete_base_type.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_concrete_base_types) + return 0; + + CORBA::ULong const tc_nfields = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nfields != this->nfields_) + return 0; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + Value_Field<StringType> const & lhs_field = this->fields_[i]; + + CORBA::Visibility const lhs_visibility = lhs_field.visibility; + CORBA::Visibility const rhs_visibility = + tc->member_visibility (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (lhs_visibility != rhs_visibility) + return 0; + + char const * const lhs_name = lhs_field.get_name (); + char const * const rhs_name = tc->member_name (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strcmp (lhs_name, rhs_name) != 0) + return 0; + + CORBA::TypeCode_ptr const lhs_tc = *(lhs_field.type); + CORBA::TypeCode_var const rhs_tc = + tc->member_type (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equal_members = + lhs_tc->equal (rhs_tc.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equal_members) + return 0; + } + + return 1; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::Boolean +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::equivalent_i ( + CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const +{ + // We could refactor this code to the CORBA::TypeCode::equivalent() + // method but doing so would force us to determine the unaliased + // kind of this TypeCode. Since we already know the unaliased kind + // of this TypeCode, choose to optimize away the additional kind + // unaliasing operation rather than save space. + + CORBA::TCKind const tc_kind = + TAO::unaliased_kind (tc + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_kind != Kind) + return 0; + + char const * const this_id = this->base_attributes_.id (); + char const * const tc_id = tc->id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (ACE_OS::strlen (this_id) == 0 + || ACE_OS::strlen (tc_id) == 0) + { + CORBA::ValueModifier const tc_type_modifier = + tc->type_modifier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_type_modifier != this->type_modifier_) + return 0; + + CORBA::TypeCode_var rhs_concrete_base_type = + tc->concrete_base_type (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equivalent_concrete_base_types = + this->equivalent (rhs_concrete_base_type.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equivalent_concrete_base_types) + return 0; + + // Perform a structural comparison, excluding the name() and + // member_name() operations. + + CORBA::ULong const tc_nfields = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (tc_nfields != this->nfields_) + return 0; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + Value_Field<StringType> const & lhs_field = this->fields_[i]; + + CORBA::Visibility const lhs_visibility = + lhs_field.visibility; + CORBA::Visibility const rhs_visibility = + tc->member_visibility (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (lhs_visibility != rhs_visibility) + return 0; + + CORBA::TypeCode_ptr const lhs_tc = *(lhs_field.type); + CORBA::TypeCode_var const rhs_tc = + tc->member_type (i + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::Boolean const equiv_types = + lhs_tc->equivalent (rhs_tc.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + if (!equiv_types) + return 0; + } + } + else if (ACE_OS::strcmp (this_id, tc_id) != 0) + { + return 0; + } + + return 1; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TCKind +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::kind_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return Kind; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const +{ + Value_Field<StringType> * tc_fields = 0; + + ACE_Auto_Array_Ptr<Value_Field<StringType> > safe_fields; + + if (this->nfields_ > 0) + { + // Dynamically construct a new array of fields stripped of + // member names. + + ACE_NEW_THROW_EX (tc_fields, + Value_Field<StringType> [this->nfields_], + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + safe_fields.reset (tc_fields); + + static char const empty_name[] = ""; + + for (CORBA::ULong i = 0; i < this->nfields_; ++i) + { + // Member names will be stripped, i.e. not embedded within + // the compact TypeCode. + + tc_fields[i].name = empty_name; + tc_fields[i].type = 0; // FIX ME!!!!! +// &(*(this->fields_[i].type))->get_compact_typecode ( +// ACE_ENV_SINGLE_ARG_PARAMETER); +// ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + tc_fields[i].visibility = this->fields_[i].visibility; + } + } + + TAO_TypeCodeFactory_Adapter * const adapter = + ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance ( + TAO_ORB_Core::typecodefactory_adapter_name ()); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL (), + CORBA::TypeCode::_nil ()); + } + + CORBA::TypeCode_var tc = + adapter->_tao_create_value_event_tc (Kind, + this->base_attributes_.id (), + "", // empty name + this->type_modifier_, + this->concrete_base_, + tc_fields, + this->nfields_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + (void) safe_fields.release (); + + return tc._retn (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::id_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.id (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::name_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + return this->base_attributes_.name (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::ULong +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_count_i ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->nfields_; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +char const * +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_name_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + // Ownership is retained by the TypeCode, as required by the C++ + // mapping. + if (index >= this->nfields_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); + + return this->fields_[index].get_name (); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_type_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + if (index >= this->nfields_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), + CORBA::TypeCode::_nil ()); + + return CORBA::TypeCode::_duplicate (*(this->fields_[index].type)); +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::Visibility +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::member_visibility_i ( + CORBA::ULong index + ACE_ENV_ARG_DECL) const +{ + if (index >= this->nfields_) + ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), + CORBA::PRIVATE_MEMBER); + + return this->fields_[index].visibility; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::ValueModifier +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::type_modifier ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return this->type_modifier_; +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +CORBA::TypeCode_ptr +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::concrete_base_type ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const +{ + return + this->concrete_base_ == 0 + ? CORBA::TypeCode::_nil () + : CORBA::TypeCode::_duplicate (*(this->concrete_base_)); +} + + +#endif /* TAO_VALUE_TYPECODE_CPP */ diff --git a/TAO/tao/Value_TypeCode.h b/TAO/tao/Value_TypeCode.h new file mode 100644 index 00000000000..5e981127a66 --- /dev/null +++ b/TAO/tao/Value_TypeCode.h @@ -0,0 +1,172 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Value_TypeCode.h + * + * $Id$ + * + * Header file for a @c tk_value and @c tk_event + * @c CORBA::TypeCodes. + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + +#ifndef TAO_VALUE_TYPECODE_H +#define TAO_VALUE_TYPECODE_H + +#include /**/ "ace/pre.h" + +#include "tao/TypeCode.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/TypeCode_Base_Attributes.h" +#include "tao/OBV_Constants.h" + + +namespace TAO +{ + namespace TypeCode + { + template<typename StringType> struct Value_Field; + + /** + * @class Value + * + * @brief @c CORBA::TypeCode implementation for an OMG IDL + * @c valuetype or @c event. + * + * This class implements a @c CORBA::TypeCode for an OMG IDL + * @c valuetype or @c event. + */ + template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> + class Value + : public CORBA::TypeCode, + private RefCountPolicy + { + public: + + /// Constructor. + Value (char const * id, + char const * name, + CORBA::ValueModifier modifier, + CORBA::TypeCode_ptr * concrete_base, + Value_Field<StringType> const * fields, + CORBA::ULong nfields); + + /** + * @name TAO-specific @c CORBA::TypeCode Methods + * + * Methods required by TAO's implementation of the + * @c CORBA::TypeCode class. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual bool tao_marshal (TAO_OutputCDR & cdr) const; + virtual void tao_duplicate (void); + virtual void tao_release (void); + //@} + + protected: + + /** + * @name @c TAO CORBA::TypeCode Template Methods + * + * @c tk_value or @c tk_event @c CORBA::TypeCode -specific + * template methods. + * + * @see @c CORBA::TypeCode + */ + //@{ + virtual CORBA::Boolean equal_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::Boolean equivalent_i (CORBA::TypeCode_ptr tc + ACE_ENV_ARG_DECL) const; + virtual CORBA::TCKind kind_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr get_compact_typecode_i ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * id_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * name_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::ULong member_count_i (ACE_ENV_SINGLE_ARG_DECL) const; + virtual char const * member_name_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::TypeCode_ptr member_type_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::Visibility member_visibility_i (CORBA::ULong index + ACE_ENV_ARG_DECL) const; + virtual CORBA::ValueModifier type_modifier ( + ACE_ENV_SINGLE_ARG_DECL) const; + virtual CORBA::TypeCode_ptr concrete_base_type ( + ACE_ENV_SINGLE_ARG_DECL) const; + //@} + + private: + + /// Get pointer to the underlying @c Value_Field array. + Value_Field<StringType> const * fields (void) const; + + private: + + /** + * @c Valuetype Attributes + * + * Attributes representing the structure of an OMG IDL + * @c valuetype or @c event. + * + * @note These attributes are declared in the order in which + * they are marshaled into a CDR stream in order to + * increase cache hits by improving spatial locality. + */ + //@{ + + /// Base attributes containing repository ID and name of + /// @c valuetype. + Base_Attributes<StringType> const base_attributes_; + + /// The @c ValueModifier of the @c valuetype of @c eventtype + /// represented by this @c TypeCode. + CORBA::ValueModifier const type_modifier_; + + /// The @c TypeCode corresponding to the concrete base + /// @c valuetype or @c eventtype. + CORBA::TypeCode_ptr * const concrete_base_; + + /// The number of fields in the OMG IDL value. + CORBA::ULong const nfields_; + + /// Array of @c TAO::TypeCode fields representing structure of the + /// OMG IDL defined @c value. + FieldArrayType const fields_; + + //@} + + }; + + } // End namespace TypeCode +} // End namespace TAO + + +#ifdef __ACE_INLINE__ +# include "tao/Value_TypeCode.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/Value_TypeCode.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("Value_TypeCode.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_VALUE_TYPECODE_H */ diff --git a/TAO/tao/Value_TypeCode.inl b/TAO/tao/Value_TypeCode.inl new file mode 100644 index 00000000000..e54295cc7e8 --- /dev/null +++ b/TAO/tao/Value_TypeCode.inl @@ -0,0 +1,66 @@ +// -*- C++ -*- +// +// $Id$ + +#include "tao/TypeCode_Value_Field.h" +#include "tao/True_RefCount_Policy.h" + +#include "ace/Auto_Ptr.h" + + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +ACE_INLINE +TAO::TypeCode::Value<StringType, FieldArrayType, Kind, RefCountPolicy>::Value ( + char const * id, + char const * name, + CORBA::ValueModifier modifier, + CORBA::TypeCode_ptr * concrete_base, + Value_Field<StringType> const * fields, + CORBA::ULong nfields) + : base_attributes_ (id, name) + , type_modifier_ (modifier) + , concrete_base_ (concrete_base) + , nfields_ (nfields) + , fields_ (fields) +{ +} + +template <typename StringType, + class FieldArrayType, + CORBA::TCKind Kind, + class RefCountPolicy> +ACE_INLINE TAO::TypeCode::Value_Field<StringType> const * +TAO::TypeCode::Value<StringType, + FieldArrayType, + Kind, + RefCountPolicy>::fields (void) const +{ + return this->fields_; +} + +// ------------------------------------------------------------- +// Member specializations +// ------------------------------------------------------------- + +ACE_INLINE TAO::TypeCode::Value_Field<CORBA::String_var> const * +TAO::TypeCode::Value< + CORBA::String_var, + ACE_Auto_Array_Ptr<TAO::TypeCode::Value_Field<CORBA::String_var> const>, + CORBA::tk_value, + TAO::True_RefCount_Policy>::fields (void) const +{ + return this->fields_.get (); +} + +ACE_INLINE TAO::TypeCode::Value_Field<CORBA::String_var> const * +TAO::TypeCode::Value< + CORBA::String_var, + ACE_Auto_Array_Ptr<TAO::TypeCode::Value_Field<CORBA::String_var> const>, + CORBA::tk_event, + TAO::True_RefCount_Policy>::fields (void) const +{ + return this->fields_.get (); +} diff --git a/TAO/tao/append.cpp b/TAO/tao/append.cpp index 9f90343bd48..fe8f03070ba 100644 --- a/TAO/tao/append.cpp +++ b/TAO/tao/append.cpp @@ -23,7 +23,7 @@ #include "tao/debug.h" #include "tao/Valuetype_Adapter.h" #include "tao/ORB_Core.h" -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "tao/Marshal.h" #include "tao/Any_Unknown_IDL_Type.h" #include "tao/CDR.h" diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index 822d5499ad2..5b52282e16d 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -34,7 +34,7 @@ // The definitions are included in the same order as they are declared // in corbafwd.h -#include "tao/Typecode.h" +#include "tao/TypeCode.h" #include "tao/Environment.h" #include "tao/SystemException.h" diff --git a/TAO/tao/operation_details.cpp b/TAO/tao/operation_details.cpp index d8d2e27a3e3..24436535e49 100644 --- a/TAO/tao/operation_details.cpp +++ b/TAO/tao/operation_details.cpp @@ -1,7 +1,7 @@ //$Id$ #include "operation_details.h" #include "Stub.h" -#include "Typecode.h" +#include "TypeCode.h" #include "ORB_Constants.h" #include "DynamicC.h" #include "Exception_Data.h" diff --git a/TAO/tao/skip.cpp b/TAO/tao/skip.cpp index bf9ed47dac2..e78b27ddd19 100644 --- a/TAO/tao/skip.cpp +++ b/TAO/tao/skip.cpp @@ -23,7 +23,7 @@ #include "debug.h" #include "Valuetype_Adapter.h" #include "ORB_Core.h" -#include "Typecode.h" +#include "TypeCode.h" #include "Any_Unknown_IDL_Type.h" #include "tao/CDR.h" #include "SystemException.h" diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc index ce8d2cdfad5..5889d0f1184 100644 --- a/TAO/tao/tao.mpc +++ b/TAO/tao/tao.mpc @@ -80,6 +80,7 @@ project(TAO) : acelib, core, tao_output, taodefaults, pidl, extra_core { Dynamic_ParameterC.cpp DynamicA.cpp DynamicC.cpp + Empty_Param_TypeCode.cpp Encodable.cpp Endpoint.cpp Endpoint_Selector_Factory.cpp @@ -256,7 +257,7 @@ project(TAO) : acelib, core, tao_output, taodefaults, pidl, extra_core { Transport_Mux_Strategy.cpp Transport_Timer.cpp TSS_Resources.cpp - Typecode.cpp + TypeCode.cpp Typecode_typesC.cpp Typecode_Constants.cpp TypeCodeFactory_Adapter.cpp @@ -588,7 +589,7 @@ project(TAO) : acelib, core, tao_output, taodefaults, pidl, extra_core { TSS_Resources.h Typecode_Constants.h TypeCodeFactory_Adapter.h - Typecode.h + TypeCode.h Typecode_typesC.h Typecode_typesS.h UB_String_Arguments.h |