TAO_DynUnion_i Class Reference

#include <DynUnion_i.h>

Inheritance diagram for TAO_DynUnion_i:

Inheritance graph
[legend]
Collaboration diagram for TAO_DynUnion_i:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_DynUnion_i (void)
 Constructor.
 ~TAO_DynUnion_i (void)
 Destructor.
void init (const CORBA::Any &any)
 Constructor taking an Any argument.
void init (CORBA::TypeCode_ptr tc)
 Constructor taking a typecode argument.
virtual DynamicAny::DynAny_ptr get_discriminator (void)
virtual void set_discriminator (DynamicAny::DynAny_ptr d)
virtual void set_to_default_member (void)
virtual void set_to_no_active_member (void)
virtual CORBA::Boolean has_no_active_member (void)
virtual CORBA::TCKind discriminator_kind (void)
virtual DynamicAny::DynAny_ptr member (void)
virtual char * member_name (void)
virtual CORBA::TCKind member_kind (void)
virtual void from_any (const CORBA::Any &value)
virtual CORBA::Any * to_any (void)
virtual CORBA::Boolean equal (DynamicAny::DynAny_ptr dyn_any)
virtual void destroy (void)
virtual DynamicAny::DynAny_ptr current_component (void)

Static Public Member Functions

static TAO_DynUnion_i_narrow (CORBA::Object_ptr obj)

Private Member Functions

void set_from_any (const CORBA::Any &any)
void init_common (void)
 Called by both versions of init().
CORBA::Boolean label_match (const CORBA::Any &my_any, const CORBA::Any &other_any)
 Iterative check for label value match.
 TAO_DynUnion_i (const TAO_DynUnion_i &src)
 Use copy() or assign() instead of these.
TAO_DynUnion_ioperator= (const TAO_DynUnion_i &src)

Private Attributes

DynamicAny::DynAny_var member_
 Just two components.
DynamicAny::DynAny_var discriminator_
CORBA::ULong member_slot_
 The active member's slot in the union type code.

Detailed Description

Implementation of Dynamic Any type for Unions.

Definition at line 41 of file DynUnion_i.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_DynUnion_i::TAO_DynUnion_i ( void   ) 

Constructor.

Definition at line 20 of file DynUnion_i.cpp.

00021 {
00022 }

TAO_DynUnion_i::~TAO_DynUnion_i ( void   ) 

Destructor.

Definition at line 24 of file DynUnion_i.cpp.

00025 {
00026 }

TAO_DynUnion_i::TAO_DynUnion_i ( const TAO_DynUnion_i src  )  [private]

Use copy() or assign() instead of these.


Member Function Documentation

TAO_DynUnion_i * TAO_DynUnion_i::_narrow ( CORBA::Object_ptr  obj  )  [static]

Reimplemented from CORBA::LocalObject.

Definition at line 125 of file DynUnion_i.cpp.

References CORBA::is_nil().

Referenced by equal().

00126 {
00127   if (CORBA::is_nil (_tao_objref))
00128     {
00129       return 0;
00130     }
00131 
00132   return dynamic_cast<TAO_DynUnion_i *> (_tao_objref);
00133 }

DynamicAny::DynAny_ptr TAO_DynUnion_i::current_component ( void   )  [virtual]

Definition at line 800 of file DynUnion_i.cpp.

References TAO_DynCommon::set_flag().

00801 {
00802   if (this->destroyed_)
00803     {
00804       throw ::CORBA::OBJECT_NOT_EXIST ();
00805     }
00806 
00807   if (this->current_position_ == 1)
00808     {
00809       this->set_flag (this->member_.in (), 0);
00810 
00811       return DynamicAny::DynAny::_duplicate (this->member_.in ());
00812     }
00813   else
00814     {
00815       this->set_flag (this->discriminator_.in (), 0);
00816 
00817       return DynamicAny::DynAny::_duplicate (this->discriminator_.in ());
00818     }
00819 }

void TAO_DynUnion_i::destroy ( void   )  [virtual]

Definition at line 773 of file DynUnion_i.cpp.

References TAO_DynCommon::destroyed_, discriminator_, CORBA::is_nil(), member_, and TAO_DynCommon::set_flag().

00774 {
00775   if (this->destroyed_)
00776     {
00777       throw ::CORBA::OBJECT_NOT_EXIST ();
00778     }
00779 
00780   if (!this->ref_to_component_ || this->container_is_destroying_)
00781     {
00782       // Free the two components.
00783 
00784       if (! CORBA::is_nil (this->member_.in ()))
00785         {
00786           this->set_flag (this->member_.in (), 1);
00787 
00788           this->member_->destroy ();
00789         }
00790 
00791       this->set_flag (this->discriminator_.in (), 1);
00792 
00793       this->discriminator_->destroy ();
00794 
00795       this->destroyed_ = 1;
00796     }
00797 }

CORBA::TCKind TAO_DynUnion_i::discriminator_kind ( void   )  [virtual]

Definition at line 529 of file DynUnion_i.cpp.

References discriminator_, TAO_Pseudo_Var_T< T >::in(), and TAO_DynAnyFactory::unalias().

