DynUnion_i.cpp

Go to the documentation of this file.
00001 // $Id: DynUnion_i.cpp 80140 2007-11-30 00:40:17Z jtc $
00002 
00003 #include "tao/DynamicAny/DynUnion_i.h"
00004 #include "tao/DynamicAny/DynEnum_i.h"
00005 #include "tao/DynamicAny/DynAnyFactory.h"
00006 #include "tao/DynamicAny/DynAnyUtils_T.h"
00007 
00008 #include "tao/AnyTypeCode/Marshal.h"
00009 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00010 #include "tao/AnyTypeCode/AnyTypeCode_methods.h"
00011 
00012 #include "tao/CDR.h"
00013 
00014 ACE_RCSID (DynamicAny,
00015            DynUnion_i,
00016            "$Id: DynUnion_i.cpp 80140 2007-11-30 00:40:17Z jtc $")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 TAO_DynUnion_i::TAO_DynUnion_i (void)
00021 {
00022 }
00023 
00024 TAO_DynUnion_i::~TAO_DynUnion_i (void)
00025 {
00026 }
00027 
00028 void
00029 TAO_DynUnion_i::init_common (void)
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 }
00039 
00040 void
00041 TAO_DynUnion_i::init (const CORBA::Any& any)
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 }
00061 
00062 void
00063 TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc)
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 }
00121 
00122 // ****************************************************************
00123 
00124 TAO_DynUnion_i *
00125 TAO_DynUnion_i::_narrow (CORBA::Object_ptr _tao_objref)
00126 {
00127   if (CORBA::is_nil (_tao_objref))
00128     {
00129       return 0;
00130     }
00131 
00132   return dynamic_cast<TAO_DynUnion_i *> (_tao_objref);
00133 }
00134 
00135 // This code is common to from_any() and the init() overload that takes
00136 // an Any argument.
00137 void
00138 TAO_DynUnion_i::set_from_any (const CORBA::Any & any)
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 }
00281 
00282 // ****************************************************************
00283 
00284 DynamicAny::DynAny_ptr
00285 TAO_DynUnion_i::get_discriminator (void)
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 }
00298 
00299 void
00300 TAO_DynUnion_i::set_discriminator (DynamicAny::DynAny_ptr value)
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 }
00424 
00425 void
00426 TAO_DynUnion_i::set_to_default_member (void)
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 }
00466 
00467 void
00468 TAO_DynUnion_i::set_to_no_active_member (void)
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 }
00515 
00516 CORBA::Boolean
00517 TAO_DynUnion_i::has_no_active_member (void)
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 }
00527 
00528 CORBA::TCKind
00529 TAO_DynUnion_i::discriminator_kind (void)
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 }
00541 
00542 DynamicAny::DynAny_ptr
00543 TAO_DynUnion_i::member (void)
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 }
00566 
00567 char *
00568 TAO_DynUnion_i::member_name (void)
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 }
00587 
00588 CORBA::TCKind
00589 TAO_DynUnion_i::member_kind (void)
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 }
00608 
00609 // ****************************************************************
00610 
00611 void
00612 TAO_DynUnion_i::from_any (const CORBA::Any& any)
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 }
00641 
00642 CORBA::Any_ptr
00643 TAO_DynUnion_i::to_any (void)
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 }
00737 
00738 CORBA::Boolean
00739 TAO_DynUnion_i::equal (DynamicAny::DynAny_ptr rhs)
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 }
00771 
00772 void
00773 TAO_DynUnion_i::destroy (void)
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 }
00798 
00799 DynamicAny::DynAny_ptr
00800 TAO_DynUnion_i::current_component (void)
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 }
00820 
00821 // ****************************************************************
00822 
00823 CORBA::Boolean
00824 TAO_DynUnion_i::label_match (const CORBA::Any &my_any,
00825                              const CORBA::Any &other_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 }
01004 
01005 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:43:11 2010 for TAO_DynamicAny by  doxygen 1.4.7