DynAny_i.cpp

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

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