DynUnion_i.cpp

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

Generated on Thu Nov 9 13:02:09 2006 for TAO_DynamicAny by doxygen 1.3.6