OpenDDS  Snapshot(2023/01/18-09:55)
XTypes/Utils.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #include <DCPS/DdsDcps_pch.h>
7 
8 #ifndef OPENDDS_SAFETY_PROFILE
9 # include "Utils.h"
10 
11 # include "DynamicDataImpl.h"
12 
13 # include <dds/DCPS/debug.h>
14 # include <dds/DCPS/DCPS_Utils.h>
15 
16 # include <algorithm>
17 
19 namespace OpenDDS {
20 namespace XTypes {
21 
23 using DCPS::LogLevel;
24 using DCPS::log_level;
25 
26 DDS::ReturnCode_t extensibility(DDS::DynamicType_ptr type, DCPS::Extensibility& ext)
27 {
28  DDS::DynamicType_var base_type = get_base_type(type);
29  if (!base_type) {
31  }
32  switch (base_type->get_kind()) {
33  case TK_STRUCTURE:
34  case TK_UNION:
35  {
36  DDS::TypeDescriptor_var td;
37  const DDS::ReturnCode_t rc = type->get_descriptor(td);
38  if (rc != DDS::RETCODE_OK) {
39  return rc;
40  }
41  ext = dds_to_opendds_ext(td->extensibility_kind());
42  }
43  break;
44  default:
45  ext = DCPS::FINAL;
46  }
47  return DDS::RETCODE_OK;
48 }
49 
51 {
52  DDS::ReturnCode_t rc = extensibility(type, ext);
53  if (rc != DDS::RETCODE_OK) {
54  return rc;
55  }
56 
57  DDS::DynamicType_var base_type = get_base_type(type);
58  const TypeKind tk = base_type->get_kind();
59  if (tk != TK_STRUCTURE && tk != TK_UNION) {
60  return DDS::RETCODE_OK;
61  }
62 
63  DDS::DynamicTypeMembersById_var members;
64  rc = base_type->get_all_members(members);
65  if (rc != DDS::RETCODE_OK) {
66  return rc;
67  }
68 
69  DynamicTypeMembersByIdImpl* const members_impl =
70  dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
71  if (!members_impl) {
73  }
74 
75  for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin();
76  it != members_impl->end(); ++it) {
77  DDS::MemberDescriptor_var md;
78  rc = it->second->get_descriptor(md);
79  if (rc != DDS::RETCODE_OK) {
80  return rc;
81  }
82 
83  DDS::DynamicType_ptr member_type = md->type();
84  if (!member_type) {
86  }
87  DCPS::Extensibility member_ext;
88  DDS::ReturnCode_t rc = max_extensibility(member_type, member_ext);
89  if (rc != DDS::RETCODE_OK) {
90  return rc;
91  }
92  ext = std::max(member_ext, ext);
93  }
94 
95  return DDS::RETCODE_OK;
96 }
97 
99 {
100  switch (ext) {
101  case DDS::FINAL:
102  return DCPS::FINAL;
103  case DDS::APPENDABLE:
104  return DCPS::APPENDABLE;
105  case DDS::MUTABLE:
106  return DCPS::MUTABLE;
107  }
108  OPENDDS_ASSERT(false);
109  return DCPS::FINAL;
110 }
111 
113  DDS::DynamicType_ptr type, DDS::DynamicTypeMember_var& member)
114 {
115  member = 0;
116  if (ids.empty()) {
118  }
119 
120  DDS::DynamicType_var base_type = get_base_type(type);
121  if (!base_type) {
123  }
124 
125  MemberIdVec::iterator it = ids.begin();
126  DDS::DynamicType_var current_type = DDS::DynamicType::_duplicate(type);
127  DDS::DynamicTypeMember_var current_member;
128  while (true) {
129  DDS::ReturnCode_t rc = current_type->get_member(current_member, *it);
130  if (rc != DDS::RETCODE_OK) {
131  return rc;
132  }
133 
134  if (++it == ids.end()) {
135  break;
136  }
137 
138  DDS::MemberDescriptor_var md;
139  rc = current_member->get_descriptor(md);
140  if (rc != DDS::RETCODE_OK) {
141  return rc;
142  }
143  DDS::DynamicType_var next = get_base_type(md->type());
144  if (!next) {
146  }
147  current_type = next;
148  }
149  member = current_member;
150 
151  return DDS::RETCODE_OK;
152 }
153 
155  DDS::DynamicData_ptr data, DDS::DynamicData_var& container, DDS::MemberId& member_id)
156 {
157  container = 0;
158  if (ids.empty()) {
160  }
161 
162  MemberIdVec::iterator it = ids.begin();
163  DDS::DynamicData_var current_container = DDS::DynamicData::_duplicate(data);
164  while (true) {
165  const DDS::MemberId current_id = *it;
166  if (++it == ids.end()) {
167  member_id = current_id;
168  break;
169  }
170 
171  DDS::DynamicData_var next;
172  DDS::ReturnCode_t rc = current_container->get_complex_value(next, current_id);
173  if (rc != DDS::RETCODE_OK) {
174  return rc;
175  }
176  current_container = next;
177  }
178  container = current_container;
179 
180  return DDS::RETCODE_OK;
181 }
182 
183 namespace {
184  DDS::ReturnCode_t get_values_i(DDS::DynamicType_ptr type, MemberPathVec& paths, Filter filter,
185  const MemberPath& base_path)
186  {
187  DDS::DynamicType_var base_type = get_base_type(type);
188  if (!base_type) {
190  }
191  const TypeKind kind = base_type->get_kind();
192  switch (kind) {
193  case TK_STRUCTURE:
194  {
195  DDS::DynamicTypeMembersById_var members;
196  DDS::ReturnCode_t rc = type->get_all_members(members);
197  if (rc != DDS::RETCODE_OK) {
198  return rc;
199  }
200 
201  DynamicTypeMembersByIdImpl* const members_i =
202  dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
203  if (!members_i) {
205  }
206 
207  bool include_all = filter == Filter_All;
208  if (filter == Filter_NestedKeys) {
209  // If there are no explicit keys, then they are implied to all be keys.
210  // TODO: Except when @key(FALSE)
211  include_all = true;
212  for (DynamicTypeMembersByIdImpl::const_iterator it = members_i->begin();
213  it != members_i->end(); ++it) {
214  DDS::MemberDescriptor_var md;
215  DDS::ReturnCode_t rc = it->second->get_descriptor(md);
216  if (rc != DDS::RETCODE_OK) {
217  return rc;
218  }
219  if (md->is_key()) {
220  include_all = false;
221  break;
222  }
223  }
224  }
225 
226  for (DynamicTypeMembersByIdImpl::const_iterator it = members_i->begin();
227  it != members_i->end(); ++it) {
228  DDS::MemberDescriptor_var md;
229  DDS::ReturnCode_t rc = it->second->get_descriptor(md);
230  if (rc != DDS::RETCODE_OK) {
231  return rc;
232  }
233  if ((filter == Filter_NonKeys) != (include_all || md->is_key())) {
234  const MemberPath path(base_path, md->id());
235  rc = get_values_i(md->type(), paths,
236  filter == Filter_Keys ? Filter_NestedKeys : filter, path);
237  if (rc != DDS::RETCODE_OK) {
238  return rc;
239  }
240  }
241  }
242  }
243  break;
244 
245  case TK_UNION:
246  {
247  DDS::DynamicTypeMember_var disc;
248  const MemberId id = DISCRIMINATOR_ID;
249  const MemberPath this_path(base_path, id);
250  bool include = false;
251  switch (filter) {
252  case Filter_Keys:
253  case Filter_NonKeys:
254  {
255  DDS::ReturnCode_t rc = type->get_member(disc, id);
256  if (rc != DDS::RETCODE_OK) {
257  return rc;
258  }
259  DDS::MemberDescriptor_var md;
260  rc = disc->get_descriptor(md);
261  if (rc != DDS::RETCODE_OK) {
262  return rc;
263  }
264  include = (filter == Filter_NonKeys) != md->is_key();
265  }
266  break;
267  case Filter_All:
268  case Filter_NestedKeys:
269  // If we're here then the union field has been marked so the
270  // disciminator is an implied key even if it doesn't have @key.
271  // TODO: Except when @key(FALSE)
272  include = true;
273  break;
274  }
275  if (include) {
276  paths.push_back(this_path);
277  }
278  }
279  break;
280 
281  default:
282  if (base_path.level() == 0) {
283  if (log_level >= LogLevel::Notice) {
284  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: get_values_i: "
285  "get_values was passed an invalid topic type: %C\n",
286  typekind_to_string(kind)));
287  }
289  }
290  paths.push_back(base_path);
291  break;
292  }
293 
294  return DDS::RETCODE_OK;
295  }
296 }
297 
298 DDS::ReturnCode_t get_values(DDS::DynamicType_ptr type, MemberPathVec& paths, Filter filter)
299 {
300  return get_values_i(type, paths, filter, MemberPath());
301 }
302 
303 DDS::ReturnCode_t get_keys(DDS::DynamicType_ptr type, MemberPathVec& paths)
304 {
305  return get_values(type, paths, Filter_Keys);
306 }
307 
308 DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t& count)
309 {
310  MemberPathVec paths;
311  const DDS::ReturnCode_t rc = get_keys(type, paths);
312  if (rc == DDS::RETCODE_OK) {
313  count = paths.size();
314  }
315  return rc;
316 }
317 
318 namespace {
319  template <typename T>
320  void cmp(int& result, T a, T b)
321  {
322  if (a < b) {
323  result = -1;
324  } else if (a > b) {
325  result = 1;
326  } else {
327  result = 0;
328  }
329  }
330 
331  bool sequence_like(DDS::TypeKind tk)
332  {
333  return tk == TK_ARRAY || tk == TK_SEQUENCE;
334  }
335 
336  DDS::ReturnCode_t get_member_type(DDS::DynamicType_var& type,
337  DDS::DynamicData_ptr data, DDS::MemberId id)
338  {
339  DDS::DynamicType_var data_type = data->type();
340  if (sequence_like(data_type->get_kind())) {
341  DDS::TypeDescriptor_var td;
342  DDS::ReturnCode_t rc = data_type->get_descriptor(td);
343  if (rc != DDS::RETCODE_OK) {
344  return rc;
345  }
346  type = get_base_type(td->element_type());
347  } else {
348  DDS::MemberDescriptor_var md;
349  DDS::ReturnCode_t rc = data->get_descriptor(md, id);
350  if (rc != DDS::RETCODE_OK) {
351  return rc;
352  }
353  type = get_base_type(md->type());
354  }
355  return DDS::RETCODE_OK;
356  }
357 
358  DDS::ReturnCode_t member_compare(int& result,
359  DDS::DynamicData_ptr a_data, DDS::MemberId a_id,
360  DDS::DynamicData_ptr b_data, DDS::MemberId b_id)
361  {
362  DDS::DynamicType_var a_type;
363  DDS::ReturnCode_t rc = get_member_type(a_type, a_data, a_id);
364  if (rc != DDS::RETCODE_OK) {
365  return rc;
366  }
367  const DDS::TypeKind tk = a_type->get_kind();
368 
369  DDS::DynamicType_var b_type;
370  rc = get_member_type(b_type, b_data, b_id);
371  if (rc != DDS::RETCODE_OK) {
372  return rc;
373  }
374  const DDS::TypeKind b_tk = b_type->get_kind();
375 
376  if (tk != b_tk) {
377  if (log_level >= LogLevel::Notice) {
378  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: member_compare: "
379  "trying to compare a %C to a %C\n",
380  typekind_to_string(tk),
381  typekind_to_string(b_tk)));
382  }
384  }
385 
388 
389  switch (tk) {
390  case TK_BOOLEAN:
391  {
392  CORBA::Boolean a_value;
393  a_rc = a_data->get_boolean_value(a_value, a_id);
394  if (a_rc == DDS::RETCODE_OK) {
395  CORBA::Boolean b_value;
396  b_rc = b_data->get_boolean_value(b_value, b_id);
397  if (b_rc == DDS::RETCODE_OK) {
398  cmp(result, a_value, b_value);
399  }
400  }
401  }
402  break;
403 
404  case TK_BYTE:
405  {
406  CORBA::Octet a_value;
407  a_rc = a_data->get_byte_value(a_value, a_id);
408  if (a_rc == DDS::RETCODE_OK) {
409  CORBA::Octet b_value;
410  b_rc = b_data->get_byte_value(b_value, b_id);
411  if (b_rc == DDS::RETCODE_OK) {
412  cmp(result, a_value, b_value);
413  }
414  }
415  }
416  break;
417 
418  case TK_UINT8:
419  case TK_UINT16:
420  case TK_UINT32:
421  case TK_UINT64:
422  {
423  CORBA::UInt64 a_value;
424  a_rc = get_uint_value(a_value, a_data, a_id, tk);
425  if (a_rc == DDS::RETCODE_OK) {
426  CORBA::UInt64 b_value;
427  b_rc = get_uint_value(b_value, b_data, b_id, tk);
428  if (b_rc == DDS::RETCODE_OK) {
429  cmp(result, a_value, b_value);
430  }
431  }
432  }
433  break;
434 
435  case TK_INT8:
436  case TK_INT16:
437  case TK_INT32:
438  case TK_INT64:
439  {
440  CORBA::Int64 a_value;
441  a_rc = get_int_value(a_value, a_data, a_id, tk);
442  if (a_rc == DDS::RETCODE_OK) {
443  CORBA::Int64 b_value;
444  b_rc = get_int_value(b_value, b_data, b_id, tk);
445  if (b_rc == DDS::RETCODE_OK) {
446  cmp(result, a_value, b_value);
447  }
448  }
449  }
450  break;
451 
452  case TK_FLOAT32:
453  {
454  CORBA::Float a_value;
455  a_rc = a_data->get_float32_value(a_value, a_id);
456  if (a_rc == DDS::RETCODE_OK) {
457  CORBA::Float b_value;
458  b_rc = b_data->get_float32_value(b_value, b_id);
459  if (b_rc == DDS::RETCODE_OK) {
460  cmp(result, a_value, b_value);
461  }
462  }
463  }
464  break;
465 
466  case TK_FLOAT64:
467  {
468  CORBA::Double a_value;
469  a_rc = a_data->get_float64_value(a_value, a_id);
470  if (a_rc == DDS::RETCODE_OK) {
471  CORBA::Double b_value;
472  b_rc = b_data->get_float64_value(b_value, b_id);
473  if (b_rc == DDS::RETCODE_OK) {
474  cmp(result, a_value, b_value);
475  }
476  }
477  }
478  break;
479 
480  case TK_FLOAT128:
481  {
482  CORBA::LongDouble a_value;
483  a_rc = a_data->get_float128_value(a_value, a_id);
484  if (a_rc == DDS::RETCODE_OK) {
485  CORBA::LongDouble b_value;
486  b_rc = b_data->get_float128_value(b_value, b_id);
487  if (b_rc == DDS::RETCODE_OK) {
488  cmp(result, a_value, b_value);
489  }
490  }
491  }
492  break;
493 
494  case TK_CHAR8:
495  {
496  CORBA::Char a_value;
497  a_rc = a_data->get_char8_value(a_value, a_id);
498  if (a_rc == DDS::RETCODE_OK) {
499  CORBA::Char b_value;
500  b_rc = b_data->get_char8_value(b_value, b_id);
501  if (b_rc == DDS::RETCODE_OK) {
502  cmp(result, a_value, b_value);
503  }
504  }
505  }
506  break;
507 
508  case TK_CHAR16:
509  {
510  CORBA::WChar a_value;
511  a_rc = a_data->get_char16_value(a_value, a_id);
512  if (a_rc == DDS::RETCODE_OK) {
513  CORBA::WChar b_value;
514  b_rc = b_data->get_char16_value(b_value, b_id);
515  if (b_rc == DDS::RETCODE_OK) {
516  cmp(result, a_value, b_value);
517  }
518  }
519  }
520  break;
521 
522  case TK_STRING8:
523  {
524  CORBA::String_var a_value;
525  a_rc = a_data->get_string_value(a_value, a_id);
526  if (a_rc == DDS::RETCODE_OK) {
527  CORBA::String_var b_value;
528  b_rc = b_data->get_string_value(b_value, b_id);
529  if (b_rc == DDS::RETCODE_OK) {
530  result = std::strcmp(a_value.in(), b_value.in());
531  }
532  }
533  }
534  break;
535 
536  case TK_STRING16:
537  {
538  CORBA::WString_var a_value;
539  a_rc = a_data->get_wstring_value(a_value, a_id);
540  if (a_rc == DDS::RETCODE_OK) {
541  CORBA::WString_var b_value;
542  b_rc = b_data->get_wstring_value(b_value, b_id);
543  if (b_rc == DDS::RETCODE_OK) {
544  result = std::wcscmp(a_value.in(), b_value.in());
545  }
546  }
547  }
548  break;
549 
550  case TK_ENUM:
551  {
552  CORBA::Int32 a_value;
553  a_rc = get_enum_value(a_value, a_type, a_data, a_id);
554  if (a_rc == DDS::RETCODE_OK) {
555  CORBA::Int32 b_value;
556  b_rc = get_enum_value(b_value, b_type, b_data, b_id);
557  if (b_rc == DDS::RETCODE_OK) {
558  cmp(result, a_value, b_value);
559  }
560  }
561  }
562  break;
563 
564  case TK_BITMASK:
565  {
566  CORBA::UInt64 a_value;
567  a_rc = get_bitmask_value(a_value, a_type, a_data, a_id);
568  if (a_rc == DDS::RETCODE_OK) {
569  CORBA::UInt64 b_value;
570  b_rc = get_bitmask_value(b_value, b_type, b_data, b_id);
571  if (b_rc == DDS::RETCODE_OK) {
572  cmp(result, a_value, b_value);
573  }
574  }
575  }
576  break;
577 
578  // TODO(iguessthislldo): I hate to leave this for later because it makes maps
579  // and bitsets just that tiny bit harder, but I'm not certain how keys
580  // would work with them.
581  /*
582  case TK_MAP:
583  case TK_BITSET:
584  */
585  case TK_SEQUENCE:
586  case TK_ARRAY:
587  {
588  DDS::DynamicData_var a_value;
589  a_rc = a_data->get_complex_value(a_value, a_id);
590  if (a_rc == DDS::RETCODE_OK) {
591  DDS::DynamicData_var b_value;
592  b_rc = b_data->get_complex_value(b_value, b_id);
593  if (b_rc == DDS::RETCODE_OK) {
594  switch (tk) {
595  case TK_ARRAY:
596  case TK_SEQUENCE:
597  {
598  const ACE_CDR::UInt32 a_count = a_value->get_item_count();
599  const ACE_CDR::UInt32 b_count = b_value->get_item_count();
600  const ACE_CDR::UInt32 count = std::min(a_count, b_count);
601  for (ACE_CDR::UInt32 i = 0;
602  a_rc == DDS::RETCODE_OK && i < count && result == 0; ++i) {
603  a_rc = b_rc = member_compare(result,
604  a_value, a_value->get_member_id_at_index(i),
605  b_value, b_value->get_member_id_at_index(i));
606  }
607  if (result == 0 && a_count != b_count) {
608  result = count == a_count ? -1 : 1;
609  }
610  }
611  break;
612 
613  default:
614  OPENDDS_ASSERT(false);
615  break;
616  }
617  }
618  }
619  }
620  break;
621 
622  case TK_STRUCTURE:
623  case TK_UNION:
624  // get_keys shouldn't be returning these directly, they should be
625  // returning either the key members of the structure or the
626  // discriminator of the union.
627  case TK_ALIAS:
628  case TK_ANNOTATION:
629  default:
630  if (log_level >= LogLevel::Warning) {
631  ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: member_compare(DynamicData): "
632  "member has unexpected TypeKind %C\n", typekind_to_string(b_tk)));
633  }
636  }
637 
638  if (a_rc != DDS::RETCODE_OK || b_rc != DDS::RETCODE_OK) {
639  const CORBA::String_var b_type_name = b_data->type()->get_name();
640  const CORBA::String_var a_type_name = a_data->type()->get_name();
641  if (log_level >= LogLevel::Warning) {
642  ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: member_compare(DynamicData): "
643  "Could not compare member type %C id %u from %C (%C) to %C (%C)\n",
644  typekind_to_string(tk), a_id,
645  a_type_name.in(), retcode_to_string(a_rc),
646  b_type_name.in(), retcode_to_string(b_rc)));
647  }
648  }
649 
650  return DDS::RETCODE_OK;
651  }
652 }
653 
655  bool& result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b, Filter filter)
656 {
657  DDS::DynamicType_var a_type = a->type();
658  MemberPathVec paths;
659  DDS::ReturnCode_t rc = get_values(a_type, paths, filter);
660  if (rc != DDS::RETCODE_OK) {
661  if (log_level >= LogLevel::Notice) {
662  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: key_compare: get_keys failed: %C\n",
663  retcode_to_string(rc)));
664  }
665  return rc;
666  }
667 
668  result = false;
669  for (MemberPathVec::iterator it = paths.begin(); it != paths.end(); it++) {
670  DDS::DynamicData_var a_container;
671  DDS::MemberId a_member_id;
672  rc = it->get_member_from_data(a, a_container, a_member_id);
673  if (rc != DDS::RETCODE_OK) {
674  if (log_level >= LogLevel::Notice) {
675  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: key_compare: "
676  "get_member_from_data for a failed: %C\n",
677  retcode_to_string(rc)));
678  }
679  return rc;
680  }
681 
682  DDS::DynamicData_var b_container;
683  DDS::MemberId b_member_id;
684  rc = it->get_member_from_data(b, b_container, b_member_id);
685  if (rc != DDS::RETCODE_OK) {
686  if (log_level >= LogLevel::Notice) {
687  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: key_compare: "
688  "get_member_from_data for b failed: %C\n",
689  retcode_to_string(rc)));
690  }
691  return rc;
692  }
693 
694  int compare = 0;
695  rc = member_compare(compare, a_container, a_member_id, b_container, b_member_id);
696  if (rc != DDS::RETCODE_OK) {
697  return rc;
698  }
699  if (compare != 0) {
700  result = compare < 0;
701  return DDS::RETCODE_OK;
702  }
703  }
704 
705  return DDS::RETCODE_OK;
706 }
707 
708 DDS::ReturnCode_t key_less_than(bool& result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b)
709 {
710  return less_than(result, a, b, Filter_Keys);
711 }
712 
714 {
715  switch (tk) {
716  case TK_INT8:
717  case TK_INT16:
718  case TK_INT32:
719  case TK_INT64:
720  return true;
721  default:
722  return false;
723  }
724 }
725 
727 {
728  switch (tk) {
729  case TK_UINT8:
730  case TK_UINT16:
731  case TK_UINT32:
732  case TK_UINT64:
733  return true;
734  default:
735  return false;
736  }
737 }
738 
740  CORBA::UInt64& value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
741 {
743  switch (kind) {
744  case TK_UINT8:
745  {
746  CORBA::UInt8 v;
747  rc = src->get_uint8_value(v, id);
748  if (rc == DDS::RETCODE_OK) {
749  value = v;
750  }
751  }
752  break;
753  case TK_UINT16:
754  {
755  CORBA::UInt16 v;
756  rc = src->get_uint16_value(v, id);
757  if (rc == DDS::RETCODE_OK) {
758  value = v;
759  }
760  }
761  break;
762  case TK_UINT32:
763  {
764  CORBA::UInt32 v;
765  rc = src->get_uint32_value(v, id);
766  if (rc == DDS::RETCODE_OK) {
767  value = v;
768  }
769  }
770  break;
771  case TK_UINT64:
772  rc = src->get_uint64_value(value, id);
773  break;
774  }
775  return rc;
776 }
777 
779  CORBA::Int64& value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
780 {
782  switch (kind) {
783  case TK_INT8:
784  {
785  CORBA::Int8 v;
786  rc = src->get_int8_value(v, id);
787  if (rc == DDS::RETCODE_OK) {
788  value = v;
789  }
790  }
791  break;
792  case TK_INT16:
793  {
794  CORBA::Int16 v;
795  rc = src->get_int16_value(v, id);
796  if (rc == DDS::RETCODE_OK) {
797  value = v;
798  }
799  }
800  break;
801  case TK_INT32:
802  {
803  CORBA::Int32 v;
804  rc = src->get_int32_value(v, id);
805  if (rc == DDS::RETCODE_OK) {
806  value = v;
807  }
808  }
809  break;
810  case TK_INT64:
811  rc = src->get_int64_value(value, id);
812  break;
813  }
814  return rc;
815 }
816 
818  DDS::DynamicType_ptr type, CORBA::UInt64& bound_max, DDS::TypeKind& bound_kind)
819 {
820  const DDS::TypeKind kind = type->get_kind();
821  if (kind != TK_BITMASK) {
822  if (log_level >= LogLevel::Notice) {
823  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: bitmask_bound: "
824  "expected bitmask, got %C\n",
825  typekind_to_string(kind)));
826  }
828  }
829 
830  DDS::TypeDescriptor_var td;
831  const DDS::ReturnCode_t rc = type->get_descriptor(td);
832  if (rc != DDS::RETCODE_OK) {
833  return rc;
834  }
835 
836  const size_t bound_size = td->bound()[0];
837  if (bound_size >= 1 && bound_size <= 8) {
838  bound_kind = TK_UINT8;
839  } else if (bound_size >= 9 && bound_size <= 16) {
840  bound_kind = TK_UINT16;
841  } else if (bound_size >= 17 && bound_size <= 32) {
842  bound_kind = TK_UINT32;
843  } else if (bound_size >= 33 && bound_size <= 64) {
844  bound_kind = TK_UINT64;
845  } else {
846  if (log_level >= LogLevel::Notice) {
847  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: bitmask_bound: "
848  "Got unexpected bound size %B\n",
849  bound_size));
850  }
852  }
853  bound_max = (1 << bound_size) - 1;
854  return DDS::RETCODE_OK;
855 }
856 
858  CORBA::UInt64& value, DDS::DynamicType_ptr type, DDS::DynamicData_ptr src, DDS::MemberId id)
859 {
860  CORBA::UInt64 bound_max;
861  DDS::TypeKind bound_kind;
862  const DDS::ReturnCode_t rc = bitmask_bound(type, bound_max, bound_kind);
863  if (rc != DDS::RETCODE_OK) {
864  return rc;
865  }
866  return get_uint_value(value, src, id, bound_kind);
867 }
868 
869 DDS::ReturnCode_t enum_bound(DDS::DynamicType_ptr type, DDS::TypeKind& bound_kind)
870 {
871  const DDS::TypeKind kind = type->get_kind();
872  if (kind != TK_ENUM) {
873  if (log_level >= LogLevel::Notice) {
874  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: enum_bound: "
875  "expected enum, got %C\n",
876  typekind_to_string(kind)));
877  }
879  }
880 
881  DDS::TypeDescriptor_var td;
882  const DDS::ReturnCode_t rc = type->get_descriptor(td);
883  if (rc != DDS::RETCODE_OK) {
884  return rc;
885  }
886 
887  const size_t bound_size = td->bound()[0];
888  if (bound_size >= 1 && bound_size <= 8) {
889  bound_kind = TK_INT8;
890  } else if (bound_size >= 9 && bound_size <= 16) {
891  bound_kind = TK_INT16;
892  } else if (bound_size >= 17 && bound_size <= 32) {
893  bound_kind = TK_INT32;
894  } else {
895  if (log_level >= LogLevel::Notice) {
896  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: enum_bound: "
897  "Got unexpected bound size %B\n",
898  bound_size));
899  }
901  }
902  return DDS::RETCODE_OK;
903 }
904 
906  CORBA::Int32& value, DDS::DynamicType_ptr type, DDS::DynamicData_ptr src, DDS::MemberId id)
907 {
908  DDS::TypeKind bound_kind;
909  DDS::ReturnCode_t rc = enum_bound(type, bound_kind);
910  if (rc != DDS::RETCODE_OK) {
911  return rc;
912  }
913  CORBA::Int64 v;
914  rc = get_int_value(v, src, id, bound_kind);
915  if (rc != DDS::RETCODE_OK) {
916  return rc;
917  }
918  value = static_cast<CORBA::Int32>(v);
919  return rc;
920 }
921 
922 } // namespace XTypes
923 } // namespace OpenDDS
925 
926 #endif // OPENDDS_SAFETY_PROFILE
DDS::ReturnCode_t get_values(DDS::DynamicType_ptr type, MemberPathVec &paths, Filter filter)
DDS::ReturnCode_t key_less_than(bool &result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b)
#define ACE_ERROR(X)
DDS::ReturnCode_t less_than(bool &result, DDS::DynamicData_ptr a, DDS::DynamicData_ptr b, Filter filter)
ACE_CDR::Int32 Int32
const TypeKind TK_INT32
Definition: TypeObject.h:146
const ReturnCode_t RETCODE_ILLEGAL_OPERATION
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
const ReturnCode_t RETCODE_OK
const TypeKind TK_UINT64
Definition: TypeObject.h:150
const TypeKind TK_UINT16
Definition: TypeObject.h:148
const TypeKind TK_FLOAT32
Definition: TypeObject.h:151
const TypeKind TK_STRING8
Definition: TypeObject.h:160
const TypeKind TK_UINT8
Definition: TypeObject.h:155
MemberPath & id(DDS::MemberId id)
Definition: XTypes/Utils.h:43
DDS::ReturnCode_t enum_bound(DDS::DynamicType_ptr type, DDS::TypeKind &bound_kind)
const TypeKind TK_INT8
Definition: TypeObject.h:154
const TypeKind TK_INT64
Definition: TypeObject.h:147
const TypeKind TK_UINT32
Definition: TypeObject.h:149
const char * retcode_to_string(DDS::ReturnCode_t value)
Definition: DCPS_Utils.cpp:29
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:143
ACE_CDR::Boolean Boolean
const TypeKind TK_STRING16
Definition: TypeObject.h:161
const ReturnCode_t RETCODE_BAD_PARAMETER
const TypeKind TK_FLOAT128
Definition: TypeObject.h:153
DDS::ReturnCode_t get_bitmask_value(CORBA::UInt64 &value, DDS::DynamicType_ptr type, DDS::DynamicData_ptr src, DDS::MemberId id)
ACE_CDR::UInt64 UInt64
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
bool is_int(DDS::TypeKind tk)
const TypeKind TK_BYTE
Definition: TypeObject.h:144
LM_NOTICE
const TypeKind TK_FLOAT64
Definition: TypeObject.h:152
const TypeKind TK_UNION
Definition: TypeObject.h:173
const TypeKind TK_INT16
Definition: TypeObject.h:145
DCPS::Extensibility dds_to_opendds_ext(DDS::ExtensibilityKind ext)
LM_WARNING
const TypeKind TK_CHAR8
Definition: TypeObject.h:156
const ACE_CDR::ULong DISCRIMINATOR_ID
Implementation specific sentinel for a union discriminator used in DynamicData.
Definition: TypeObject.h:832
ACE_CDR::ULong MemberId
Definition: TypeObject.h:829
DDS::ReturnCode_t get_keys(DDS::DynamicType_ptr type, MemberPathVec &paths)
ACE_CDR::Int64 Int64
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:172
const LogLevel::Value value
Definition: debug.cpp:61
DDS::ReturnCode_t get_uint_value(CORBA::UInt64 &value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
DDS::ReturnCode_t get_member_from_type(DDS::DynamicType_ptr type, DDS::DynamicTypeMember_var &member)
DDS::ReturnCode_t get_member_from_data(DDS::DynamicData_ptr data, DDS::DynamicData_var &container, DDS::MemberId &member_id)
OpenDDS_Dcps_Export LogLevel log_level
ACE_CDR::Char Char
ULong UInt32
const TypeKind TK_ENUM
Definition: TypeObject.h:167
ACE_CDR::Octet Octet
DDS::DynamicType_var get_base_type(DDS::DynamicType_ptr type)
const TypeKind TK_ALIAS
Definition: TypeObject.h:164
ACE_CDR::Int16 Int16
const TypeKind TK_ANNOTATION
Definition: TypeObject.h:171
ACE_CDR::WChar WChar
const character_type * in(void) const
const TypeKind TK_ARRAY
Definition: TypeObject.h:178
const char * typekind_to_string(TypeKind tk)
DDS::ReturnCode_t get_int_value(CORBA::Int64 &value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
DDS::ReturnCode_t get_enum_value(CORBA::Int32 &value, DDS::DynamicType_ptr type, DDS::DynamicData_ptr src, DDS::MemberId id)
DDS::ReturnCode_t max_extensibility(DDS::DynamicType_ptr type, DCPS::Extensibility &ext)
const TypeKind TK_BITMASK
Definition: TypeObject.h:168
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:66
const TypeKind TK_CHAR16
Definition: TypeObject.h:157
DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t &count)
ACE_CDR::UInt32 UInt32
DDS::ReturnCode_t bitmask_bound(DDS::DynamicType_ptr type, CORBA::UInt64 &bound_max, DDS::TypeKind &bound_kind)
bool is_uint(DDS::TypeKind tk)
ACE_CDR::UInt16 UInt16
ACE_CDR::Octet TypeKind
Definition: TypeObject.h:139
extensibility(MUTABLE) struct TypeLookup_getTypes_In
Definition: TypeLookup.idl:29
ExtensibilityKind
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:177