OpenDDS  Snapshot(2023/04/28-20:55)
DynamicTypeImpl.cpp
Go to the documentation of this file.
1 #include <DCPS/DdsDcps_pch.h>
2 
3 #ifndef OPENDDS_SAFETY_PROFILE
4 
5 #include "DynamicTypeImpl.h"
6 
8 
9 #include <dds/DCPS/debug.h>
10 
11 #include <dds/DdsDcpsInfrastructureC.h>
12 
13 #include <stdexcept>
14 
16 
17 namespace OpenDDS {
18 namespace XTypes {
19 
21  : preset_type_info_set_(false)
22 {}
23 
25 {}
26 
28 {
29  // ValueTypes don't have a duplicate so manually add_ref.
30  CORBA::add_ref(descriptor);
31  descriptor_ = descriptor;
32 }
33 
35 {
36  DDS::TypeDescriptor_var descriptor_v(descriptor);
37  descriptor = descriptor_;
38  CORBA::add_ref(descriptor);
39  return DDS::RETCODE_OK;
40 }
41 
43 {
44  CORBA::String_var str = descriptor_->name();
45  return str._retn();
46 }
47 
49 {
50  return descriptor_->kind();
51 }
52 
53 DDS::ReturnCode_t DynamicTypeImpl::get_member_by_name(DDS::DynamicTypeMember_ptr& member, const char* name)
54 {
56  if (pos != member_by_name_.end()) {
57  DDS::DynamicTypeMember_var member_v(member);
58  member = DDS::DynamicTypeMember::_duplicate(pos->second);
59  return DDS::RETCODE_OK;
60  }
61  return DDS::RETCODE_ERROR;
62 }
63 
64 DDS::ReturnCode_t DynamicTypeImpl::get_all_members_by_name(DDS::DynamicTypeMembersByName_ptr& member)
65 {
66  DDS::DynamicTypeMembersByName_var member_v(member);
67  member = DDS::DynamicTypeMembersByName::_duplicate(&member_by_name_);
68  return DDS::RETCODE_OK;
69 }
70 
71 DDS::ReturnCode_t DynamicTypeImpl::get_member(DDS::DynamicTypeMember_ptr& member, MemberId id)
72 {
74  if (pos == member_by_id_.end()) {
77  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  }
81  }
82 
83  DDS::DynamicTypeMember_var member_v(member);
84  member = DDS::DynamicTypeMember::_duplicate(pos->second);
85  return DDS::RETCODE_OK;
86 }
87 
88 DDS::ReturnCode_t DynamicTypeImpl::get_all_members(DDS::DynamicTypeMembersById_ptr& member)
89 {
90  DDS::DynamicTypeMembersById_var member_v(member);
91  member = DDS::DynamicTypeMembersById::_duplicate(&member_by_id_);
92  return DDS::RETCODE_OK;
93 }
94 
96 {
97  return ACE_CDR::ULong(member_by_index_.size());
98 }
99 
101 {
102  if (index >= member_by_index_.size()) {
105  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  }
109  }
110 
111  DDS::DynamicTypeMember_var member_v(member);
112  member = DDS::DynamicTypeMember::_duplicate(member_by_index_[index]);
113  return DDS::RETCODE_OK;
114 }
115 
117 {
118  // FUTURE
119  return 0;
120 }
121 
123 {
124  // FUTURE
126 }
127 
129 {
130  // FUTURE
131  return 0;
132 }
133 
135 {
136  // FUTURE
138 }
139 
140 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  DynamicTypePtrPairSeen dt_ptr_pair;
151  return test_equality(this, other, dt_ptr_pair);
152 }
153 
154 void DynamicTypeImpl::insert_dynamic_member(DDS::DynamicTypeMember_ptr dtm)
155 {
156  DDS::MemberDescriptor_var d;
157  if (dtm->get_descriptor(d) != DDS::RETCODE_OK) {
158  throw std::runtime_error("Could not get type descriptor of dynamic member");
159  }
160 
161  member_by_index_.push_back(DDS::DynamicTypeMember::_duplicate(dtm));
162 
163  if (d->id() != MEMBER_ID_INVALID) {
164  member_by_id_.insert(std::make_pair(d->id(), DDS::DynamicTypeMember::_duplicate(dtm)));
165  }
166  member_by_name_.insert(std::make_pair(d->name(), DDS::DynamicTypeMember::_duplicate(dtm)));
167 }
168 
170 {
173  member_by_index_.clear();
174  descriptor_ = 0;
175 }
176 
177 DDS::DynamicType_var get_base_type(DDS::DynamicType_ptr type)
178 {
179  if (!type) {
180  return 0;
181  }
182 
183  DDS::DynamicType_var t = DDS::DynamicType::_duplicate(type);
184  if (t->get_kind() != TK_ALIAS) {
185  return t;
186  }
187 
188  DDS::TypeDescriptor_var descriptor;
189  if (t->get_descriptor(descriptor) != DDS::RETCODE_OK) {
190  return 0;
191  }
192 
193  return get_base_type(descriptor->base_type());
194 }
195 
196 bool test_equality(DDS::DynamicType_ptr lhs, DDS::DynamicType_ptr rhs, DynamicTypePtrPairSeen& dt_ptr_pair)
197 {
198  if (lhs == rhs) {
199  return true;
200  }
201 
202  OPENDDS_ASSERT(lhs);
203  OPENDDS_ASSERT(rhs);
204 
205  if (lhs == 0 || rhs == 0) {
206  return false;
207  }
208 
209  const DynamicTypePtrPair this_pair = std::make_pair(lhs, rhs);
210  DynamicTypePtrPairSeen::const_iterator have_seen = dt_ptr_pair.find(this_pair);
211  if (have_seen == dt_ptr_pair.end()) {
212  dt_ptr_pair.insert(this_pair);
213 
214  DDS::TypeDescriptor_var lhs_descriptor;
215  DDS::TypeDescriptor_var rhs_descriptor;
216  DDS::DynamicTypeMembersByName_var lhs_members_by_name;
217  DDS::DynamicTypeMembersByName_var rhs_members_by_name;
218  DDS::DynamicTypeMembersById_var lhs_members_by_id;
219  DDS::DynamicTypeMembersById_var rhs_members_by_id;
220 
221  if (lhs->get_descriptor(lhs_descriptor) != DDS::RETCODE_OK ||
222  rhs->get_descriptor(rhs_descriptor) != DDS::RETCODE_OK ||
223  lhs->get_all_members_by_name(lhs_members_by_name) != DDS::RETCODE_OK ||
224  rhs->get_all_members_by_name(rhs_members_by_name) != DDS::RETCODE_OK ||
225  lhs->get_all_members(lhs_members_by_id) != DDS::RETCODE_OK ||
226  rhs->get_all_members(rhs_members_by_id) != DDS::RETCODE_OK) {
227  return false;
228  }
229 
230  return
231  test_equality(lhs_descriptor, rhs_descriptor, dt_ptr_pair) &&
232  test_equality(dynamic_cast<DynamicTypeMembersByNameImpl*>(lhs_members_by_name.in()),
233  dynamic_cast<DynamicTypeMembersByNameImpl*>(rhs_members_by_name.in()), dt_ptr_pair) &&
234  test_equality(dynamic_cast<DynamicTypeMembersByIdImpl*>(lhs_members_by_id.in()),
235  dynamic_cast<DynamicTypeMembersByIdImpl*>(rhs_members_by_id.in()), dt_ptr_pair);
236  }
237 
238  return true;
239 }
240 
241 bool test_equality(DynamicTypeMembersByNameImpl* lhs, DynamicTypeMembersByNameImpl* rhs, DynamicTypePtrPairSeen& dt_ptr_pair)
242 {
243  if (lhs == rhs) {
244  return true;
245  }
246 
247  if (lhs == 0 || rhs == 0) {
248  return false;
249  }
250 
251  if (lhs->size() != rhs->size()) {
252  return false;
253  }
254 
255  for (DynamicTypeMembersByNameImpl::const_iterator lhs_it = lhs->begin(); lhs_it != lhs->end(); ++lhs_it) {
256  const DynamicTypeMembersByNameImpl::const_iterator rhs_it = rhs->find(lhs_it->first);
257  if (rhs_it == rhs->end()) {
258  return false;
259  }
260  DDS::MemberDescriptor_var lhs_md;
261  DDS::MemberDescriptor_var rhs_md;
262  if (lhs_it->second->get_descriptor(lhs_md) != DDS::RETCODE_OK ||
263  rhs_it->second->get_descriptor(rhs_md) != DDS::RETCODE_OK) {
264  return false;
265  }
266  if (!test_equality(lhs_md, rhs_md, dt_ptr_pair)) {
267  return false;
268  }
269  }
270  return true;
271 }
272 
273 bool test_equality(DynamicTypeMembersByIdImpl* lhs, DynamicTypeMembersByIdImpl* rhs, DynamicTypePtrPairSeen& dt_ptr_pair)
274 {
275  if (lhs == rhs) {
276  return true;
277  }
278 
279  if (lhs == 0 || rhs == 0) {
280  return false;
281  }
282 
283  if (lhs->size() != rhs->size()) {
284  return false;
285  }
286 
287  for (DynamicTypeMembersByIdImpl::const_iterator lhs_it = lhs->begin(); lhs_it != lhs->end(); ++lhs_it) {
288  const DynamicTypeMembersByIdImpl::const_iterator rhs_it = rhs->find(lhs_it->first);
289  if (rhs_it == rhs->end()) {
290  return false;
291  }
292  DDS::MemberDescriptor_var lhs_md;
293  DDS::MemberDescriptor_var rhs_md;
294  if (lhs_it->second->get_descriptor(lhs_md) != DDS::RETCODE_OK ||
295  rhs_it->second->get_descriptor(rhs_md) != DDS::RETCODE_OK) {
296  return false;
297  }
298  if (!test_equality(lhs_md, rhs_md, dt_ptr_pair)) {
299  return false;
300  }
301  }
302  return true;
303 }
304 
305 } // namespace XTypes
306 } // namespace OpenDDS
307 
309 
310 #endif // OPENDDS_SAFETY_PROFILE
#define ACE_ERROR(X)
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
bool equals(DDS::DynamicType_ptr other)
DDS::ReturnCode_t get_descriptor(DDS::TypeDescriptor *&descriptor)
DynamicTypeMembersByNameImpl member_by_name_
DDS::DynamicType_var get_base_type(DDS::DynamicType_ptr type)
DDS::ReturnCode_t get_annotation(DDS::AnnotationDescriptor *&descriptor, CORBA::ULong idx)
DDS::ReturnCode_t get_verbatim_text(DDS::VerbatimTextDescriptor *&descriptor, CORBA::ULong idx)
DynamicTypeMembersByIdImpl member_by_id_
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:72
DDS::TypeDescriptor_var descriptor_
const_iterator find(const OpenDDS::DCPS::String &key) const
DDS::ReturnCode_t get_all_members(DDS::DynamicTypeMembersById_ptr &member)
void insert(const MapType::value_type &value)
void insert_dynamic_member(DDS::DynamicTypeMember_ptr dtm)
void insert(const MapType::value_type &value)
bool test_equality(DDS::DynamicType_ptr lhs, DDS::DynamicType_ptr rhs, DynamicTypePtrPairSeen &dt_ptr_pair)
void set_descriptor(DDS::TypeDescriptor *descriptor)
ACE_CDR::Octet TypeKind
Definition: TypeObject.h:210
const_iterator find(MemberId key) const
ACE_CDR::ULong ULong
LM_NOTICE
const ACE_CDR::ULong MEMBER_ID_INVALID
Definition: TypeObject.h:911
DynamicTypeMembersByIndex member_by_index_
ACE_UINT32 ULong
const char *const name
Definition: debug.cpp:60
character_type * _retn(void)
OpenDDS_Dcps_Export LogLevel log_level
DDS::ReturnCode_t get_member_by_index(DDS::DynamicTypeMember_ptr &member, ACE_CDR::ULong index)
const TypeKind TK_ALIAS
Definition: TypeObject.h:235
const ReturnCode_t RETCODE_ERROR
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
const ReturnCode_t RETCODE_OK
const ReturnCode_t RETCODE_UNSUPPORTED
DDS::ReturnCode_t get_member_by_name(DDS::DynamicTypeMember_ptr &member, const char *name)
const character_type * in(void) const
std::pair< const DDS::DynamicType *, const DDS::DynamicType * > DynamicTypePtrPair
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
DDS::ReturnCode_t get_all_members_by_name(DDS::DynamicTypeMembersByName_ptr &member)
DDS::ReturnCode_t get_member(DDS::DynamicTypeMember_ptr &member, MemberId id)
const ReturnCode_t RETCODE_BAD_PARAMETER