00530 {
00531   if (this->destroyed_)
00532     {
00533       throw ::CORBA::OBJECT_NOT_EXIST ();
00534     }
00535 
00536   CORBA::TypeCode_var tc =
00537     this->discriminator_->type ();
00538 
00539   return TAO_DynAnyFactory::unalias (tc.in ());
00540 }

CORBA::Boolean TAO_DynUnion_i::equal ( DynamicAny::DynAny_ptr  dyn_any  )  [virtual]

Definition at line 739 of file DynUnion_i.cpp.

References _narrow(), CORBA::Object::_remove_ref(), discriminator_, TAO_Pseudo_Var_T< T >::in(), member_, and TAO_DynCommon::type_.

00740 {
00741   if (this->destroyed_)
00742     {
00743       throw ::CORBA::OBJECT_NOT_EXIST ();
00744     }
00745 
00746   TAO_DynUnion_i *impl = TAO_DynUnion_i::_narrow (rhs);
00747 
00748   if (impl == 0)
00749     {
00750       return 0;
00751     }
00752 
00753   CORBA::Boolean equivalent =
00754     this->type_->equivalent (impl->type_.in ());
00755 
00756   if (!equivalent)
00757     {
00758       return 0;
00759     }
00760 
00761   CORBA::Boolean member_equal =
00762     this->member_->equal (impl->member_.in ());
00763 
00764   CORBA::Boolean disc_equal =
00765     this->discriminator_->equal (impl->discriminator_.in ());
00766 
00767   impl->_remove_ref ();
00768 
00769   return (member_equal && disc_equal);
00770 }

void TAO_DynUnion_i::from_any ( const CORBA::Any &  value  )  [virtual]

Definition at line 612 of file DynUnion_i.cpp.

References TAO_DynCommon::component_count_, TAO_DynCommon::current_position_, TAO_Pseudo_Var_T< T >::in(), set_from_any(), and TAO_DynCommon::type_.

00613 {
00614   if (this->destroyed_)
00615     {
00616       throw ::CORBA::OBJECT_NOT_EXIST ();
00617     }
00618 
00619   CORBA::TypeCode_var tc = any.type ();
00620   CORBA::Boolean equivalent =
00621     this->type_.in ()->equivalent (tc.in ());
00622 
00623   if (equivalent)
00624     {
00625       // CORBA 2.3.1 section 9.2.3.3.
00626       this->current_position_ = 0;
00627 
00628       // May be changed in set_from_any().
00629       this->component_count_ = 2;
00630 
00631       // Set the from_factory arg to FALSE, so any problems will throw
00632       // TypeMismatch.
00633       this->set_from_any (any
00634                          );
00635     }
00636   else
00637     {
00638       throw DynamicAny::DynAny::TypeMismatch ();
00639     }
00640 }

DynamicAny::DynAny_ptr TAO_DynUnion_i::get_discriminator ( void   )  [virtual]

Definition at line 285 of file DynUnion_i.cpp.

References TAO_DynCommon::set_flag().

00286 {
00287   if (this->destroyed_)
00288     {
00289       throw ::CORBA::OBJECT_NOT_EXIST ();
00290     }
00291 
00292   // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00293   // Set the flag so the caller can't destroy.
00294   this->set_flag (this->discriminator_.in (), 0);
00295 
00296   return DynamicAny::DynAny::_duplicate (this->discriminator_.in ());
00297 }

CORBA::Boolean TAO_DynUnion_i::has_no_active_member ( void   )  [virtual]

Definition at line 517 of file DynUnion_i.cpp.

Referenced by member(), member_kind(), and member_name().

00518 {
00519   if (this->destroyed_)
00520     {
00521       throw ::CORBA::OBJECT_NOT_EXIST ();
00522     }
00523 
00524   // No active member (CORBA 2.3.1).
00525   return (this->current_position_ == 0 && this->component_count_ == 1);
00526 }

void TAO_DynUnion_i::init ( CORBA::TypeCode_ptr  tc  ) 

Constructor taking a typecode argument.

Definition at line 63 of file DynUnion_i.cpp.

References TAO_DynEnum_i::_narrow(), discriminator_, TAO_Pseudo_Var_T< T >::in(), init_common(), member_, TAO_DynAnyFactory::strip_alias(), CORBA::tk_enum, CORBA::tk_ulong, CORBA::tk_union, TAO_DynCommon::type_, and TAO_DynAnyFactory::unalias().

