DynAny_i.cpp

Go to the documentation of this file.
00001 // $Id: DynAny_i.cpp 80297 2007-12-18 07:50:05Z johnnyw $
00002 
00003 #include "tao/AnyTypeCode/TypeCode.h"
00004 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00005 #include "tao/AnyTypeCode/AnyTypeCode_methods.h"
00006 
00007 #include "tao/DynamicAny/DynAny_i.h"
00008 #include "tao/DynamicAny/DynAnyFactory.h"
00009 
00010 #include "tao/DynamicAny/DynAnyUtils_T.h"
00011 
00012 #include "tao/CDR.h"
00013 
00014 #include "ace/OS_NS_wchar.h"
00015 #include "ace/OS_NS_string.h"
00016 
00017 ACE_RCSID (DynamicAny,
00018            DynAny_i,
00019            "$Id: DynAny_i.cpp 80297 2007-12-18 07:50:05Z johnnyw $")
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 TAO_DynAny_i::TAO_DynAny_i (void)
00024 {
00025 }
00026 
00027 TAO_DynAny_i::~TAO_DynAny_i (void)
00028 {
00029 }
00030 
00031 void
00032 TAO_DynAny_i::check_typecode (CORBA::TypeCode_ptr tc)
00033 {
00034   // Check to see if it's a simple type.
00035   CORBA::TCKind tk = TAO_DynAnyFactory::unalias (tc);
00036 
00037   switch (tk)
00038   {
00039     case CORBA::tk_null:
00040     case CORBA::tk_void:
00041     case CORBA::tk_short:
00042     case CORBA::tk_long:
00043     case CORBA::tk_ushort:
00044     case CORBA::tk_ulong:
00045     case CORBA::tk_float:
00046     case CORBA::tk_double:
00047     case CORBA::tk_longlong:
00048     case CORBA::tk_ulonglong:
00049     case CORBA::tk_boolean:
00050     case CORBA::tk_char:
00051     case CORBA::tk_wchar:
00052     case CORBA::tk_octet:
00053     case CORBA::tk_any:
00054     case CORBA::tk_TypeCode:
00055     case CORBA::tk_objref:
00056     case CORBA::tk_string:
00057     case CORBA::tk_wstring:
00058     case CORBA::tk_longdouble:
00059       break;
00060     case CORBA::tk_sequence:
00061       if (tc == CORBA::_tc_BooleanSeq
00062           || tc == CORBA::_tc_OctetSeq
00063           || tc == CORBA::_tc_CharSeq
00064           || tc == CORBA::_tc_WCharSeq
00065           || tc == CORBA::_tc_ShortSeq
00066           || tc == CORBA::_tc_UShortSeq
00067           || tc == CORBA::_tc_LongSeq
00068           || tc == CORBA::_tc_ULongSeq
00069           || tc == CORBA::_tc_LongLongSeq
00070           || tc == CORBA::_tc_ULongLongSeq
00071           || tc == CORBA::_tc_FloatSeq
00072           || tc == CORBA::_tc_DoubleSeq
00073           || tc == CORBA::_tc_LongDoubleSeq)
00074         {
00075           // Otherwise fall through.
00076           break;
00077         }
00078     default:
00079       throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
00080   }
00081 }
00082 
00083 void
00084 TAO_DynAny_i::set_to_default_value (CORBA::TypeCode_ptr tc)
00085 {
00086   CORBA::TCKind tk = TAO_DynAnyFactory::unalias (tc);
00087 
00088   switch (tk)
00089   {
00090     case CORBA::tk_null:
00091       break;
00092     case CORBA::tk_void:
00093       this->any_._tao_set_typecode (CORBA::_tc_void);
00094       break;
00095     case CORBA::tk_short:
00096       this->any_ <<= static_cast<CORBA::Short> (0);
00097       break;
00098     case CORBA::tk_long:
00099       this->any_ <<= static_cast<CORBA::Long> (0);
00100       break;
00101     case CORBA::tk_ushort:
00102       this->any_ <<= static_cast<CORBA::UShort> (0);
00103       break;
00104     case CORBA::tk_ulong:
00105       this->any_ <<= static_cast<CORBA::ULong> (0);
00106       break;
00107 #if !defined (ACE_LACKS_LONGLONG_T)
00108     case CORBA::tk_longlong:
00109       this->any_ <<= static_cast<CORBA::LongLong> (0);
00110       break;
00111     case CORBA::tk_ulonglong:
00112       this->any_ <<= static_cast<CORBA::ULongLong> (0);
00113       break;
00114 #endif /* ACE_LACKS_LONGLONG_T */
00115     case CORBA::tk_boolean:
00116       this->any_ <<= CORBA::Any::from_boolean (0);
00117       break;
00118     case CORBA::tk_octet:
00119       this->any_ <<= CORBA::Any::from_octet (0);
00120       break;
00121     case CORBA::tk_char:
00122       this->any_ <<= CORBA::Any::from_char (0);
00123       break;
00124     case CORBA::tk_wchar:
00125       this->any_ <<= CORBA::Any::from_wchar (0);
00126       break;
00127     case CORBA::tk_float:
00128       this->any_ <<= static_cast<CORBA::Float> (0);
00129       break;
00130     case CORBA::tk_double:
00131       this->any_ <<= static_cast<CORBA::Double> (0);
00132       break;
00133     case CORBA::tk_any:
00134       this->any_._tao_set_typecode (CORBA::_tc_null);
00135       break;
00136     case CORBA::tk_TypeCode:
00137       this->any_ <<= CORBA::_tc_null;
00138       break;
00139     case CORBA::tk_objref:
00140       {
00141         TAO_OutputCDR stream;
00142         stream << CORBA::Object::_nil ();
00143         TAO_InputCDR in (stream);
00144         TAO::Unknown_IDL_Type *unk = 0;
00145         ACE_NEW (unk,
00146                  TAO::Unknown_IDL_Type (tc, in));
00147         this->any_.replace (unk);
00148         break;
00149       }
00150     case CORBA::tk_string:
00151       this->any_ <<= "";
00152       break;
00153     case CORBA::tk_wstring:
00154       {
00155         CORBA::WChar wstr[1];
00156         wstr[0] = 0;
00157         this->any_ <<= wstr;
00158         break;
00159       }
00160     default:
00161       // Should never get here - check_typecode() has already been called.
00162       break;
00163   }
00164 }
00165 
00166 void
00167 TAO_DynAny_i::init_common (void)
00168 {
00169   this->ref_to_component_ = false;
00170   this->container_is_destroying_ = false;
00171   this->has_components_ = false;
00172   this->destroyed_ = false;
00173   this->current_position_ = -1;
00174   this->component_count_ = 0;
00175 }
00176 
00177 void
00178 TAO_DynAny_i::init (CORBA::TypeCode_ptr tc)
00179 {
00180   this->check_typecode (tc);
00181 
00182   this->set_to_default_value (tc);
00183 
00184   this->init_common ();
00185 
00186   this->type_ = CORBA::TypeCode::_duplicate (tc);
00187 }
00188 
00189 void
00190 TAO_DynAny_i::init (const CORBA::Any& any)
00191 {
00192   this->type_ = any.type ();
00193   this->check_typecode (this->type_.in ());
00194 
00195   this->init_common ();
00196 
00197   this->any_ = any;
00198 }
00199 
00200 // ****************************************************************
00201 
00202 TAO_DynAny_i *
00203 TAO_DynAny_i::_narrow (CORBA::Object_ptr _tao_objref)
00204 {
00205   if (CORBA::is_nil (_tao_objref))
00206     {
00207       return 0;
00208     }
00209 
00210   return dynamic_cast<TAO_DynAny_i *> (_tao_objref);
00211 }
00212 
00213 // ****************************************************************
00214 
00215 void
00216 TAO_DynAny_i::from_any (const CORBA::Any &any)
00217 {
00218   if (this->destroyed_)
00219     {
00220       throw ::CORBA::OBJECT_NOT_EXIST ();
00221     }
00222 
00223   CORBA::TypeCode_var any_tc = any.type ();
00224 
00225   if (!this->type_->equivalent (any_tc.in ()))
00226     {
00227       throw DynamicAny::DynAny::TypeMismatch ();
00228     }
00229 
00230 // @@@ (JP) Spec also says we should check for illegal Any
00231 // value here, and throw InvalidValue if we find one.
00232 // Something like a null string will be caught in the constructor.
00233 
00234   this->any_ = any;
00235 }
00236 
00237 CORBA::Any_ptr
00238 TAO_DynAny_i::to_any (void)
00239 {
00240   if (this->destroyed_)
00241     {
00242       throw ::CORBA::OBJECT_NOT_EXIST ();
00243     }
00244 
00245   CORBA::Any_ptr retval;
00246 
00247   ACE_NEW_THROW_EX (retval,
00248                     CORBA::Any (this->any_),
00249                     CORBA::NO_MEMORY ());
00250 
00251   return retval;
00252 }
00253 
00254 CORBA::Boolean
00255 TAO_DynAny_i::equal (DynamicAny::DynAny_ptr rhs)
00256 {
00257   if (this->destroyed_)
00258     {
00259       throw ::CORBA::OBJECT_NOT_EXIST ();
00260     }
00261 
00262   TAO_DynAny_i *rhs_n = TAO_DynAny_i::_narrow (rhs);
00263 
00264   if (rhs_n == 0)
00265     {
00266       return false;
00267     }
00268 
00269   if (!this->type_->equivalent (rhs_n->type_.in ()))
00270     {
00271       return false;
00272     }
00273 
00274   CORBA::TCKind tk = TAO_DynAnyFactory::unalias (this->type_.in ());
00275 
00276   switch (tk)
00277     {
00278     case CORBA::tk_null:
00279     case CORBA::tk_void:
00280       return true;
00281     case CORBA::tk_short:
00282       {
00283         CORBA::Short rhs_v;
00284         rhs_n->any_ >>= rhs_v;
00285         CORBA::Short lhs_v;
00286         this->any_ >>= lhs_v;
00287         return (lhs_v == rhs_v);
00288       }
00289     case CORBA::tk_long:
00290       {
00291         CORBA::Long rhs_v;
00292         rhs_n->any_ >>= rhs_v;
00293         CORBA::Long lhs_v;
00294         this->any_ >>= lhs_v;
00295         return (lhs_v == rhs_v);
00296       }
00297     case CORBA::tk_ushort:
00298       {
00299         CORBA::UShort rhs_v;
00300         rhs_n->any_ >>= rhs_v;
00301         CORBA::UShort lhs_v;
00302         this->any_ >>= lhs_v;
00303         return (lhs_v == rhs_v);
00304       }
00305     case CORBA::tk_ulong:
00306       {
00307         CORBA::ULong rhs_v;
00308         rhs_n->any_ >>= rhs_v;
00309         CORBA::ULong lhs_v;
00310         this->any_ >>= lhs_v;
00311         return (lhs_v == rhs_v);
00312       }
00313     case CORBA::tk_float:
00314       {
00315         CORBA::Float rhs_v;
00316         rhs_n->any_ >>= rhs_v;
00317         CORBA::Float lhs_v;
00318         this->any_ >>= lhs_v;
00319         return (lhs_v == rhs_v);
00320       }
00321     case CORBA::tk_double:
00322       {
00323         CORBA::Double rhs_v;
00324         rhs_n->any_ >>= rhs_v;
00325         CORBA::Double lhs_v;
00326         this->any_ >>= lhs_v;
00327         return (lhs_v == rhs_v);
00328       }
00329     case CORBA::tk_longlong:
00330       {
00331         CORBA::LongLong rhs_v;
00332         rhs_n->any_ >>= rhs_v;
00333         CORBA::LongLong lhs_v;
00334         this->any_ >>= lhs_v;
00335         return (lhs_v == rhs_v);
00336       }
00337     case CORBA::tk_ulonglong:
00338       {
00339         CORBA::ULongLong rhs_v;
00340         rhs_n->any_ >>= rhs_v;
00341         CORBA::ULongLong lhs_v;
00342         this->any_ >>= lhs_v;
00343         return (lhs_v == rhs_v);
00344       }
00345     case CORBA::tk_boolean:
00346       {
00347         CORBA::Boolean rhs_v;
00348         rhs_n->any_ >>= CORBA::Any::to_boolean (rhs_v);
00349         CORBA::Boolean lhs_v;
00350         this->any_ >>= CORBA::Any::to_boolean (lhs_v);
00351         return (lhs_v == rhs_v);
00352       }
00353     case CORBA::tk_char:
00354       {
00355         CORBA::Char rhs_v;
00356         rhs_n->any_ >>= CORBA::Any::to_char (rhs_v);
00357         CORBA::Char lhs_v;
00358         this->any_ >>= CORBA::Any::to_char (lhs_v);
00359         return (lhs_v == rhs_v);
00360       }
00361     case CORBA::tk_wchar:
00362       {
00363         CORBA::WChar rhs_v;
00364         rhs_n->any_ >>= CORBA::Any::to_wchar (rhs_v);
00365         CORBA::WChar lhs_v;
00366         this->any_ >>= CORBA::Any::to_wchar (lhs_v);
00367         return (lhs_v == rhs_v);
00368       }
00369     case CORBA::tk_octet:
00370       {
00371         CORBA::Octet rhs_v;
00372         rhs_n->any_ >>= CORBA::Any::to_octet (rhs_v);
00373         CORBA::Octet lhs_v;
00374         this->any_ >>= CORBA::Any::to_octet (lhs_v);
00375         return (lhs_v == rhs_v);
00376       }
00377     case CORBA::tk_any:
00378       {
00379         const CORBA::Any *rhs_v;
00380         rhs_n->any_ >>= rhs_v;
00381         const CORBA::Any *lhs_v;
00382         this->any_ >>= lhs_v;
00383 
00384         DynamicAny::DynAny_var rhs_dyn =
00385           TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00386             rhs_v->_tao_get_typecode (),
00387             *rhs_v);
00388 
00389         DynamicAny::DynAny_var lhs_dyn =
00390           TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
00391             lhs_v->_tao_get_typecode (),
00392             *lhs_v);
00393 
00394         CORBA::Boolean const b = rhs_dyn->equal (lhs_dyn.in ());
00395 
00396         rhs_dyn->destroy ();
00397 
00398         lhs_dyn->destroy ();
00399 
00400         return b;
00401       }
00402     case CORBA::tk_TypeCode:
00403       {
00404         CORBA::TypeCode_ptr rhs_v;
00405         rhs_n->any_ >>= rhs_v;
00406         CORBA::TypeCode_ptr lhs_v;
00407         this->any_ >>= lhs_v;
00408         // See CORBA 2.4.2 - must use equal() here.
00409         return lhs_v->equal (lhs_v);
00410       }
00411     case CORBA::tk_objref:
00412       {
00413         CORBA::Object_ptr rhs_v;
00414         rhs_n->any_ >>= CORBA::Any::to_object (rhs_v);
00415         CORBA::Object_ptr lhs_v;
00416         this->any_ >>= CORBA::Any::to_object (lhs_v);
00417         return lhs_v->_is_equivalent (lhs_v);
00418       }
00419     case CORBA::tk_string:
00420       {
00421         CORBA::TypeCode_var unaliased_tc =
00422           TAO_DynAnyFactory::strip_alias (this->type_.in ());
00423 
00424         CORBA::ULong bound =
00425           unaliased_tc->length ();
00426 
00427         const char *rhs_v, *lhs_v;
00428         CORBA::Boolean rstatus, lstatus;
00429 
00430         if (bound == 0)
00431           {
00432             rstatus = rhs_n->any_ >>= rhs_v;
00433             lstatus = this->any_ >>= lhs_v;
00434 
00435             if ((rstatus && lstatus) == 0)
00436               {
00437                 return 0;
00438               }
00439           }
00440         else
00441           {
00442             rstatus = rhs_n->any_ >>= CORBA::Any::to_string (rhs_v, bound);
00443             lstatus = this->any_ >>= CORBA::Any::to_string (lhs_v, bound);
00444 
00445             if ((rstatus && lstatus) == 0)
00446               {
00447                 return 0;
00448               }
00449           }
00450 
00451         return ACE_OS::strcmp (rhs_v, lhs_v) == 0;
00452       }
00453     case CORBA::tk_wstring:
00454       {
00455         CORBA::TypeCode_var unaliased_tc =
00456           TAO_DynAnyFactory::strip_alias (this->type_.in ());
00457 
00458         CORBA::ULong bound =
00459           unaliased_tc->length ();
00460 
00461         const CORBA::WChar *rhs_v, *lhs_v;
00462         CORBA::Boolean rstatus, lstatus;
00463 
00464         if (bound == 0)
00465           {
00466             rstatus = rhs_n->any_ >>= rhs_v;
00467             lstatus = this->any_ >>= lhs_v;
00468 
00469             if ((rstatus && lstatus) == 0)
00470               {
00471                 return 0;
00472               }
00473           }
00474         else
00475           {
00476             rstatus = rhs_n->any_ >>= CORBA::Any::to_wstring (rhs_v,
00477                                                               bound);
00478             lstatus = this->any_ >>= CORBA::Any::to_wstring (lhs_v,
00479                                                              bound);
00480 
00481             if ((rstatus && lstatus) == 0)
00482               {
00483                 return 0;
00484               }
00485           }
00486 
00487         return ACE_OS::wscmp (rhs_v, lhs_v) == 0;
00488       }
00489     default:
00490       break; // Cannot happen...
00491     }
00492 
00493   return 0;
00494 }
00495 
00496 void
00497 TAO_DynAny_i::destroy (void)
00498 {
00499   if (this->destroyed_)
00500     {
00501       throw ::CORBA::OBJECT_NOT_EXIST ();
00502     }
00503 
00504   if (!this->ref_to_component_ || this->container_is_destroying_)
00505     {
00506       this->destroyed_ = 1;
00507     }
00508 }
00509 
00510 
00511 DynamicAny::DynAny_ptr
00512 TAO_DynAny_i::current_component (void)
00513 {
00514   if (this->destroyed_)
00515     {
00516       throw ::CORBA::OBJECT_NOT_EXIST ();
00517     }
00518 
00519   throw DynamicAny::DynAny::TypeMismatch ();
00520 }
00521 
00522 TAO_END_VERSIONED_NAMESPACE_DECL

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