00001 // -*- C++ -*- 00002 // $Id: TAO_ETCL_Constraint.cpp 82804 2008-09-22 14:58:36Z jtc $ 00003 00004 #include "ace/ETCL/ETCL_Constraint_Visitor.h" 00005 00006 #include "tao/AnyTypeCode/AnyTypeCode_methods.h" 00007 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h" 00008 #include "tao/AnyTypeCode/TypeCode.h" 00009 #include "tao/AnyTypeCode/Any.h" 00010 #include "tao/CDR.h" 00011 #include "tao/SystemException.h" 00012 00013 #include "tao/ETCL/TAO_ETCL_Constraint.h" 00014 00015 #if ! defined (__ACE_INLINE__) 00016 #include "tao/ETCL/TAO_ETCL_Constraint.inl" 00017 #endif /* __ACE_INLINE__ */ 00018 00019 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00020 00021 TAO_ETCL_Literal_Constraint::TAO_ETCL_Literal_Constraint ( 00022 const TAO_ETCL_Literal_Constraint & lit) 00023 : ETCL_Literal_Constraint (), 00024 any_ (0) 00025 { 00026 this->copy (lit); 00027 } 00028 00029 TAO_ETCL_Literal_Constraint::TAO_ETCL_Literal_Constraint (CORBA::Any * any) 00030 : any_ (0) 00031 { 00032 CORBA::Any& any_ref = *any; 00033 CORBA::TypeCode_var type = any_ref.type (); 00034 CORBA::TCKind corba_type = CORBA::tk_null; 00035 00036 try 00037 { 00038 corba_type = type->kind (); 00039 } 00040 catch (const CORBA::Exception&) 00041 { 00042 // @@ Seth: Don't know what else to do. Make sure we can tell 00043 // when this constructor fails. 00044 return; 00045 } 00046 00047 this->type_ = 00048 TAO_ETCL_Literal_Constraint::comparable_type (type.in ()); 00049 00050 switch (this->type_) 00051 { 00052 case ACE_ETCL_SIGNED: 00053 this->op_.integer_ = 0; 00054 00055 if (corba_type == CORBA::tk_short) 00056 { 00057 CORBA::Short sh; 00058 any_ref >>= sh; 00059 this->op_.integer_ = (CORBA::Long) sh; 00060 } 00061 else 00062 { 00063 any_ref >>= this->op_.integer_; 00064 } 00065 00066 break; 00067 case ACE_ETCL_UNSIGNED: 00068 this->op_.uinteger_ = 0; 00069 00070 if (corba_type == CORBA::tk_ushort) 00071 { 00072 CORBA::UShort sh; 00073 any_ref >>= sh; 00074 this->op_.uinteger_ = (CORBA::ULong) sh; 00075 } 00076 else if (corba_type == CORBA::tk_enum) 00077 { 00078 TAO::Any_Impl *impl = any->impl (); 00079 00080 if (impl->encoded ()) 00081 { 00082 TAO::Unknown_IDL_Type *unk = 00083 dynamic_cast<TAO::Unknown_IDL_Type *> (impl); 00084 00085 if (unk == 0) 00086 { 00087 throw CORBA::INTERNAL (); 00088 } 00089 00090 // We don't want unk's rd_ptr to move, in case we are shared by 00091 // another Any, so we use this to copy the state, not the buffer. 00092 TAO_InputCDR for_reading (unk->_tao_get_cdr ()); 00093 for_reading.read_ulong (this->op_.uinteger_); 00094 } 00095 else 00096 { 00097 TAO_OutputCDR out; 00098 impl->marshal_value (out); 00099 TAO_InputCDR in (out); 00100 in.read_ulong (this->op_.uinteger_); 00101 } 00102 } 00103 else 00104 { 00105 any_ref >>= this->op_.uinteger_; 00106 } 00107 00108 break; 00109 case ACE_ETCL_DOUBLE: 00110 if (corba_type == CORBA::tk_float) 00111 { 00112 CORBA::Float fl; 00113 (*any) >>= fl; 00114 this->op_.double_ = (CORBA::Double) fl; 00115 } 00116 else 00117 { 00118 (*any) >>= this->op_.double_; 00119 } 00120 00121 break; 00122 case ACE_ETCL_BOOLEAN: 00123 { 00124 CORBA::Any::to_boolean tmp (this->op_.bool_); 00125 (*any) >>= tmp; 00126 } 00127 break; 00128 case ACE_ETCL_STRING: 00129 { 00130 const char* s; 00131 any_ref >>= s; 00132 this->op_.str_ = CORBA::string_dup (s); 00133 } 00134 break; 00135 case ACE_ETCL_COMPONENT: 00136 this->any_ = any->impl (); 00137 this->any_->_add_ref (); 00138 break; 00139 } 00140 } 00141 00142 TAO_ETCL_Literal_Constraint::~TAO_ETCL_Literal_Constraint (void) 00143 { 00144 if (this->any_ != 0) 00145 { 00146 this->any_->_remove_ref (); 00147 } 00148 } 00149 00150 void 00151 TAO_ETCL_Literal_Constraint::operator= (const TAO_ETCL_Literal_Constraint& co) 00152 { 00153 this->copy (co); 00154 } 00155 00156 TAO_ETCL_Literal_Constraint::operator CORBA::Boolean (void) const 00157 { 00158 return this->ETCL_Literal_Constraint::operator ACE_CDR::Boolean (); 00159 } 00160 00161 TAO_ETCL_Literal_Constraint::operator CORBA::ULong (void) const 00162 { 00163 switch (this->type_) 00164 { 00165 case ACE_ETCL_COMPONENT: 00166 { 00167 CORBA::ULong retval = 0; 00168 CORBA::Any tmp; 00169 tmp.replace (this->any_); 00170 this->any_->_add_ref (); 00171 tmp >>= retval; 00172 return retval; 00173 } 00174 default: 00175 return this->ETCL_Literal_Constraint::operator ACE_CDR::ULong (); 00176 } 00177 } 00178 00179 TAO_ETCL_Literal_Constraint::operator CORBA::Long (void) const 00180 { 00181 switch (this->type_) 00182 { 00183 case ACE_ETCL_COMPONENT: 00184 { 00185 CORBA::Long retval = 0; 00186 CORBA::Any tmp; 00187 tmp.replace (this->any_); 00188 this->any_->_add_ref (); 00189 tmp >>= retval; 00190 return retval; 00191 } 00192 default: 00193 return this->ETCL_Literal_Constraint::operator ACE_CDR::Long (); 00194 } 00195 } 00196 00197 TAO_ETCL_Literal_Constraint::operator CORBA::Double (void) const 00198 { 00199 switch (this->type_) 00200 { 00201 case ACE_ETCL_COMPONENT: 00202 { 00203 CORBA::Double retval = 0.0; 00204 CORBA::Any tmp; 00205 tmp.replace (this->any_); 00206 this->any_->_add_ref (); 00207 tmp >>= retval; 00208 return retval; 00209 } 00210 default: 00211 return this->ETCL_Literal_Constraint::operator ACE_CDR::Double (); 00212 } 00213 } 00214 00215 TAO_ETCL_Literal_Constraint::operator const char* (void) const 00216 { 00217 switch (this->type_) 00218 { 00219 case ACE_ETCL_COMPONENT: 00220 { 00221 const char *retval = 0; 00222 CORBA::Any tmp; 00223 tmp.replace (this->any_); 00224 this->any_->_add_ref (); 00225 tmp >>= retval; 00226 return retval; 00227 } 00228 default: 00229 return this->ETCL_Literal_Constraint::operator const char * (); 00230 } 00231 } 00232 00233 TAO_ETCL_Literal_Constraint::operator TAO::Any_Impl* (void) const 00234 { 00235 return (this->type_ == ACE_ETCL_COMPONENT) ? this->any_ : 0; 00236 } 00237 00238 Literal_Type 00239 TAO_ETCL_Literal_Constraint::comparable_type (CORBA::TypeCode_ptr type) 00240 { 00241 // Convert a CORBA::TCKind into a Literal_Type 00242 Literal_Type return_value = ACE_ETCL_UNKNOWN; 00243 CORBA::TCKind kind = CORBA::tk_null; 00244 00245 try 00246 { 00247 kind = type->kind (); 00248 CORBA::TypeCode_var tmp = CORBA::TypeCode::_duplicate (type); 00249 00250 while (kind == CORBA::tk_alias) 00251 { 00252 tmp = tmp->content_type (); 00253 00254 kind = tmp->kind (); 00255 } 00256 } 00257 catch (const CORBA::Exception&) 00258 { 00259 return return_value; 00260 } 00261 // Since this is a top level try block, no need to check again. 00262 00263 switch (kind) 00264 { 00265 case CORBA::tk_ushort: 00266 case CORBA::tk_ulong: 00267 case CORBA::tk_enum: 00268 case CORBA::tk_ulonglong: 00269 return_value = ACE_ETCL_UNSIGNED; 00270 break; 00271 case CORBA::tk_short: 00272 case CORBA::tk_long: 00273 case CORBA::tk_longlong: 00274 return_value = ACE_ETCL_SIGNED; 00275 break; 00276 case CORBA::tk_boolean: 00277 return_value = ACE_ETCL_BOOLEAN; 00278 break; 00279 case CORBA::tk_float: 00280 case CORBA::tk_double: 00281 return_value = ACE_ETCL_DOUBLE; 00282 break; 00283 case CORBA::tk_string: 00284 return_value = ACE_ETCL_STRING; 00285 break; 00286 default: 00287 return_value = ACE_ETCL_COMPONENT; 00288 break; 00289 } 00290 00291 return return_value; 00292 } 00293 00294 TAO_ETCL_Literal_Constraint 00295 TAO_ETCL_Literal_Constraint::operator+ (const TAO_ETCL_Literal_Constraint & rhs) 00296 { 00297 Literal_Type widest_type = this->widest_type (rhs); 00298 00299 switch (widest_type) 00300 { 00301 case ACE_ETCL_DOUBLE: 00302 { 00303 CORBA::Double result = (CORBA::Double) *this + (CORBA::Double) rhs; 00304 return TAO_ETCL_Literal_Constraint ((CORBA::Double) result); 00305 } 00306 case ACE_ETCL_INTEGER: 00307 case ACE_ETCL_SIGNED: 00308 { 00309 CORBA::Long result = (CORBA::Long) *this + (CORBA::Long) rhs; 00310 return TAO_ETCL_Literal_Constraint ((CORBA::Long) result); 00311 } 00312 case ACE_ETCL_UNSIGNED: 00313 { 00314 CORBA::ULong result = (CORBA::ULong) *this + (CORBA::ULong) rhs; 00315 return TAO_ETCL_Literal_Constraint ((CORBA::ULong) result); 00316 } 00317 default: 00318 return TAO_ETCL_Literal_Constraint ((CORBA::Long) 0); 00319 } 00320 } 00321 00322 TAO_ETCL_Literal_Constraint 00323 TAO_ETCL_Literal_Constraint::operator- (const TAO_ETCL_Literal_Constraint & rhs) 00324 { 00325 Literal_Type widest_type = this->widest_type (rhs); 00326 00327 switch (widest_type) 00328 { 00329 case ACE_ETCL_DOUBLE: 00330 { 00331 CORBA::Double result = (CORBA::Double) *this - (CORBA::Double) rhs; 00332 return TAO_ETCL_Literal_Constraint ((CORBA::Double) result); 00333 } 00334 case ACE_ETCL_INTEGER: 00335 case ACE_ETCL_SIGNED: 00336 { 00337 CORBA::Long result = (CORBA::Long) *this - (CORBA::Long) rhs; 00338 return TAO_ETCL_Literal_Constraint ((CORBA::Long) result); 00339 } 00340 case ACE_ETCL_UNSIGNED: 00341 { 00342 CORBA::ULong result = (CORBA::ULong) *this - (CORBA::ULong) rhs; 00343 return TAO_ETCL_Literal_Constraint ((CORBA::ULong) result); 00344 } 00345 default: 00346 return TAO_ETCL_Literal_Constraint ((CORBA::Long) 0); 00347 } 00348 } 00349 00350 TAO_ETCL_Literal_Constraint 00351 TAO_ETCL_Literal_Constraint::operator* (const TAO_ETCL_Literal_Constraint & rhs) 00352 { 00353 Literal_Type widest_type = this->widest_type (rhs); 00354 00355 switch (widest_type) 00356 { 00357 case ACE_ETCL_DOUBLE: 00358 { 00359 CORBA::Double result = (CORBA::Double) *this * (CORBA::Double) rhs; 00360 return TAO_ETCL_Literal_Constraint ((CORBA::Double) result); 00361 } 00362 case ACE_ETCL_INTEGER: 00363 case ACE_ETCL_SIGNED: 00364 { 00365 CORBA::Long result = (CORBA::Long) *this * (CORBA::Long) rhs; 00366 return TAO_ETCL_Literal_Constraint ((CORBA::Long) result); 00367 } 00368 case ACE_ETCL_UNSIGNED: 00369 { 00370 CORBA::ULong result = (CORBA::ULong) *this * (CORBA::ULong) rhs; 00371 return TAO_ETCL_Literal_Constraint ((CORBA::ULong) result); 00372 } 00373 default: 00374 return TAO_ETCL_Literal_Constraint ((CORBA::Long) 0); 00375 } 00376 } 00377 00378 TAO_ETCL_Literal_Constraint 00379 TAO_ETCL_Literal_Constraint::operator/ (const TAO_ETCL_Literal_Constraint & rhs) 00380 { 00381 Literal_Type widest_type = this->widest_type (rhs); 00382 00383 switch (widest_type) 00384 { 00385 case ACE_ETCL_DOUBLE: 00386 { 00387 if ((ACE_CDR::Double) rhs == 0.0) 00388 return TAO_ETCL_Literal_Constraint ((ACE_CDR::Double) 0.0); 00389 00390 CORBA::Double result = (CORBA::Double) *this / (CORBA::Double) rhs; 00391 return TAO_ETCL_Literal_Constraint ((CORBA::Double) result); 00392 } 00393 case ACE_ETCL_INTEGER: 00394 case ACE_ETCL_SIGNED: 00395 { 00396 if ((ACE_CDR::Long) rhs == 0) 00397 return TAO_ETCL_Literal_Constraint ((ACE_CDR::Long) 0); 00398 00399 CORBA::Long result = (CORBA::Long) *this / (CORBA::Long) rhs; 00400 return TAO_ETCL_Literal_Constraint ((CORBA::Long) result); 00401 } 00402 case ACE_ETCL_UNSIGNED: 00403 { 00404 if ((ACE_CDR::ULong) rhs == 0) 00405 return TAO_ETCL_Literal_Constraint ((ACE_CDR::ULong) 0); 00406 00407 CORBA::ULong result = (CORBA::ULong) *this / (CORBA::ULong) rhs; 00408 return TAO_ETCL_Literal_Constraint ((CORBA::ULong) result); 00409 } 00410 default: 00411 return TAO_ETCL_Literal_Constraint ((CORBA::Long) 0); 00412 } 00413 } 00414 00415 TAO_ETCL_Literal_Constraint 00416 TAO_ETCL_Literal_Constraint::operator- (void) 00417 { 00418 switch (this->type_) 00419 { 00420 case ACE_ETCL_DOUBLE: 00421 return TAO_ETCL_Literal_Constraint (- this->op_.double_); 00422 case ACE_ETCL_INTEGER: 00423 case ACE_ETCL_SIGNED: 00424 return TAO_ETCL_Literal_Constraint (- this->op_.integer_); 00425 case ACE_ETCL_UNSIGNED: 00426 return TAO_ETCL_Literal_Constraint (- (CORBA::Long) this->op_.uinteger_); 00427 default: 00428 return TAO_ETCL_Literal_Constraint ((CORBA::Long) 0); 00429 } 00430 } 00431 00432 Literal_Type 00433 TAO_ETCL_Literal_Constraint::widest_type ( 00434 const ETCL_Literal_Constraint & rhs) 00435 { 00436 Literal_Type rhs_type = rhs.expr_type (); 00437 Literal_Type return_value = rhs_type; 00438 00439 if (rhs_type == ACE_ETCL_COMPONENT) 00440 { 00441 const TAO_ETCL_Literal_Constraint& actual = 00442 dynamic_cast<const TAO_ETCL_Literal_Constraint&> (rhs); 00443 CORBA::TypeCode_var tc = actual.any_->type (); 00444 rhs_type = TAO_ETCL_Literal_Constraint::comparable_type (tc.in ()); 00445 return return_value; 00446 } 00447 00448 return this->ETCL_Literal_Constraint::widest_type (rhs); 00449 } 00450 00451 void 00452 TAO_ETCL_Literal_Constraint::copy (const TAO_ETCL_Literal_Constraint &lit) 00453 { 00454 if (this->type_ == ACE_ETCL_COMPONENT && this->any_ != 0) 00455 { 00456 this->any_->_remove_ref (); 00457 this->any_ = 0; 00458 } 00459 00460 switch (lit.type_) 00461 { 00462 case ACE_ETCL_COMPONENT: 00463 this->type_ = ACE_ETCL_COMPONENT; 00464 this->any_ = lit.any_; 00465 this->any_->_add_ref (); 00466 break; 00467 default: 00468 this->ETCL_Literal_Constraint::copy (lit); 00469 break; 00470 } 00471 } 00472 00473 TAO_END_VERSIONED_NAMESPACE_DECL