00064 {
00065   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc);
00066 
00067   if (kind != CORBA::tk_union)
00068     {
00069       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00070     }
00071 
00072   // Initialize the typecode holder and current index.
00073   this->type_ = CORBA::TypeCode::_duplicate (tc);
00074 
00075   this->init_common ();
00076 
00077   // member_type()/member_label() do not work with aliased type codes.
00078   CORBA::TypeCode_var unaliased_tc =
00079   TAO_DynAnyFactory::strip_alias (this->type_.in ());
00080 
00081   CORBA::Any_var first_label =
00082     unaliased_tc->member_label (this->current_position_);
00083 
00084   // Initialize the discriminator to the label value of the first member.
00085   CORBA::TypeCode_var disc_tc = unaliased_tc->discriminator_type ();
00086   CORBA::TCKind disc_kind = TAO_DynAnyFactory::unalias (disc_tc.in ());
00087   CORBA::TCKind label_kind = TAO_DynAnyFactory::unalias (first_label->_tao_get_typecode ());
00088   if (disc_kind == CORBA::tk_enum &&
00089       label_kind == CORBA::tk_ulong)
00090     {
00091       // incase the discriminator is an enum type we have to walk
00092       // a slightly more complex path because enum labels are
00093       // stored as ulong in the union tc
00094       this->discriminator_ =
00095         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00096           disc_tc.in (),
00097           disc_tc.in ());
00098       CORBA::ULong label_val;
00099       first_label >>= label_val;
00100       TAO_DynEnum_i::_narrow (this->discriminator_.in ())
00101                                     ->set_as_ulong (label_val);
00102     }
00103   else
00104     {
00105       this->discriminator_ =
00106         TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00107           first_label.in ()._tao_get_typecode (),
00108           first_label.in ());
00109     }
00110 
00111   CORBA::TypeCode_var first_type =
00112     unaliased_tc->member_type (this->current_position_
00113                               );
00114 
00115   // Recursively initialize the member to its default value.
00116   this->member_ =
00117     TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00118       first_type.in (),
00119       first_type.in ());
00120 }

void TAO_DynUnion_i::init ( const CORBA::Any &  any  ) 

Constructor taking an Any argument.

Definition at line 41 of file DynUnion_i.cpp.

References TAO_Pseudo_Var_T< T >::in(), init_common(), set_from_any(), CORBA::tk_union, TAO_DynCommon::type_, and TAO_DynAnyFactory::unalias().

00042 {
00043   CORBA::TypeCode_var tc = any.type ();
00044 
00045   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00046 
00047   if (kind != CORBA::tk_union)
00048     {
00049       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00050     }
00051 
00052   // Initialize the typecode holder.
00053   this->type_ = tc;
00054 
00055   this->init_common ();
00056 
00057   // Set the from_factory arg to TRUE, so any problems will throw
00058   // InconsistentTypeCode.
00059   this->set_from_any (any);
00060 }

void TAO_DynUnion_i::init_common ( void   )  [private]

Called by both versions of init().

Definition at line 29 of file DynUnion_i.cpp.

References TAO_DynCommon::component_count_, TAO_DynCommon::container_is_destroying_, TAO_DynCommon::current_position_, TAO_DynCommon::destroyed_, TAO_DynCommon::has_components_, member_slot_, and TAO_DynCommon::ref_to_component_.

Referenced by init().

00030 {
00031   this->ref_to_component_ = false;
00032   this->container_is_destroying_ = false;
00033   this->has_components_ = true;
00034   this->destroyed_ = false;
00035   this->component_count_ = 2;
00036   this->current_position_ = 0;
00037   this->member_slot_ = 0;
00038 }

CORBA::Boolean TAO_DynUnion_i::label_match ( const CORBA::Any &  my_any,
const CORBA::Any &  other_any 
) [private]

Iterative check for label value match.

Definition at line 824 of file DynUnion_i.cpp.

References TAO_Pseudo_Var_T< T >::in(), ACE_InputCDR::read_ulong(), CORBA::tk_boolean, CORBA::tk_char, CORBA::tk_enum, CORBA::tk_long, CORBA::tk_longlong, CORBA::tk_octet, CORBA::tk_short, CORBA::tk_ulong, CORBA::tk_ulonglong, CORBA::tk_ushort, CORBA::tk_wchar, and TAO_DynAnyFactory::unalias().

Referenced by set_discriminator(), and set_from_any().

