diff options
author | Ossama Othman <ossama-othman@users.noreply.github.com> | 2004-09-23 08:15:19 +0000 |
---|---|---|
committer | Ossama Othman <ossama-othman@users.noreply.github.com> | 2004-09-23 08:15:19 +0000 |
commit | 4409846b58d730cd34faf4cc0286d4bfb03c5e41 (patch) | |
tree | 513d3bae8b2233b277c5212af326180738d8d2e4 | |
parent | beb7fc025e1ad90642e14fc5f91704dd5d165894 (diff) | |
download | ATCD-4409846b58d730cd34faf4cc0286d4bfb03c5e41.tar.gz |
*** empty log message ***
-rw-r--r-- | TAO/tao/TypeCode/Enum_TypeCode.cpp | 10 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Enum_TypeCode.h | 2 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Struct_TypeCode.cpp | 12 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Struct_TypeCode.h | 2 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case.cpp | 94 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case.h | 126 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case.inl | 15 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case_Base.cpp | 21 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case_Base.h | 128 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Case_Base.inl | 55 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Default_Case.cpp | 59 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Default_Case.h | 78 | ||||
-rw-r--r-- | TAO/tao/TypeCode/TypeCode_Default_Case.inl | 20 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Union_TypeCode.cpp | 383 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Union_TypeCode.h | 191 | ||||
-rw-r--r-- | TAO/tao/TypeCode/Union_TypeCode.inl | 73 |
16 files changed, 1256 insertions, 13 deletions
diff --git a/TAO/tao/TypeCode/Enum_TypeCode.cpp b/TAO/tao/TypeCode/Enum_TypeCode.cpp index 2e05cb4a9d1..a3646acfb81 100644 --- a/TAO/tao/TypeCode/Enum_TypeCode.cpp +++ b/TAO/tao/TypeCode/Enum_TypeCode.cpp @@ -33,12 +33,12 @@ TAO::TypeCode::Enum<StringType, if (!success) return false; - Enumerator<STRING_TYPE> const * const begin = this->enumerators (); - Enumerator<STRING_TYPE> const * const end = begin + this->nenumerators_; + Enumerator<StringType> const * const begin = this->enumerators (); + Enumerator<StringType> const * const end = begin + this->nenumerators_; - for (Enumerator<STRING_TYPE> const * i = begin; i != end; ++i) + for (Enumerator<StringType> const * i = begin; i != end; ++i) { - Enumerator<STRING_TYPE> const & enumerator = *i; + Enumerator<StringType> const & enumerator = *i; if (!(cdr << enumerator.get_name ())) return false; @@ -256,7 +256,7 @@ TAO::TypeCode::Enum<StringType, if (index >= this->nenumerators_) ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); - return this->enumerators_[i].get_name (); + return this->enumerators_[index].get_name (); } #endif /* TAO_ENUM_TYPECODE_CPP */ diff --git a/TAO/tao/TypeCode/Enum_TypeCode.h b/TAO/tao/TypeCode/Enum_TypeCode.h index f4030cd7409..753d1d8aa91 100644 --- a/TAO/tao/TypeCode/Enum_TypeCode.h +++ b/TAO/tao/TypeCode/Enum_TypeCode.h @@ -96,7 +96,7 @@ namespace TAO private: /// Get pointer to the underlying @c Enumerator array. - Enumerator<STRING_TYPE> const * enumerators (void) const; + Enumerator<StringType> const * enumerators (void) const; private: diff --git a/TAO/tao/TypeCode/Struct_TypeCode.cpp b/TAO/tao/TypeCode/Struct_TypeCode.cpp index ca160d08dea..5248aa7a032 100644 --- a/TAO/tao/TypeCode/Struct_TypeCode.cpp +++ b/TAO/tao/TypeCode/Struct_TypeCode.cpp @@ -33,12 +33,12 @@ TAO::TypeCode::Struct<StringType, if (!success) return false; - Field<STRING_TYPE> const * const begin = this->fields (); - Field<STRING_TYPE> const * const end = begin + this->nfields_; + Field<StringType> const * const begin = this->fields (); + Field<StringType> const * const end = begin + this->nfields_; - for (Field<STRING_TYPE> const * i = begin; i != end; ++i) + for (Field<StringType> const * i = begin; i != end; ++i) { - Field<STRING_TYPE> const & field = *i; + Field<StringType> const & field = *i; if (!(cdr << field.get_name ()) || !(cdr << *(field.type))) @@ -299,7 +299,7 @@ TAO::TypeCode::Struct<StringType, if (index >= this->nfields_) ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); - return this->fields_[i].get_name (); + return this->fields_[index].get_name (); } template <typename StringType, class FieldArrayType, class RefCountPolicy> @@ -314,7 +314,7 @@ TAO::TypeCode::Struct<StringType, ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), CORBA::TypeCode::_nil ()); - return CORBA::TypeCode::_duplicate (*(this->fields_[i].type)); + return CORBA::TypeCode::_duplicate (*(this->fields_[index].type)); } #endif /* TAO_STRUCT_TYPECODE_CPP */ diff --git a/TAO/tao/TypeCode/Struct_TypeCode.h b/TAO/tao/TypeCode/Struct_TypeCode.h index 5c2edeff449..52bdcebdbba 100644 --- a/TAO/tao/TypeCode/Struct_TypeCode.h +++ b/TAO/tao/TypeCode/Struct_TypeCode.h @@ -97,7 +97,7 @@ namespace TAO private: /// Get pointer to the underlying @c Field array. - Field<STRING_TYPE> const * fields (void) const; + Field<StringType> const * fields (void) const; private: diff --git a/TAO/tao/TypeCode/TypeCode_Case.cpp b/TAO/tao/TypeCode/TypeCode_Case.cpp new file mode 100644 index 00000000000..137b00ac8a8 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case.cpp @@ -0,0 +1,94 @@ +// $Id$ + +#ifndef TAO_TYPECODE_CASE_CPP +#define TAO_TYPECODE_CASE_CPP + +#include "TypeCode_Case.h" + +#include "tao/CDR.h" +#include "tao/Any.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Case.inl" +#endif /* __ACE_INLINE__ */ + +namespace TAO +{ + namespace TypeCode + { + template <typename T> + struct Case_Traits + { + inline static T any_from (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); + } + }; + + template <> + struct Case_Traits<CORBA::Char> + { + inline static CORBA::Any::from_char any_from (CORBA::Char v) + { + return CORBA::Any::from_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); + } + }; + + } // End TypeCode namespace +} // End TAO namespace + +// ---------------------------------------------------------------- + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +bool +TAO::TypeCode::Case<DISCRIMINATOR_TYPE, STRING_TYPE>::marshal_label ( + TAO_OutputCDR & cdr) const +{ + return (cdr << this->label_); +} + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +CORBA::Any * +TAO::TypeCode::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_CASE_CPP */ diff --git a/TAO/tao/TypeCode/TypeCode_Case.h b/TAO/tao/TypeCode/TypeCode_Case.h new file mode 100644 index 00000000000..e97e9e15f78 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case.h @@ -0,0 +1,126 @@ +// -*- 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 */ + +#include "tao/TypeCode_Case_Base.h" + + +namespace TAO +{ + namespace TypeCode + { + + /** + * @class Case + * + * @brief Representation of an OMG IDL defined @c union @c case. + * + * A @c 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::Case array: + * + * \code + * TAO::TypeCode::Case<CORBA::Short, char const *> _tao_cases_Foo[] = + * { + * { Case<CORBA::Short, char const *> (0, "a", &CORBA::_tc_short), + * { Case<CORBA::Short, char const *> (1, "b", &CORBA::_tc_short), + * { Case<CORBA::Short, char const *> (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 Case : public Case_Base<STRING_TYPE> + { + public: + + /// Constructor. + Case (DISCRIMINATOR_TYPE member_label, + char const * member_name, + CORBA::TypeCode_ptr * member_type); + + /// Return the IDL @c union case label value embedded within a + /// @c CORBA::Any. + virtual CORBA::Any * label (ACE_ENV_SINGLE_ARG_DECL) const; + + /// Marshal this IDL @c union member into the given output CDR + /// stream. + virtual bool marshal_label (TAO_OutputCDR & cdr) 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_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/TypeCode_Case.inl b/TAO/tao/TypeCode/TypeCode_Case.inl new file mode 100644 index 00000000000..7a8f7e665bc --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case.inl @@ -0,0 +1,15 @@ +// -*- C++ -*- +// +// $Id$ + +template <typename DISCRIMINATOR_TYPE, typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Case<DISCRIMINATOR_TYPE, STRING_TYPE>::Case ( + DISCRIMINATOR_TYPE member_label, + char const * member_name, + CORBA::TypeCode_ptr * member_type) + : Case_Base<STRING_TYPE> (member_name, + member_type) + , label_ (member_label) +{ +} diff --git a/TAO/tao/TypeCode/TypeCode_Case_Base.cpp b/TAO/tao/TypeCode/TypeCode_Case_Base.cpp new file mode 100644 index 00000000000..161d362e452 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case_Base.cpp @@ -0,0 +1,21 @@ +// $Id$ + +#ifndef TAO_TYPECODE_CASE_BASE_CPP +#define TAO_TYPECODE_CASE_BASE_CPP + +#include "TypeCode_Case_Base.h" + +#ifndef __ACE_INLINE__ +# include "tao/TypeCode_Case_Base.inl" +#endif /* __ACE_INLINE__ */ + + +template <typename DISCRIMINATOR, typename STRING_TYPE> +char const * +TAO::TypeCode::Case_Base<DISCRIMINATOR, STRING_TYPE>::~Case_Base (void) +{ + if (this->type_) + CORBA::release (*(this->type_)); +} + +#endif /* TAO_TYPECODE_CASE_BASE_CPP */ diff --git a/TAO/tao/TypeCode/TypeCode_Case_Base.h b/TAO/tao/TypeCode/TypeCode_Case_Base.h new file mode 100644 index 00000000000..a397ab6f097 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case_Base.h @@ -0,0 +1,128 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file TypeCode_Case_Base.h + * + * $Id$ + * + * Header file for @c TAO::TypeCode::Case_Base type. + * + * @author Ossama Othman + */ +//============================================================================= + +#ifndef TAO_TYPECODE_CASE_BASE_H +#define TAO_TYPECODE_CASE_BASE_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_Base + * + * @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_Base + { + public: + + /// Constructor. + Case_Base (char const * name, + CORBA::TypeCode_ptr * tc); + + /// Destructor. + virtual ~Case_Base (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; + + 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; + + 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_Base.inl" +#endif /* __ACE_INLINE__ */ + +#ifdef ACE_TEMPLATES_REQUIRE_SOURCE +# include "tao/TypeCode_Case_Base.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#ifdef ACE_TEMPLATES_REQUIRE_PRAGMA +# pragma implementation ("TypeCode_Case_Base.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* TAO_TYPECODE_CASE_BASE_H */ diff --git a/TAO/tao/TypeCode/TypeCode_Case_Base.inl b/TAO/tao/TypeCode/TypeCode_Case_Base.inl new file mode 100644 index 00000000000..bdf0fc125f6 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Case_Base.inl @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// $Id$ + +#include "tao/CDR.h" + + +template <typename STRING_TYPE> +ACE_INLINE char const * +TAO::TypeCode::Case_Base<STRING_TYPE>::Case_Base ( + 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_Base<STRING_TYPE>::name (void) const +{ + return this->name_; +} + +template <typename STRING_TYPE> +ACE_INLINE CORBA::TypeCode_ptr +TAO::TypeCode::Case_Base<STRING_TYPE>::type (void) const +{ + return *this->type_; +} + +template <typename DISCRIMINATOR, typename STRING_TYPE> +ACE_INLINE bool +TAO::TypeCode::Case<DISCRIMINATOR, 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_Base<CORBA::String_var>::name (void) const +{ + return this->name_.in (); +} diff --git a/TAO/tao/TypeCode/TypeCode_Default_Case.cpp b/TAO/tao/TypeCode/TypeCode_Default_Case.cpp new file mode 100644 index 00000000000..90fdb8732e9 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Default_Case.cpp @@ -0,0 +1,59 @@ +// $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 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/TypeCode_Default_Case.h b/TAO/tao/TypeCode/TypeCode_Default_Case.h new file mode 100644 index 00000000000..cc5a7b27340 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Default_Case.h @@ -0,0 +1,78 @@ +// -*- 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_Base.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_Base<STRING_TYPE> + { + public: + + /// Constructor. + Default_Case (char const * member_name, + CORBA::TypeCode_ptr * member_type); + + /// Return the IDL @c union default_case label value embedded within a + /// @c CORBA::Any. + virtual CORBA::Any * label (ACE_ENV_SINGLE_ARG_DECL) const; + + /// Marshal this IDL @c union member into the given output CDR + /// stream. + virtual bool marshal_label (TAO_OutputCDR & cdr) 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/TypeCode_Default_Case.inl b/TAO/tao/TypeCode/TypeCode_Default_Case.inl new file mode 100644 index 00000000000..362655988d9 --- /dev/null +++ b/TAO/tao/TypeCode/TypeCode_Default_Case.inl @@ -0,0 +1,20 @@ +// -*- 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_Base<STRING_TYPE> (member_name, + member_type) +{ +} + +template <typename STRING_TYPE> +ACE_INLINE CORBA::Long +TAO::TypeCode::Default_Case<STRING_TYPE>::index (void) const +{ + return this->index_; +} diff --git a/TAO/tao/TypeCode/Union_TypeCode.cpp b/TAO/tao/TypeCode/Union_TypeCode.cpp new file mode 100644 index 00000000000..ada6a299e25 --- /dev/null +++ b/TAO/tao/TypeCode/Union_TypeCode.cpp @@ -0,0 +1,383 @@ +// $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. + + // Create a CDR encapsulation. + bool const success = + (cdr << TAO_ENCAP_BYTE_ORDER) + && (cdr << this->base_attributes_.id ()) + && (cdr << this->base_attributes_.name ()) + && (cdr << *(this->discriminant_type_)) + && (cdr << this->default_index_) + && (cdr << this->ncases_); + + 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. + + CORBA::ULong const len = this->case_count (); + + for (unsigned int i = 0; i < len; ++i) + { + Case 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 (void); +} + +template <typename StringType, class CaseArrayType, class RefCountPolicy> +void +TAO::TypeCode::Union<StringType, + CaseArrayType, + RefCountPolicy>::tao_release (void) +{ + this->RefCountPolicy::remove_ref (void); +} + +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 +{ + // 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_count = + tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + CORBA::ULong const this_count = this->case_count (); + + if (tc_count != this_count) + return 0; + + ............. ADD REMAINING ATTRIBUTE CHECKS ........... + + for (CORBA::ULong i = 0; i < this_count; ++i) + { + Case const & lhs_case = this->cases (i); + + char const * const lhs_name = lhs_case.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_case.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 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) + { + .... CHECK EQUIVALENCE OF MEMBER LABELS ... + + CORBA::TypeCode_ptr const lhs = this->case (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 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 * tc_cases = 0; + + ACE_Auto_Array_Ptr<Case> safe_cases; + + CORBA::ULong const len = this->case_count (); + +............. BUSTED ... NO DEFAULT CASE HANDLING ... + + if (len > 0) + { + // Dynamically construct a new array of cases stripped of + // member names. + + ACE_NEW_THROW_EX (tc_cases, + Case[len], + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + + safe_cases.reset (cases); + + for (CORBA::ULong i = 0; i < len; ++i) + { + // Member names will be stripped, i.e. not embedded within + // the compact TypeCode. + + tc_cases[i].type = + &(this->cases (i).type ()->get_compact_typecode ( + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK_RETURN (CORBA::TypeCode::_nil ()); + } + } + + 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_except_tc (........ FIX ME .... + 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) 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) 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) const +{ + return this->default_index_; +} + + +#endif /* TAO_UNION_TYPECODE_CPP */ diff --git a/TAO/tao/TypeCode/Union_TypeCode.h b/TAO/tao/TypeCode/Union_TypeCode.h new file mode 100644 index 00000000000..0d44d7c5026 --- /dev/null +++ b/TAO/tao/TypeCode/Union_TypeCode.h @@ -0,0 +1,191 @@ +// -*- 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_Base<StringType> Case; + + /// Constructor. + 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); + + /** + * @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 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 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 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/TypeCode/Union_TypeCode.inl b/TAO/tao/TypeCode/Union_TypeCode.inl new file mode 100644 index 00000000000..bdf30ac3044 --- /dev/null +++ b/TAO/tao/TypeCode/Union_TypeCode.inl @@ -0,0 +1,73 @@ +// -*- 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 TAO::TypeCode::Case<StringType> const * +TAO::TypeCode::Union<StringType, + CaseArrayType>::cases (void) const +{ + return this->cases_; +} + +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 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 (); +} |