00001 // $Id: DynEnum_i.cpp 80298 2007-12-18 07:51:16Z 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 #include "tao/DynamicAny/DynEnum_i.h" 00007 #include "tao/DynamicAny/DynAnyFactory.h" 00008 #include "tao/CDR.h" 00009 00010 #include "ace/OS_NS_string.h" 00011 00012 00013 ACE_RCSID (DynamicAny, 00014 DynEnum_i, 00015 "$Id: DynEnum_i.cpp 80298 2007-12-18 07:51:16Z johnnyw $") 00016 00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00018 00019 TAO_DynEnum_i::TAO_DynEnum_i (void) 00020 { 00021 } 00022 00023 TAO_DynEnum_i::~TAO_DynEnum_i (void) 00024 { 00025 } 00026 00027 void 00028 TAO_DynEnum_i::init_common (void) 00029 { 00030 this->ref_to_component_ = false; 00031 this->container_is_destroying_ = false; 00032 this->has_components_ = false; 00033 this->destroyed_ = false; 00034 this->current_position_ = -1; 00035 this->component_count_ = 0; 00036 } 00037 00038 void 00039 TAO_DynEnum_i::init (const CORBA::Any &any) 00040 { 00041 CORBA::TypeCode_var tc = any.type (); 00042 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ()); 00043 00044 if (kind != CORBA::tk_enum) 00045 { 00046 throw DynamicAny::DynAnyFactory::InconsistentTypeCode (); 00047 } 00048 00049 this->type_ = tc; 00050 00051 TAO::Any_Impl *impl = any.impl (); 00052 00053 if (impl->encoded ()) 00054 { 00055 TAO::Unknown_IDL_Type * const unk = 00056 dynamic_cast<TAO::Unknown_IDL_Type *> (impl); 00057 00058 if (!unk) 00059 throw CORBA::INTERNAL (); 00060 00061 // We don't want unk's rd_ptr to move, in case we are shared by 00062 // another Any, so we use this to copy the state, not the buffer. 00063 TAO_InputCDR for_reading (unk->_tao_get_cdr ()); 00064 for_reading.read_ulong (this->value_); 00065 } 00066 else 00067 { 00068 TAO_OutputCDR out; 00069 impl->marshal_value (out); 00070 TAO_InputCDR in (out); 00071 in.read_ulong (this->value_); 00072 } 00073 00074 this->init_common (); 00075 } 00076 00077 void 00078 TAO_DynEnum_i::init (CORBA::TypeCode_ptr tc) 00079 { 00080 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc); 00081 00082 if (kind != CORBA::tk_enum) 00083 { 00084 throw DynamicAny::DynAnyFactory::InconsistentTypeCode (); 00085 } 00086 00087 this->type_ = CORBA::TypeCode::_duplicate (tc); 00088 00089 this->value_ = 0; 00090 00091 this->init_common (); 00092 } 00093 00094 // **************************************************************** 00095 00096 TAO_DynEnum_i * 00097 TAO_DynEnum_i::_narrow (CORBA::Object_ptr _tao_objref) 00098 { 00099 if (CORBA::is_nil (_tao_objref)) 00100 { 00101 return 0; 00102 } 00103 00104 return dynamic_cast<TAO_DynEnum_i *> (_tao_objref); 00105 } 00106 00107 // **************************************************************** 00108 00109 char * 00110 TAO_DynEnum_i::get_as_string (void) 00111 { 00112 CORBA::TypeCode_var ct = TAO_DynAnyFactory::strip_alias (this->type_.in ()); 00113 00114 const char *retval = ct.in ()->member_name (this->value_); 00115 00116 return CORBA::string_dup (retval); 00117 } 00118 00119 void 00120 TAO_DynEnum_i::set_as_string (const char *value_as_string) 00121 { 00122 CORBA::TypeCode_var ct = TAO_DynAnyFactory::strip_alias (this->type_.in ()); 00123 00124 CORBA::ULong count = ct.in ()->member_count (); 00125 00126 CORBA::ULong i; 00127 const char *temp = 0; 00128 00129 for (i = 0; i < count; ++i) 00130 { 00131 temp = ct.in ()->member_name (i); 00132 00133 if (!ACE_OS::strcmp (value_as_string, temp)) 00134 { 00135 break; 00136 } 00137 } 00138 00139 if (i < count) 00140 { 00141 this->value_ = i; 00142 } 00143 else 00144 { 00145 throw DynamicAny::DynAny::InvalidValue (); 00146 } 00147 } 00148 00149 CORBA::ULong 00150 TAO_DynEnum_i::get_as_ulong (void) 00151 { 00152 return this->value_; 00153 } 00154 00155 void 00156 TAO_DynEnum_i::set_as_ulong (CORBA::ULong value_as_ulong) 00157 { 00158 CORBA::TypeCode_var ct = TAO_DynAnyFactory::strip_alias (this->type_.in ()); 00159 CORBA::ULong const max = ct.in ()->member_count (); 00160 00161 if (value_as_ulong < max) 00162 { 00163 this->value_ = value_as_ulong; 00164 } 00165 else 00166 { 00167 throw DynamicAny::DynAny::InvalidValue (); 00168 } 00169 } 00170 00171 // **************************************************************** 00172 00173 void 00174 TAO_DynEnum_i::from_any (const CORBA::Any& any) 00175 { 00176 CORBA::TypeCode_var tc = any.type (); 00177 CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ()); 00178 00179 if (kind == CORBA::tk_enum) 00180 { 00181 // Get the CDR stream of the Any, if there isn't one, make one. 00182 TAO::Any_Impl *impl = any.impl (); 00183 00184 if (impl->encoded ()) 00185 { 00186 TAO::Unknown_IDL_Type * const unk = 00187 dynamic_cast<TAO::Unknown_IDL_Type *> (impl); 00188 00189 if (!unk) 00190 throw CORBA::INTERNAL (); 00191 00192 // We don't want unk's rd_ptr to move, in case we are shared by 00193 // another Any, so we use this to copy the state, not the buffer. 00194 TAO_InputCDR for_reading (unk->_tao_get_cdr ()); 00195 for_reading.read_ulong (this->value_); 00196 } 00197 else 00198 { 00199 TAO_OutputCDR out; 00200 impl->marshal_value (out); 00201 TAO_InputCDR in (out); 00202 in.read_ulong (this->value_); 00203 } 00204 } 00205 else 00206 { 00207 throw DynamicAny::DynAny::TypeMismatch (); 00208 } 00209 } 00210 00211 CORBA::Any_ptr 00212 TAO_DynEnum_i::to_any (void) 00213 { 00214 TAO_OutputCDR out_cdr; 00215 00216 out_cdr.write_ulong (this->value_); 00217 00218 CORBA::Any *retval; 00219 ACE_NEW_THROW_EX (retval, 00220 CORBA::Any, 00221 CORBA::NO_MEMORY ()); 00222 00223 TAO_InputCDR in_cdr (out_cdr); 00224 TAO::Unknown_IDL_Type *unk = 0; 00225 ACE_NEW_THROW_EX (unk, 00226 TAO::Unknown_IDL_Type (this->type_.in (), 00227 in_cdr), 00228 CORBA::NO_MEMORY ()); 00229 00230 retval->replace (unk); 00231 return retval; 00232 } 00233 00234 CORBA::Boolean 00235 TAO_DynEnum_i::equal (DynamicAny::DynAny_ptr rhs) 00236 { 00237 CORBA::TypeCode_var tc = rhs->type (); 00238 00239 CORBA::Boolean equivalent = tc->equivalent (this->type_.in ()); 00240 00241 if (!equivalent) 00242 { 00243 return false; 00244 } 00245 00246 CORBA::Any_var any = rhs->to_any (); 00247 00248 TAO::Any_Impl *impl = any->impl (); 00249 CORBA::ULong value; 00250 00251 if (impl->encoded ()) 00252 { 00253 TAO::Unknown_IDL_Type * const unk = 00254 dynamic_cast<TAO::Unknown_IDL_Type *> (impl); 00255 00256 if (!unk) 00257 throw CORBA::INTERNAL (); 00258 00259 // We don't want unk's rd_ptr to move, in case we are shared by 00260 // another Any, so we use this to copy the state, not the buffer. 00261 TAO_InputCDR for_reading (unk->_tao_get_cdr ()); 00262 for_reading.read_ulong (value); 00263 } 00264 else 00265 { 00266 TAO_OutputCDR out; 00267 impl->marshal_value (out); 00268 TAO_InputCDR in (out); 00269 in.read_ulong (value); 00270 } 00271 00272 return value == this->value_; 00273 } 00274 00275 void 00276 TAO_DynEnum_i::destroy (void) 00277 { 00278 if (this->destroyed_) 00279 { 00280 throw ::CORBA::OBJECT_NOT_EXIST (); 00281 } 00282 00283 if (!this->ref_to_component_ || this->container_is_destroying_) 00284 { 00285 this->destroyed_ = true; 00286 } 00287 } 00288 00289 DynamicAny::DynAny_ptr 00290 TAO_DynEnum_i::current_component (void) 00291 { 00292 if (this->destroyed_) 00293 { 00294 throw ::CORBA::OBJECT_NOT_EXIST (); 00295 } 00296 00297 throw DynamicAny::DynAny::TypeMismatch (); 00298 } 00299 00300 TAO_END_VERSIONED_NAMESPACE_DECL