00826 {
00827   // Use my_any so we can detect a default case label,
00828   // if we are iterating through the union type code's
00829   // member_label() calls.
00830   CORBA::TypeCode_var tc = my_any.type ();
00831 
00832   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00833 
00834   // No need to do any type checking - it was done before this
00835   // call was made.
00836   switch (kind)
00837   {
00838     case CORBA::tk_octet:
00839       // Default case label - just skip it.
00840       return 0;
00841     case CORBA::tk_short:
00842       {
00843         CORBA::Short my_val;
00844         CORBA::Short other_val;
00845         my_any >>= my_val;
00846         other_any >>= other_val;
00847         return my_val == other_val;
00848       }
00849     case CORBA::tk_long:
00850       {
00851         CORBA::Long my_val;
00852         CORBA::Long other_val;
00853         my_any >>= my_val;
00854         other_any >>= other_val;
00855         return my_val == other_val;
00856       }
00857     case CORBA::tk_ushort:
00858       {
00859         CORBA::UShort my_val;
00860         CORBA::UShort other_val;
00861         my_any >>= my_val;
00862         other_any >>= other_val;
00863         return my_val == other_val;
00864       }
00865     case CORBA::tk_ulong:
00866       {
00867         CORBA::ULong my_val;
00868         CORBA::ULong other_val;
00869         my_any >>= my_val;
00870 
00871         // check whether the discriminator is possibly an enum type
00872         // since these get stored as ulong label values as well
00873         CORBA::TypeCode_var other_tc = other_any.type ();
00874         CORBA::TCKind kind = TAO_DynAnyFactory::unalias (other_tc.in ());
00875         if (kind == CORBA::tk_enum)
00876           {
00877             TAO::Any_Impl *other_impl = other_any.impl ();
00878 
00879             if (other_impl->encoded ())
00880               {
00881                 TAO::Unknown_IDL_Type *other_unk =
00882                   dynamic_cast<TAO::Unknown_IDL_Type *> (other_impl);
00883 
00884                 // We don't want unk's rd_ptr to move, in case we are
00885                 // shared by another Any, so we use this to copy the
00886                 // state, not the buffer.
00887                 TAO_InputCDR for_reading (other_unk->_tao_get_cdr ());
00888                 for_reading.read_ulong (other_val);
00889               }
00890             else
00891               {
00892                 TAO_OutputCDR other_out;
00893                 other_impl->marshal_value (other_out);
00894                 TAO_InputCDR other_in (other_out);
00895                 other_in.read_ulong (other_val);
00896               }
00897           }
00898         else
00899           other_any >>= other_val;
00900 
00901         return my_val == other_val;
00902       }
00903     case CORBA::tk_boolean:
00904       {
00905         CORBA::Boolean my_val;
00906         CORBA::Boolean other_val;
00907         my_any >>= CORBA::Any::to_boolean (my_val);
00908         other_any >>= CORBA::Any::to_boolean (other_val);
00909         return my_val == other_val;
00910       }
00911     case CORBA::tk_char:
00912       {
00913         CORBA::Char my_val;
00914         CORBA::Char other_val;
00915         my_any >>= CORBA::Any::to_char (my_val);
00916         other_any >>= CORBA::Any::to_char (other_val);
00917         return my_val == other_val;
00918       }
00919 // For platforms without native 64-bit ints.
00920 #if !defined (ACE_LACKS_LONGLONG_T)
00921     case CORBA::tk_longlong:
00922       {
00923         CORBA::LongLong my_val;
00924         CORBA::LongLong other_val;
00925         my_any >>= my_val;
00926         other_any >>= other_val;
00927         return my_val == other_val;
00928       }
00929 #endif /* ACE_LACKS_LONGLONG_T */
00930     case CORBA::tk_ulonglong:
00931       {
00932         CORBA::ULongLong my_val;
00933         CORBA::ULongLong other_val;
00934         my_any >>= my_val;
00935         other_any >>= other_val;
00936         return my_val == other_val;
00937       }
00938     case CORBA::tk_wchar:
00939       {
00940         CORBA::WChar my_val;
00941         CORBA::WChar other_val;
00942         my_any >>= CORBA::Any::to_wchar (my_val);
00943         other_any >>= CORBA::Any::to_wchar (other_val);
00944         return my_val == other_val;
00945       }
00946     case CORBA::tk_enum:
00947       {
00948         CORBA::ULong my_val;
00949         CORBA::ULong other_val;
00950 
00951         TAO::Any_Impl *my_impl = my_any.impl ();
00952 
00953         if (my_impl->encoded ())
00954           {
00955             TAO::Unknown_IDL_Type * const my_unk =
00956               dynamic_cast<TAO::Unknown_IDL_Type *> (my_impl);
00957 
00958             if (!my_unk)
00959               throw CORBA::INTERNAL ();
00960 
00961             // We don't want unk's rd_ptr to move, in case we are shared by
00962             // another Any, so we use this to copy the state, not the buffer.
00963             TAO_InputCDR for_reading (my_unk->_tao_get_cdr ());
00964             for_reading.read_ulong (my_val);
00965           }
00966         else
00967           {
00968             TAO_OutputCDR my_out;
00969             my_impl->marshal_value (my_out);
00970             TAO_InputCDR my_in (my_out);
00971             my_in.read_ulong (my_val);
00972           }
00973 
00974         TAO::Any_Impl *other_impl = other_any.impl ();
00975 
00976         if (other_impl->encoded ())
00977           {
00978             TAO::Unknown_IDL_Type * const other_unk =
00979               dynamic_cast<TAO::Unknown_IDL_Type *> (other_impl);
00980 
00981             if (!other_unk)
00982               throw CORBA::INTERNAL ();
00983 
00984             // We don't want unk's rd_ptr to move, in case we are shared by
00985             // another Any, so we use this to copy the state, not the buffer.
00986             TAO_InputCDR for_reading (other_unk->_tao_get_cdr ());
00987             for_reading.read_ulong (other_val);
00988           }
00989         else
00990           {
00991             TAO_OutputCDR other_out;
00992             other_impl->marshal_value (other_out);
00993             TAO_InputCDR other_in (other_out);
00994             other_in.read_ulong (other_val);
00995           }
00996 
00997         return my_val == other_val;
00998       }
00999     // Cannot happen - we've covered all the legal discriminator types.
01000     default:
01001       return 0;
01002   }
01003 }

