DynStruct_i.cpp

Go to the documentation of this file.
00001 // DynStruct_i.cpp,v 1.37 2006/03/10 07:19:08 jtc Exp
00002 
00003 #include "tao/DynamicAny/DynStruct_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            DynStruct_i,
00011            "DynStruct_i.cpp,v 1.37 2006/03/10 07:19:08 jtc Exp")
00012 
00013 
00014 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00015 
00016 TAO_DynStruct_i::TAO_DynStruct_i (void)
00017 {
00018 }
00019 
00020 TAO_DynStruct_i::~TAO_DynStruct_i (void)
00021 {
00022 }
00023 
00024 void
00025 TAO_DynStruct_i::check_typecode (CORBA::TypeCode_ptr tc
00026                                  ACE_ENV_ARG_DECL)
00027 {
00028   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc
00029                                                    ACE_ENV_ARG_PARAMETER);
00030   ACE_CHECK;
00031 
00032   if (kind == CORBA::tk_struct || kind == CORBA::tk_except)
00033     {
00034       return;
00035     }
00036 
00037   ACE_THROW (DynamicAny::DynAnyFactory::InconsistentTypeCode ());
00038 }
00039 
00040 void
00041 TAO_DynStruct_i::init_common (void)
00042 {
00043   this->ref_to_component_ = 0;
00044   this->container_is_destroying_ = 0;
00045   this->has_components_ = 1;
00046   this->destroyed_ = 0;
00047   this->component_count_ = static_cast <CORBA::ULong> (this->da_members_.size ());
00048   this->current_position_ = this->component_count_ ? 0 : -1;
00049 }
00050 
00051 void
00052 TAO_DynStruct_i::init (const CORBA::Any& any
00053                        ACE_ENV_ARG_DECL)
00054 {
00055   CORBA::TypeCode_ptr tc = any._tao_get_typecode ();
00056   this->check_typecode (tc
00057                         ACE_ENV_ARG_PARAMETER);
00058   ACE_CHECK;
00059 
00060   this->type_ = CORBA::TypeCode::_duplicate (tc);
00061 
00062   this->set_from_any (any
00063                       ACE_ENV_ARG_PARAMETER);
00064   ACE_CHECK;
00065 }
00066 
00067 
00068 // This code is common to from_any() and the init() overload that takes
00069 // an Any argument.
00070 void
00071 TAO_DynStruct_i::set_from_any (const CORBA::Any & any
00072                                ACE_ENV_ARG_DECL)
00073 {
00074   // member_type() does not work with aliased type codes.
00075   CORBA::TypeCode_var unaliased_tc =
00076     TAO_DynAnyFactory::strip_alias (any._tao_get_typecode ()
00077                                     ACE_ENV_ARG_PARAMETER);
00078   ACE_CHECK;
00079 
00080   CORBA::ULong numfields =
00081     unaliased_tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
00082   ACE_CHECK;
00083 
00084   // Resize the array.
00085   this->da_members_.size (numfields);
00086 
00087   this->init_common ();
00088 
00089   // Get the CDR stream of the Any, if there isn't one, make one.
00090   TAO::Any_Impl *impl = any.impl ();
00091   TAO_OutputCDR out;
00092   TAO_InputCDR in (static_cast<ACE_Message_Block *> (0));
00093   TAO::Unknown_IDL_Type *unk = 0;
00094 
00095   if (impl->encoded ())
00096     {
00097       unk = dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00098 
00099       in = unk->_tao_get_cdr ();
00100     }
00101   else
00102     {
00103       impl->marshal_value (out);
00104       TAO_InputCDR tmp_in (out);
00105       in = tmp_in;
00106     }
00107 
00108   // If we have an exception type, unmarshal the repository ID.
00109   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (any._tao_get_typecode ()
00110                                                    ACE_ENV_ARG_PARAMETER);
00111   ACE_CHECK;
00112 
00113   if (kind == CORBA::tk_except)
00114     {
00115       CORBA::String_var str;
00116       in >> str.out ();
00117     }
00118 
00119   for (CORBA::ULong i = 0; i < numfields; i++)
00120     {
00121       CORBA::TypeCode_var field_tc =
00122         unaliased_tc->member_type (i
00123                                    ACE_ENV_ARG_PARAMETER);
00124       ACE_CHECK;
00125 
00126       CORBA::Any field_any;
00127       TAO_InputCDR unk_in (in);
00128       ACE_NEW (unk,
00129                TAO::Unknown_IDL_Type (field_tc.in (),
00130                                       unk_in));
00131       field_any.replace (unk);
00132 
00133       // This recursive step will call the correct constructor
00134       // based on the type of field_any.
00135       this->da_members_[i] =
00136         TAO_DynAnyFactory::make_dyn_any (field_any
00137                                          ACE_ENV_ARG_PARAMETER);
00138       ACE_CHECK;
00139 
00140       // Move to the next field in the CDR stream.
00141       (void) TAO_Marshal_Object::perform_skip (field_tc.in (),
00142                                                &in
00143                                                ACE_ENV_ARG_PARAMETER);
00144       ACE_CHECK;
00145     }
00146 }
00147 
00148 void
00149 TAO_DynStruct_i::init (CORBA::TypeCode_ptr tc
00150                        ACE_ENV_ARG_DECL)
00151 {
00152   this->check_typecode (tc
00153                         ACE_ENV_ARG_PARAMETER);
00154   ACE_CHECK;
00155 
00156   this->type_ = CORBA::TypeCode::_duplicate (tc);
00157 
00158   // member_type() does not work with aliased type codes.
00159   CORBA::TypeCode_var unaliased_tc =
00160   TAO_DynAnyFactory::strip_alias (this->type_.in ()
00161                                   ACE_ENV_ARG_PARAMETER);
00162   ACE_CHECK;
00163 
00164   this->component_count_ =
00165     unaliased_tc->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
00166   ACE_CHECK;
00167 
00168   // Resize the array.
00169   this->da_members_.size (this->component_count_);
00170 
00171   this->init_common ();
00172 
00173   CORBA::TypeCode_var mtype;
00174 
00175   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00176     {
00177       mtype = unaliased_tc->member_type (i
00178                                          ACE_ENV_ARG_PARAMETER);
00179       ACE_CHECK;
00180 
00181       // Recursively initialize each member.
00182       this->da_members_[i] =
00183         TAO_DynAnyFactory::make_dyn_any (mtype.in ()
00184                                          ACE_ENV_ARG_PARAMETER);
00185       ACE_CHECK;
00186     }
00187 }
00188 
00189 // ****************************************************************
00190 
00191 TAO_DynStruct_i *
00192 TAO_DynStruct_i::_narrow (CORBA::Object_ptr _tao_objref
00193                           ACE_ENV_ARG_DECL_NOT_USED)
00194 {
00195   if (CORBA::is_nil (_tao_objref))
00196     {
00197       return 0;
00198     }
00199 
00200   return dynamic_cast<TAO_DynStruct_i *> (_tao_objref);
00201 }
00202 
00203 // ****************************************************************
00204 
00205 DynamicAny::FieldName
00206 TAO_DynStruct_i::current_member_name (ACE_ENV_SINGLE_ARG_DECL)
00207   ACE_THROW_SPEC ((
00208       CORBA::SystemException,
00209       DynamicAny::DynAny::TypeMismatch,
00210       DynamicAny::DynAny::InvalidValue
00211     ))
00212 {
00213   if (this->destroyed_)
00214     {
00215       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00216                         0);
00217     }
00218 
00219   // Is this an empty exception?
00220   if (this->component_count_ == 0)
00221     {
00222       ACE_THROW_RETURN (DynamicAny::DynAny::TypeMismatch (),
00223                         0);
00224     }
00225 
00226   if (this->current_position_ == -1)
00227     {
00228       ACE_THROW_RETURN (DynamicAny::DynAny::InvalidValue (),
00229                         0);
00230     }
00231 
00232   // member_name() does not work with aliased type codes.
00233   CORBA::TypeCode_var unaliased_tc =
00234     TAO_DynAnyFactory::strip_alias (this->type_.in ()
00235                                     ACE_ENV_ARG_PARAMETER);
00236   ACE_CHECK_RETURN (0);
00237   const char *name =
00238     unaliased_tc->member_name (this->current_position_
00239                                ACE_ENV_ARG_PARAMETER);
00240   ACE_CHECK_RETURN (0);
00241 
00242   return CORBA::string_dup (name);
00243 }
00244 
00245 // Returns the unaliased TCKind.
00246 CORBA::TCKind
00247 TAO_DynStruct_i::current_member_kind (ACE_ENV_SINGLE_ARG_DECL)
00248   ACE_THROW_SPEC ((
00249       CORBA::SystemException,
00250       DynamicAny::DynAny::TypeMismatch,
00251       DynamicAny::DynAny::InvalidValue
00252     ))
00253 {
00254   if (this->destroyed_)
00255     {
00256       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00257                         CORBA::tk_null);
00258     }
00259 
00260   // Is this an empty exception?
00261   if (this->component_count_ == 0)
00262     {
00263       ACE_THROW_RETURN (DynamicAny::DynAny::TypeMismatch (),
00264                         CORBA::tk_null);
00265     }
00266 
00267   if (this->current_position_ == -1)
00268     {
00269       ACE_THROW_RETURN (DynamicAny::DynAny::InvalidValue (),
00270                         CORBA::tk_null);
00271     }
00272 
00273   // member_type() does not work with aliased type codes.
00274   CORBA::TypeCode_var unaliased_tc =
00275     TAO_DynAnyFactory::strip_alias (this->type_.in ()
00276                                     ACE_ENV_ARG_PARAMETER);
00277   ACE_CHECK_RETURN (CORBA::tk_null);
00278   CORBA::TypeCode_var tc =
00279   unaliased_tc->member_type (this->current_position_
00280                                   ACE_ENV_ARG_PARAMETER);
00281   ACE_CHECK_RETURN (CORBA::tk_null);
00282 
00283   CORBA::TCKind retval = TAO_DynAnyFactory::unalias (tc.in ()
00284                                                      ACE_ENV_ARG_PARAMETER);
00285   ACE_CHECK_RETURN (CORBA::tk_null);
00286 
00287   return retval;
00288 }
00289 
00290 DynamicAny::NameValuePairSeq *
00291 TAO_DynStruct_i::get_members (ACE_ENV_SINGLE_ARG_DECL)
00292   ACE_THROW_SPEC ((
00293       CORBA::SystemException
00294     ))
00295 {
00296   if (this->destroyed_)
00297     {
00298       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00299                         0);
00300     }
00301 
00302   DynamicAny::NameValuePairSeq* members;
00303   ACE_NEW_THROW_EX (members,
00304                     DynamicAny::NameValuePairSeq (this->component_count_),
00305                     CORBA::NO_MEMORY ());
00306   ACE_CHECK_RETURN (0);
00307 
00308   // We must do this explicitly.
00309   members->length (this->component_count_);
00310 
00311   DynamicAny::NameValuePairSeq_var safe_retval = members;
00312   CORBA::Any_var temp;
00313   CORBA::TypeCode_var unaliased_tc;
00314 
00315   CORBA::TCKind const tc_kind =
00316     this->type_->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
00317   ACE_CHECK_RETURN (0);
00318 
00319   if (tc_kind == CORBA::tk_alias)
00320     {
00321       unaliased_tc =
00322         TAO_DynAnyFactory::strip_alias (this->type_.in ()
00323                                         ACE_ENV_ARG_PARAMETER);
00324       ACE_CHECK_RETURN (0);
00325     }
00326   else
00327     {
00328       unaliased_tc = CORBA::TypeCode::_duplicate (this->type_.in ());
00329     }
00330 
00331   // Assign name and value to each pearl on the string.
00332   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00333     {
00334       safe_retval[i].id =
00335         CORBA::string_dup (unaliased_tc->member_name (i
00336                                                       ACE_ENV_ARG_PARAMETER));
00337       ACE_CHECK_RETURN (0);
00338 
00339       temp = this->da_members_[i]->to_any (ACE_ENV_SINGLE_ARG_PARAMETER);
00340       ACE_CHECK_RETURN (0);
00341 
00342       safe_retval[i].value = temp.in ();
00343     }
00344 
00345   return safe_retval._retn ();
00346 }
00347 
00348 void
00349 TAO_DynStruct_i::set_members (const DynamicAny::NameValuePairSeq & values
00350                               ACE_ENV_ARG_DECL)
00351   ACE_THROW_SPEC ((
00352       CORBA::SystemException,
00353       DynamicAny::DynAny::TypeMismatch,
00354       DynamicAny::DynAny::InvalidValue
00355     ))
00356 {
00357   if (this->destroyed_)
00358     {
00359       ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
00360     }
00361 
00362   CORBA::ULong length = values.length ();
00363 
00364   // Check for length match.
00365   if (length != this->component_count_)
00366     {
00367       ACE_THROW (DynamicAny::DynAny::InvalidValue ());
00368     }
00369 
00370   CORBA::TypeCode_var value_tc;
00371   CORBA::TypeCode_var my_tc;
00372   CORBA::Boolean equivalent;
00373 
00374   // member_type() does not work with aliased type codes.
00375   CORBA::TypeCode_var unaliased_tc =
00376     TAO_DynAnyFactory::strip_alias (this->type_.in ()
00377                                     ACE_ENV_ARG_PARAMETER);
00378   ACE_CHECK;
00379 
00380   for (CORBA::ULong i = 0; i < length; ++i)
00381     {
00382       // Check for type and name match.
00383       my_tc = unaliased_tc->member_type (i
00384                                          ACE_ENV_ARG_PARAMETER);
00385       ACE_CHECK;
00386 
00387       value_tc = values[i].value.type ();
00388 
00389       equivalent = my_tc->equivalent (value_tc.in ()
00390                                       ACE_ENV_ARG_PARAMETER);
00391       ACE_CHECK;
00392 
00393       if (!equivalent)
00394         {
00395           ACE_THROW (DynamicAny::DynAny::TypeMismatch ());
00396         }
00397 
00398       this->da_members_[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00399       ACE_CHECK;
00400 
00401       this->da_members_[i] =
00402         TAO_DynAnyFactory::make_dyn_any (values[i].value
00403                                          ACE_ENV_ARG_PARAMETER);
00404       ACE_CHECK;
00405     }
00406 
00407   this->current_position_ = length ? 0 : -1;
00408 }
00409 
00410 DynamicAny::NameDynAnyPairSeq *
00411 TAO_DynStruct_i::get_members_as_dyn_any (ACE_ENV_SINGLE_ARG_DECL)
00412   ACE_THROW_SPEC ((
00413       CORBA::SystemException
00414     ))
00415 {
00416   if (this->destroyed_)
00417     {
00418       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00419                         0);
00420     }
00421 
00422   DynamicAny::NameDynAnyPairSeq * members;
00423   ACE_NEW_THROW_EX (members,
00424                     DynamicAny::NameDynAnyPairSeq (this->component_count_),
00425                     CORBA::NO_MEMORY ());
00426   ACE_CHECK_RETURN (0);
00427 
00428   // We must do this explicitly.
00429   members->length (this->component_count_);
00430 
00431   DynamicAny::NameDynAnyPairSeq_var safe_retval = members;
00432 
00433   // member_name() does not work with aliased type codes.
00434   CORBA::TypeCode_var unaliased_tc =
00435     TAO_DynAnyFactory::strip_alias (this->type_.in ()
00436                                     ACE_ENV_ARG_PARAMETER);
00437   ACE_CHECK_RETURN (0);
00438 
00439   // Assign name and value to each pearl on the string.
00440   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00441     {
00442       safe_retval[i].id =
00443         CORBA::string_dup (unaliased_tc->member_name (i
00444                                                       ACE_ENV_ARG_PARAMETER));
00445       ACE_CHECK_RETURN (0);
00446 
00447       // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00448       // Set the flag so the caller can't destroy.
00449       this->set_flag (this->da_members_[i].in (),
00450                       0
00451                       ACE_ENV_ARG_PARAMETER);
00452       ACE_CHECK_RETURN (0);
00453 
00454       safe_retval[i].value =
00455         DynamicAny::DynAny::_duplicate (this->da_members_[i].in ());
00456       ACE_CHECK_RETURN (0);
00457     }
00458 
00459   return safe_retval._retn ();
00460 }
00461 
00462 void
00463 TAO_DynStruct_i::set_members_as_dyn_any (
00464     const DynamicAny::NameDynAnyPairSeq & values
00465     ACE_ENV_ARG_DECL
00466   )
00467   ACE_THROW_SPEC ((
00468       CORBA::SystemException,
00469       DynamicAny::DynAny::TypeMismatch,
00470       DynamicAny::DynAny::InvalidValue
00471     ))
00472 {
00473   if (this->destroyed_)
00474     {
00475       ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
00476     }
00477 
00478   CORBA::ULong length = values.length ();
00479 
00480   // Check for length match.
00481   if (length != this->component_count_)
00482     {
00483       ACE_THROW (DynamicAny::DynAny::InvalidValue ());
00484     }
00485 
00486   CORBA::TypeCode_var value_tc;
00487   CORBA::TypeCode_var my_tc;
00488   CORBA::Boolean equivalent;
00489 
00490   // member_type() does not work with aliased type codes.
00491   CORBA::TypeCode_var unaliased_tc =
00492     TAO_DynAnyFactory::strip_alias (this->type_.in ()
00493                                     ACE_ENV_ARG_PARAMETER);
00494   ACE_CHECK;
00495 
00496   for (CORBA::ULong i = 0; i < length; ++i)
00497     {
00498       // Check for type and name match.
00499       my_tc = unaliased_tc->member_type (i
00500                                          ACE_ENV_ARG_PARAMETER);
00501       ACE_CHECK;
00502 
00503       value_tc = values[i].value->type (ACE_ENV_SINGLE_ARG_PARAMETER);
00504       ACE_CHECK;
00505 
00506       equivalent = my_tc->equivalent (value_tc.in ()
00507                                       ACE_ENV_ARG_PARAMETER);
00508       ACE_CHECK;
00509 
00510       if (!equivalent)
00511         {
00512           ACE_THROW (DynamicAny::DynAny::TypeMismatch ());
00513         }
00514 
00515       this->da_members_[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00516       ACE_CHECK;
00517 
00518       this->da_members_[i] =
00519         values[i].value->copy (ACE_ENV_SINGLE_ARG_PARAMETER);
00520       ACE_CHECK;
00521     }
00522 
00523   this->current_position_ = length ? 0 : -1;
00524 }
00525 
00526 // ****************************************************************
00527 
00528 void
00529 TAO_DynStruct_i::from_any (const CORBA::Any & any
00530                            ACE_ENV_ARG_DECL)
00531   ACE_THROW_SPEC ((
00532       CORBA::SystemException,
00533       DynamicAny::DynAny::TypeMismatch,
00534       DynamicAny::DynAny::InvalidValue
00535     ))
00536 {
00537   if (this->destroyed_)
00538     {
00539       ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
00540     }
00541 
00542   CORBA::TypeCode_var tc = any.type ();
00543   CORBA::Boolean equivalent =
00544     this->type_->equivalent (tc.in ()
00545                              ACE_ENV_ARG_PARAMETER);
00546   ACE_CHECK;
00547 
00548   if (equivalent)
00549     {
00550       // Get the CDR stream of the Any, if there isn't one, make one.
00551       TAO::Any_Impl *impl = any.impl ();
00552       TAO_OutputCDR out;
00553       TAO_InputCDR in (static_cast<ACE_Message_Block *> (0));
00554       TAO::Unknown_IDL_Type *unk = 0;
00555 
00556       if (impl->encoded ())
00557         {
00558           unk = dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00559 
00560           in = unk->_tao_get_cdr ();
00561         }
00562       else
00563         {
00564           impl->marshal_value (out);
00565           TAO_InputCDR tmp_in (out);
00566           in = tmp_in;
00567         }
00568 
00569       // If we have an exception type, unmarshal the repository ID.
00570       CORBA::TCKind kind =
00571         TAO_DynAnyFactory::unalias (this->type_.in ()
00572                                     ACE_ENV_ARG_PARAMETER);
00573       ACE_CHECK;
00574 
00575       if (kind == CORBA::tk_except)
00576         {
00577           CORBA::String_var str;
00578           in >> str.out ();
00579         }
00580 
00581       CORBA::TypeCode_var field_tc;
00582       CORBA::TypeCode_var unaliased =
00583         TAO::unaliased_typecode (this->type_.in ()
00584                                  ACE_ENV_ARG_PARAMETER);
00585       ACE_CHECK;
00586 
00587       for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00588         {
00589           field_tc = unaliased->member_type (i
00590                                              ACE_ENV_ARG_PARAMETER);
00591           ACE_CHECK;
00592 
00593           CORBA::Any field_any;
00594           TAO_InputCDR unk_in (in);
00595           TAO::Unknown_IDL_Type *unk = 0;
00596           ACE_NEW (unk,
00597                    TAO::Unknown_IDL_Type (field_tc.in (),
00598                                           unk_in));
00599           field_any.replace (unk);
00600 
00601           this->da_members_[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00602           ACE_CHECK;
00603 
00604           this->da_members_[i] =
00605             TAO_DynAnyFactory::make_dyn_any (field_any
00606                                              ACE_ENV_ARG_PARAMETER);
00607           ACE_CHECK;
00608 
00609           // Move to the next field in the CDR stream.
00610           (void) TAO_Marshal_Object::perform_skip (field_tc.in (),
00611                                                    &in
00612                                                    ACE_ENV_ARG_PARAMETER);
00613           ACE_CHECK;
00614         }
00615 
00616       this->current_position_ = this->component_count_ ? 0 : -1;
00617     }
00618   else
00619     {
00620       ACE_THROW (DynamicAny::DynAny::TypeMismatch ());
00621     }
00622 }
00623 
00624 CORBA::Any_ptr
00625 TAO_DynStruct_i::to_any (ACE_ENV_SINGLE_ARG_DECL)
00626   ACE_THROW_SPEC ((
00627       CORBA::SystemException
00628     ))
00629 {
00630   if (this->destroyed_)
00631     {
00632       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00633                         0);
00634     }
00635 
00636   TAO_OutputCDR out_cdr;
00637 
00638   // If we have an exception type, marshal the repository ID.
00639   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (this->type_.in ()
00640                                                    ACE_ENV_ARG_PARAMETER);
00641   ACE_CHECK_RETURN (0);
00642 
00643   if (kind == CORBA::tk_except)
00644     {
00645       out_cdr << this->type_->id (ACE_ENV_SINGLE_ARG_PARAMETER);
00646       ACE_CHECK_RETURN (0);
00647     }
00648 
00649   TAO::Any_Impl *field_impl = 0;
00650   TAO::Unknown_IDL_Type *field_unk = 0;
00651   TAO_InputCDR field_in_cdr (static_cast<ACE_Message_Block *> (0));
00652 
00653   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00654     {
00655       CORBA::TypeCode_var field_tc =
00656         this->da_members_[i]->type (ACE_ENV_SINGLE_ARG_PARAMETER);
00657       ACE_CHECK_RETURN (0);
00658 
00659       // Recursive step.
00660       CORBA::Any_var field_any =
00661         this->da_members_[i]->to_any (ACE_ENV_SINGLE_ARG_PARAMETER);
00662       ACE_CHECK_RETURN (0);
00663 
00664       TAO_OutputCDR field_out_cdr;
00665       field_impl = field_any->impl ();
00666 
00667       if (field_impl->encoded ())
00668         {
00669           field_unk =
00670             dynamic_cast<TAO::Unknown_IDL_Type *> (field_impl);
00671 
00672           field_in_cdr = field_unk->_tao_get_cdr ();
00673         }
00674       else
00675         {
00676           field_impl->marshal_value (field_out_cdr);
00677           TAO_InputCDR tmp (field_out_cdr);
00678           field_in_cdr = tmp;
00679         }
00680 
00681       (void) TAO_Marshal_Object::perform_append (field_tc.in (),
00682                                                  &field_in_cdr,
00683                                                  &out_cdr
00684                                                  ACE_ENV_ARG_PARAMETER);
00685       ACE_CHECK_RETURN (0);
00686     }
00687 
00688   TAO_InputCDR in_cdr (out_cdr);
00689 
00690   CORBA::Any_ptr retval = 0;
00691   ACE_NEW_THROW_EX (retval,
00692                     CORBA::Any,
00693                     CORBA::NO_MEMORY ());
00694   ACE_CHECK_RETURN (0);
00695 
00696   TAO::Unknown_IDL_Type *unk = 0;
00697   ACE_NEW_THROW_EX (unk,
00698                     TAO::Unknown_IDL_Type (this->type_.in (),
00699                                            in_cdr),
00700                     CORBA::NO_MEMORY ());
00701   ACE_CHECK_RETURN (0);
00702 
00703   retval->replace (unk);
00704   return retval;
00705 }
00706 
00707 CORBA::Boolean
00708 TAO_DynStruct_i::equal (DynamicAny::DynAny_ptr rhs
00709                         ACE_ENV_ARG_DECL)
00710   ACE_THROW_SPEC ((
00711       CORBA::SystemException
00712     ))
00713 {
00714   if (this->destroyed_)
00715     {
00716       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00717                         0);
00718     }
00719 
00720   CORBA::TypeCode_var tc = rhs->type (ACE_ENV_SINGLE_ARG_PARAMETER);
00721   ACE_CHECK_RETURN (0);
00722 
00723   CORBA::Boolean equivalent = tc->equivalent (this->type_.in ()
00724                                               ACE_ENV_ARG_PARAMETER);
00725   ACE_CHECK_RETURN (0);
00726 
00727   if (!equivalent)
00728     {
00729       return 0;
00730     }
00731 
00732   DynamicAny::DynAny_var tmp;
00733   CORBA::Boolean member_equal;
00734 
00735   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00736     {
00737       rhs->seek (static_cast <CORBA::Long> (i)
00738                  ACE_ENV_ARG_PARAMETER);
00739       ACE_CHECK_RETURN (0);
00740 
00741       tmp = rhs->current_component (ACE_ENV_SINGLE_ARG_PARAMETER);
00742       ACE_CHECK_RETURN (0);
00743 
00744       // Recursive step.
00745       member_equal = tmp->equal (this->da_members_[i].in ()
00746                                  ACE_ENV_ARG_PARAMETER);
00747       ACE_CHECK_RETURN (0);
00748 
00749       if (!member_equal)
00750         {
00751           return 0;
00752         }
00753     }
00754 
00755   return 1;
00756 }
00757 
00758 void
00759 TAO_DynStruct_i::destroy (ACE_ENV_SINGLE_ARG_DECL)
00760   ACE_THROW_SPEC ((
00761       CORBA::SystemException
00762     ))
00763 {
00764   if (this->destroyed_)
00765     {
00766       ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
00767     }
00768 
00769   if (!this->ref_to_component_ || this->container_is_destroying_)
00770     {
00771       // Do a deep destroy.
00772       for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00773         {
00774           this->set_flag (da_members_[i].in (),
00775                           1
00776                           ACE_ENV_ARG_PARAMETER);
00777           ACE_CHECK;
00778 
00779           this->da_members_[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00780           ACE_CHECK;
00781         }
00782 
00783       this->destroyed_ = 1;
00784     }
00785 }
00786 
00787 DynamicAny::DynAny_ptr
00788 TAO_DynStruct_i::current_component (ACE_ENV_SINGLE_ARG_DECL)
00789   ACE_THROW_SPEC ((
00790       CORBA::SystemException,
00791       DynamicAny::DynAny::TypeMismatch
00792     ))
00793 {
00794   if (this->destroyed_)
00795     {
00796       ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
00797                         DynamicAny::DynAny::_nil ());
00798     }
00799 
00800   if (this->component_count_ == 0)
00801     {
00802       // Empty exception - no component.
00803       ACE_THROW_RETURN (DynamicAny::DynAny::TypeMismatch (),
00804                         DynamicAny::DynAny::_nil ());
00805     }
00806 
00807   if (this->current_position_ == -1)
00808     {
00809       return DynamicAny::DynAny::_nil ();
00810     }
00811 
00812   CORBA::ULong index = static_cast <CORBA::ULong> (this->current_position_);
00813 
00814   this->set_flag (this->da_members_[index].in (),
00815                   0
00816                   ACE_ENV_ARG_PARAMETER);
00817   ACE_CHECK_RETURN (DynamicAny::DynAny::_nil ());
00818 
00819   return DynamicAny::DynAny::_duplicate (
00820             this->da_members_[index].in ()
00821           );
00822 }
00823 
00824 TAO_END_VERSIONED_NAMESPACE_DECL

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