Line data Source code
1 : #include <DCPS/DdsDcps_pch.h> 2 : 3 : #ifndef OPENDDS_SAFETY_PROFILE 4 : 5 : #include "DynamicTypeImpl.h" 6 : 7 : #include "DynamicTypeMemberImpl.h" 8 : 9 : #include <dds/DCPS/debug.h> 10 : 11 : #include <dds/DdsDcpsInfrastructureC.h> 12 : 13 : #include <stdexcept> 14 : 15 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 16 : 17 : namespace OpenDDS { 18 : namespace XTypes { 19 : 20 2273 : DynamicTypeImpl::DynamicTypeImpl() 21 2273 : : preset_type_info_set_(false) 22 2273 : {} 23 : 24 4546 : DynamicTypeImpl::~DynamicTypeImpl() 25 4546 : {} 26 : 27 1933 : void DynamicTypeImpl::set_descriptor(DDS::TypeDescriptor* descriptor) 28 : { 29 : // ValueTypes don't have a duplicate so manually add_ref. 30 1933 : CORBA::add_ref(descriptor); 31 1933 : descriptor_ = descriptor; 32 1933 : } 33 : 34 10585 : DDS::ReturnCode_t DynamicTypeImpl::get_descriptor(DDS::TypeDescriptor*& descriptor) 35 : { 36 10585 : DDS::TypeDescriptor_var descriptor_v(descriptor); 37 10585 : descriptor = descriptor_; 38 10585 : CORBA::add_ref(descriptor); 39 10585 : return DDS::RETCODE_OK; 40 10585 : } 41 : 42 30 : char* DynamicTypeImpl::get_name() 43 : { 44 30 : CORBA::String_var str = descriptor_->name(); 45 60 : return str._retn(); 46 30 : } 47 : 48 46650 : TypeKind DynamicTypeImpl::get_kind() 49 : { 50 46650 : return descriptor_->kind(); 51 : } 52 : 53 3 : DDS::ReturnCode_t DynamicTypeImpl::get_member_by_name(DDS::DynamicTypeMember_ptr& member, const char* name) 54 : { 55 3 : const DynamicTypeMembersByNameImpl::const_iterator pos = member_by_name_.find(name); 56 3 : if (pos != member_by_name_.end()) { 57 3 : DDS::DynamicTypeMember_var member_v(member); 58 3 : member = DDS::DynamicTypeMember::_duplicate(pos->second); 59 3 : return DDS::RETCODE_OK; 60 3 : } 61 0 : return DDS::RETCODE_ERROR; 62 : } 63 : 64 84 : DDS::ReturnCode_t DynamicTypeImpl::get_all_members_by_name(DDS::DynamicTypeMembersByName_ptr& member) 65 : { 66 84 : DDS::DynamicTypeMembersByName_var member_v(member); 67 84 : member = DDS::DynamicTypeMembersByName::_duplicate(&member_by_name_); 68 84 : return DDS::RETCODE_OK; 69 84 : } 70 : 71 6814 : DDS::ReturnCode_t DynamicTypeImpl::get_member(DDS::DynamicTypeMember_ptr& member, MemberId id) 72 : { 73 6814 : const DynamicTypeMembersByIdImpl::const_iterator pos = member_by_id_.find(id); 74 6814 : if (pos == member_by_id_.end()) { 75 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) { 76 0 : CORBA::String_var name = descriptor_->name(); 77 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicTypeImpl::get_member: " 78 : "type %C doesn't have a member with id %u\n", name.in(), id)); 79 0 : } 80 0 : return DDS::RETCODE_BAD_PARAMETER; 81 : } 82 : 83 6814 : DDS::DynamicTypeMember_var member_v(member); 84 6814 : member = DDS::DynamicTypeMember::_duplicate(pos->second); 85 6814 : return DDS::RETCODE_OK; 86 6814 : } 87 : 88 425 : DDS::ReturnCode_t DynamicTypeImpl::get_all_members(DDS::DynamicTypeMembersById_ptr& member) 89 : { 90 425 : DDS::DynamicTypeMembersById_var member_v(member); 91 425 : member = DDS::DynamicTypeMembersById::_duplicate(&member_by_id_); 92 425 : return DDS::RETCODE_OK; 93 425 : } 94 : 95 47836 : ACE_CDR::ULong DynamicTypeImpl::get_member_count() 96 : { 97 47836 : return ACE_CDR::ULong(member_by_index_.size()); 98 : } 99 : 100 53382 : DDS::ReturnCode_t DynamicTypeImpl::get_member_by_index(DDS::DynamicTypeMember_ptr& member, ACE_CDR::ULong index) 101 : { 102 53382 : if (index >= member_by_index_.size()) { 103 0 : if (DCPS::log_level >= DCPS::LogLevel::Notice) { 104 0 : CORBA::String_var name = descriptor_->name(); 105 0 : ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicTypeImpl::get_member_by_index: " 106 : "type %C doesn't have a member with index %u\n", name.in(), index)); 107 0 : } 108 0 : return DDS::RETCODE_BAD_PARAMETER; 109 : } 110 : 111 53382 : DDS::DynamicTypeMember_var member_v(member); 112 53382 : member = DDS::DynamicTypeMember::_duplicate(member_by_index_[index]); 113 53382 : return DDS::RETCODE_OK; 114 53382 : } 115 : 116 0 : CORBA::ULong DynamicTypeImpl::get_annotation_count() 117 : { 118 : // FUTURE 119 0 : return 0; 120 : } 121 : 122 0 : DDS::ReturnCode_t DynamicTypeImpl::get_annotation(DDS::AnnotationDescriptor*&, CORBA::ULong) 123 : { 124 : // FUTURE 125 0 : return DDS::RETCODE_UNSUPPORTED; 126 : } 127 : 128 0 : CORBA::ULong DynamicTypeImpl::get_verbatim_text_count() 129 : { 130 : // FUTURE 131 0 : return 0; 132 : } 133 : 134 0 : DDS::ReturnCode_t DynamicTypeImpl::get_verbatim_text(DDS::VerbatimTextDescriptor*&, CORBA::ULong) 135 : { 136 : // FUTURE 137 0 : return DDS::RETCODE_UNSUPPORTED; 138 : } 139 : 140 41 : bool DynamicTypeImpl::equals(DDS::DynamicType_ptr other) 141 : { 142 : //7.5.2.8.4 Operation: equals 143 : //Two types shall be considered equal if and only if all of their respective properties, as identified 144 : //in Table 54 above, are equal. 145 : 146 : //In addition to what the spec says to compare, we will be comparing the TypeDescriptors of both 147 : //DynamicTypes. The spec seems to assume this is the case, despite not listing the TypeDescriptor 148 : //as a property in table 54. This is done to allow the recursive comparison required by the changes 149 : //to DynamicTypeMember::equals. 150 41 : DynamicTypePtrPairSeen dt_ptr_pair; 151 82 : return test_equality(this, other, dt_ptr_pair); 152 41 : } 153 : 154 2339 : void DynamicTypeImpl::insert_dynamic_member(DDS::DynamicTypeMember_ptr dtm) 155 : { 156 2339 : DDS::MemberDescriptor_var d; 157 2339 : if (dtm->get_descriptor(d) != DDS::RETCODE_OK) { 158 0 : throw std::runtime_error("Could not get type descriptor of dynamic member"); 159 : } 160 : 161 2339 : member_by_index_.push_back(DDS::DynamicTypeMember::_duplicate(dtm)); 162 : 163 2339 : if (d->id() != MEMBER_ID_INVALID) { 164 2339 : member_by_id_.insert(std::make_pair(d->id(), DDS::DynamicTypeMember::_duplicate(dtm))); 165 : } 166 2339 : member_by_name_.insert(std::make_pair(d->name(), DDS::DynamicTypeMember::_duplicate(dtm))); 167 2339 : } 168 : 169 1791 : void DynamicTypeImpl::clear() 170 : { 171 1791 : member_by_name_.clear(); 172 1791 : member_by_id_.clear(); 173 1791 : member_by_index_.clear(); 174 1791 : descriptor_ = 0; 175 1791 : } 176 : 177 17806 : DDS::DynamicType_var get_base_type(DDS::DynamicType_ptr type) 178 : { 179 17806 : if (!type) { 180 0 : return 0; 181 : } 182 : 183 17806 : DDS::DynamicType_var t = DDS::DynamicType::_duplicate(type); 184 17806 : if (t->get_kind() != TK_ALIAS) { 185 16036 : return t; 186 : } 187 : 188 1770 : DDS::TypeDescriptor_var descriptor; 189 1770 : if (t->get_descriptor(descriptor) != DDS::RETCODE_OK) { 190 0 : return 0; 191 : } 192 : 193 1770 : return get_base_type(descriptor->base_type()); 194 17806 : } 195 : 196 259 : bool test_equality(DDS::DynamicType_ptr lhs, DDS::DynamicType_ptr rhs, DynamicTypePtrPairSeen& dt_ptr_pair) 197 : { 198 259 : if (lhs == rhs) { 199 189 : return true; 200 : } 201 : 202 70 : OPENDDS_ASSERT(lhs); 203 70 : OPENDDS_ASSERT(rhs); 204 : 205 70 : if (lhs == 0 || rhs == 0) { 206 0 : return false; 207 : } 208 : 209 70 : const DynamicTypePtrPair this_pair = std::make_pair(lhs, rhs); 210 70 : DynamicTypePtrPairSeen::const_iterator have_seen = dt_ptr_pair.find(this_pair); 211 70 : if (have_seen == dt_ptr_pair.end()) { 212 42 : dt_ptr_pair.insert(this_pair); 213 : 214 42 : DDS::TypeDescriptor_var lhs_descriptor; 215 42 : DDS::TypeDescriptor_var rhs_descriptor; 216 42 : DDS::DynamicTypeMembersByName_var lhs_members_by_name; 217 42 : DDS::DynamicTypeMembersByName_var rhs_members_by_name; 218 42 : DDS::DynamicTypeMembersById_var lhs_members_by_id; 219 42 : DDS::DynamicTypeMembersById_var rhs_members_by_id; 220 : 221 42 : if (lhs->get_descriptor(lhs_descriptor) != DDS::RETCODE_OK || 222 42 : rhs->get_descriptor(rhs_descriptor) != DDS::RETCODE_OK || 223 42 : lhs->get_all_members_by_name(lhs_members_by_name) != DDS::RETCODE_OK || 224 42 : rhs->get_all_members_by_name(rhs_members_by_name) != DDS::RETCODE_OK || 225 126 : lhs->get_all_members(lhs_members_by_id) != DDS::RETCODE_OK || 226 42 : rhs->get_all_members(rhs_members_by_id) != DDS::RETCODE_OK) { 227 0 : return false; 228 : } 229 : 230 : return 231 42 : test_equality(lhs_descriptor, rhs_descriptor, dt_ptr_pair) && 232 84 : test_equality(dynamic_cast<DynamicTypeMembersByNameImpl*>(lhs_members_by_name.in()), 233 126 : dynamic_cast<DynamicTypeMembersByNameImpl*>(rhs_members_by_name.in()), dt_ptr_pair) && 234 84 : test_equality(dynamic_cast<DynamicTypeMembersByIdImpl*>(lhs_members_by_id.in()), 235 126 : dynamic_cast<DynamicTypeMembersByIdImpl*>(rhs_members_by_id.in()), dt_ptr_pair); 236 42 : } 237 : 238 28 : return true; 239 : } 240 : 241 42 : bool test_equality(DynamicTypeMembersByNameImpl* lhs, DynamicTypeMembersByNameImpl* rhs, DynamicTypePtrPairSeen& dt_ptr_pair) 242 : { 243 42 : if (lhs == rhs) { 244 0 : return true; 245 : } 246 : 247 42 : if (lhs == 0 || rhs == 0) { 248 0 : return false; 249 : } 250 : 251 42 : if (lhs->size() != rhs->size()) { 252 0 : return false; 253 : } 254 : 255 67 : for (DynamicTypeMembersByNameImpl::const_iterator lhs_it = lhs->begin(); lhs_it != lhs->end(); ++lhs_it) { 256 25 : const DynamicTypeMembersByNameImpl::const_iterator rhs_it = rhs->find(lhs_it->first); 257 25 : if (rhs_it == rhs->end()) { 258 0 : return false; 259 : } 260 25 : DDS::MemberDescriptor_var lhs_md; 261 25 : DDS::MemberDescriptor_var rhs_md; 262 50 : if (lhs_it->second->get_descriptor(lhs_md) != DDS::RETCODE_OK || 263 25 : rhs_it->second->get_descriptor(rhs_md) != DDS::RETCODE_OK) { 264 0 : return false; 265 : } 266 25 : if (!test_equality(lhs_md, rhs_md, dt_ptr_pair)) { 267 0 : return false; 268 : } 269 25 : } 270 42 : return true; 271 : } 272 : 273 42 : bool test_equality(DynamicTypeMembersByIdImpl* lhs, DynamicTypeMembersByIdImpl* rhs, DynamicTypePtrPairSeen& dt_ptr_pair) 274 : { 275 42 : if (lhs == rhs) { 276 0 : return true; 277 : } 278 : 279 42 : if (lhs == 0 || rhs == 0) { 280 0 : return false; 281 : } 282 : 283 42 : if (lhs->size() != rhs->size()) { 284 0 : return false; 285 : } 286 : 287 67 : for (DynamicTypeMembersByIdImpl::const_iterator lhs_it = lhs->begin(); lhs_it != lhs->end(); ++lhs_it) { 288 25 : const DynamicTypeMembersByIdImpl::const_iterator rhs_it = rhs->find(lhs_it->first); 289 25 : if (rhs_it == rhs->end()) { 290 0 : return false; 291 : } 292 25 : DDS::MemberDescriptor_var lhs_md; 293 25 : DDS::MemberDescriptor_var rhs_md; 294 50 : if (lhs_it->second->get_descriptor(lhs_md) != DDS::RETCODE_OK || 295 25 : rhs_it->second->get_descriptor(rhs_md) != DDS::RETCODE_OK) { 296 0 : return false; 297 : } 298 25 : if (!test_equality(lhs_md, rhs_md, dt_ptr_pair)) { 299 0 : return false; 300 : } 301 25 : } 302 42 : return true; 303 : } 304 : 305 : } // namespace XTypes 306 : } // namespace OpenDDS 307 : 308 : OPENDDS_END_VERSIONED_NAMESPACE_DECL 309 : 310 : #endif // OPENDDS_SAFETY_PROFILE