DynamicAny::DynAny_ptr TAO_DynUnion_i::member ( void   )  [virtual]

Definition at line 543 of file DynUnion_i.cpp.

References has_no_active_member(), and TAO_DynCommon::set_flag().

00544 {
00545   if (this->destroyed_)
00546     {
00547       throw ::CORBA::OBJECT_NOT_EXIST ();
00548     }
00549 
00550   CORBA::Boolean has_no_active_member =
00551     this->has_no_active_member ();
00552 
00553   if (has_no_active_member)
00554     {
00555       throw DynamicAny::DynAny::InvalidValue ();
00556     }
00557 
00558   // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00559   // Set the flag so the caller can't destroy.
00560   this->set_flag (this->member_.in (),
00561                   0
00562                  );
00563 
00564   return DynamicAny::DynAny::_duplicate (this->member_.in ());
00565 }

CORBA::TCKind TAO_DynUnion_i::member_kind ( void   )  [virtual]

Definition at line 589 of file DynUnion_i.cpp.

References has_no_active_member(), TAO_Pseudo_Var_T< T >::in(), member_, and TAO_DynAnyFactory::unalias().

00590 {
00591   if (this->destroyed_)
00592     {
00593       throw ::CORBA::OBJECT_NOT_EXIST ();
00594     }
00595 
00596   CORBA::Boolean has_no_active_member =
00597     this->has_no_active_member ();
00598 
00599   if (has_no_active_member)
00600     {
00601       throw DynamicAny::DynAny::InvalidValue ();
00602     }
00603 
00604   CORBA::TypeCode_var tc = this->member_->type ();
00605 
00606   return TAO_DynAnyFactory::unalias (tc.in ());
00607 }

char * TAO_DynUnion_i::member_name ( void   )  [virtual]

Definition at line 568 of file DynUnion_i.cpp.

References has_no_active_member(), CORBA::string_dup(), and TAO_DynCommon::type_.

00569 {
00570   if (this->destroyed_)
00571     {
00572       throw ::CORBA::OBJECT_NOT_EXIST ();
00573     }
00574 
00575   CORBA::Boolean has_no_active_member =
00576     this->has_no_active_member ();
00577 
00578   if (has_no_active_member)
00579     {
00580       throw DynamicAny::DynAny::InvalidValue ();
00581     }
00582 
00583   const char *retval = this->type_->member_name (this->member_slot_);
00584 
00585   return CORBA::string_dup (retval);
00586 }

TAO_DynUnion_i& TAO_DynUnion_i::operator= ( const TAO_DynUnion_i src  )  [private]

void TAO_DynUnion_i::set_discriminator ( DynamicAny::DynAny_ptr  d  )  [virtual]

Definition at line 300 of file DynUnion_i.cpp.

References TAO_DynEnum_i::_narrow(), TAO_DynCommon::component_count_, TAO_DynCommon::current_position_, discriminator_, TAO_Pseudo_Var_T< T >::in(), label_match(), member_, member_slot_, set_to_default_member(), set_to_no_active_member(), TAO_DynAnyFactory::strip_alias(), CORBA::tk_enum, CORBA::tk_ulong, TAO_DynCommon::type_, and TAO_DynAnyFactory::unalias().

