DynUnion_i.cpp

Go to the documentation of this file.
00001 // $Id: DynUnion_i.cpp 78012 2007-04-13 19:56:11Z dai_y $
00002 
00003 #include "tao/DynamicAny/DynUnion_i.h"
00004 #include "tao/DynamicAny/DynAnyFactory.h"
00005 #include "tao/DynamicAny/DynAnyUtils_T.h"
00006 
00007 #include "tao/AnyTypeCode/Marshal.h"
00008 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00009 #include "tao/AnyTypeCode/AnyTypeCode_methods.h"
00010 
00011 #include "tao/CDR.h"
00012 
00013 ACE_RCSID (DynamicAny,
00014            DynUnion_i,
00015            "$Id: DynUnion_i.cpp 78012 2007-04-13 19:56:11Z dai_y $")
00016 
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 TAO_DynUnion_i::TAO_DynUnion_i (void)
00020 {
00021 }
00022 
00023 TAO_DynUnion_i::~TAO_DynUnion_i (void)
00024 {
00025 }
00026 
00027 void
00028 TAO_DynUnion_i::init_common (void)
00029 {
00030   this->ref_to_component_ = false;
00031   this->container_is_destroying_ = false;
00032   this->has_components_ = true;
00033   this->destroyed_ = false;
00034   this->component_count_ = 2;
00035   this->current_position_ = 0;
00036   this->member_slot_ = 0;
00037 }
00038 
00039 void
00040 TAO_DynUnion_i::init (const CORBA::Any& any)
00041 {
00042   CORBA::TypeCode_var tc = any.type ();
00043 
00044   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00045 
00046   if (kind != CORBA::tk_union)
00047     {
00048       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00049     }
00050 
00051   // Initialize the typecode holder.
00052   this->type_ = tc;
00053 
00054   this->init_common ();
00055 
00056   // Set the from_factory arg to TRUE, so any problems will throw
00057   // InconsistentTypeCode.
00058   this->set_from_any (any);
00059 }
00060 
00061 void
00062 TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc)
00063 {
00064   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc);
00065 
00066   if (kind != CORBA::tk_union)
00067     {
00068       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00069     }
00070 
00071   // Initialize the typecode holder and current index.
00072   this->type_ = CORBA::TypeCode::_duplicate (tc);
00073 
00074   this->init_common ();
00075 
00076   // member_type()/member_label() do not work with aliased type codes.
00077   CORBA::TypeCode_var unaliased_tc =
00078   TAO_DynAnyFactory::strip_alias (this->type_.in ());
00079 
00080   CORBA::Any_var first_label =
00081     unaliased_tc->member_label (this->current_position_);
00082 
00083   // Initialize the discriminator to the label value of the first member.
00084   CORBA::TypeCode_var disc_tc = unaliased_tc->discriminator_type ();
00085   CORBA::TCKind disc_kind = TAO_DynAnyFactory::unalias (disc_tc.in ());
00086   CORBA::TCKind label_kind = TAO_DynAnyFactory::unalias (first_label->_tao_get_typecode ());
00087   if (disc_kind == CORBA::tk_enum &&
00088       label_kind == CORBA::tk_ulong)
00089     {
00090       // incase the discriminator is an enum type we have to walk
00091       // a slightly more complex path because enum labels are
00092       // stored as ulong in the union tc
00093       this->discriminator_ =
00094         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00095           disc_tc.in (),
00096           disc_tc.in ());
00097       CORBA::ULong label_val;
00098       first_label >>= label_val;
00099       TAO_DynEnum_i::_narrow (this->discriminator_.in ())
00100                                     ->set_as_ulong (label_val);
00101     }
00102   else
00103     {
00104       this->discriminator_ =
00105         TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00106           first_label.in ()._tao_get_typecode (),
00107           first_label.in ());
00108     }
00109 
00110   CORBA::TypeCode_var first_type =
00111     unaliased_tc->member_type (this->current_position_
00112                               );
00113 
00114   // Recursively initialize the member to its default value.
00115   this->member_ =
00116     TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00117       first_type.in (),
00118       first_type.in ());
00119 }
00120 
00121 // ****************************************************************
00122 
00123 TAO_DynUnion_i *
00124 TAO_DynUnion_i::_narrow (CORBA::Object_ptr _tao_objref)
00125 {
00126   if (CORBA::is_nil (_tao_objref))
00127     {
00128       return 0;
00129     }
00130 
00131   return dynamic_cast<TAO_DynUnion_i *> (_tao_objref);
00132 }
00133 
00134 // This code is common to from_any() and the init() overload that takes
00135 // an Any argument.
00136 void
00137 TAO_DynUnion_i::set_from_any (const CORBA::Any & any)
00138 {
00139   // discriminator_type () does not work with aliased type codes,
00140   // only on unions, so strip the alias out of the type code
00141   //
00142   CORBA::TypeCode_var tc =
00143    TAO_DynAnyFactory::strip_alias (any._tao_get_typecode ());
00144 
00145   CORBA::TypeCode_var disc_tc =
00146     tc->discriminator_type ();
00147 
00148   CORBA::Any disc_any;
00149   TAO::Unknown_IDL_Type *unk = 0;
00150 
00151   // Get a CDR stream - if the Any doesn't have one, make one.
00152   TAO::Any_Impl *impl = any.impl ();
00153   TAO_OutputCDR out;
00154   TAO_InputCDR in (static_cast<ACE_Message_Block *> (0));
00155 
00156   if (impl->encoded ())
00157     {
00158       TAO::Unknown_IDL_Type * const tmp =
00159         dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00160 
00161       if (!tmp)
00162         throw CORBA::INTERNAL ();
00163 
00164       in = tmp->_tao_get_cdr ();
00165     }
00166   else
00167     {
00168       impl->marshal_value (out);
00169       TAO_InputCDR tmp_in (out);
00170       in = tmp_in;
00171     }
00172 
00173   TAO_InputCDR unk_in (in);
00174   ACE_NEW (unk,
00175            TAO::Unknown_IDL_Type (disc_tc.in (),
00176                                   unk_in));
00177 
00178   disc_any.replace (unk);
00179 
00180   // Need this here because we might have been called from init().
00181   if (!CORBA::is_nil (this->discriminator_.in ()))
00182     {
00183       this->discriminator_->destroy ();
00184     }
00185 
00186   // Set the discriminator.
00187   this->discriminator_ =
00188     TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00189       disc_any._tao_get_typecode (),
00190       disc_any);
00191 
00192   // Move to the next field in the CDR stream.
00193   (void) TAO_Marshal_Object::perform_skip (disc_tc.in (), &in);
00194 
00195   CORBA::TypeCode_var unaliased =
00196     TAO_DynAnyFactory::strip_alias (tc.in ());
00197 
00198   CORBA::ULong const count = unaliased->member_count ();
00199 
00200   CORBA::Boolean match = false;
00201   CORBA::ULong i;
00202 
00203   // Get the index.
00204   for (i = 0; i < count; ++i)
00205     {
00206       CORBA::Any_var label_any = tc->member_label (i);
00207 
00208       match = this->label_match (label_any.in (), disc_any);
00209 
00210       if (match)
00211         {
00212           break;
00213         }
00214     }
00215 
00216   // Need this here because we might have been called from init().
00217   if (!CORBA::is_nil (this->member_.in ()))
00218     {
00219       this->member_->destroy ();
00220     }
00221 
00222   if (match)
00223     {
00224       CORBA::TypeCode_var member_tc = tc->member_type (i);
00225 
00226       CORBA::Any member_any;
00227       TAO::Unknown_IDL_Type *unk = 0;
00228       ACE_NEW (unk,
00229                TAO::Unknown_IDL_Type (member_tc.in (),
00230                                       in));
00231       member_any.replace (unk);
00232 
00233       this->member_ =
00234         TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00235           member_any._tao_get_typecode (),
00236           member_any);
00237 
00238       this->member_slot_ = i;
00239     }
00240   else
00241     {
00242       // If no match, either the Any contains the default member or the
00243       // type code was bad.
00244 
00245       // default_index() does not work with aliased type codes.
00246       CORBA::TypeCode_var unaliased_tc =
00247         TAO_DynAnyFactory::strip_alias (this->type_.in ());
00248 
00249       CORBA::Long default_index =
00250         unaliased_tc->default_index ();
00251 
00252       if (default_index == -1)
00253         {
00254            set_to_no_active_member ();
00255         }
00256       else
00257         {
00258           CORBA::ULong index = static_cast<CORBA::ULong> (default_index);
00259 
00260           CORBA::TypeCode_var default_tc =
00261             tc->member_type (index
00262                             );
00263 
00264           CORBA::Any default_any;
00265           TAO::Unknown_IDL_Type *unk = 0;
00266           ACE_NEW (unk,
00267                    TAO::Unknown_IDL_Type (default_tc.in (),
00268                                           in));
00269           default_any.replace (unk);
00270 
00271           this->member_ =
00272             TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00273               default_any._tao_get_typecode (),
00274               default_any);
00275 
00276           this->member_slot_ = index;
00277         }
00278     }
00279 }
00280 
00281 // ****************************************************************
00282 
00283 DynamicAny::DynAny_ptr
00284 TAO_DynUnion_i::get_discriminator (void)
00285 {
00286   if (this->destroyed_)
00287     {
00288       throw ::CORBA::OBJECT_NOT_EXIST ();
00289     }
00290 
00291   // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00292   // Set the flag so the caller can't destroy.
00293   this->set_flag (this->discriminator_.in (), 0);
00294 
00295   return DynamicAny::DynAny::_duplicate (this->discriminator_.in ());
00296 }
00297 
00298 void
00299 TAO_DynUnion_i::set_discriminator (DynamicAny::DynAny_ptr value)
00300 {
00301   if (this->destroyed_)
00302     {
00303       throw ::CORBA::OBJECT_NOT_EXIST ();
00304     }
00305 
00306   CORBA::TypeCode_var tc = value->type ();
00307 
00308   CORBA::TypeCode_var disc_tc =
00309     this->discriminator_->type ();
00310 
00311   CORBA::Boolean equivalent = disc_tc->equivalent (tc.in ());
00312 
00313   if (!equivalent)
00314     {
00315       throw DynamicAny::DynAny::TypeMismatch ();
00316     }
00317 
00318   CORBA::Any_var value_any = value->to_any ();
00319 
00320   CORBA::ULong length =
00321     this->type_->member_count ();
00322 
00323   CORBA::Any_var label_any;
00324   CORBA::ULong i;
00325 
00326   // member_label() does not work with aliased type codes.
00327   CORBA::TypeCode_var unaliased_tc =
00328     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00329 
00330   CORBA::Boolean match = 0;
00331 
00332   for (i = 0; i < length; ++i)
00333     {
00334       label_any = unaliased_tc->member_label (i);
00335 
00336       match = this->label_match (label_any.in (), value_any.in ());
00337 
00338       if (match)
00339         {
00340           break;
00341         }
00342     }
00343 
00344   if (match)
00345     {
00346       // If the incoming label value matches the one we already
00347       // have, we do nothing.
00348       if (i == this->member_slot_)
00349         {
00350           return;
00351         }
00352 
00353       // If we got a match, a named member will be active.
00354       CORBA::TCKind disc_kind = TAO_DynAnyFactory::unalias (disc_tc.in ());
00355       CORBA::TCKind label_kind = TAO_DynAnyFactory::unalias (label_any->_tao_get_typecode ());
00356       if (disc_kind == CORBA::tk_enum &&
00357           label_kind == CORBA::tk_ulong)
00358         {
00359           // incase the discriminator is an enum type we have to walk
00360           // a slightly more complex path because enum labels are
00361           // stored as ulong in the union tc
00362           CORBA::ULong label_val;
00363           label_any >>= label_val;
00364           TAO_DynEnum_i::_narrow (this->discriminator_.in ())
00365                                         ->set_as_ulong (label_val);
00366         }
00367       else
00368         {
00369           this->discriminator_->from_any (label_any.in ());
00370         }
00371 
00372       // member_type() does not work with aliased type codes.
00373       CORBA::TypeCode_var member_tc = unaliased_tc->member_type (i);
00374 
00375       this->member_->destroy ();
00376 
00377       // Initialize member to default value.
00378       this->member_ =
00379         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00380           member_tc.in (),
00381           member_tc.in ());
00382 
00383       // Named active member (CORBA 2.3.1).
00384       this->current_position_ = 1;
00385       this->component_count_ = 2;
00386 
00387       this->member_slot_ = i;
00388 
00389       // we're through, disc, value has already been set
00390       // no need for the copy operation below.
00391       return;
00392     }
00393   else
00394     {
00395       // default_index() does not work with aliased type codes.
00396       CORBA::TypeCode_var unaliased_tc =
00397         TAO_DynAnyFactory::strip_alias (this->type_.in ());
00398 
00399       // If no match, either the default member or no member is active.
00400       CORBA::Long default_index =
00401         unaliased_tc->default_index ();
00402 
00403       if (default_index == -1)
00404         {
00405           // This can't throw InvalidValue - if there's no default case
00406           // and all possible labels are used, we'd have had a match above.
00407           this->set_to_no_active_member ();
00408         }
00409       else
00410         {
00411           this->set_to_default_member ();
00412 
00413           this->member_slot_ = static_cast<CORBA::ULong> (default_index);
00414         }
00415     }
00416 
00417   // If we get here, we update the discriminator no matter what.
00418   // Any value will correspond to one of the three cases above.
00419   this->discriminator_->destroy ();
00420 
00421   this->discriminator_ = value->copy ();
00422 }
00423 
00424 void
00425 TAO_DynUnion_i::set_to_default_member (void)
00426 {
00427   if (this->destroyed_)
00428     {
00429       throw ::CORBA::OBJECT_NOT_EXIST ();
00430     }
00431 
00432   // default_index() does not work with aliased type codes.
00433   CORBA::TypeCode_var unaliased_tc =
00434     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00435 
00436   CORBA::Long default_index =
00437     unaliased_tc->default_index ();
00438 
00439   if (default_index == -1)
00440     {
00441       // No explicit default case.
00442       throw DynamicAny::DynAny::TypeMismatch ();
00443     }
00444   else
00445     {
00446       CORBA::ULong index = static_cast<CORBA::ULong> (default_index);
00447 
00448       CORBA::TypeCode_var default_tc =
00449         unaliased_tc->member_type (index);
00450 
00451       this->member_->destroy ();
00452 
00453       this->member_ =
00454         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00455           default_tc.in (),
00456           default_tc.in ());
00457 
00458       // Default member active (CORBA 2.3.1).
00459       this->current_position_ = 0;
00460       this->component_count_ = 2;
00461 
00462       this->member_slot_ = index;
00463     }
00464 }
00465 
00466 void
00467 TAO_DynUnion_i::set_to_no_active_member (void)
00468 {
00469   if (this->destroyed_)
00470     {
00471       throw ::CORBA::OBJECT_NOT_EXIST ();
00472     }
00473 
00474   // default_index() does not work with aliased type codes.
00475   CORBA::TypeCode_var unaliased_tc =
00476     TAO_DynAnyFactory::strip_alias (this->type_.in ());
00477 
00478   CORBA::Long default_index =
00479     unaliased_tc->default_index ();
00480 
00481   // Throw an exception is there is an explicit default case or if all
00482   // possible case label values are used.
00483   if (default_index != -1)
00484     {
00485       throw DynamicAny::DynAny::TypeMismatch ();
00486     }
00487   else
00488     {
00489       CORBA::TypeCode_var disc_tc =
00490         this->discriminator_->type ();
00491 
00492       CORBA::TCKind kind =
00493         TAO_DynAnyFactory::unalias (disc_tc.in ());
00494 
00495       if (kind == CORBA::tk_enum)
00496         {
00497           CORBA::ULong const member_count =
00498             this->type_->member_count ();
00499 
00500           CORBA::ULong const label_count =
00501             disc_tc->member_count ();
00502 
00503           if (member_count == label_count)
00504             {
00505               throw DynamicAny::DynAny::TypeMismatch ();
00506             }
00507         }
00508     }
00509 
00510   // No active member (CORBA 2.3.1).
00511   this->current_position_ = 0;
00512   this->component_count_ = 1;
00513 }
00514 
00515 CORBA::Boolean
00516 TAO_DynUnion_i::has_no_active_member (void)
00517 {
00518   if (this->destroyed_)
00519     {
00520       throw ::CORBA::OBJECT_NOT_EXIST ();
00521     }
00522 
00523   // No active member (CORBA 2.3.1).
00524   return (this->current_position_ == 0 && this->component_count_ == 1);
00525 }
00526 
00527 CORBA::TCKind
00528 TAO_DynUnion_i::discriminator_kind (void)
00529 {
00530   if (this->destroyed_)
00531     {
00532       throw ::CORBA::OBJECT_NOT_EXIST ();
00533     }
00534 
00535   CORBA::TypeCode_var tc =
00536     this->discriminator_->type ();
00537 
00538   return TAO_DynAnyFactory::unalias (tc.in ());
00539 }
00540 
00541 DynamicAny::DynAny_ptr
00542 TAO_DynUnion_i::member (void)
00543 {
00544   if (this->destroyed_)
00545     {
00546       throw ::CORBA::OBJECT_NOT_EXIST ();
00547     }
00548 
00549   CORBA::Boolean has_no_active_member =
00550     this->has_no_active_member ();
00551 
00552   if (has_no_active_member)
00553     {
00554       throw DynamicAny::DynAny::InvalidValue ();
00555     }
00556 
00557   // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00558   // Set the flag so the caller can't destroy.
00559   this->set_flag (this->member_.in (),
00560                   0
00561                  );
00562 
00563   return DynamicAny::DynAny::_duplicate (this->member_.in ());
00564 }
00565 
00566 char *
00567 TAO_DynUnion_i::member_name (void)
00568 {
00569   if (this->destroyed_)
00570     {
00571       throw ::CORBA::OBJECT_NOT_EXIST ();
00572     }
00573 
00574   CORBA::Boolean has_no_active_member =
00575     this->has_no_active_member ();
00576 
00577   if (has_no_active_member)
00578     {
00579       throw DynamicAny::DynAny::InvalidValue ();
00580     }
00581 
00582   const char *retval = this->type_->member_name (this->member_slot_);
00583 
00584   return CORBA::string_dup (retval);
00585 }
00586 
00587 CORBA::TCKind
00588 TAO_DynUnion_i::member_kind (void)
00589 {
00590   if (this->destroyed_)
00591     {
00592       throw ::CORBA::OBJECT_NOT_EXIST ();
00593     }
00594 
00595   CORBA::Boolean has_no_active_member =
00596     this->has_no_active_member ();
00597 
00598   if (has_no_active_member)
00599     {
00600       throw DynamicAny::DynAny::InvalidValue ();
00601     }
00602 
00603   CORBA::TypeCode_var tc = this->member_->type ();
00604 
00605   return TAO_DynAnyFactory::unalias (tc.in ());
00606 }
00607 
00608 // ****************************************************************
00609 
00610 void
00611 TAO_DynUnion_i::from_any (const CORBA::Any& any)
00612 {
00613   if (this->destroyed_)
00614     {
00615       throw ::CORBA::OBJECT_NOT_EXIST ();
00616     }
00617 
00618   CORBA::TypeCode_var tc = any.type ();
00619   CORBA::Boolean equivalent =
00620     this->type_.in ()->equivalent (tc.in ());
00621 
00622   if (equivalent)
00623     {
00624       // CORBA 2.3.1 section 9.2.3.3.
00625       this->current_position_ = 0;
00626 
00627       // May be changed in set_from_any().
00628       this->component_count_ = 2;
00629 
00630       // Set the from_factory arg to FALSE, so any problems will throw
00631       // TypeMismatch.
00632       this->set_from_any (any
00633                          );
00634     }
00635   else
00636     {
00637       throw DynamicAny::DynAny::TypeMismatch ();
00638     }
00639 }
00640 
00641 CORBA::Any_ptr
00642 TAO_DynUnion_i::to_any (void)
00643 {
00644   if (this->destroyed_)
00645     {
00646       throw ::CORBA::OBJECT_NOT_EXIST ();
00647     }
00648 
00649   TAO_OutputCDR out_cdr;
00650 
00651   // Add the discriminator to the CDR stream.
00652 
00653   CORBA::TypeCode_var disc_tc =
00654     this->discriminator_->type ();
00655 
00656   CORBA::Any_var disc_any =
00657     this->discriminator_->to_any ();
00658 
00659   TAO::Any_Impl *disc_any_impl = disc_any->impl ();
00660   TAO_OutputCDR disc_out_cdr;
00661   TAO_InputCDR disc_in_cdr (static_cast<ACE_Message_Block *> (0));
00662 
00663   if (disc_any_impl->encoded ())
00664     {
00665       TAO::Unknown_IDL_Type * const disc_unk =
00666         dynamic_cast<TAO::Unknown_IDL_Type *> (disc_any_impl);
00667 
00668       if (!disc_unk)
00669         throw CORBA::INTERNAL ();
00670 
00671       disc_in_cdr = disc_unk->_tao_get_cdr ();
00672     }
00673   else
00674     {
00675       disc_any_impl->marshal_value (disc_out_cdr);
00676       TAO_InputCDR disc_tmp_in_cdr (disc_out_cdr);
00677       disc_in_cdr = disc_tmp_in_cdr;
00678     }
00679 
00680   (void) TAO_Marshal_Object::perform_append (disc_tc.in (),
00681                                              &disc_in_cdr,
00682                                              &out_cdr);
00683 
00684   // Add the member to the CDR stream unless it has no active member.
00685   if (this->has_no_active_member () == 0)
00686     {
00687       CORBA::TypeCode_var member_tc =
00688         this->member_->type ();
00689 
00690       CORBA::Any_var member_any =
00691         this->member_->to_any ();
00692 
00693       TAO::Any_Impl *member_any_impl = member_any->impl ();
00694       TAO_OutputCDR member_out_cdr;
00695       TAO_InputCDR member_in_cdr (static_cast<ACE_Message_Block *> (0));
00696 
00697       if (member_any_impl->encoded ())
00698         {
00699           TAO::Unknown_IDL_Type * const member_unk =
00700             dynamic_cast<TAO::Unknown_IDL_Type *> (member_any_impl);
00701 
00702           if (!member_unk)
00703             throw CORBA::INTERNAL ();
00704 
00705           member_in_cdr = member_unk->_tao_get_cdr ();
00706         }
00707       else
00708         {
00709           member_any_impl->marshal_value (member_out_cdr);
00710           TAO_InputCDR member_tmp_in_cdr (member_out_cdr);
00711           member_in_cdr = member_tmp_in_cdr;
00712         }
00713 
00714       (void) TAO_Marshal_Object::perform_append (member_tc.in (),
00715                                                 &member_in_cdr,
00716                                                 &out_cdr);
00717     }
00718 
00719   // Make the Any.
00720   TAO_InputCDR in_cdr (out_cdr);
00721 
00722   CORBA::Any_ptr retval = 0;
00723   ACE_NEW_THROW_EX (retval,
00724                     CORBA::Any,
00725                     CORBA::NO_MEMORY ());
00726 
00727   TAO::Unknown_IDL_Type *unk = 0;
00728   ACE_NEW_THROW_EX (unk,
00729                     TAO::Unknown_IDL_Type (this->type_.in (),
00730                                            in_cdr),
00731                     CORBA::NO_MEMORY ());
00732 
00733   retval->replace (unk);
00734   return retval;
00735 }
00736 
00737 CORBA::Boolean
00738 TAO_DynUnion_i::equal (DynamicAny::DynAny_ptr rhs)
00739 {
00740   if (this->destroyed_)
00741     {
00742       throw ::CORBA::OBJECT_NOT_EXIST ();
00743     }
00744 
00745   TAO_DynUnion_i *impl = TAO_DynUnion_i::_narrow (rhs);
00746 
00747   if (impl == 0)
00748     {
00749       return 0;
00750     }
00751 
00752   CORBA::Boolean equivalent =
00753     this->type_->equivalent (impl->type_.in ());
00754 
00755   if (!equivalent)
00756     {
00757       return 0;
00758     }
00759 
00760   CORBA::Boolean member_equal =
00761     this->member_->equal (impl->member_.in ());
00762 
00763   CORBA::Boolean disc_equal =
00764     this->discriminator_->equal (impl->discriminator_.in ());
00765 
00766   impl->_remove_ref ();
00767 
00768   return (member_equal && disc_equal);
00769 }
00770 
00771 void
00772 TAO_DynUnion_i::destroy (void)
00773 {
00774   if (this->destroyed_)
00775     {
00776       throw ::CORBA::OBJECT_NOT_EXIST ();
00777     }
00778 
00779   if (!this->ref_to_component_ || this->container_is_destroying_)
00780     {
00781       // Free the two components.
00782 
00783       if (! CORBA::is_nil (this->member_.in ()))
00784         {
00785           this->set_flag (this->member_.in (), 1);
00786 
00787           this->member_->destroy ();
00788         }
00789 
00790       this->set_flag (this->discriminator_.in (), 1);
00791 
00792       this->discriminator_->destroy ();
00793 
00794       this->destroyed_ = 1;
00795     }
00796 }
00797 
00798 DynamicAny::DynAny_ptr
00799 TAO_DynUnion_i::current_component (void)
00800 {
00801   if (this->destroyed_)
00802     {
00803       throw ::CORBA::OBJECT_NOT_EXIST ();
00804     }
00805 
00806   if (this->current_position_ == 1)
00807     {
00808       this->set_flag (this->member_.in (), 0);
00809 
00810       return DynamicAny::DynAny::_duplicate (this->member_.in ());
00811     }
00812   else
00813     {
00814       this->set_flag (this->discriminator_.in (), 0);
00815 
00816       return DynamicAny::DynAny::_duplicate (this->discriminator_.in ());
00817     }
00818 }
00819 
00820 // ****************************************************************
00821 
00822 CORBA::Boolean
00823 TAO_DynUnion_i::label_match (const CORBA::Any &my_any,
00824                              const CORBA::Any &other_any)
00825 {
00826   // Use my_any so we can detect a default case label,
00827   // if we are iterating through the union type code's
00828   // member_label() calls.
00829   CORBA::TypeCode_var tc = my_any.type ();
00830 
00831   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00832 
00833   // No need to do any type checking - it was done before this
00834   // call was made.
00835   switch (kind)
00836   {
00837     case CORBA::tk_octet:
00838       // Default case label - just skip it.
00839       return 0;
00840     case CORBA::tk_short:
00841       {
00842         CORBA::Short my_val;
00843         CORBA::Short other_val;
00844         my_any >>= my_val;
00845         other_any >>= other_val;
00846         return my_val == other_val;
00847       }
00848     case CORBA::tk_long:
00849       {
00850         CORBA::Long my_val;
00851         CORBA::Long other_val;
00852         my_any >>= my_val;
00853         other_any >>= other_val;
00854         return my_val == other_val;
00855       }
00856     case CORBA::tk_ushort:
00857       {
00858         CORBA::UShort my_val;
00859         CORBA::UShort other_val;
00860         my_any >>= my_val;
00861         other_any >>= other_val;
00862         return my_val == other_val;
00863       }
00864     case CORBA::tk_ulong:
00865       {
00866         CORBA::ULong my_val;
00867         CORBA::ULong other_val;
00868         my_any >>= my_val;
00869 
00870         // check whether the discriminator is possibly an enum type
00871         // since these get stored as ulong label values as well
00872         CORBA::TypeCode_var other_tc = other_any.type ();
00873         CORBA::TCKind kind = TAO_DynAnyFactory::unalias (other_tc.in ());
00874         if (kind == CORBA::tk_enum)
00875           {
00876             TAO::Any_Impl *other_impl = other_any.impl ();
00877 
00878             if (other_impl->encoded ())
00879               {
00880                 TAO::Unknown_IDL_Type *other_unk =
00881                   dynamic_cast<TAO::Unknown_IDL_Type *> (other_impl);
00882 
00883                 // We don't want unk's rd_ptr to move, in case we are
00884                 // shared by another Any, so we use this to copy the
00885                 // state, not the buffer.
00886                 TAO_InputCDR for_reading (other_unk->_tao_get_cdr ());
00887                 for_reading.read_ulong (other_val);
00888               }
00889             else
00890               {
00891                 TAO_OutputCDR other_out;
00892                 other_impl->marshal_value (other_out);
00893                 TAO_InputCDR other_in (other_out);
00894                 other_in.read_ulong (other_val);
00895               }
00896           }
00897         else
00898           other_any >>= other_val;
00899 
00900         return my_val == other_val;
00901       }
00902     case CORBA::tk_boolean:
00903       {
00904         CORBA::Boolean my_val;
00905         CORBA::Boolean other_val;
00906         my_any >>= CORBA::Any::to_boolean (my_val);
00907         other_any >>= CORBA::Any::to_boolean (other_val);
00908         return my_val == other_val;
00909       }
00910     case CORBA::tk_char:
00911       {
00912         CORBA::Char my_val;
00913         CORBA::Char other_val;
00914         my_any >>= CORBA::Any::to_char (my_val);
00915         other_any >>= CORBA::Any::to_char (other_val);
00916         return my_val == other_val;
00917       }
00918 // For platforms without native 64-bit ints.
00919 #if !defined (ACE_LACKS_LONGLONG_T)
00920     case CORBA::tk_longlong:
00921       {
00922         CORBA::LongLong my_val;
00923         CORBA::LongLong other_val;
00924         my_any >>= my_val;
00925         other_any >>= other_val;
00926         return my_val == other_val;
00927       }
00928 #endif /* ACE_LACKS_LONGLONG_T */
00929     case CORBA::tk_ulonglong:
00930       {
00931         CORBA::ULongLong my_val;
00932         CORBA::ULongLong other_val;
00933         my_any >>= my_val;
00934         other_any >>= other_val;
00935         return my_val == other_val;
00936       }
00937     case CORBA::tk_wchar:
00938       {
00939         CORBA::WChar my_val;
00940         CORBA::WChar other_val;
00941         my_any >>= CORBA::Any::to_wchar (my_val);
00942         other_any >>= CORBA::Any::to_wchar (other_val);
00943         return my_val == other_val;
00944       }
00945     case CORBA::tk_enum:
00946       {
00947         CORBA::ULong my_val;
00948         CORBA::ULong other_val;
00949 
00950         TAO::Any_Impl *my_impl = my_any.impl ();
00951 
00952         if (my_impl->encoded ())
00953           {
00954             TAO::Unknown_IDL_Type * const my_unk =
00955               dynamic_cast<TAO::Unknown_IDL_Type *> (my_impl);
00956 
00957             if (!my_unk)
00958               throw CORBA::INTERNAL ();
00959 
00960             // We don't want unk's rd_ptr to move, in case we are shared by
00961             // another Any, so we use this to copy the state, not the buffer.
00962             TAO_InputCDR for_reading (my_unk->_tao_get_cdr ());
00963             for_reading.read_ulong (my_val);
00964           }
00965         else
00966           {
00967             TAO_OutputCDR my_out;
00968             my_impl->marshal_value (my_out);
00969             TAO_InputCDR my_in (my_out);
00970             my_in.read_ulong (my_val);
00971           }
00972 
00973         TAO::Any_Impl *other_impl = other_any.impl ();
00974 
00975         if (other_impl->encoded ())
00976           {
00977             TAO::Unknown_IDL_Type * const other_unk =
00978               dynamic_cast<TAO::Unknown_IDL_Type *> (other_impl);
00979 
00980             if (!other_unk)
00981               throw CORBA::INTERNAL ();
00982 
00983             // We don't want unk's rd_ptr to move, in case we are shared by
00984             // another Any, so we use this to copy the state, not the buffer.
00985             TAO_InputCDR for_reading (other_unk->_tao_get_cdr ());
00986             for_reading.read_ulong (other_val);
00987           }
00988         else
00989           {
00990             TAO_OutputCDR other_out;
00991             other_impl->marshal_value (other_out);
00992             TAO_InputCDR other_in (other_out);
00993             other_in.read_ulong (other_val);
00994           }
00995 
00996         return my_val == other_val;
00997       }
00998     // Cannot happen - we've covered all the legal discriminator types.
00999     default:
01000       return 0;
01001   }
01002 }
01003 
01004 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:36:29 2008 for TAO_DynamicAny by doxygen 1.3.6