DynArray_i.cpp

Go to the documentation of this file.
00001 // $Id: DynArray_i.cpp 77779 2007-03-23 11:48:02Z johnnyw $
00002 
00003 #include "tao/DynamicAny/DynArray_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            DynArray_i,
00015            "$Id: DynArray_i.cpp 77779 2007-03-23 11:48:02Z johnnyw $")
00016 
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 TAO_DynArray_i::TAO_DynArray_i (void)
00020 {
00021 }
00022 
00023 TAO_DynArray_i::~TAO_DynArray_i (void)
00024 {
00025 }
00026 
00027 void
00028 TAO_DynArray_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->current_position_ = 0;
00035   this->component_count_ = static_cast<CORBA::ULong> (this->da_members_.size ());
00036 }
00037 
00038 void
00039 TAO_DynArray_i::init (const CORBA::Any & any)
00040 {
00041   CORBA::TypeCode_var tc = any.type ();
00042 
00043   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ());
00044 
00045   if (kind != CORBA::tk_array)
00046     {
00047       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00048     }
00049 
00050   this->type_ = tc;
00051 
00052   CORBA::ULong numfields = this->get_tc_length (tc.in ());
00053   // Resize the array.
00054   this->da_members_.size (numfields);
00055 
00056   this->init_common ();
00057 
00058   // Get the CDR stream of the Any, if there isn't one, make one.
00059   TAO::Any_Impl *impl = any.impl ();
00060   TAO_OutputCDR out;
00061   TAO_InputCDR cdr (static_cast<ACE_Message_Block *> (0));
00062 
00063   if (impl->encoded  ())
00064     {
00065       TAO::Unknown_IDL_Type * const unk =
00066         dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00067 
00068       if (!unk)
00069         throw CORBA::INTERNAL ();
00070 
00071       cdr = unk->_tao_get_cdr ();
00072     }
00073   else
00074     {
00075       impl->marshal_value (out);
00076       TAO_InputCDR tmp_in (out);
00077       cdr = tmp_in;
00078     }
00079 
00080   CORBA::TypeCode_var field_tc =
00081     this->get_element_type ();
00082 
00083   for (CORBA::ULong i = 0; i < numfields; ++i)
00084     {
00085       CORBA::Any field_any;
00086       TAO::Unknown_IDL_Type *field_unk = 0;
00087       TAO_InputCDR unk_in (cdr);
00088       ACE_NEW (field_unk,
00089                TAO::Unknown_IDL_Type (field_tc.in (), unk_in));
00090       field_any.replace (field_unk);
00091 
00092       // This recursive step will call the correct constructor
00093       // based on the type of field_any.
00094       this->da_members_[i] =
00095         TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00096           field_any._tao_get_typecode (),
00097           field_any);
00098 
00099       // Move to the next field in the CDR stream.
00100       (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr);
00101     }
00102 }
00103 
00104 void
00105 TAO_DynArray_i::init (CORBA::TypeCode_ptr tc)
00106 {
00107   CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc);
00108 
00109   if (kind != CORBA::tk_array)
00110     {
00111       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00112     }
00113 
00114   this->type_ = CORBA::TypeCode::_duplicate (tc);
00115 
00116   CORBA::ULong numfields = this->get_tc_length (tc);
00117 
00118   // Resize the array.
00119   this->da_members_.size (numfields);
00120 
00121   this->init_common ();
00122 
00123   CORBA::TypeCode_var elemtype = this->get_element_type ();
00124 
00125   for (CORBA::ULong i = 0; i < numfields; ++i)
00126     {
00127       // Recursively initialize each element.
00128       this->da_members_[i] =
00129         TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> (
00130           elemtype.in (),
00131           elemtype.in ());
00132     }
00133 }
00134 
00135 CORBA::TypeCode_ptr
00136 TAO_DynArray_i::get_element_type (void)
00137 {
00138   CORBA::TypeCode_var element_type =
00139     CORBA::TypeCode::_duplicate (this->type_.in ());
00140 
00141   // Strip away aliases (if any) on top of the outer type
00142   CORBA::TCKind kind = element_type->kind ();
00143 
00144   while (kind != CORBA::tk_array)
00145     {
00146       element_type = element_type->content_type ();
00147 
00148       kind = element_type->kind ();
00149     }
00150 
00151   // Return the content type.
00152   return element_type->content_type ();
00153 }
00154 
00155 // Get the length from the (possibly aliased) typecode.
00156 CORBA::ULong
00157 TAO_DynArray_i::get_tc_length (CORBA::TypeCode_ptr tc)
00158 {
00159   CORBA::TypeCode_var tctmp = CORBA::TypeCode::_duplicate (tc);
00160   CORBA::TCKind kind = tctmp->kind ();
00161 
00162   while (kind == CORBA::tk_alias)
00163     {
00164       tctmp = tctmp->content_type ();
00165       kind = tctmp->kind ();
00166     }
00167 
00168   return tctmp->length ();
00169 }
00170 
00171 // ****************************************************************
00172 
00173 TAO_DynArray_i *
00174 TAO_DynArray_i::_narrow (CORBA::Object_ptr _tao_objref)
00175 {
00176   if (CORBA::is_nil (_tao_objref))
00177     {
00178       return 0;
00179     }
00180 
00181   return dynamic_cast<TAO_DynArray_i *> (_tao_objref);
00182 }
00183 
00184 // ****************************************************************
00185 
00186 DynamicAny::AnySeq *
00187 TAO_DynArray_i::get_elements (void)
00188 {
00189   if (this->destroyed_)
00190     {
00191       throw ::CORBA::OBJECT_NOT_EXIST ();
00192     }
00193 
00194   CORBA::ULong length = static_cast<CORBA::ULong> (this->da_members_.size ());
00195 
00196   DynamicAny::AnySeq *elements = 0;
00197   ACE_NEW_THROW_EX (elements,
00198                     DynamicAny::AnySeq (length),
00199                     CORBA::NO_MEMORY ());
00200 
00201   elements->length (length);
00202   DynamicAny::AnySeq_var safe_retval (elements);
00203 
00204   CORBA::Any_var tmp;
00205 
00206   // Initialize each Any.
00207   for (CORBA::ULong i = 0; i < length; i++)
00208     {
00209       tmp = this->da_members_[i]->to_any ();
00210 
00211       safe_retval[i] = tmp.in ();
00212     }
00213 
00214   return safe_retval._retn ();
00215 }
00216 
00217 void
00218 TAO_DynArray_i::set_elements (const DynamicAny::AnySeq & value)
00219 {
00220   if (this->destroyed_)
00221     {
00222       throw ::CORBA::OBJECT_NOT_EXIST ();
00223     }
00224 
00225   CORBA::ULong const length = value.length ();
00226 
00227   if (length != this->da_members_.size ())
00228     {
00229       throw DynamicAny::DynAny::InvalidValue ();
00230     }
00231 
00232   CORBA::TypeCode_var value_tc;
00233   CORBA::TypeCode_var element_type = this->get_element_type ();
00234 
00235   for (CORBA::ULong i = 0; i < length; i++)
00236     {
00237       // Check each arg element for type match.
00238       value_tc = value[i].type ();
00239       CORBA::Boolean equivalent =
00240         value_tc->equivalent (element_type.in ());
00241 
00242       if (equivalent)
00243         {
00244           this->da_members_[i]->destroy ();
00245 
00246           this->da_members_[i] =
00247             TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00248               value[i]._tao_get_typecode (),
00249               value[i]);
00250         }
00251       else
00252         {
00253           throw DynamicAny::DynAny::TypeMismatch ();
00254         }
00255     }
00256 }
00257 
00258 DynamicAny::DynAnySeq *
00259 TAO_DynArray_i::get_elements_as_dyn_any (void)
00260 {
00261   if (this->destroyed_)
00262     {
00263       throw ::CORBA::OBJECT_NOT_EXIST ();
00264     }
00265 
00266   DynamicAny::DynAnySeq *retval = 0;
00267   ACE_NEW_THROW_EX (retval,
00268                     DynamicAny::DynAnySeq (this->component_count_),
00269                     CORBA::NO_MEMORY ());
00270 
00271   retval->length (this->component_count_);
00272   DynamicAny::DynAnySeq_var safe_retval (retval);
00273 
00274   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00275     {
00276       // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
00277       // Set the flag so the caller can't destroy.
00278       this->set_flag (this->da_members_[i].in (), 0);
00279 
00280       safe_retval[i] =
00281         DynamicAny::DynAny::_duplicate (this->da_members_[i].in ());
00282     }
00283 
00284   return safe_retval._retn ();
00285 }
00286 
00287 void
00288 TAO_DynArray_i::set_elements_as_dyn_any (
00289     const DynamicAny::DynAnySeq & values
00290 
00291   )
00292 {
00293   if (this->destroyed_)
00294     {
00295       throw ::CORBA::OBJECT_NOT_EXIST ();
00296     }
00297 
00298   CORBA::ULong length = static_cast<CORBA::ULong> (this->da_members_.size ());
00299 
00300   if (values.length () != length)
00301     {
00302       throw DynamicAny::DynAny::InvalidValue ();
00303     }
00304 
00305   CORBA::TypeCode_var element_type = this->get_element_type ();
00306 
00307   CORBA::TypeCode_var val_type;
00308   CORBA::Boolean equivalent;
00309 
00310   for (CORBA::ULong i = 0; i < length; ++i)
00311     {
00312       val_type = values[i]->type ();
00313 
00314       equivalent = val_type->equivalent (element_type.in ());
00315 
00316 
00317       if (equivalent)
00318         {
00319           this->da_members_[i] = values[i]->copy ();
00320         }
00321       else
00322         {
00323           throw DynamicAny::DynAny::TypeMismatch ();
00324         }
00325     }
00326 }
00327 
00328 // ****************************************************************
00329 
00330 void
00331 TAO_DynArray_i::from_any (const CORBA::Any& any)
00332 {
00333   if (this->destroyed_)
00334     {
00335       throw ::CORBA::OBJECT_NOT_EXIST ();
00336     }
00337 
00338   CORBA::TypeCode_var tc = any.type ();
00339   CORBA::Boolean equivalent = this->type_.in ()->equivalent (tc.in ());
00340 
00341   if (equivalent)
00342     {
00343       // Get the CDR stream of the Any,if there isn't one, make one.
00344       TAO::Any_Impl *impl = any.impl ();
00345       TAO_OutputCDR out;
00346       TAO_InputCDR cdr (static_cast<ACE_Message_Block *> (0));
00347 
00348       if (impl->encoded ())
00349         {
00350           TAO::Unknown_IDL_Type * const unk =
00351             dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00352 
00353           if (!unk)
00354             throw CORBA::INTERNAL ();
00355 
00356           cdr = unk->_tao_get_cdr ();
00357         }
00358       else
00359         {
00360           impl->marshal_value (out);
00361           TAO_InputCDR tmp_in (out);
00362           cdr = tmp_in;
00363         }
00364 
00365       CORBA::ULong length = static_cast<CORBA::ULong> (this->da_members_.size ());
00366       CORBA::ULong arg_length = this->get_tc_length (tc.in ());
00367 
00368       if (length != arg_length)
00369         {
00370           throw DynamicAny::DynAny::TypeMismatch ();
00371         }
00372 
00373       CORBA::TypeCode_var field_tc = this->get_element_type ();
00374 
00375       for (CORBA::ULong i = 0; i < arg_length; ++i)
00376         {
00377           CORBA::Any field_any;
00378           TAO_InputCDR unk_in (cdr);
00379           TAO::Unknown_IDL_Type *field_unk = 0;
00380           ACE_NEW (field_unk,
00381                    TAO::Unknown_IDL_Type (field_tc.in (), unk_in));
00382           field_any.replace (field_unk);
00383 
00384           this->da_members_[i]->destroy ();
00385 
00386           this->da_members_[i] =
00387             TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00388               field_any._tao_get_typecode (),
00389               field_any);
00390 
00391           // Move to the next field in the CDR stream.
00392           (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr);
00393         }
00394 
00395       this->current_position_ = arg_length ? 0 : -1;
00396     }
00397   else
00398     {
00399       throw DynamicAny::DynAny::TypeMismatch ();
00400     }
00401 }
00402 
00403 CORBA::Any_ptr
00404 TAO_DynArray_i::to_any (void)
00405 {
00406   if (this->destroyed_)
00407     {
00408       throw ::CORBA::OBJECT_NOT_EXIST ();
00409     }
00410 
00411   CORBA::TypeCode_var field_tc = this->get_element_type ();
00412 
00413   TAO_OutputCDR out_cdr;
00414   CORBA::Any_var field_any;
00415   size_t length = this->da_members_.size ();
00416 
00417   for (size_t i = 0; i < length; ++i)
00418     {
00419       // Recursive step.
00420       field_any = this->da_members_[i]->to_any ();
00421 
00422       TAO::Any_Impl *field_impl = field_any->impl ();
00423       TAO_OutputCDR field_out;
00424       TAO_InputCDR field_cdr (static_cast<ACE_Message_Block *> (0));
00425 
00426       if (field_impl->encoded ())
00427         {
00428           TAO::Unknown_IDL_Type * const field_unk =
00429             dynamic_cast<TAO::Unknown_IDL_Type *> (field_impl);
00430 
00431           if (!field_unk)
00432             throw CORBA::INTERNAL ();
00433 
00434           field_cdr = field_unk->_tao_get_cdr ();
00435         }
00436       else
00437         {
00438           field_impl->marshal_value (field_out);
00439           TAO_InputCDR tmp_in (field_out);
00440           field_cdr = tmp_in;
00441         }
00442 
00443       (void) TAO_Marshal_Object::perform_append (field_tc.in (),
00444                                                  &field_cdr,
00445                                                  &out_cdr);
00446     }
00447 
00448   TAO_InputCDR in_cdr (out_cdr);
00449 
00450   CORBA::Any_ptr retval = 0;
00451   ACE_NEW_THROW_EX (retval,
00452                     CORBA::Any,
00453                     CORBA::NO_MEMORY ());
00454 
00455   TAO::Unknown_IDL_Type *unk = 0;
00456   ACE_NEW_THROW_EX (unk,
00457                     TAO::Unknown_IDL_Type (this->type_.in (),
00458                                            in_cdr),
00459                     CORBA::NO_MEMORY ());
00460 
00461   retval->replace (unk);
00462   return retval;
00463 }
00464 
00465 CORBA::Boolean
00466 TAO_DynArray_i::equal (DynamicAny::DynAny_ptr rhs)
00467 {
00468   if (this->destroyed_)
00469     {
00470       throw ::CORBA::OBJECT_NOT_EXIST ();
00471     }
00472 
00473   CORBA::TypeCode_var tc = rhs->type ();
00474 
00475   CORBA::Boolean equivalent = tc->equivalent (this->type_.in ());
00476 
00477   if (!equivalent)
00478     {
00479       return false;
00480     }
00481 
00482   DynamicAny::DynAny_var tmp;
00483   CORBA::Boolean member_equal;
00484 
00485   for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00486     {
00487       rhs->seek (static_cast<CORBA::Long> (i));
00488 
00489       tmp = rhs->current_component ();
00490 
00491       // Recursive step.
00492       member_equal = tmp->equal (this->da_members_[i].in ());
00493 
00494       if (!member_equal)
00495         {
00496           return false;
00497         }
00498     }
00499 
00500   return true;
00501 }
00502 
00503 void
00504 TAO_DynArray_i::destroy (void)
00505 {
00506   if (this->destroyed_)
00507     {
00508       throw ::CORBA::OBJECT_NOT_EXIST ();
00509     }
00510 
00511   if (!this->ref_to_component_ || this->container_is_destroying_)
00512     {
00513       // Do a deep destroy.
00514       for (CORBA::ULong i = 0; i < this->component_count_; ++i)
00515         {
00516           this->set_flag (da_members_[i].in (), 1);
00517 
00518           this->da_members_[i]->destroy ();
00519         }
00520 
00521       this->destroyed_ = 1;
00522     }
00523 }
00524 
00525 DynamicAny::DynAny_ptr
00526 TAO_DynArray_i::current_component (void)
00527 {
00528   if (this->destroyed_)
00529     {
00530       throw ::CORBA::OBJECT_NOT_EXIST ();
00531     }
00532 
00533   if (this->current_position_ == -1)
00534     {
00535       return DynamicAny::DynAny::_nil ();
00536     }
00537 
00538   CORBA::ULong index = static_cast<CORBA::ULong> (this->current_position_);
00539 
00540   this->set_flag (this->da_members_[index].in (), 0);
00541 
00542   return DynamicAny::DynAny::_duplicate (this->da_members_[index].in ());
00543 }
00544 
00545 TAO_END_VERSIONED_NAMESPACE_DECL

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