00301 {
00302   if (this->destroyed_)
00303     {
00304       throw ::CORBA::OBJECT_NOT_EXIST ();
00305     }
00306 
00307   CORBA::TypeCode_var tc = value->type ();
00308 
00309   CORBA::TypeCode_var disc_tc =
00310     this->discriminator_->type ();
00311 
00312   CORBA::Boolean equivalent = disc_tc->equivalent (tc.in ());
00313 
00314   if (!equivalent)
00315     {
00316       throw DynamicAny::DynAny::TypeMismatch ();
00317     }
00318 
00319   CORBA::Any_var value_any = value->to_any ();
00320 
00321   CORBA::ULong length =
00322     this->type_->member_count ();
00323 
00324   CORBA::Any_var label_any;
00325   CORBA::ULong i;
00326 
00327   // member_label() does not work with aliased type codes.
00328   CORBA::TypeCode_var unaliased_tc =
00329     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00330 
00331   CORBA::Boolean match = 0;
00332 
00333   for (i = 0; i < length; ++i)
00334     {
00335       label_any = unaliased_tc->member_label (i);
00336 
00337       match = this->label_match (label_any.in (), value_any.in ());
00338 
00339       if (match)
00340         {
00341           break;
00342         }
00343     }
00344 
00345   if (match)
00346     {
00347       // If the incoming label value matches the one we already
00348       // have, we do nothing.
00349       if (i == this->member_slot_)
00350         {
00351           return;
00352         }
00353 
00354       // If we got a match, a named member will be active.
00355       CORBA::TCKind disc_kind = TAO_DynAnyFactory::unalias (disc_tc.in ());
00356       CORBA::TCKind label_kind = TAO_DynAnyFactory::unalias (label_any->_tao_get_typecode ());
00357       if (disc_kind == CORBA::tk_enum &&
00358           label_kind == CORBA::tk_ulong)
00359         {
00360           // incase the discriminator is an enum type we have to walk
00361           // a slightly more complex path because enum labels are
00362           // stored as ulong in the union tc
00363           CORBA::ULong label_val;
00364           label_any >>= label_val;
00365           TAO_DynEnum_i::_narrow (this->discriminator_.in ())
00366                                         ->set_as_ulong (label_val);
00367         }
00368       else
00369         {
00370           this->discriminator_->from_any (label_any.in ());
00371         }
00372 
00373       // member_type() does not work with aliased type codes.
00374       CORBA::TypeCode_var member_tc = unaliased_tc->member_type (i);
00375 
00376       this->member_->destroy ();
00377 
00378       // Initialize member to default value.
00379       this->member_ =
00380         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00381           member_tc.in (),
00382           member_tc.in ());
00383 
00384       // Named active member (CORBA 2.3.1).
00385       this->current_position_ = 1;
00386       this->component_count_ = 2;
00387 
00388       this->member_slot_ = i;
00389 
00390       // we're through, disc, value has already been set
00391       // no need for the copy operation below.
00392       return;
00393     }
00394   else
00395     {
00396       // default_index() does not work with aliased type codes.
00397       CORBA::TypeCode_var unaliased_tc =
00398         TAO_DynAnyFactory::strip_alias (this->type_.in ());
00399 
00400       // If no match, either the default member or no member is active.
00401       CORBA::Long default_index =
00402         unaliased_tc->default_index ();
00403 
00404       if (default_index == -1)
00405         {
00406           // This can't throw InvalidValue - if there's no default case
00407           // and all possible labels are used, we'd have had a match above.
00408           this->set_to_no_active_member ();
00409         }
00410       else
00411         {
00412           this->set_to_default_member ();
00413 
00414           this->member_slot_ = static_cast<CORBA::ULong> (default_index);
00415         }
00416     }
00417 
00418   // If we get here, we update the discriminator no matter what.
00419   // Any value will correspond to one of the three cases above.
00420   this->discriminator_->destroy ();
00421 
00422   this->discriminator_ = value->copy ();
00423 }

void TAO_DynUnion_i::set_from_any ( const CORBA::Any &  any  )  [private]

Code common to the constructor from an Any arg and the member function from_any().

Definition at line 138 of file DynUnion_i.cpp.

References ACE_NEW, discriminator_, TAO_Pseudo_Var_T< T >::in(), CORBA::is_nil(), label_match(), member_, member_slot_, set_to_no_active_member(), and TAO_DynAnyFactory::strip_alias().

Referenced by from_any(), and init().

00139 {
00140   // discriminator_type () does not work with aliased type codes,
00141   // only on unions, so strip the alias out of the type code
00142   //
00143   CORBA::TypeCode_var tc =
00144    TAO_DynAnyFactory::strip_alias (any._tao_get_typecode ());
00145 
00146   CORBA::TypeCode_var disc_tc =
00147     tc->discriminator_type ();
00148 
00149   CORBA::Any disc_any;
00150   TAO::Unknown_IDL_Type *unk = 0;
00151 
00152   // Get a CDR stream - if the Any doesn't have one, make one.
00153   TAO::Any_Impl *impl = any.impl ();
00154   TAO_OutputCDR out;
00155   TAO_InputCDR in (static_cast<ACE_Message_Block *> (0));
00156 
00157   if (impl->encoded ())
00158     {
00159       TAO::Unknown_IDL_Type * const tmp =
00160         dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00161 
00162       if (!tmp)
00163         throw CORBA::INTERNAL ();
00164 
00165       in = tmp->_tao_get_cdr ();
00166     }
00167   else
00168     {
00169       impl->marshal_value (out);
00170       TAO_InputCDR tmp_in (out);
00171       in = tmp_in;
00172     }
00173 
00174   TAO_InputCDR unk_in (in);
00175   ACE_NEW (unk,
00176            TAO::Unknown_IDL_Type (disc_tc.in (),
00177                                   unk_in));
00178 
00179   disc_any.replace (unk);
00180 
00181   // Need this here because we might have been called from init().
00182   if (!CORBA::is_nil (this->discriminator_.in ()))
00183     {
00184       this->discriminator_->destroy ();
00185     }
00186 
00187   // Set the discriminator.
00188   this->discriminator_ =
00189     TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00190       disc_any._tao_get_typecode (),
00191       disc_any);
00192 
00193   // Move to the next field in the CDR stream.
00194   (void) TAO_Marshal_Object::perform_skip (disc_tc.in (), &in);
00195 
00196   CORBA::TypeCode_var unaliased =
00197     TAO_DynAnyFactory::strip_alias (tc.in ());
00198 
00199   CORBA::ULong const count = unaliased->member_count ();
00200 
00201   CORBA::Boolean match = false;
00202   CORBA::ULong i;
00203 
00204   // Get the index.
00205   for (i = 0; i < count; ++i)
00206     {
00207       CORBA::Any_var label_any = tc->member_label (i);
00208 
00209       match = this->label_match (label_any.in (), disc_any);
00210 
00211       if (match)
00212         {
00213           break;
00214         }
00215     }
00216 
00217   // Need this here because we might have been called from init().
00218   if (!CORBA::is_nil (this->member_.in ()))
00219     {
00220       this->member_->destroy ();
00221     }
00222 
00223   if (match)
00224     {
00225       CORBA::TypeCode_var member_tc = tc->member_type (i);
00226 
00227       CORBA::Any member_any;
00228       TAO::Unknown_IDL_Type *unk = 0;
00229       ACE_NEW (unk,
00230                TAO::Unknown_IDL_Type (member_tc.in (),
00231                                       in));
00232       member_any.replace (unk);
00233 
00234       this->member_ =
00235         TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00236           member_any._tao_get_typecode (),
00237           member_any);
00238 
00239       this->member_slot_ = i;
00240     }
00241   else
00242     {
00243       // If no match, either the Any contains the default member or the
00244       // type code was bad.
00245 
00246       // default_index() does not work with aliased type codes.
00247       CORBA::TypeCode_var unaliased_tc =
00248         TAO_DynAnyFactory::strip_alias (this->type_.in ());
00249 
00250       CORBA::Long default_index =
00251         unaliased_tc->default_index ();
00252 
00253       if (default_index == -1)
00254         {
00255            set_to_no_active_member ();
00256         }
00257       else
00258         {
00259           CORBA::ULong index = static_cast<CORBA::ULong> (default_index);
00260 
00261           CORBA::TypeCode_var default_tc =
00262             tc->member_type (index
00263                             );
00264 
00265           CORBA::Any default_any;
00266           TAO::Unknown_IDL_Type *unk = 0;
00267           ACE_NEW (unk,
00268                    TAO::Unknown_IDL_Type (default_tc.in (),
00269                                           in));
00270           default_any.replace (unk);
00271 
00272           this->member_ =
00273             TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00274               default_any._tao_get_typecode (),
00275               default_any);
00276 
00277           this->member_slot_ = index;
00278         }
00279     }
00280 }

