DynAny_i.cpp

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

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