void TAO_DynUnion_i::set_to_default_member ( void   )  [virtual]

Definition at line 426 of file DynUnion_i.cpp.

References TAO_DynCommon::component_count_, TAO_DynCommon::current_position_, member_, member_slot_, and TAO_DynAnyFactory::strip_alias().

Referenced by set_discriminator().

00427 {
00428   if (this->destroyed_)
00429     {
00430       throw ::CORBA::OBJECT_NOT_EXIST ();
00431     }
00432 
00433   // default_index() does not work with aliased type codes.
00434   CORBA::TypeCode_var unaliased_tc =
00435     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00436 
00437   CORBA::Long default_index =
00438     unaliased_tc->default_index ();
00439 
00440   if (default_index == -1)
00441     {
00442       // No explicit default case.
00443       throw DynamicAny::DynAny::TypeMismatch ();
00444     }
00445   else
00446     {
00447       CORBA::ULong index = static_cast<CORBA::ULong> (default_index);
00448 
00449       CORBA::TypeCode_var default_tc =
00450         unaliased_tc->member_type (index);
00451 
00452       this->member_->destroy ();
00453 
00454       this->member_ =
00455         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00456           default_tc.in (),
00457           default_tc.in ());
00458 
00459       // Default member active (CORBA 2.3.1).
00460       this->current_position_ = 0;
00461       this->component_count_ = 2;
00462 
00463       this->member_slot_ = index;
00464     }
00465 }

void TAO_DynUnion_i::set_to_no_active_member ( void   )  [virtual]

Definition at line 468 of file DynUnion_i.cpp.

References TAO_DynCommon::component_count_, TAO_DynCommon::current_position_, discriminator_, TAO_Pseudo_Var_T< T >::in(), TAO_DynAnyFactory::strip_alias(), CORBA::tk_enum, TAO_DynCommon::type_, and TAO_DynAnyFactory::unalias().

Referenced by set_discriminator(), and set_from_any().

00469 {
00470   if (this->destroyed_)
00471     {
00472       throw ::CORBA::OBJECT_NOT_EXIST ();
00473     }
00474 
00475   // default_index() does not work with aliased type codes.
00476   CORBA::TypeCode_var unaliased_tc =
00477     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00478 
00479   CORBA::Long default_index =
00480     unaliased_tc->default_index ();
00481 
00482   // Throw an exception is there is an explicit default case or if all
00483   // possible case label values are used.
00484   if (default_index != -1)
00485     {
00486       throw DynamicAny::DynAny::TypeMismatch ();
00487     }
00488   else
00489     {
00490       CORBA::TypeCode_var disc_tc =
00491         this->discriminator_->type ();
00492 
00493       CORBA::TCKind kind =
00494         TAO_DynAnyFactory::unalias (disc_tc.in ());
00495 
00496       if (kind == CORBA::tk_enum)
00497         {
00498           CORBA::ULong const member_count =
00499             this->type_->member_count ();
00500 
00501           CORBA::ULong const label_count =
00502             disc_tc->member_count ();
00503 
00504           if (member_count == label_count)
00505             {
00506               throw DynamicAny::DynAny::TypeMismatch ();
00507             }
00508         }
00509     }
00510 
00511   // No active member (CORBA 2.3.1).
00512   this->current_position_ = 0;
00513   this->component_count_ = 1;
00514 }

CORBA::Any_ptr TAO_DynUnion_i::to_any ( void   )  [virtual]

Definition at line 643 of file DynUnion_i.cpp.

References ACE_NEW_THROW_EX, discriminator_, TAO_Pseudo_Var_T< T >::in(), and member_.

00644 {
00645   if (this->destroyed_)
00646     {
00647       throw ::CORBA::OBJECT_NOT_EXIST ();
00648     }
00649 
00650   TAO_OutputCDR out_cdr;
00651 
00652   // Add the discriminator to the CDR stream.
00653 
00654   CORBA::TypeCode_var disc_tc =
00655     this->discriminator_->type ();
00656 
00657   CORBA::Any_var disc_any =
00658     this->discriminator_->to_any ();
00659 
00660   TAO::Any_Impl *disc_any_impl = disc_any->impl ();
00661   TAO_OutputCDR disc_out_cdr;
00662   TAO_InputCDR disc_in_cdr (static_cast<ACE_Message_Block *> (0));
00663 
00664   if (disc_any_impl->encoded ())
00665     {
00666       TAO::Unknown_IDL_Type * const disc_unk =
00667         dynamic_cast<TAO::Unknown_IDL_Type *> (disc_any_impl);
00668 
00669       if (!disc_unk)
00670         throw CORBA::INTERNAL ();
00671 
00672       disc_in_cdr = disc_unk->_tao_get_cdr ();
00673     }
00674   else
00675     {
00676       disc_any_impl->marshal_value (disc_out_cdr);
00677       TAO_InputCDR disc_tmp_in_cdr (disc_out_cdr);
00678       disc_in_cdr = disc_tmp_in_cdr;
00679     }
00680 
00681   (void) TAO_Marshal_Object::perform_append (disc_tc.in (),
00682                                              &disc_in_cdr,
00683                                              &out_cdr);
00684 
00685   // Add the member to the CDR stream unless it has no active member.
00686   if (this->has_no_active_member () == 0)
00687     {
00688       CORBA::TypeCode_var member_tc =
00689         this->member_->type ();
00690 
00691       CORBA::Any_var member_any =
00692         this->member_->to_any ();
00693 
00694       TAO::Any_Impl *member_any_impl = member_any->impl ();
00695       TAO_OutputCDR member_out_cdr;
00696       TAO_InputCDR member_in_cdr (static_cast<ACE_Message_Block *> (0));
00697 
00698       if (member_any_impl->encoded ())
00699         {
00700           TAO::Unknown_IDL_Type * const member_unk =
00701             dynamic_cast<TAO::Unknown_IDL_Type *> (member_any_impl);
00702 
00703           if (!member_unk)
00704             throw CORBA::INTERNAL ();
00705 
00706           member_in_cdr = member_unk->_tao_get_cdr ();
00707         }
00708       else
00709         {
00710           member_any_impl->marshal_value (member_out_cdr);
00711           TAO_InputCDR member_tmp_in_cdr (member_out_cdr);
00712           member_in_cdr = member_tmp_in_cdr;
00713         }
00714 
00715       (void) TAO_Marshal_Object::perform_append (member_tc.in (),
00716                                                 &member_in_cdr,
00717                                                 &out_cdr);
00718     }
00719 
00720   // Make the Any.
00721   TAO_InputCDR in_cdr (out_cdr);
00722 
00723   CORBA::Any_ptr retval = 0;
00724   ACE_NEW_THROW_EX (retval,
00725                     CORBA::Any,
00726                     CORBA::NO_MEMORY ());
00727 
00728   TAO::Unknown_IDL_Type *unk = 0;
00729   ACE_NEW_THROW_EX (unk,
00730                     TAO::Unknown_IDL_Type (this->type_.in (),
00731                                            in_cdr),
00732                     CORBA::NO_MEMORY ());
00733 
00734   retval->replace (unk);
00735   return retval;
00736 }


Member Data Documentation

DynamicAny::DynAny_var TAO_DynUnion_i::discriminator_ [private]

Definition at line 113 of file DynUnion_i.h.

Referenced by destroy(), discriminator_kind(), equal(), init(), set_discriminator(), set_from_any(), set_to_no_active_member(), and to_any().

DynamicAny::DynAny_var TAO_DynUnion_i::member_ [private]

Just two components.

Definition at line 112 of file DynUnion_i.h.

Referenced by destroy(), equal(), init(), member_kind(), set_discriminator(), set_from_any(), set_to_default_member(), and to_any().

CORBA::ULong TAO_DynUnion_i::member_slot_ [private]

The active member's slot in the union type code.

Definition at line 116 of file DynUnion_i.h.

Referenced by init_common(), set_discriminator(), set_from_any(), and set_to_default_member().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:43:16 2010 for TAO_DynamicAny by  doxygen 1.4.7