OpenDDS  Snapshot(2023/04/28-20:55)
DynamicDataXcdrReadImpl.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
10 
11 # include "DynamicTypeMemberImpl.h"
12 # include "Utils.h"
13 
14 # include <dds/DCPS/debug.h>
17 # include <dds/DCPS/ValueHelper.h>
18 
19 # include <dds/DdsDcpsCoreTypeSupportImpl.h>
20 # include <dds/DdsDcpsInfrastructureC.h>
21 # include <dds/DdsDynamicDataSeqTypeSupportImpl.h>
22 # include <dds/CorbaSeq/LongSeqTypeSupportImpl.h>
23 # include <dds/CorbaSeq/ULongSeqTypeSupportImpl.h>
24 # include <dds/CorbaSeq/Int8SeqTypeSupportImpl.h>
25 # include <dds/CorbaSeq/UInt8SeqTypeSupportImpl.h>
26 # include <dds/CorbaSeq/ShortSeqTypeSupportImpl.h>
27 # include <dds/CorbaSeq/UShortSeqTypeSupportImpl.h>
28 # include <dds/CorbaSeq/LongLongSeqTypeSupportImpl.h>
29 # include <dds/CorbaSeq/ULongLongSeqTypeSupportImpl.h>
30 # include <dds/CorbaSeq/FloatSeqTypeSupportImpl.h>
31 # include <dds/CorbaSeq/DoubleSeqTypeSupportImpl.h>
32 # include <dds/CorbaSeq/LongDoubleSeqTypeSupportImpl.h>
33 # include <dds/CorbaSeq/CharSeqTypeSupportImpl.h>
34 # include <dds/CorbaSeq/WCharSeqTypeSupportImpl.h>
35 # include <dds/CorbaSeq/OctetSeqTypeSupportImpl.h>
36 # include <dds/CorbaSeq/BooleanSeqTypeSupportImpl.h>
37 # include <dds/CorbaSeq/StringSeqTypeSupportImpl.h>
38 # include <dds/CorbaSeq/WStringSeqTypeSupportImpl.h>
39 
40 # include <ace/OS_NS_string.h>
41 
42 # include <stdexcept>
43 
45 namespace OpenDDS {
46 namespace XTypes {
47 
48 using DCPS::log_level;
49 using DCPS::LogLevel;
50 
52  : chain_(0)
53  , encoding_(DCPS::Encoding::KIND_XCDR2)
54  , extent_(DCPS::Sample::Full)
55  , reset_align_state_(false)
56  , strm_(0, encoding_)
57  , item_count_(ITEM_COUNT_INVALID)
58 {}
59 
61  const DCPS::Encoding& encoding,
62  DDS::DynamicType_ptr type,
64  : DynamicDataBase(type)
65  , chain_(chain->duplicate())
66  , encoding_(encoding)
67  , extent_(ext)
68  , reset_align_state_(false)
71 {
74  throw std::runtime_error("DynamicDataXcdrReadImpl only supports XCDR1 and XCDR2");
75  }
76 }
77 
80  : DynamicDataBase(type)
81  , chain_(ser.current()->duplicate())
82  , encoding_(ser.encoding())
83  , extent_(ext)
84  , reset_align_state_(true)
85  , align_state_(ser.rdstate())
88 {
91  throw std::runtime_error("DynamicDataXcdrReadImpl only supports XCDR1 and XCDR2");
92  }
93 
95 }
96 
98  : CORBA::Object()
99  , DDS::DynamicData()
100  , CORBA::LocalObject()
101  , RcObject()
102  , DynamicDataBase()
103  , chain_(0)
104  , strm_(0, other.encoding_)
105 {
106  copy(other);
107 }
108 
110 {
111  if (this != &other) {
112  copy(other);
113  }
114  return *this;
115 }
116 
118 {
120 }
121 
123 {
125  chain_ = other.chain_->duplicate();
126  encoding_ = other.encoding_;
127  extent_ = other.extent_;
129  align_state_ = other.align_state_;
130  strm_ = other.strm_;
131  type_ = other.type_;
132  item_count_ = other.item_count_;
133 }
134 
136 {
138 }
139 
140 bool DynamicDataXcdrReadImpl::has_optional_member(bool& has_optional) const
141 {
142  if (type_->get_kind() != TK_STRUCTURE) {
143  return false;
144  }
145 
146  const ACE_CDR::ULong count = type_->get_member_count();
147  for (unsigned i = 0; i < count; ++i) {
148  DDS::DynamicTypeMember_var member;
149  if (type_->get_member_by_index(member, i) != DDS::RETCODE_OK) {
150  return false;
151  }
152  DDS::MemberDescriptor_var descriptor;
153  if (member->get_descriptor(descriptor) != DDS::RETCODE_OK) {
154  return false;
155  }
156  if (descriptor->is_optional()) {
157  has_optional = true;
158  return true;
159  }
160  }
161  has_optional = false;
162  return true;
163 }
164 
166 {
168  get_item_count();
169  }
170  if (index >= item_count_) {
171  return MEMBER_ID_INVALID;
172  }
173 
174  ScopedChainManager chain_manager(*this);
175 
176  const TypeKind tk = type_->get_kind();
177  switch (tk) {
178  case TK_BOOLEAN:
179  case TK_BYTE:
180  case TK_INT16:
181  case TK_INT32:
182  case TK_INT64:
183  case TK_UINT16:
184  case TK_UINT32:
185  case TK_UINT64:
186  case TK_FLOAT32:
187  case TK_FLOAT64:
188  case TK_FLOAT128:
189  case TK_INT8:
190  case TK_UINT8:
191  case TK_CHAR8:
192 #ifdef DDS_HAS_WCHAR
193  case TK_CHAR16:
194 #endif
195  case TK_ENUM:
196  // Value of enum or primitive types can be indicated by Id MEMBER_ID_INVALID
197  // or by index 0 (Section 7.5.2.11.1).
198  if (index != 0 && DCPS::log_level >= DCPS::LogLevel::Notice) {
199  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_member_id_at_index:"
200  " Received invalid index (%d) for type %C\n", index, typekind_to_string(tk)));
201  }
202  return MEMBER_ID_INVALID;
203  case TK_STRING8:
204 #ifdef DDS_HAS_WCHAR
205  case TK_STRING16:
206 #endif
207  case TK_BITMASK:
208  case TK_SEQUENCE:
209  case TK_ARRAY:
210  case TK_MAP:
211  return index;
212  case TK_STRUCTURE:
213  {
214  DDS::TypeDescriptor_var descriptor;
215  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
216  return MEMBER_ID_INVALID;
217  }
218  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
219  if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
220  if (!strm_.skip_delimiter()) {
221  return MEMBER_ID_INVALID;
222  }
223  }
224 
225  if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
226  bool has_optional;
227  if (!has_optional_member(has_optional)) {
228  return MEMBER_ID_INVALID;
229  }
230 
231  if (extent_ != DCPS::Sample::Full) {
233  if (struct_has_explicit_keys) {
234  // All and only explicit keys will be present in the binary stream.
235  // Index of the next member in the binary stream.
236  ACE_CDR::ULong curr_index = 0;
237  for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
238  DDS::DynamicTypeMember_var dtm;
239  if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
240  return MEMBER_ID_INVALID;
241  }
242  DDS::MemberDescriptor_var md;
243  if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
244  return MEMBER_ID_INVALID;
245  }
246  if (exclude_member(extent_, md->is_key(), struct_has_explicit_keys)) {
247  continue;
248  }
249  if (curr_index == index) {
250  return md->id();
251  }
252  ++curr_index;
253  }
254  // Should never reach here!
255  return MEMBER_ID_INVALID;
256  } else if (extent_ == DCPS::Sample::KeyOnly) {
257  return MEMBER_ID_INVALID;
258  }
259  }
260 
261  // A Full sample or a NestedKeyOnly sample with no explicit key.
262  if (!has_optional) {
263  DDS::DynamicTypeMember_var member;
264  if (type_->get_member_by_index(member, index) != DDS::RETCODE_OK) {
265  return MEMBER_ID_INVALID;
266  }
267  return member->get_id();
268  } else {
270  ACE_CDR::ULong total_skipped = 0;
271  for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
272  ACE_CDR::ULong num_skipped;
273  if (!skip_struct_member_at_index(i, num_skipped)) {
274  break;
275  }
276  total_skipped += num_skipped;
277  if (total_skipped == index + 1) {
278  DDS::DynamicTypeMember_var member;
279  if (type_->get_member_by_index(member, i) == DDS::RETCODE_OK) {
280  id = member->get_id();
281  }
282  break;
283  }
284  }
285  return id;
286  }
287  } else { // Mutable
288  ACE_CDR::ULong member_id;
289  size_t member_size;
290  bool must_understand;
291  bool good = true;
292  for (unsigned i = 0; i < index; ++i) {
293  if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
294  good = false;
295  break;
296  }
297 
298  DDS::DynamicTypeMember_var dtm;
299  if (type_->get_member(dtm, member_id) != DDS::RETCODE_OK) {
300  good = false;
301  break;
302  }
303  DDS::MemberDescriptor_var descriptor;
304  if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
305  good = false;
306  break;
307  }
308  const DDS::DynamicType_ptr mt = descriptor->type();
309  if (!mt) {
310  good = false;
311  break;
312  }
313  const DDS::DynamicType_var member = get_base_type(mt);
314  if (member->get_kind() == TK_SEQUENCE) {
315  if (!skip_sequence_member(member)) {
316  good = false;
317  break;
318  }
319  } else if (!strm_.skip(member_size)) {
320  good = false;
321  break;
322  }
323  }
324 
325  if (!good || !strm_.read_parameter_id(member_id, member_size, must_understand)) {
326  member_id = MEMBER_ID_INVALID;
327  }
328  return member_id;
329  }
330  }
331  case TK_UNION:
332  {
334  DDS::DynamicTypeMember_var disc_dtm;
335  if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
336  return MEMBER_ID_INVALID;
337  }
338  DDS::MemberDescriptor_var disc_md;
339  if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
340  return MEMBER_ID_INVALID;
341  }
342  if (!disc_md->is_key()) {
343  // The sample is empty.
344  return MEMBER_ID_INVALID;
345  }
346  }
347 
348  if (index == 0) {
349  return DISCRIMINATOR_ID;
350  }
351 
352  if (extent_ != DCPS::Sample::Full) {
353  // KeyOnly or NestedKeyOnly sample can only contain discriminator.
354  return MEMBER_ID_INVALID;
355  }
356 
357  // Get the Id of the selected member.
358  DDS::MemberDescriptor_var selected_md = get_union_selected_member();
359  if (!selected_md) {
360  return MEMBER_ID_INVALID;
361  }
362 
363  return selected_md->id();
364  }
365  }
366 
367  if (DCPS::DCPS_debug_level >= 1) {
368  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_member_id_at_index -")
369  ACE_TEXT(" Calling on an unexpected type %C\n"), typekind_to_string(tk)));
370  }
371  return MEMBER_ID_INVALID;
372 }
373 
375 {
377  return item_count_;
378  }
379 
380  ScopedChainManager chain_manager(*this);
381 
382  DDS::TypeDescriptor_var descriptor;
383  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
384  return 0;
385  }
386 
387  const TypeKind tk = type_->get_kind();
388  switch (tk) {
389  case TK_BOOLEAN:
390  case TK_BYTE:
391  case TK_INT16:
392  case TK_INT32:
393  case TK_INT64:
394  case TK_UINT16:
395  case TK_UINT32:
396  case TK_UINT64:
397  case TK_FLOAT32:
398  case TK_FLOAT64:
399  case TK_FLOAT128:
400  case TK_INT8:
401  case TK_UINT8:
402  case TK_CHAR8:
403  case TK_CHAR16:
404  case TK_ENUM:
405  return 1;
406  case TK_STRING8:
407  case TK_STRING16:
408  {
409  ACE_CDR::ULong bytes;
410  if (!(strm_ >> bytes)) {
411  return 0;
412  }
413  return (type_->get_kind() == TK_STRING8) ? bytes : bytes/2;
414  }
415  case TK_BITMASK:
416  return descriptor->bound()[0];
417  case TK_STRUCTURE:
418  {
419  bool has_optional;
420  if (!has_optional_member(has_optional)) {
421  return 0;
422  }
423 
424  if (extent_ != DCPS::Sample::Full) {
426  if (struct_has_explicit_keys) {
427  ACE_CDR::ULong num_explicit_keys = 0;
428  for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
429  DDS::DynamicTypeMember_var dtm;
430  if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
431  return 0;
432  }
433  DDS::MemberDescriptor_var md;
434  if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
435  return 0;
436  }
437  if (md->is_key()) {
438  ++num_explicit_keys;
439  }
440  }
441  return num_explicit_keys;
442  } else if (extent_ == DCPS::Sample::KeyOnly) {
443  return 0;
444  }
445  }
446 
447  // Full sample or NestedKeyOnly sample with no explicit key.
448  if (!has_optional) {
449  return type_->get_member_count();
450  }
451 
452  // Optional members can be omitted, so we need to count members one by one.
453  ACE_CDR::ULong actual_count = 0;
454  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
455  if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
456  if (ek == DDS::APPENDABLE) {
457  if (!strm_.skip_delimiter()) {
458  return 0;
459  }
460  }
461  for (ACE_CDR::ULong i = 0; i < type_->get_member_count(); ++i) {
462  ACE_CDR::ULong num_skipped;
463  if (!skip_struct_member_at_index(i, num_skipped)) {
464  actual_count = 0;
465  break;
466  }
467  actual_count += num_skipped;
468  }
469  } else { // Mutable
470  size_t dheader = 0;
471  if (!strm_.read_delimiter(dheader)) {
472  return 0;
473  }
474 
475  const size_t end_of_struct = strm_.rpos() + dheader;
476  while (strm_.rpos() < end_of_struct) {
477  ACE_CDR::ULong member_id;
478  size_t member_size;
479  bool must_understand;
480  if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
481  actual_count = 0;
482  break;
483  }
484 
485  DDS::DynamicTypeMember_var dtm;
486  if (type_->get_member(dtm, member_id) != DDS::RETCODE_OK) {
487  actual_count = 0;
488  break;
489  }
490  DDS::MemberDescriptor_var descriptor;
491  if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
492  actual_count = 0;
493  break;
494  }
495  const DDS::DynamicType_ptr mt = descriptor->type();
496  if (!mt) {
497  actual_count = 0;
498  break;
499  }
500  const DDS::DynamicType_var member = get_base_type(mt);
501  if (member->get_kind() == TK_SEQUENCE) {
502  if (!skip_sequence_member(member)) {
503  actual_count = 0;
504  break;
505  }
506  } else if (!strm_.skip(member_size)) {
507  actual_count = 0;
508  break;
509  }
510  ++actual_count;
511  }
512  }
513  return actual_count;
514  }
515  case TK_UNION:
516  {
518  DDS::DynamicTypeMember_var disc_dtm;
519  if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
520  return 0;
521  }
522  DDS::MemberDescriptor_var disc_md;
523  if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
524  return 0;
525  }
526  if (!disc_md->is_key()) {
527  return 0;
528  }
529  }
530  if (extent_ != DCPS::Sample::Full) {
531  return 1;
532  }
533 
534  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
535  if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
536  if (!strm_.skip_delimiter()) {
537  return 0;
538  }
539  }
540  const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
541  const DDS::ExtensibilityKind extend = descriptor->extensibility_kind();
542  ACE_CDR::Long label;
543  if (!read_discriminator(disc_type, extend, label)) {
544  return 0;
545  }
546 
547  DDS::DynamicTypeMembersById_var members;
548  if (type_->get_all_members(members) != DDS::RETCODE_OK) {
549  return 0;
550  }
551  DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
552  if (!members_impl) {
553  return 0;
554  }
555  for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
556  DDS::MemberDescriptor_var md;
557  if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
558  return 0;
559  }
560  if (md->is_default_label()) {
561  return 2;
562  }
563  const DDS::UnionCaseLabelSeq& labels = md->label();
564  for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
565  if (label == labels[i]) {
566  return 2;
567  }
568  }
569  }
570  return 1;
571  }
572  case TK_SEQUENCE:
573  {
574  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
575  if (!is_primitive(elem_type->get_kind())) {
576  if (!strm_.skip_delimiter()) {
577  return 0;
578  }
579  }
580  ACE_CDR::ULong length;
581  if (!(strm_ >> length)) {
582  return 0;
583  }
584  return length;
585  }
586  case TK_ARRAY:
587  return bound_total(type_desc_);
588  case TK_MAP:
589  {
590  const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
591  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
592  if (is_primitive(key_type->get_kind()) &&
593  is_primitive(elem_type->get_kind())) {
594  ACE_CDR::ULong length;
595  if (!(strm_ >> length)) {
596  return 0;
597  }
598  return length;
599  }
600 
601  size_t dheader;
602  if (!strm_.read_delimiter(dheader)) {
603  return 0;
604  }
605  const size_t end_of_map = strm_.rpos() + dheader;
606 
607  ACE_CDR::ULong length = 0;
608  while (strm_.rpos() < end_of_map) {
609  if (!skip_member(key_type) || !skip_member(elem_type)) {
610  length = 0;
611  break;
612  }
613  ++length;
614  }
615  return length;
616  }
617  }
618 
619  if (DCPS::DCPS_debug_level >= 1) {
620  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_item_count -")
621  ACE_TEXT(" Calling on an unexpected type %C\n"), typekind_to_string(tk)));
622  }
623  return 0;
624 }
625 
627 {
629 }
630 
632 {
634 }
635 
637 {
639 }
640 
642 {
643  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::loan_value: Not implemented\n"));
644  return 0;
645 }
646 
648 {
649  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::return_loaned_value: Not implemented\n"));
651 }
652 
653 
654 DDS::DynamicData_ptr DynamicDataXcdrReadImpl::clone()
655 {
657 }
658 
659 template<typename ValueType>
661 {
662  switch (tk) {
663  case TK_INT32:
664  case TK_UINT32:
665  case TK_INT16:
666  case TK_UINT16:
667  case TK_INT64:
668  case TK_UINT64:
669  case TK_FLOAT32:
670  case TK_FLOAT64:
671  case TK_FLOAT128:
672  case TK_INT8:
673  case TK_UINT8:
674  case TK_CHAR8:
675  case TK_CHAR16:
676  case TK_BYTE:
677  case TK_BOOLEAN:
678  case TK_STRING8:
679  case TK_STRING16:
680  if (strm_ >> value) {
681  return true;
682  }
683  break;
684  default:
685  if (log_level >= LogLevel::Notice) {
686  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_value: "
687  "Calling on an unexpected type %C\n", typekind_to_string(tk)));
688  }
689  return false;
690  }
691 
692  if (log_level >= LogLevel::Notice) {
693  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_value: "
694  "failed to deserialize type %C\n", typekind_to_string(tk)));
695  }
696  return false;
697 }
698 
699 // Check if a struct member with the given Id is excluded from a sample (in case of
700 // KeyOnly or NestedKeyOnly serialization).
701 bool DynamicDataXcdrReadImpl::exclude_struct_member(MemberId id, DDS::MemberDescriptor_var& md) const
702 {
703  DDS::DynamicTypeMember_var dtm;
704  if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
705  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
706  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_struct_member:"
707  " Failed to get DynamicTypeMember for member with ID %d\n", id));
708 
709  }
710  return false;
711  }
712  if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
713  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
714  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_struct_member:"
715  " Failed to get MemberDescriptor for member with ID %d\n", id));
716  }
717  return false;
718  }
719  return exclude_member(extent_, md->is_key(), has_explicit_keys(type_));
720 }
721 
722 template<TypeKind MemberTypeKind, typename MemberType>
724  TypeKind enum_or_bitmask, LBound lower, LBound upper)
725 {
726  DDS::MemberDescriptor_var md;
727  if (exclude_struct_member(id, md)) {
728  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
729  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_value_from_struct:"
730  " Attempted to read an excluded member from a %C sample\n",
731  extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
732  }
733  return DDS::RETCODE_NO_DATA;
734  }
735 
737  if (get_from_struct_common_checks(md, id, MemberTypeKind)) {
738  rc = skip_to_struct_member(md, id);
739  if (rc != DDS::RETCODE_OK) {
740  return rc;
741  }
742  return read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
743  }
744 
745  if (get_from_struct_common_checks(md, id, enum_or_bitmask)) {
746  const DDS::DynamicType_ptr member_type = md->type();
747  if (member_type) {
748  DDS::TypeDescriptor_var td;
749  rc = get_base_type(member_type)->get_descriptor(td);
750  if (rc != DDS::RETCODE_OK) {
751  return rc;
752  }
753  const LBound bit_bound = td->bound()[0];
754  if (bit_bound >= lower && bit_bound <= upper) {
755  rc = skip_to_struct_member(md, id);
756  if (rc != DDS::RETCODE_OK) {
757  return rc;
758  }
759  if (read_value(value, MemberTypeKind)) {
760  return DDS::RETCODE_OK;
761  }
762  }
763  }
764  }
765 
766  return DDS::RETCODE_ERROR;
767 }
768 
770 {
771  DDS::TypeDescriptor_var descriptor;
772  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
773  return 0;
774  }
775 
776  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
777  if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
778  if (!strm_.skip_delimiter()) {
779  return 0;
780  }
781  }
782 
783  const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
784  ACE_CDR::Long label;
785  if (!read_discriminator(disc_type, ek, label)) {
786  return 0;
787  }
788 
789  DDS::DynamicTypeMembersById_var members;
790  if (type_->get_all_members(members) != DDS::RETCODE_OK) {
791  return 0;
792  }
793  DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
794  if (!members_impl) {
795  return 0;
796  }
797 
798  bool has_default = false;
799  DDS::MemberDescriptor_var default_member;
800  for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
801  DDS::MemberDescriptor_var md;
802  if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
803  return 0;
804  }
805  const DDS::UnionCaseLabelSeq& labels = md->label();
806  for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
807  if (label == labels[i]) {
808  return md._retn();
809  }
810  }
811 
812  if (md->is_default_label()) {
813  has_default = true;
814  default_member = md;
815  }
816  }
817 
818  if (has_default) {
819  return default_member._retn();;
820  }
821 
822  // The union has no selected member.
823  return 0;
824 }
825 
827 {
828  DDS::MemberDescriptor_var md = get_union_selected_member();
829  if (!md) {
830  if (DCPS::DCPS_debug_level >= 1) {
831  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - Could not find")
832  ACE_TEXT(" MemberDescriptor for the selected union member\n"), func_name));
833  }
834  return 0;
835  }
836 
837  if (md->id() == MEMBER_ID_INVALID) {
838  if (DCPS::DCPS_debug_level >= 1) {
839  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - Union has no selected member\n"), func_name));
840  }
841  return 0;
842  }
843 
844  if (md->id() != id) {
845  if (DCPS::DCPS_debug_level >= 1) {
846  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C -")
847  ACE_TEXT(" ID of the selected member (%d) is not the requested ID (%d)\n"),
848  func_name, md->id(), id));
849  }
850  return 0;
851  }
852 
853  return md._retn();
854 }
855 
857 {
858  if (extent_ == DCPS::Sample::Full) {
859  return false;
860  }
861 
862  if (id != DISCRIMINATOR_ID) {
863  return true;
864  }
865 
867  // Discriminator not marked as key is not included in a KeyOnly sample.
868  DDS::DynamicTypeMember_var disc_dtm;
869  if (type_->get_member(disc_dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
870  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
871  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_union_member:"
872  " Failed to get DynamicTypeMember for discriminator\n"));
873  }
874  return false;
875  }
876  DDS::MemberDescriptor_var disc_md;
877  if (disc_dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) {
878  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
879  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::exclude_union_member:"
880  " Failed to get MemberDescriptor for discriminator\n"));
881  }
882  return false;
883  }
884  if (!disc_md->is_key()) {
885  return true;
886  }
887  }
888  return false;
889 }
890 
891 template<TypeKind MemberTypeKind, typename MemberType>
893  MemberType& value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
894 {
895  if (exclude_union_member(id)) {
896  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
897  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_value_from_union:"
898  " Reading an excluded member with Id %u\n", id));
899  }
900  return DDS::RETCODE_NO_DATA;
901  }
902 
903  DDS::TypeDescriptor_var descriptor;
904  DDS::ReturnCode_t rc = type_->get_descriptor(descriptor);
905  if (rc != DDS::RETCODE_OK) {
906  return rc;
907  }
908 
909  DDS::DynamicType_var member_type;
910  if (id == DISCRIMINATOR_ID) {
911  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
912  if (ek == DDS::APPENDABLE || ek == DDS::MUTABLE) {
913  if (!strm_.skip_delimiter()) {
914  return DDS::RETCODE_ERROR;
915  }
916  }
917  member_type = get_base_type(descriptor->discriminator_type());
918  } else {
919  DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_value_from_union");
920  if (!md) {
921  return DDS::RETCODE_ERROR;
922  }
923 
924  const DDS::DynamicType_ptr type = md->type();
925  if (!type) {
926  if (DCPS::DCPS_debug_level >= 1) {
927  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_union -")
928  ACE_TEXT(" Could not get DynamicType of the selected member\n")));
929  }
930  return DDS::RETCODE_ERROR;
931  }
932  member_type = get_base_type(type);
933  }
934 
935  const TypeKind member_tk = member_type->get_kind();
936  if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) {
937  if (DCPS::DCPS_debug_level >= 1) {
938  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_union -")
939  ACE_TEXT(" Could not read a value of type %C from type %C\n"),
940  typekind_to_string(MemberTypeKind), typekind_to_string(member_tk)));
941  }
942  return DDS::RETCODE_ERROR;
943  }
944 
945  if (descriptor->extensibility_kind() == DDS::MUTABLE) {
946  unsigned member_id;
947  size_t member_size;
948  bool must_understand;
949  if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
950  return DDS::RETCODE_ERROR;
951  }
952  }
953 
954  if (member_tk == MemberTypeKind) {
955  return read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
956  }
957 
958  DDS::TypeDescriptor_var td;
959  rc = member_type->get_descriptor(td);
960  if (rc != DDS::RETCODE_OK) {
961  return rc;
962  }
963  const LBound bit_bound = td->bound()[0];
964  return bit_bound >= lower && bit_bound <= upper &&
965  read_value(value, MemberTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
966 }
967 
968 bool DynamicDataXcdrReadImpl::skip_to_sequence_element(MemberId id, DDS::DynamicType_ptr coll_type)
969 {
970  DDS::TypeDescriptor_var descriptor;
971  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
972  return false;
973  }
974 
975  DDS::DynamicType_var elem_type;
976  bool skip_all = false;
977  if (!coll_type) {
978  elem_type = get_base_type(descriptor->element_type());
979  } else {
980  DDS::TypeDescriptor_var descriptor;
981  if (coll_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
982  return false;
983  }
984  elem_type = get_base_type(descriptor->element_type());
985  skip_all = true;
986  }
987  ACE_CDR::ULong size;
988  if (get_primitive_size(elem_type, size)) {
989  ACE_CDR::ULong length, index;
990  return (strm_ >> length) &&
991  get_index_from_id(id, index, length) &&
992  strm_.skip(index, size);
993  } else {
994  ACE_CDR::ULong length, index;
995  if (!strm_.skip_delimiter() || !(strm_ >> length)) {
996  return false;
997  }
998  if (skip_all) {
999  index = length;
1000  } else if (!get_index_from_id(id, index, length)) {
1001  return false;
1002  }
1003  for (ACE_CDR::ULong i = 0; i < index; ++i) {
1004  if (!skip_member(elem_type)) {
1005  return false;
1006  }
1007  }
1008  return true;
1009  }
1010 }
1011 
1012 bool DynamicDataXcdrReadImpl::skip_to_array_element(MemberId id, DDS::DynamicType_ptr coll_type)
1013 {
1014  DDS::TypeDescriptor_var descriptor;
1015  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1016  return false;
1017  }
1018 
1019  DDS::DynamicType_var elem_type;
1020  bool skip_all = false;
1021  DDS::TypeDescriptor_var coll_descriptor;
1022 
1023  if (!coll_type) {
1024  elem_type = get_base_type(descriptor->element_type());
1025  coll_type = type_;
1026  if (coll_type->get_descriptor(coll_descriptor) != DDS::RETCODE_OK) {
1027  return false;
1028  }
1029  } else {
1030  if (coll_type->get_descriptor(coll_descriptor) != DDS::RETCODE_OK) {
1031  return false;
1032  }
1033  elem_type = get_base_type(coll_descriptor->element_type());
1034  skip_all = true;
1035  }
1036 
1037  const ACE_CDR::ULong length = bound_total(coll_descriptor);
1038 
1039  ACE_CDR::ULong size;
1040  if (get_primitive_size(elem_type, size)) {
1041  ACE_CDR::ULong index;
1042  return get_index_from_id(id, index, length) && strm_.skip(index, size);
1043  } else {
1044  if (!strm_.skip_delimiter()) {
1045  return false;
1046  }
1047  ACE_CDR::ULong index;
1048  if (skip_all) {
1049  index = length;
1050  } else if (!get_index_from_id(id, index, length)) {
1051  return false;
1052  }
1053  for (ACE_CDR::ULong i = 0; i < index; ++i) {
1054  if (!skip_member(elem_type)) {
1055  return false;
1056  }
1057  }
1058  return true;
1059  }
1060 }
1061 
1063 {
1064  DDS::TypeDescriptor_var descriptor;
1065  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1066  return false;
1067  }
1068 
1069  const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
1070  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1071  ACE_CDR::ULong key_size, elem_size;
1072 
1073  if (get_primitive_size(key_type, key_size) &&
1074  get_primitive_size(elem_type, elem_size)) {
1075  ACE_CDR::ULong length, index;
1076  if (!(strm_ >> length) || !get_index_from_id(id, index, length)) {
1077  return false;
1078  }
1079 
1080  for (ACE_CDR::ULong i = 0; i < index; ++i) {
1081  if (!strm_.skip(1, key_size) || !strm_.skip(1, elem_size)) {
1082  return false;
1083  }
1084  }
1085  return strm_.skip(1, key_size);
1086  } else {
1087  size_t dheader;
1088  ACE_CDR::ULong index;
1089  if (!strm_.read_delimiter(dheader) || !get_index_from_id(id, index, ACE_UINT32_MAX)) {
1090  return false;
1091  }
1092  const size_t end_of_map = strm_.rpos() + dheader;
1093 
1094  for (ACE_CDR::ULong i = 0; i < index; ++i) {
1095  if (strm_.rpos() >= end_of_map || !skip_member(key_type) || !skip_member(elem_type)) {
1096  return false;
1097  }
1098  }
1099  return (strm_.rpos() < end_of_map) && skip_member(key_type);
1100  }
1101 }
1102 
1103 template<TypeKind ElementTypeKind, typename ElementType>
1105  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1106 {
1107  DDS::TypeDescriptor_var descriptor;
1108  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1109  return false;
1110  }
1111 
1112  DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1113  const TypeKind elem_tk = elem_type->get_kind();
1114 
1115  if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
1116  if (DCPS::DCPS_debug_level >= 1) {
1117  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_value_from_collection -")
1118  ACE_TEXT(" Could not read a value of type %C from %C with element type %C\n"),
1119  typekind_to_string(ElementTypeKind), typekind_to_string(collection_tk),
1120  typekind_to_string(elem_tk)));
1121  }
1122  return false;
1123  }
1124 
1125  if (elem_tk == enum_or_bitmask) {
1126  DDS::TypeDescriptor_var td;
1127  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1128  return false;
1129  }
1130  const LBound bit_bound = td->bound()[0];
1131  if (bit_bound < lower || bit_bound > upper) {
1132  return false;
1133  }
1134  }
1135 
1136  switch (collection_tk) {
1137  case TK_SEQUENCE:
1138  if (!skip_to_sequence_element(id)) {
1139  return false;
1140  }
1141  break;
1142  case TK_ARRAY:
1143  if (!skip_to_array_element(id)) {
1144  return false;
1145  }
1146  break;
1147  case TK_MAP:
1148  if (!skip_to_map_element(id)) {
1149  return false;
1150  }
1151  break;
1152  default:
1153  return false;
1154  }
1155 
1156  return read_value(value, ElementTypeKind);
1157 }
1158 
1160 {
1161  strm_ = DCPS::Serializer(chain, encoding_);
1162  if (reset_align_state_) {
1164  }
1165 }
1166 
1167 template<TypeKind ValueTypeKind, typename ValueType>
1169  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1170 {
1171  if (!is_type_supported(ValueTypeKind, "get_single_value")) {
1172  return DDS::RETCODE_ERROR;
1173  }
1174 
1175  ScopedChainManager chain_manager(*this);
1176 
1177  const TypeKind tk = type_->get_kind();
1178  bool good = true;
1179 
1180  // This is an extension to the XTypes spec where the value of a bitmask DynamicData
1181  // can be read as a whole as a unsigned integer.
1182  if (tk == enum_or_bitmask) {
1183  // Per XTypes spec, the value of a DynamicData object of primitive type or TK_ENUM is
1184  // accessed with MEMBER_ID_INVALID Id. However, there is only a single value in such
1185  // a DynamicData object, and checking for MEMBER_ID_INVALID from the input is perhaps
1186  // unnecessary. So, we read the value immediately here.
1187  DDS::TypeDescriptor_var descriptor;
1188  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1189  return DDS::RETCODE_ERROR;
1190  }
1191  const LBound bit_bound = descriptor->bound()[0];
1192  good = bit_bound >= lower && bit_bound <= upper && read_value(value, ValueTypeKind);
1193  } else {
1194  switch (tk) {
1195  case ValueTypeKind:
1196  good = is_primitive(tk) && read_value(value, ValueTypeKind);
1197  break;
1198  case TK_STRUCTURE:
1199  {
1200  const DDS::ReturnCode_t rc =
1201  get_value_from_struct<ValueTypeKind>(value, id, enum_or_bitmask, lower, upper);
1202  if (rc == DDS::RETCODE_NO_DATA) {
1203  return rc;
1204  }
1205  good = rc == DDS::RETCODE_OK;
1206  }
1207  break;
1208  case TK_UNION:
1209  {
1210  const DDS::ReturnCode_t rc =
1211  get_value_from_union<ValueTypeKind>(value, id, enum_or_bitmask, lower, upper);
1212  if (rc == DDS::RETCODE_NO_DATA) {
1213  return rc;
1214  }
1215  good = rc == DDS::RETCODE_OK;
1216  }
1217  break;
1218  case TK_SEQUENCE:
1219  case TK_ARRAY:
1220  case TK_MAP:
1221  good = get_value_from_collection<ValueTypeKind>(value, id, tk, enum_or_bitmask, lower, upper);
1222  break;
1223  default:
1224  good = false;
1225  break;
1226  }
1227  }
1228 
1229  if (!good && DCPS::DCPS_debug_level >= 1) {
1230  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_single_value -")
1231  ACE_TEXT(" Failed to read a value of %C from a DynamicData object of type %C\n"),
1232  typekind_to_string(ValueTypeKind), typekind_to_string(tk)));
1233  }
1234  return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1235 }
1236 
1238 {
1239  return get_single_value<TK_INT32>(value, id, TK_ENUM,
1240  static_cast<LBound>(17), static_cast<LBound>(32));
1241 }
1242 
1244 {
1245  return get_single_value<TK_UINT32>(value, id, TK_BITMASK,
1246  static_cast<LBound>(17), static_cast<LBound>(32));
1247 }
1248 
1250 {
1251  ACE_InputCDR::to_int8 to_int8(value);
1252  return get_single_value<TK_INT8>(to_int8, id, TK_ENUM, 1, 8);
1253 }
1254 
1256 {
1257  ACE_InputCDR::to_uint8 to_uint8(value);
1258  return get_single_value<TK_UINT8>(to_uint8, id, TK_BITMASK, 1, 8);
1259 }
1260 
1262 {
1263  return get_single_value<TK_INT16>(value, id, TK_ENUM, 9, 16);
1264 }
1265 
1267 {
1268  return get_single_value<TK_UINT16>(value, id, TK_BITMASK, 9, 16);
1269 }
1270 
1272 {
1273  return get_single_value<TK_INT64>(value, id);
1274 }
1275 
1277 {
1278  return get_single_value<TK_UINT64>(value, id, TK_BITMASK, 33, 64);
1279 }
1280 
1282 {
1283  return get_single_value<TK_FLOAT32>(value, id);
1284 }
1285 
1287 {
1288  return get_single_value<TK_FLOAT64>(value, id);
1289 }
1290 
1292 {
1293  return get_single_value<TK_FLOAT128>(value, id);
1294 }
1295 
1296 template<TypeKind CharKind, TypeKind StringKind, typename ToCharT, typename CharT>
1298 {
1299  ScopedChainManager chain_manager(*this);
1300 
1301  const TypeKind tk = type_->get_kind();
1302  bool good = true;
1303 
1304  switch (tk) {
1305  case CharKind:
1306  {
1307  ToCharT wrap(value);
1308  good = strm_ >> wrap;
1309  break;
1310  }
1311  case StringKind:
1312  {
1313  CharT* str;
1314  if (!(strm_ >> str)) {
1315  if (DCPS::DCPS_debug_level >= 1) {
1316  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1317  ACE_TEXT(" Failed to read wstring with ID %d\n"), id));
1318  }
1319  good = false;
1320  break;
1321  }
1322  ACE_CDR::ULong index;
1323  const size_t str_len = ACE_OS::strlen(str);
1324  if (!get_index_from_id(id, index, static_cast<ACE_CDR::ULong>(str_len))) {
1325  if (DCPS::DCPS_debug_level >= 1) {
1326  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1327  ACE_TEXT(" ID %d is not valid in a string (or wstring) with length %d\n"),
1328  id, str_len));
1329  }
1330  good = false;
1331  } else {
1332  value = str[index];
1333  }
1334  break;
1335  }
1336  case TK_STRUCTURE:
1337  {
1338  ToCharT wrap(value);
1339  const DDS::ReturnCode_t rc = get_value_from_struct<CharKind>(wrap, id, extent_);
1340  if (rc == DDS::RETCODE_NO_DATA) {
1341  return rc;
1342  }
1343  good = rc == DDS::RETCODE_OK;
1344  break;
1345  }
1346  case TK_UNION:
1347  {
1348  ToCharT wrap(value);
1349  const DDS::ReturnCode_t rc = get_value_from_union<CharKind>(wrap, id);
1350  if (rc == DDS::RETCODE_NO_DATA) {
1351  return rc;
1352  }
1353  good = rc == DDS::RETCODE_OK;
1354  break;
1355  }
1356  case TK_SEQUENCE:
1357  case TK_ARRAY:
1358  case TK_MAP:
1359  {
1360  ToCharT wrap(value);
1361  good = get_value_from_collection<CharKind>(wrap, id, tk);
1362  break;
1363  }
1364  default:
1365  good = false;
1366  break;
1367  }
1368 
1369  if (!good && DCPS::DCPS_debug_level >= 1) {
1370  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_char_common -")
1371  ACE_TEXT(" Failed to read DynamicData object of type %C\n"), typekind_to_string(tk)));
1372  }
1373  return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1374 }
1375 
1377 {
1378  return get_char_common<TK_CHAR8, TK_STRING8, ACE_InputCDR::to_char>(value, id);
1379 }
1380 
1382 {
1383 #ifdef DDS_HAS_WCHAR
1384  return get_char_common<TK_CHAR16, TK_STRING16, ACE_InputCDR::to_wchar>(value, id);
1385 #else
1386  return DDS::RETCODE_UNSUPPORTED;
1387 #endif
1388 }
1389 
1391 {
1392  ACE_InputCDR::to_octet to_octet(value);
1393  return get_single_value<TK_BYTE>(to_octet, id);
1394 }
1395 
1396 template<typename UIntType, TypeKind UIntTypeKind>
1398 {
1399  UIntType bitmask;
1400  if (!read_value(bitmask, UIntTypeKind)) {
1401  return false;
1402  }
1403 
1404  value = ((1ULL << index) & bitmask) ? true : false;
1405  return true;
1406 }
1407 
1409 {
1410  ScopedChainManager chain_manager(*this);
1411 
1412  const TypeKind tk = type_->get_kind();
1413  bool good = true;
1414 
1415  switch (tk) {
1416  case TK_BOOLEAN:
1417  good = strm_ >> ACE_InputCDR::to_boolean(value);
1418  break;
1419  case TK_BITMASK:
1420  {
1421  DDS::TypeDescriptor_var descriptor;
1422  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1423  return DDS::RETCODE_ERROR;
1424  }
1425  const LBound bit_bound = descriptor->bound()[0];
1426  ACE_CDR::ULong index;
1427  if (!get_index_from_id(id, index, bit_bound)) {
1428  if (DCPS::DCPS_debug_level >= 1) {
1429  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_boolean_value -")
1430  ACE_TEXT(" Id %d is not valid in a bitmask with bit_bound %d\n"),
1431  id, bit_bound));
1432  }
1433  good = false;
1434  break;
1435  }
1436 
1437  // Bit with index 0 is the least-significant bit of the representing integer.
1438  if (bit_bound >= 1 && bit_bound <= 8) {
1439  ACE_CDR::UInt8 bitmask;
1440  ACE_InputCDR::to_uint8 to_uint8(bitmask);
1441  if (!read_value(to_uint8, TK_UINT8)) {
1442  good = false;
1443  } else {
1444  value = ((1 << index) & bitmask) ? true : false;
1445  }
1446  } else if (bit_bound >= 9 && bit_bound <= 16) {
1447  good = get_boolean_from_bitmask<ACE_CDR::UInt16, TK_UINT16>(index, value);
1448  } else if (bit_bound >= 17 && bit_bound <= 32) {
1449  good = get_boolean_from_bitmask<ACE_CDR::UInt32, TK_UINT32>(index, value);
1450  } else {
1451  good = get_boolean_from_bitmask<ACE_CDR::UInt64, TK_UINT64>(index, value);
1452  }
1453  break;
1454  }
1455  case TK_STRUCTURE:
1456  {
1457  ACE_InputCDR::to_boolean to_bool(value);
1458  const DDS::ReturnCode_t rc = get_value_from_struct<TK_BOOLEAN>(to_bool, id, extent_);
1459  if (rc == DDS::RETCODE_NO_DATA) {
1460  return rc;
1461  }
1462  good = rc == DDS::RETCODE_OK;
1463  break;
1464  }
1465  case TK_UNION:
1466  {
1467  ACE_InputCDR::to_boolean to_bool(value);
1468  const DDS::ReturnCode_t rc = get_value_from_union<TK_BOOLEAN>(to_bool, id);
1469  if (rc == DDS::RETCODE_NO_DATA) {
1470  return rc;
1471  }
1472  good = rc == DDS::RETCODE_OK;
1473  break;
1474  }
1475  case TK_SEQUENCE:
1476  case TK_ARRAY:
1477  case TK_MAP:
1478  {
1479  ACE_InputCDR::to_boolean to_bool(value);
1480  good = get_value_from_collection<TK_BOOLEAN>(to_bool, id, tk);
1481  break;
1482  }
1483  default:
1484  good = false;
1485  break;
1486  }
1487 
1488  if (!good && DCPS::DCPS_debug_level >= 1) {
1489  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_boolean_value -")
1490  ACE_TEXT(" Failed to read DynamicData object of type %C\n"), typekind_to_string(tk)));
1491  }
1492  return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1493 }
1494 
1496 {
1497  if (enum_string_helper(value, id)) {
1498  return DDS::RETCODE_OK;
1499  }
1500  CORBA::string_free(value);
1501  return get_single_value<TK_STRING8>(value, id);
1502 }
1503 
1505 {
1506 #ifdef DDS_HAS_WCHAR
1507  CORBA::wstring_free(value);
1508  return get_single_value<TK_STRING16>(value, id);
1509 #else
1510  return DDS::RETCODE_UNSUPPORTED;
1511 #endif
1512 }
1513 
1515 {
1516  ScopedChainManager chain_manager(*this);
1517 
1518  DDS::TypeDescriptor_var descriptor;
1519  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1520  return DDS::RETCODE_ERROR;
1521  }
1522 
1523  const TypeKind tk = type_->get_kind();
1524  bool good = true;
1525 
1526  switch (tk) {
1527  case TK_STRUCTURE:
1528  {
1529  DDS::MemberDescriptor_var md;
1530  if (exclude_struct_member(id, md)) {
1531  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1532  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_complex_value:"
1533  " Attempted to read an excluded member from a %C struct sample\n",
1534  extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1535  }
1536  return DDS::RETCODE_NO_DATA;
1537  }
1538 
1539  const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1540  if (rc == DDS::RETCODE_NO_DATA) {
1541  return rc;
1542  } else if (rc == DDS::RETCODE_OK) {
1543  DDS::DynamicType_ptr member_type = md->type();
1544  if (!member_type) {
1545  good = false;
1546  } else {
1547  CORBA::release(value);
1548  value = new DynamicDataXcdrReadImpl(strm_, member_type, nested(extent_));
1549  }
1550  } else {
1551  good = false;
1552  }
1553  break;
1554  }
1555  case TK_UNION:
1556  {
1557  if (exclude_union_member(id)) {
1558  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1559  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_complex_value:"
1560  " Attempted to read an excluded member from a %C union sample\n",
1561  extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1562  }
1563  good = false;
1564  break;
1565  }
1566 
1567  if (id == DISCRIMINATOR_ID) {
1568  if (descriptor->extensibility_kind() == DDS::APPENDABLE || descriptor->extensibility_kind() == DDS::MUTABLE) {
1569  if (!strm_.skip_delimiter()) {
1570  good = false;
1571  break;
1572  }
1573  }
1574 
1575  const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
1576  if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1577  unsigned id;
1578  size_t size;
1579  bool must_understand;
1580  if (!strm_.read_parameter_id(id, size, must_understand)) {
1581  good = false;
1582  break;
1583  }
1584  }
1585  CORBA::release(value);
1586  value = new DynamicDataXcdrReadImpl(strm_, disc_type, nested(extent_));
1587  break;
1588  }
1589 
1590  DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_complex_value");
1591  if (!md) {
1592  good = false;
1593  break;
1594  }
1595 
1596  if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1597  unsigned id;
1598  size_t size;
1599  bool must_understand;
1600  if (!strm_.read_parameter_id(id, size, must_understand)) {
1601  good = false;
1602  break;
1603  }
1604  }
1605  const DDS::DynamicType_ptr member_type = md->type();
1606  if (!member_type) {
1607  good = false;
1608  } else {
1609  CORBA::release(value);
1610  value = new DynamicDataXcdrReadImpl(strm_, member_type, nested(extent_));
1611  }
1612  break;
1613  }
1614  case TK_SEQUENCE:
1615  case TK_ARRAY:
1616  case TK_MAP:
1617  {
1618  if ((tk == TK_SEQUENCE && !skip_to_sequence_element(id)) ||
1619  (tk == TK_ARRAY && !skip_to_array_element(id)) ||
1620  (tk == TK_MAP && !skip_to_map_element(id))) {
1621  good = false;
1622  } else {
1623  CORBA::release(value);
1624  value = new DynamicDataXcdrReadImpl(strm_, descriptor->element_type(), nested(extent_));
1625  }
1626  break;
1627  }
1628  default:
1629  if (DCPS::DCPS_debug_level >= 1) {
1630  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_complex_value -")
1631  ACE_TEXT(" Called on an unsupported type (%C)\n"), typekind_to_string(tk)));
1632  }
1633  good = false;
1634  break;
1635  }
1636  return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1637 }
1638 
1639 template<typename SequenceType>
1641 {
1642  using OpenDDS::DCPS::operator>>;
1643 
1644  switch(elem_tk) {
1645  case TK_INT32:
1646  case TK_UINT32:
1647  case TK_INT16:
1648  case TK_UINT16:
1649  case TK_INT64:
1650  case TK_UINT64:
1651  case TK_FLOAT32:
1652  case TK_FLOAT64:
1653  case TK_FLOAT128:
1654  case TK_INT8:
1655  case TK_UINT8:
1656  case TK_CHAR8:
1657  case TK_CHAR16:
1658  case TK_BYTE:
1659  case TK_BOOLEAN:
1660  case TK_STRING8:
1661  case TK_STRING16:
1662  if (strm_ >> value) {
1663  return true;
1664  }
1665  break;
1666  case TK_ENUM:
1667  case TK_BITMASK:
1668  if (strm_.skip_delimiter() && strm_ >> value) {
1669  return true;
1670  }
1671  break;
1672  default:
1673  if (log_level >= LogLevel::Notice) {
1674  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_values: "
1675  "Calling on an unexpected element type %C\n", typekind_to_string(elem_tk)));
1676  }
1677  return false;
1678  }
1679 
1680  if (log_level >= LogLevel::Notice) {
1681  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::read_values: "
1682  "failed to deserialize element type %C\n", typekind_to_string(elem_tk)));
1683  }
1684  return false;
1685 }
1686 
1687 template<TypeKind ElementTypeKind, typename SequenceType>
1689  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1690 {
1691  DDS::MemberDescriptor_var md;
1692  if (exclude_struct_member(id, md)) {
1693  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1694  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_struct:"
1695  " Attempted to read a member not included in a %C sample\n",
1696  extent_ == DCPS::Sample::KeyOnly ? "KeyOnly" : "NestedKeyOnly"));
1697  }
1698  return DDS::RETCODE_NO_DATA;
1699  }
1700 
1701  if (get_from_struct_common_checks(md, id, ElementTypeKind, true)) {
1702  const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1703  if (rc != DDS::RETCODE_OK) {
1704  return rc;
1705  }
1706  return read_values(value, ElementTypeKind) ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
1707  }
1708 
1709  if (get_from_struct_common_checks(md, id, enum_or_bitmask, true)) {
1710  const DDS::DynamicType_ptr member_type = md->type();
1711  if (member_type) {
1712  DDS::TypeDescriptor_var td;
1713  DDS::ReturnCode_t rc = get_base_type(member_type)->get_descriptor(td);
1714  if (rc != DDS::RETCODE_OK) {
1715  return rc;
1716  }
1717  DDS::TypeDescriptor_var etd;
1718  rc = get_base_type(td->element_type())->get_descriptor(etd);
1719  if (rc != DDS::RETCODE_OK) {
1720  return rc;
1721  }
1722  const LBound bit_bound = etd->bound()[0];
1723  if (bit_bound >= lower && bit_bound <= upper) {
1724  const DDS::ReturnCode_t rc = skip_to_struct_member(md, id);
1725  if (rc != DDS::RETCODE_OK) {
1726  return rc;
1727  }
1728  if (read_values(value, enum_or_bitmask)) {
1729  return DDS::RETCODE_OK;
1730  }
1731  }
1732  }
1733  }
1734 
1735  return DDS::RETCODE_ERROR;
1736 }
1737 
1738 template<TypeKind ElementTypeKind, typename SequenceType>
1740  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1741 {
1742  if (id == DISCRIMINATOR_ID) {
1743  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1744  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_union:"
1745  " Attempted to read discriminator as a sequence\n"));
1746  }
1747  return false;
1748  }
1749 
1750  if (exclude_union_member(id)) {
1751  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
1752  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::get_values_from_union:"
1753  " Attempted to read an excluded member with Id %u\n", id));
1754  }
1755  return false;
1756  }
1757 
1758  DDS::MemberDescriptor_var md = get_from_union_common_checks(id, "get_values_from_union");
1759  if (!md) {
1760  return false;
1761  }
1762 
1763  const DDS::DynamicType_ptr member_type = md->type();
1764  if (!member_type) {
1765  if (DCPS::DCPS_debug_level >= 1) {
1766  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1767  ACE_TEXT(" Could not get DynamicType of the selected member\n")));
1768  }
1769  return false;
1770  }
1771 
1772  DDS::DynamicType_var selected_type = get_base_type(member_type);
1773  const TypeKind selected_tk = selected_type->get_kind();
1774  if (selected_tk != TK_SEQUENCE) {
1775  if (DCPS::DCPS_debug_level >= 1) {
1776  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1777  ACE_TEXT(" The selected member is not a sequence, but %C\n"),
1778  typekind_to_string(selected_tk)));
1779  }
1780  return false;
1781  }
1782 
1783  DDS::TypeDescriptor_var td;
1784  if (selected_type->get_descriptor(td) != DDS::RETCODE_OK) {
1785  return false;
1786  }
1787  const DDS::DynamicType_var elem_type = get_base_type(td->element_type());
1788  const TypeKind elem_tk = elem_type->get_kind();
1789  if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
1790  if (DCPS::DCPS_debug_level >= 1) {
1791  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_union -")
1792  ACE_TEXT(" Could not read a sequence of %C from a sequence of %C\n"),
1793  typekind_to_string(ElementTypeKind), typekind_to_string(elem_tk)));
1794  }
1795  return false;
1796  }
1797 
1798  DDS::TypeDescriptor_var descriptor;
1799  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1800  return false;
1801  }
1802 
1803  if (descriptor->extensibility_kind() == DDS::MUTABLE) {
1804  unsigned member_id;
1805  size_t member_size;
1806  bool must_understand;
1807  if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
1808  return false;
1809  }
1810  }
1811 
1812  if (elem_tk == ElementTypeKind) {
1813  return read_values(value, ElementTypeKind);
1814  }
1815 
1816  // Reset.
1817  td = 0;
1818  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1819  return false;
1820  }
1821  const LBound bit_bound = td->bound()[0];
1822  return bit_bound >= lower && bit_bound <= upper && read_values(value, enum_or_bitmask);
1823 }
1824 
1825 template<TypeKind ElementTypeKind, typename SequenceType>
1827  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1828 {
1829  DDS::TypeDescriptor_var descriptor;
1830  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1831  return false;
1832  }
1833 
1834  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1835  const TypeKind elem_tk = elem_type->get_kind();
1836 
1837  if (elem_tk == ElementTypeKind) {
1838  return read_values(value, ElementTypeKind);
1839  } else if (elem_tk == enum_or_bitmask) {
1840  // Read from a sequence of enums or bitmasks.
1841  DDS::TypeDescriptor_var td;
1842  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1843  return false;
1844  }
1845  const LBound bit_bound = td->bound()[0];
1846  return bit_bound >= lower && bit_bound <= upper && read_values(value, enum_or_bitmask);
1847  } else if (elem_tk == TK_SEQUENCE) {
1848  DDS::TypeDescriptor_var td;
1849  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1850  return false;
1851  }
1852  const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1853  const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1854  if (nested_elem_tk == ElementTypeKind) {
1855  // Read from a sequence of sequences of ElementTypeKind.
1856  return skip_to_sequence_element(id) && read_values(value, ElementTypeKind);
1857  } else if (nested_elem_tk == enum_or_bitmask) {
1858  // Read from a sequence of sequences of enums or bitmasks.
1859  DDS::TypeDescriptor_var td;
1860  if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1861  return false;
1862  }
1863  const LBound bit_bound = td->bound()[0];
1864  return bit_bound >= lower && bit_bound <= upper &&
1865  skip_to_sequence_element(id) && read_values(value, enum_or_bitmask);
1866  }
1867  }
1868 
1869  if (DCPS::DCPS_debug_level >= 1) {
1870  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_sequence -")
1871  ACE_TEXT(" Could not read a sequence of %C from an incompatible type\n"),
1872  typekind_to_string(ElementTypeKind)));
1873  }
1874  return false;
1875 }
1876 
1877 template<TypeKind ElementTypeKind, typename SequenceType>
1879  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1880 {
1881  DDS::TypeDescriptor_var descriptor;
1882  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1883  return false;
1884  }
1885 
1886  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1887  if (elem_type->get_kind() != TK_SEQUENCE) {
1888  if (DCPS::DCPS_debug_level >= 1) {
1889  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_array -")
1890  ACE_TEXT(" Could not read a sequence of %C from an array of %C\n"),
1891  typekind_to_string(ElementTypeKind), typekind_to_string(elem_type->get_kind())));
1892  }
1893  return false;
1894  }
1895 
1896  DDS::TypeDescriptor_var td;
1897  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1898  return false;
1899  }
1900  const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1901  const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1902  if (nested_elem_tk == ElementTypeKind) {
1903  return skip_to_array_element(id) && read_values(value, nested_elem_tk);
1904  } else if (nested_elem_tk == enum_or_bitmask) {
1905  DDS::TypeDescriptor_var td;
1906  if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1907  return false;
1908  }
1909  const LBound bit_bound = td->bound()[0];
1910  return bit_bound >= lower && bit_bound <= upper &&
1911  skip_to_array_element(id) && read_values(value, nested_elem_tk);
1912  }
1913 
1914  if (DCPS::DCPS_debug_level >= 1) {
1915  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_array -")
1916  ACE_TEXT(" Could not read a sequence of %C from an array of sequence of %C\n"),
1917  typekind_to_string(ElementTypeKind), typekind_to_string(nested_elem_tk)));
1918  }
1919  return false;
1920 }
1921 
1922 template<TypeKind ElementTypeKind, typename SequenceType>
1924  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1925 {
1926  DDS::TypeDescriptor_var descriptor;
1927  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
1928  return false;
1929  }
1930 
1931  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
1932  if (elem_type->get_kind() != TK_SEQUENCE) {
1933  if (DCPS::DCPS_debug_level >= 1) {
1934  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_map -")
1935  ACE_TEXT(" Getting sequence<%C> from a map with element type of %C\n"),
1936  typekind_to_string(ElementTypeKind), typekind_to_string(elem_type->get_kind())));
1937  }
1938  return false;
1939  }
1940 
1941  DDS::TypeDescriptor_var td;
1942  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1943  return false;
1944  }
1945  const DDS::DynamicType_var nested_elem_type = get_base_type(td->element_type());
1946  const TypeKind nested_elem_tk = nested_elem_type->get_kind();
1947  if (nested_elem_tk == ElementTypeKind) {
1948  return skip_to_map_element(id) && read_values(value, nested_elem_tk);
1949  } else if (nested_elem_tk == enum_or_bitmask) {
1950  DDS::TypeDescriptor_var td;
1951  if (nested_elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
1952  return false;
1953  }
1954  const LBound bit_bound = td->bound()[0];
1955  return bit_bound >= lower && bit_bound <= upper &&
1956  skip_to_map_element(id) && read_values(value, nested_elem_tk);
1957  }
1958 
1959  if (DCPS::DCPS_debug_level >= 1) {
1960  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_values_from_map -")
1961  ACE_TEXT(" Could not read a sequence of %C from a map with element type sequence of %C\n"),
1962  typekind_to_string(ElementTypeKind), typekind_to_string(nested_elem_tk)));
1963  }
1964  return false;
1965 }
1966 
1967 template<TypeKind ElementTypeKind, typename SequenceType>
1969  TypeKind enum_or_bitmask, LBound lower, LBound upper)
1970 {
1971  if (!is_type_supported(ElementTypeKind, "get_sequence_values")) {
1972  return DDS::RETCODE_ERROR;
1973  }
1974 
1975  ScopedChainManager chain_manager(*this);
1976 
1977  const TypeKind tk = type_->get_kind();
1978  bool good = true;
1979 
1980  switch (tk) {
1981  case TK_STRUCTURE:
1982  {
1983  const DDS::ReturnCode_t rc =
1984  get_values_from_struct<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1985  if (rc == DDS::RETCODE_NO_DATA) {
1986  return rc;
1987  }
1988  good = rc == DDS::RETCODE_OK;
1989  }
1990  break;
1991  case TK_UNION:
1992  good = get_values_from_union<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1993  break;
1994  case TK_SEQUENCE:
1995  good = get_values_from_sequence<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1996  break;
1997  case TK_ARRAY:
1998  good = get_values_from_array<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
1999  break;
2000  case TK_MAP:
2001  good = get_values_from_map<ElementTypeKind>(value, id, enum_or_bitmask, lower, upper);
2002  break;
2003  default:
2004  if (DCPS::DCPS_debug_level >= 1) {
2005  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_sequence_values -")
2006  ACE_TEXT(" A sequence<%C> can't be read as a member of type %C"),
2007  typekind_to_string(ElementTypeKind), typekind_to_string(tk)));
2008  }
2009  return DDS::RETCODE_ERROR;
2010  }
2011 
2012  if (!good && DCPS::DCPS_debug_level >= 1) {
2013  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_sequence_values -")
2014  ACE_TEXT(" Failed to read sequence<%C> from a DynamicData object of type %C\n"),
2015  typekind_to_string(ElementTypeKind), typekind_to_string(tk)));
2016  }
2017  return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
2018 }
2019 
2021 {
2022  return get_sequence_values<TK_INT32>(value, id, TK_ENUM, 17, 32);
2023 }
2024 
2026 {
2027  return get_sequence_values<TK_UINT32>(value, id, TK_BITMASK, 17, 32);
2028 }
2029 
2031 {
2032  return get_sequence_values<TK_INT8>(value, id, TK_ENUM, 1, 8);
2033 }
2034 
2036 {
2037  return get_sequence_values<TK_UINT8>(value, id, TK_BITMASK, 1, 8);
2038 }
2039 
2041 {
2042  return get_sequence_values<TK_INT16>(value, id, TK_ENUM, 9, 16);
2043 }
2044 
2046 {
2047  return get_sequence_values<TK_UINT16>(value, id, TK_BITMASK, 9, 16);
2048 }
2049 
2051 {
2052  return get_sequence_values<TK_INT64>(value, id);
2053 }
2054 
2056 {
2057  return get_sequence_values<TK_UINT64>(value, id, TK_BITMASK, 33, 64);
2058 }
2059 
2061 {
2062  return get_sequence_values<TK_FLOAT32>(value, id);
2063 }
2064 
2066 {
2067  return get_sequence_values<TK_FLOAT64>(value, id);
2068 }
2069 
2071 {
2072  return get_sequence_values<TK_FLOAT128>(value, id);
2073 }
2074 
2076 {
2077  return get_sequence_values<TK_CHAR8>(value, id);
2078 }
2079 
2081 {
2082 #ifdef DDS_HAS_WCHAR
2083  return get_sequence_values<TK_CHAR16>(value, id);
2084 #else
2085  return DDS::RETCODE_UNSUPPORTED;
2086 #endif
2087 }
2088 
2090 {
2091  return get_sequence_values<TK_BYTE>(value, id);
2092 }
2093 
2095 {
2096  return get_sequence_values<TK_BOOLEAN>(value, id);
2097 }
2098 
2100 {
2101  return get_sequence_values<TK_STRING8>(value, id);
2102 }
2103 
2105 {
2106 #ifdef DDS_HAS_WCHAR
2107  return get_sequence_values<TK_STRING16>(value, id);
2108 #else
2109  return DDS::RETCODE_UNSUPPORTED;
2110 #endif
2111 }
2112 
2113 DDS::DynamicType_ptr DynamicDataXcdrReadImpl::type()
2114 {
2115  return DDS::DynamicType::_duplicate(type_);
2116 }
2117 
2119 {
2120  DynamicTypeNameSet dtns;
2121  return check_xcdr1_mutable_i(dt, dtns);
2122 }
2123 
2125 {
2126  // FUTURE: Implement this.
2127  ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: DynamicDataXcdrReadImpl::equals: Not implemented\n"));
2128  return false;
2129 }
2130 
2132 {
2133  DDS::TypeDescriptor_var descriptor;
2134  DDS::ReturnCode_t rc = type_->get_descriptor(descriptor);
2135  if (rc != DDS::RETCODE_OK) {
2136  return rc;
2137  }
2138 
2139  const DDS::ExtensibilityKind ek = descriptor->extensibility_kind();
2140  if (ek == DDS::FINAL || ek == DDS::APPENDABLE) {
2141  size_t dheader = 0;
2142  const bool xcdr2_appendable = encoding_.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2 &&
2143  ek == DDS::APPENDABLE;
2144  if (xcdr2_appendable && !strm_.read_delimiter(dheader)) {
2145  if (log_level >= LogLevel::Notice) {
2146  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member: "
2147  "Failed to read DHEADER for member ID %d\n", id));
2148  }
2149  return DDS::RETCODE_ERROR;
2150  }
2151  const size_t end_of_struct = strm_.rpos() + dheader;
2152 
2153  for (ACE_CDR::ULong i = 0; i < member_desc->index(); ++i) {
2154  DDS::DynamicTypeMember_var dtm;
2155  rc = type_->get_member_by_index(dtm, i);
2156  if (rc != DDS::RETCODE_OK) {
2157  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2158  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member:"
2159  " Failed to get DynamicTypeMember for member at index %d\n", i));
2160  }
2161  return rc;
2162  }
2163  DDS::MemberDescriptor_var md;
2164  rc = dtm->get_descriptor(md);
2165  if (rc != DDS::RETCODE_OK) {
2166  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2167  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_to_struct_member:"
2168  " Failed to get MemberDescriptor for member at index %d\n", i));
2169  }
2170  return rc;
2171  }
2172  if (exclude_member(extent_, md->is_key(), has_explicit_keys(type_))) {
2173  // This member is not present in the sample, don't need to do anything.
2174  continue;
2175  }
2176 
2177  ACE_CDR::ULong num_skipped;
2178  if (!skip_struct_member_at_index(i, num_skipped)) {
2179  if (DCPS::DCPS_debug_level >= 1) {
2180  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2181  ACE_TEXT(" Failed to skip member at index %d\n"), i));
2182  }
2183  return DDS::RETCODE_ERROR;
2184  }
2185  if (xcdr2_appendable && strm_.rpos() >= end_of_struct) {
2186  return DDS::RETCODE_NO_DATA;
2187  }
2188  }
2189  return DDS::RETCODE_OK;
2190  } else {
2191  size_t dheader = 0;
2192  if (!strm_.read_delimiter(dheader)) {
2193  if (DCPS::DCPS_debug_level >= 1) {
2194  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2195  ACE_TEXT(" Failed to read DHEADER for member ID %d\n"), id));
2196  }
2197  return DDS::RETCODE_ERROR;
2198  }
2199 
2200  const size_t end_of_struct = strm_.rpos() + dheader;
2201  while (true) {
2202  if (strm_.rpos() >= end_of_struct) {
2203  if (DCPS::DCPS_debug_level >= 1) {
2204  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2205  ACE_TEXT(" Could not find a member with ID %d\n"), id));
2206  }
2207  return DDS::RETCODE_NO_DATA;
2208  }
2209 
2210  ACE_CDR::ULong member_id;
2211  size_t member_size;
2212  bool must_understand;
2213  if (!strm_.read_parameter_id(member_id, member_size, must_understand)) {
2214  if (DCPS::DCPS_debug_level >= 1) {
2215  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2216  ACE_TEXT(" Failed to read EMHEADER while finding member ID %d\n"), id));
2217  }
2218  return DDS::RETCODE_ERROR;
2219  }
2220 
2221  if (member_id == id) {
2222  return DDS::RETCODE_OK;
2223  }
2224 
2225  if (!strm_.skip(member_size)) {
2226  if (DCPS::DCPS_debug_level >= 1) {
2227  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_to_struct_member -")
2228  ACE_TEXT(" Failed to skip a member with ID %d\n"), member_id));
2229  }
2230  return DDS::RETCODE_ERROR;
2231  }
2232  }
2233  }
2234 }
2235 
2236 bool DynamicDataXcdrReadImpl::get_from_struct_common_checks(const DDS::MemberDescriptor_var& md,
2237  MemberId id, TypeKind kind, bool is_sequence)
2238 {
2239  const DDS::DynamicType_ptr member_dt = md->type();
2240  if (!member_dt) {
2241  if (DCPS::DCPS_debug_level >= 1) {
2242  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2243  ACE_TEXT(" Could not get DynamicType for member with ID %d\n"), id));
2244  }
2245  return false;
2246  }
2247 
2248  const DDS::DynamicType_var member_type = get_base_type(member_dt);
2249  const TypeKind member_kind = member_type->get_kind();
2250 
2251  if ((!is_sequence && member_kind != kind) || (is_sequence && member_kind != TK_SEQUENCE)) {
2252  if (DCPS::DCPS_debug_level >= 1) {
2253  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2254  ACE_TEXT(" Member with ID %d has kind %C, not %C\n"),
2255  id, typekind_to_string(member_kind),
2256  is_sequence ? typekind_to_string(TK_SEQUENCE) : typekind_to_string(kind)));
2257  }
2258  return false;
2259  }
2260 
2261  if (member_kind == TK_SEQUENCE) {
2262  DDS::TypeDescriptor_var member_td;
2263  if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
2264  if (DCPS::DCPS_debug_level >= 1) {
2265  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2266  ACE_TEXT(" Could not get type descriptor for member %d\n"),
2267  id));
2268  }
2269  return false;
2270  }
2271  const TypeKind elem_kind = get_base_type(member_td->element_type())->get_kind();
2272  if (elem_kind != kind) {
2273  if (DCPS::DCPS_debug_level >= 1) {
2274  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::get_from_struct_common_checks -")
2275  ACE_TEXT(" Member with ID %d is a sequence of %C, not %C\n"),
2276  id, typekind_to_string(elem_kind), typekind_to_string(kind)));
2277  }
2278  return false;
2279  }
2280  }
2281 
2282  return true;
2283 }
2284 
2286 {
2287  DDS::DynamicTypeMember_var member;
2288  if (type_->get_member_by_index(member, index) != DDS::RETCODE_OK) {
2289  if (DCPS::DCPS_debug_level >= 1) {
2290  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_struct_member_at_index -")
2291  ACE_TEXT(" Failed to get DynamicTypeMember for member index %d\n"), index));
2292  }
2293  return false;
2294  }
2295 
2296  DDS::MemberDescriptor_var md;
2297  if (member->get_descriptor(md) != DDS::RETCODE_OK) {
2298  return false;
2299  }
2300  if (strm_.encoding().kind() == DCPS::Encoding::KIND_XCDR2 && md->is_optional()) {
2301  ACE_CDR::Boolean present;
2302  if (!(strm_ >> ACE_InputCDR::to_boolean(present))) {
2303  return false;
2304  }
2305  // Optional member that is omitted is not counted as a skipped member.
2306  if (!present) {
2307  num_skipped = 0;
2308  return true;
2309  }
2310  }
2311 
2312  num_skipped = 1;
2313  const DDS::DynamicType_ptr member_type = md->type();
2314  return member_type && skip_member(member_type);
2315 }
2316 
2317 bool DynamicDataXcdrReadImpl::skip_member(DDS::DynamicType_ptr type)
2318 {
2319  const DDS::DynamicType_var member_type = get_base_type(type);
2320  const TypeKind member_kind = member_type->get_kind();
2321 
2322  switch (member_kind) {
2323  case TK_BOOLEAN:
2324  case TK_BYTE:
2325  case TK_INT8:
2326  case TK_UINT8:
2327  case TK_CHAR8:
2328  if (!skip("skip_member", "Failed to skip a member of size 1 byte", 1, 1)) {
2329  return false;
2330  }
2331  break;
2332  case TK_INT16:
2333  case TK_UINT16:
2334  case TK_CHAR16:
2335  if (!skip("skip_member", "Failed to skip a member of size 2 bytes", 1, 2)) {
2336  return false;
2337  }
2338  break;
2339  case TK_INT32:
2340  case TK_UINT32:
2341  case TK_FLOAT32:
2342  if (!skip("skip_member", "Failed to skip a member of size 4 bytes", 1, 4)) {
2343  return false;
2344  }
2345  break;
2346  case TK_INT64:
2347  case TK_UINT64:
2348  case TK_FLOAT64:
2349  if (!skip("skip_member", "Failed to skip a member of size 8 bytes", 1, 8)) {
2350  return false;
2351  }
2352  break;
2353  case TK_FLOAT128:
2354  if (!skip("skip_member", "Failed to skip a member of size 16 bytes", 1, 16)) {
2355  return false;
2356  }
2357  break;
2358  case TK_STRING8:
2359  case TK_STRING16:
2360  {
2361  const char* str_kind = member_kind == TK_STRING8 ? "string" : "wstring";
2362  ACE_CDR::ULong bytes;
2363  if (!(strm_ >> bytes)) {
2364  if (DCPS::DCPS_debug_level >= 1) {
2365  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member -")
2366  ACE_TEXT(" Failed to read length of a %C member\n"), str_kind));
2367  }
2368  return false;
2369  }
2370 
2371  const DCPS::String err_msg = DCPS::String("Failed to skip a ") + str_kind + " member";
2372  if (!skip("skip_member", err_msg.c_str(), bytes)) {
2373  return false;
2374  }
2375  break;
2376  }
2377  case TK_ENUM:
2378  case TK_BITMASK:
2379  {
2380  DDS::TypeDescriptor_var member_td;
2381  if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
2382  return false;
2383  }
2384  const ACE_CDR::ULong bit_bound = member_td->bound()[0];
2385  const char* err_msg = member_kind == TK_ENUM ?
2386  "Failed to skip an enum member" : "Failed to skip a bitmask member";
2387 
2388  if (bit_bound >= 1 && bit_bound <= 8) {
2389  if (!skip("skip_member", err_msg, 1, 1)) {
2390  return false;
2391  }
2392  } else if (bit_bound >= 9 && bit_bound <= 16) {
2393  if (!skip("skip_member", err_msg, 1, 2)) {
2394  return false;
2395  }
2396  } else if (bit_bound >= 17 && bit_bound <= 32) {
2397  if (!skip("skip_member", err_msg, 1, 4)) {
2398  return false;
2399  }
2400  } else if (bit_bound >= 33 && bit_bound <= 64 && member_kind == TK_BITMASK) {
2401  if (!skip("skip_member", err_msg, 1, 8)) {
2402  return false;
2403  }
2404  } else {
2405  if (DCPS::DCPS_debug_level >= 1) {
2406  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member - Found a%C")
2407  ACE_TEXT(" member with bit bound %d\n"),
2408  member_kind == TK_ENUM ? "n enum" : " bitmask", bit_bound));
2409  }
2410  return false;
2411  }
2412  break;
2413  }
2414  case TK_STRUCTURE:
2415  case TK_UNION:
2416  return skip_aggregated_member(member_type);
2417  case TK_SEQUENCE:
2418  return skip_sequence_member(member_type);
2419  case TK_ARRAY:
2420  return skip_array_member(member_type);
2421  case TK_MAP:
2422  return skip_map_member(member_type);
2423  default:
2424  {
2425  if (DCPS::DCPS_debug_level >= 1) {
2426  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_member -")
2427  ACE_TEXT(" Found a member of kind %C\n"), typekind_to_string(member_kind)));
2428  }
2429  return false;
2430  }
2431  }
2432 
2433  return true;
2434 }
2435 
2436 bool DynamicDataXcdrReadImpl::skip_sequence_member(DDS::DynamicType_ptr seq_type)
2437 {
2438  DDS::TypeDescriptor_var descriptor;
2439  if (seq_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2440  return false;
2441  }
2442  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2443 
2444  ACE_CDR::ULong primitive_size = 0;
2445  if (get_primitive_size(elem_type, primitive_size)) {
2446  ACE_CDR::ULong length;
2447  if (!(strm_ >> length)) {
2448  if (DCPS::DCPS_debug_level >= 1) {
2449  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_sequence_member -")
2450  ACE_TEXT(" Failed to deserialize a primitive sequence member\n")));
2451  }
2452  return false;
2453  }
2454 
2455  return skip("skip_sequence_member", "Failed to skip a primitive sequence member",
2456  length, primitive_size);
2457  } else {
2458  return skip_collection_member(seq_type);
2459  }
2460 }
2461 
2462 bool DynamicDataXcdrReadImpl::skip_array_member(DDS::DynamicType_ptr array_type)
2463 {
2464  DDS::TypeDescriptor_var descriptor;
2465  if (array_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2466  return false;
2467  }
2468  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2469 
2470  ACE_CDR::ULong primitive_size = 0;
2471  if (get_primitive_size(elem_type, primitive_size)) {
2472  return skip("skip_array_member", "Failed to skip a primitive array member",
2473  bound_total(descriptor), primitive_size);
2474  } else {
2475  return skip_collection_member(array_type);
2476  }
2477 }
2478 
2479 bool DynamicDataXcdrReadImpl::skip_map_member(DDS::DynamicType_ptr map_type)
2480 {
2481  DDS::TypeDescriptor_var descriptor;
2482  if (map_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2483  return false;
2484  }
2485  const DDS::DynamicType_var elem_type = get_base_type(descriptor->element_type());
2486  const DDS::DynamicType_var key_type = get_base_type(descriptor->key_element_type());
2487 
2488  ACE_CDR::ULong key_primitive_size = 0, elem_primitive_size = 0;
2489  if (get_primitive_size(key_type, key_primitive_size) &&
2490  get_primitive_size(elem_type, elem_primitive_size)) {
2491  ACE_CDR::ULong length;
2492  if (!(strm_ >> length)) {
2493  if (DCPS::DCPS_debug_level >= 1) {
2494  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_map_member -")
2495  ACE_TEXT(" Failed to deserialize length of a primitive map member\n")));
2496  }
2497  return false;
2498  }
2499 
2500  for (unsigned i = 0; i < length; ++i) {
2501  if (!skip("skip_map_member", "Failed to skip a key of a primitive map member",
2502  1, key_primitive_size)) {
2503  return false;
2504  }
2505  if (!skip("skip_map_member", "Failed to skip an element of a primitive map member",
2506  1, elem_primitive_size)) {
2507  return false;
2508  }
2509  }
2510  return true;
2511  } else {
2512  return skip_collection_member(map_type);
2513  }
2514 }
2515 
2516 bool DynamicDataXcdrReadImpl::skip_collection_member(DDS::DynamicType_ptr coll_type)
2517 {
2518  const TypeKind kind = coll_type->get_kind();
2519  if (kind == TK_SEQUENCE || kind == TK_ARRAY || kind == TK_MAP) {
2520  const char* kind_str = typekind_to_string(kind);
2522  size_t dheader;
2523  if (!strm_.read_delimiter(dheader)) {
2524  if (DCPS::DCPS_debug_level >= 1) {
2525  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_collection_member -")
2526  ACE_TEXT(" Failed to deserialize DHEADER of a non-primitive %C member\n"),
2527  kind_str));
2528  }
2529  return false;
2530  }
2531  const DCPS::String err_msg = DCPS::String("Failed to skip a non-primitive ") + kind_str + " member";
2532  return skip("skip_collection_member", err_msg.c_str(), dheader);
2533  } else if (kind == TK_SEQUENCE) {
2534  return skip_to_sequence_element(0, coll_type);
2535  } else if (kind == TK_ARRAY) {
2536  return skip_to_array_element(0, coll_type);
2537  } else if (kind == TK_MAP) {
2538  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2539  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::skip_collection_member: "
2540  "DynamicData does not currently support XCDR1 maps\n"));
2541  }
2542  return false;
2543  }
2544  }
2545 
2546  return false;
2547 }
2548 
2549 bool DynamicDataXcdrReadImpl::skip_aggregated_member(DDS::DynamicType_ptr member_type)
2550 {
2551  DynamicDataXcdrReadImpl nested_data(strm_, member_type);
2552  if (!nested_data.skip_all()) {
2553  return false;
2554  }
2555 
2556  // Collect the intermediate message block chains that were created recursively
2557  // when skipping nested_data.
2558  const IntermediateChains& chains = nested_data.get_intermediate_chains();
2559  chains_to_release.insert(chains_to_release.end(), chains.begin(), chains.end());
2560 
2561  ACE_Message_Block* const result_chain = nested_data.strm_.current()->duplicate();
2562  strm_ = DCPS::Serializer(result_chain, encoding_);
2563  const DCPS::Serializer::RdState curr_state = nested_data.strm_.rdstate();
2564  strm_.rdstate(curr_state);
2565  chains_to_release.push_back(result_chain);
2566  return true;
2567 }
2568 
2570 {
2571  for (ACE_CDR::ULong i = 0; i < chains_to_release.size(); ++i) {
2573  }
2574  chains_to_release.clear();
2575 }
2576 
2577 bool DynamicDataXcdrReadImpl::read_discriminator(const DDS::DynamicType_ptr disc_type, DDS::ExtensibilityKind union_ek, ACE_CDR::Long& label)
2578 {
2579  if (union_ek == DDS::MUTABLE) {
2580  unsigned id;
2581  size_t size;
2582  bool must_understand;
2583  if (!strm_.read_parameter_id(id, size, must_understand)) { return false; }
2584  }
2585 
2586  const TypeKind disc_tk = disc_type->get_kind();
2587  switch (disc_tk) {
2588  case TK_BOOLEAN:
2589  {
2591  if (!(strm_ >> ACE_InputCDR::to_boolean(value))) { return false; }
2592  label = static_cast<ACE_CDR::Long>(value);
2593  return true;
2594  }
2595  case TK_BYTE:
2596  {
2598  if (!(strm_ >> ACE_InputCDR::to_octet(value))) { return false; }
2599  label = static_cast<ACE_CDR::Long>(value);
2600  return true;
2601  }
2602  case TK_CHAR8:
2603  {
2605  if (!(strm_ >> ACE_InputCDR::to_char(value))) { return false; }
2606  label = static_cast<ACE_CDR::Long>(value);
2607  return true;
2608  }
2609  case TK_CHAR16:
2610  {
2612  if (!(strm_ >> ACE_InputCDR::to_wchar(value))) { return false; }
2613  label = static_cast<ACE_CDR::Long>(value);
2614  return true;
2615  }
2616  case TK_INT8:
2617  {
2619  if (!(strm_ >> ACE_InputCDR::to_int8(value))) { return false; }
2620  label = static_cast<ACE_CDR::Long>(value);
2621  return true;
2622  }
2623  case TK_UINT8:
2624  {
2626  if (!(strm_ >> ACE_InputCDR::to_uint8(value))) { return false; }
2627  label = static_cast<ACE_CDR::Long>(value);
2628  return true;
2629  }
2630  case TK_INT16:
2631  {
2633  if (!(strm_ >> value)) { return false; }
2634  label = static_cast<ACE_CDR::Long>(value);
2635  return true;
2636  }
2637  case TK_UINT16:
2638  {
2640  if (!(strm_ >> value)) { return false; }
2641  label = static_cast<ACE_CDR::Long>(value);
2642  return true;
2643  }
2644  case TK_INT32:
2645  return strm_ >> label;
2646  case TK_UINT32:
2647  {
2649  if (!(strm_ >> value)) { return false; }
2650  label = static_cast<ACE_CDR::Long>(value);
2651  return true;
2652  }
2653  case TK_INT64:
2654  {
2656  if (!(strm_ >> value)) { return false; }
2657  label = static_cast<ACE_CDR::Long>(value);
2658  return true;
2659  }
2660  case TK_UINT64:
2661  {
2663  if (!(strm_ >> value)) { return false; }
2664  label = static_cast<ACE_CDR::Long>(value);
2665  return true;
2666  }
2667  case TK_ENUM:
2668  {
2669  DDS::TypeDescriptor_var disc_td;
2670  if (disc_type->get_descriptor(disc_td) != DDS::RETCODE_OK) {
2671  return false;
2672  }
2673  const ACE_CDR::ULong bit_bound = disc_td->bound()[0];
2674  if (bit_bound >= 1 && bit_bound <= 8) {
2676  if (!(strm_ >> ACE_InputCDR::to_int8(value))) { return false; }
2677  label = static_cast<ACE_CDR::Long>(value);
2678  } else if (bit_bound >= 9 && bit_bound <= 16) {
2680  if (!(strm_ >> value)) { return false; }
2681  label = static_cast<ACE_CDR::Long>(value);
2682  } else {
2683  return strm_ >> label;
2684  }
2685  return true;
2686  }
2687  default:
2688  if (DCPS::DCPS_debug_level >= 1) {
2689  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::read_discriminator - Union has")
2690  ACE_TEXT(" unsupported discriminator type (%C)\n"), typekind_to_string(disc_tk)));
2691  }
2692  return false;
2693  }
2694 }
2695 
2697 {
2698  DDS::TypeDescriptor_var descriptor;
2699  if (type_->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2700  return false;
2701  }
2702 
2703  const TypeKind tk = type_->get_kind();
2704  if (tk != TK_STRUCTURE && tk != TK_UNION) {
2705  return false;
2706  }
2707 
2708  const DDS::ExtensibilityKind extensibility = descriptor->extensibility_kind();
2709  if (strm_.encoding().kind() == DCPS::Encoding::KIND_XCDR2 && (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE)) {
2710  size_t dheader;
2711  if (!strm_.read_delimiter(dheader)) {
2712  if (DCPS::DCPS_debug_level >= 1) {
2713  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_all - Failed to read")
2714  ACE_TEXT(" DHEADER of the DynamicData object\n")));
2715  }
2716  return false;
2717  }
2718  return skip("skip_all", "Failed to skip the whole DynamicData object\n", dheader);
2719  } else {
2720  if (tk == TK_STRUCTURE) {
2721  const ACE_CDR::ULong member_count = type_->get_member_count();
2722  bool good = true;
2723  for (ACE_CDR::ULong i = 0; i < member_count; ++i) {
2724  ACE_CDR::ULong num_skipped;
2725  if (!skip_struct_member_at_index(i, num_skipped)) {
2726  good = false;
2727  break;
2728  }
2729  }
2730  return good;
2731  } else { // Union
2732  const DDS::DynamicType_var disc_type = get_base_type(descriptor->discriminator_type());
2733  ACE_CDR::Long label;
2734  if (!read_discriminator(disc_type, extensibility, label)) {
2735  return false;
2736  }
2737 
2738  DDS::DynamicTypeMembersById_var members;
2739  if (type_->get_all_members(members) != DDS::RETCODE_OK) {
2740  return false;
2741  }
2742  DynamicTypeMembersByIdImpl* members_impl = dynamic_cast<DynamicTypeMembersByIdImpl*>(members.in());
2743  if (!members_impl) {
2744  return false;
2745  }
2746 
2747  bool has_default = false;
2748  DDS::MemberDescriptor_var default_member;
2749  for (DynamicTypeMembersByIdImpl::const_iterator it = members_impl->begin(); it != members_impl->end(); ++it) {
2750  DDS::MemberDescriptor_var md;
2751  if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
2752  return false;
2753  }
2754  const DDS::UnionCaseLabelSeq& labels = md->label();
2755  for (ACE_CDR::ULong i = 0; i < labels.length(); ++i) {
2756  if (label == labels[i]) {
2757  const DDS::DynamicType_ptr selected_member = md->type();
2758  bool good = selected_member && skip_member(selected_member);
2759  return good;
2760  }
2761  }
2762 
2763  if (md->is_default_label()) {
2764  has_default = true;
2765  default_member = md;
2766  }
2767  }
2768 
2769  if (has_default) {
2770  const DDS::DynamicType_ptr default_dt = default_member->type();
2771  bool good = default_dt && skip_member(default_dt);
2772  return good;
2773  }
2774  if (DCPS::DCPS_debug_level >= 1) {
2775  ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::skip_all - Skip a union with no")
2776  ACE_TEXT(" selected member and a discriminator with value %d\n"), label));
2777  }
2778  return true;
2779  }
2780  }
2781 }
2782 
2783 bool DynamicDataXcdrReadImpl::skip(const char* func_name, const char* description, size_t n, int size)
2784 {
2785  if (!strm_.skip(n, size)) {
2786  if (DCPS::DCPS_debug_level >= 1) {
2787  ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) DynamicDataXcdrReadImpl::%C - %C\n"), func_name, description));
2788  }
2789  return false;
2790  }
2791  return true;
2792 }
2793 
2794 bool DynamicDataXcdrReadImpl::get_primitive_size(DDS::DynamicType_ptr dt, ACE_CDR::ULong& size) const
2795 {
2796  size = 0;
2797 
2798  switch (dt->get_kind()) {
2799  case TK_BOOLEAN:
2800  case TK_BYTE:
2801  case TK_INT8:
2802  case TK_UINT8:
2803  case TK_CHAR8:
2804  size = 1;
2805  break;
2806  case TK_INT16:
2807  case TK_UINT16:
2808  case TK_CHAR16:
2809  size = 2;
2810  break;
2811  case TK_INT32:
2812  case TK_UINT32:
2813  case TK_FLOAT32:
2814  size = 4;
2815  break;
2816  case TK_INT64:
2817  case TK_UINT64:
2818  case TK_FLOAT64:
2819  size = 8;
2820  break;
2821  case TK_FLOAT128:
2822  size = 16;
2823  break;
2824  default:
2825  return false;
2826  }
2827  return true;
2828 }
2829 
2830 bool DynamicDataXcdrReadImpl::check_xcdr1_mutable_i(DDS::DynamicType_ptr dt, DynamicTypeNameSet& dtns)
2831 {
2832  DDS::TypeDescriptor_var descriptor;
2833  if (dt->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2834  return false;
2835  }
2836 
2837  if (dtns.find(descriptor->name()) != dtns.end()) {
2838  return true;
2839  }
2840  if (descriptor->extensibility_kind() == DDS::MUTABLE &&
2842  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2843  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::check_xcdr1_mutable: "
2844  "XCDR1 mutable is not currently supported in OpenDDS\n"));
2845  }
2846  return false;
2847  }
2848  dtns.insert(descriptor->name());
2849  for (ACE_CDR::ULong i = 0; i < dt->get_member_count(); ++i) {
2850  DDS::DynamicTypeMember_var dtm;
2851  if (dt->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
2852  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
2853  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataXcdrReadImpl::check_xcdr1_mutable: "
2854  "Failed to get member from DynamicType\n"));
2855  }
2856  return false;
2857  }
2858  DDS::MemberDescriptor_var descriptor;
2859  if (dtm->get_descriptor(descriptor) != DDS::RETCODE_OK) {
2860  return false;
2861  }
2862  if (!check_xcdr1_mutable_i(descriptor->type(), dtns)) {
2863  return false;
2864  }
2865  }
2866  return true;
2867 }
2868 
2869 #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
2870 namespace {
2871  template <typename T>
2874  {
2875  T v;
2876  const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2877  if (ret == DDS::RETCODE_OK) {
2878  value = v;
2879  }
2880  return ret;
2881  }
2882 
2883  DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn,
2885  {
2887  const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2888  if (ret == DDS::RETCODE_OK) {
2889  value = v.in();
2890  }
2891  return ret;
2892  }
2893 
2894  DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn,
2896  {
2898  const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id);
2899  if (ret == DDS::RETCODE_OK) {
2900  value = v.in();
2901  }
2902  return ret;
2903  }
2904 }
2905 
2907 {
2908  DDS::DynamicTypeMember_var dtm;
2909  if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
2910  return DDS::RETCODE_ERROR;
2911  }
2912  DDS::MemberDescriptor_var md;
2913  if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
2914  return DDS::RETCODE_ERROR;
2915  }
2916  DDS::DynamicType_var member_type = get_base_type(md->type());
2917  const TypeKind member_kind = member_type->get_kind();
2918  switch (member_kind) {
2919  case TK_BOOLEAN:
2920  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_boolean_value);
2921  case TK_BYTE:
2922  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_byte_value);
2923  case TK_INT8:
2924  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int8_value);
2925  case TK_INT16:
2926  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int16_value);
2927  case TK_INT32:
2928  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int32_value);
2929  case TK_INT64:
2930  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int64_value_impl);
2931  case TK_UINT8:
2932  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint8_value);
2933  case TK_UINT16:
2934  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint16_value);
2935  case TK_UINT32:
2936  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint32_value);
2937  case TK_UINT64:
2938  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint64_value_impl);
2939  case TK_FLOAT32:
2940  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float32_value);
2941  case TK_FLOAT64:
2942  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float64_value);
2943  case TK_FLOAT128:
2944  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float128_value);
2945  case TK_CHAR8:
2946  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char8_value);
2947  case TK_CHAR16:
2948  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char16_value);
2949  case TK_ENUM:
2950  case TK_STRING8:
2951  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_string_value);
2952  case TK_STRING16:
2953  return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_wstring_value);
2954  default:
2955  return DDS::RETCODE_UNSUPPORTED;
2956  }
2957 }
2958 #endif
2959 
2960 #ifndef OPENDDS_SAFETY_PROFILE
2961 bool print_member(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent,
2962  MemberId member_id);
2963 
2964 bool print_members(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent, bool print_name)
2965 {
2966  DCPS::String temp_indent = indent;
2967  indent += " ";
2968  const DDS::DynamicType_var type = dd->type();
2969  const DDS::DynamicType_var base_type = get_base_type(type);
2970  const char* const kind = base_type->get_kind() == TK_STRUCTURE ? "struct" : "union";
2971  if (print_name) {
2972  CORBA::String_var type_name = type->get_name();
2973  type_string += DCPS::String(kind) + " " + DCPS::String(type_name);
2974  }
2975  type_string += "\n";
2976 
2977  const ACE_CDR::ULong item_count = dd->get_item_count();
2978  for (ACE_CDR::ULong idx = 0; idx != item_count; ++idx) {
2979  // Translate the item number into a MemberId.
2980  const MemberId member_id = dd->get_member_id_at_index(idx);
2981  if (member_id == MEMBER_ID_INVALID) {
2982  if (log_level >= LogLevel::Notice) {
2983  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_members: "
2984  "failed to get %C member at index %u\n", kind, idx));
2985  }
2986  return false;
2987  }
2988 
2989  if (!print_member(dd, type_string, indent, member_id)) {
2990  if (log_level >= LogLevel::Notice) {
2991  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_members: "
2992  "failed to print %C member with id %u\n", kind, member_id));
2993  }
2994  return false;
2995  }
2996  }
2997 
2998  indent = temp_indent;
2999  return true;
3000 }
3001 
3002 bool print_member(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent,
3003  MemberId member_id)
3004 {
3005  DDS::DynamicType_ptr member_type;
3006  DDS::MemberDescriptor_var member_descriptor;
3007  const DDS::DynamicType_var container_type = dd->type();
3008  const DDS::TypeKind container_kind = container_type->get_kind();
3009  const bool sequence_like = is_sequence_like(container_kind);
3010  if (sequence_like) {
3011  DDS::TypeDescriptor_var td;
3012  if (container_type->get_descriptor(td) != DDS::RETCODE_OK) {
3013  return false;
3014  }
3015  member_type = td->element_type();
3016 
3017  } else {
3018  DDS::DynamicTypeMember_var dtm;
3019  if (container_type->get_member(dtm, member_id) != DDS::RETCODE_OK) {
3020  return false;
3021  }
3022  if (dtm->get_descriptor(member_descriptor) != DDS::RETCODE_OK) {
3023  return false;
3024  }
3025  member_type = member_descriptor->type();
3026  }
3027 
3028  const DDS::DynamicType_var member_base_type = get_base_type(member_type);
3029  const DDS::TypeKind tk = member_base_type->get_kind();
3030  DDS::TypeDescriptor_var member_type_descriptor;
3031  if (member_base_type->get_descriptor(member_type_descriptor) != DDS::RETCODE_OK) {
3032  return false;
3033  }
3034 
3035  if (member_descriptor) {
3036  type_string += indent;
3037  const bool struct_or_union = tk == TK_STRUCTURE || tk == TK_UNION;
3038  if (struct_or_union) {
3039  type_string += (tk == TK_STRUCTURE ? "struct " : "union ");
3040  }
3041  const CORBA::String_var member_type_name = member_type->get_name();
3042  const DCPS::String member_name = member_descriptor->name();
3043  type_string += DCPS::String(member_type_name.in()) + " " + member_name;
3044  if (!struct_or_union) {
3045  type_string += " ";
3046  }
3047  if (tk == TK_ARRAY || tk == TK_SEQUENCE) {
3048  DDS::TypeDescriptor_var td;
3049  const DDS::DynamicType_var elem_type = get_base_type(member_type_descriptor->element_type());
3050  if (elem_type->get_descriptor(td) != DDS::RETCODE_OK) {
3051  return false;
3052  }
3053  DCPS::String ele_type_name = td->name();
3054  type_string += ele_type_name;
3055  }
3056  }
3057 
3058  if (!is_complex(tk)) {
3059  type_string += "= ";
3060  }
3061 
3062  switch (tk) {
3063  case TK_ENUM: {
3064  DDS::Int32 value;
3065  if (get_enum_value(value, member_base_type, dd, member_id) != DDS::RETCODE_OK) {
3066  return false;
3067  }
3068  DDS::String8_var name;
3069  if (get_enumerator_name(name, value, member_base_type) == DDS::RETCODE_OK) {
3070  type_string += name.in();
3071  } else {
3072  type_string += DCPS::to_dds_string(value);
3073  }
3074  type_string += "\n";
3075  break;
3076  }
3077  case TK_INT8:
3078  case TK_INT16:
3079  case TK_INT32:
3080  case TK_INT64: {
3081  DDS::Int64 value;
3082  if (get_int_value(value, dd, member_id, tk) != DDS::RETCODE_OK) {
3083  return false;
3084  }
3085  type_string += DCPS::to_dds_string(value) + "\n";
3086  break;
3087  }
3088  case TK_UINT8:
3089  case TK_UINT16:
3090  case TK_UINT32:
3091  case TK_UINT64: {
3092  DDS::UInt64 value;
3093  if (get_uint_value(value, dd, member_id, tk) != DDS::RETCODE_OK) {
3094  return false;
3095  }
3096  type_string += DCPS::to_dds_string(value) + "\n";
3097  break;
3098  }
3099  case TK_BOOLEAN: {
3100  ACE_CDR::Boolean my_bool;
3101  if (dd->get_boolean_value(my_bool, member_id) != DDS::RETCODE_OK) {
3102  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3103  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_boolean_value\n"));
3104  }
3105  return false;
3106  }
3107  DCPS::String bool_string = my_bool ? "true" : "false";
3108  type_string += bool_string + "\n";
3109  break;
3110  }
3111  case TK_BYTE: {
3112  ACE_CDR::Octet my_byte;
3113  if (dd->get_byte_value(my_byte, member_id) != DDS::RETCODE_OK) {
3114  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3115  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_byte_value\n"));
3116  }
3117  return false;
3118  }
3119  std::stringstream os;
3120  os << std::hex << std::setfill('0') << std::setw(2) << int(my_byte);
3121  type_string += "0x" + os.str() + "\n";
3122  break;
3123  }
3124  case TK_CHAR8: {
3125  ACE_CDR::Char my_char;
3126  if (dd->get_char8_value(my_char, member_id) != DDS::RETCODE_OK) {
3127  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3128  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_char8_value\n"));
3129  }
3130  return false;
3131  }
3132  std::stringstream os;
3133  DCPS::char_helper<ACE_CDR::Char>(os, my_char);
3134  type_string += "'" + os.str() + "'\n";
3135  break;
3136  }
3137 #ifdef DDS_HAS_WCHAR
3138  case TK_CHAR16: {
3139  ACE_CDR::WChar my_wchar;
3140  if (dd->get_char16_value(my_wchar, member_id) != DDS::RETCODE_OK) {
3141  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3142  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_char16_value\n"));
3143  }
3144  return false;
3145  }
3146  std::stringstream os;
3147  DCPS::char_helper<ACE_CDR::WChar>(os, my_wchar);
3148  type_string += "L'" + os.str() + "'\n";
3149  break;
3150  }
3151 #endif
3152  case TK_FLOAT32: {
3153  ACE_CDR::Float my_float;
3154  if (dd->get_float32_value(my_float, member_id) != DDS::RETCODE_OK) {
3155  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3156  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float32_value\n"));
3157  }
3158  return false;
3159  }
3160  std::stringstream os;
3161  os << my_float;
3162  type_string += os.str() + "\n";
3163  break;
3164  }
3165  case TK_FLOAT64: {
3166  ACE_CDR::Double my_double;
3167  if (dd->get_float64_value(my_double, member_id) != DDS::RETCODE_OK) {
3168  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3169  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float64_value\n"));
3170  }
3171  return false;
3172  }
3173  std::stringstream os;
3174  os << my_double;
3175  type_string += os.str() + "\n";
3176  break;
3177  }
3178  case TK_FLOAT128: {
3179  ACE_CDR::LongDouble my_longdouble;
3180  if (dd->get_float128_value(my_longdouble, member_id) != DDS::RETCODE_OK) {
3181  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3182  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_float128_value\n"));
3183  }
3184  return false;
3185  }
3186  std::stringstream os;
3187  os << my_longdouble;
3188  type_string += os.str() + "\n";
3189  break;
3190  }
3191  case TK_STRING8: {
3192  CORBA::String_var my_string;
3193  if (dd->get_string_value(my_string, member_id) != DDS::RETCODE_OK) {
3194  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3195  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_string_value\n"));
3196  }
3197  return false;
3198  }
3199  std::stringstream os;
3200  DCPS::string_helper(os, my_string.inout());
3201  type_string += DCPS::String("\"") + os.str() + "\"\n";
3202  break;
3203  }
3204 #ifdef DDS_HAS_WCHAR
3205  case TK_STRING16: {
3206  CORBA::WString_var my_wstring;
3207  if (dd->get_wstring_value(my_wstring, member_id) != DDS::RETCODE_OK) {
3208  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3209  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: failed to get_wstring_value\n"));
3210  }
3211  return false;
3212  }
3213  std::stringstream os;
3214  DCPS::string_helper(os, my_wstring.inout());
3215  type_string += "L\"" + os.str() + "\"\n";
3216  break;
3217  }
3218 #endif
3219  case TK_BITMASK:
3220  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3221  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: Bitmask is an unsupported type in OpenDDS\n"));
3222  }
3223  break;
3224  case TK_BITSET:
3225  if (DCPS::log_level >= DCPS::LogLevel::Notice) {
3226  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: Bitset is an unsupported type in OpenDDS\n"));
3227  }
3228  break;
3229  case TK_ARRAY:
3230  case TK_SEQUENCE: {
3231  DCPS::String temp_indent = indent;
3232  indent += " ";
3233  DDS::DynamicData_var temp_dd;
3234  if (dd->get_complex_value(temp_dd, member_id) != DDS::RETCODE_OK) {
3235  return false;
3236  }
3237  const ACE_CDR::ULong count = temp_dd->get_item_count();
3238  type_string += "[" + DCPS::to_dds_string(count) + "] =\n";
3239  for (ACE_CDR::ULong i = 0; i < count; ++i) {
3240  type_string += indent + "[" + DCPS::to_dds_string(i) + "] ";
3241  if (!print_member(temp_dd, type_string, indent, temp_dd->get_member_id_at_index(i))) {
3242  if (log_level >= LogLevel::Notice) {
3243  ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: print_member: "
3244  "failed to read array/sequence member\n"));
3245  }
3246  return false;
3247  }
3248  }
3249  indent = temp_indent;
3250  break;
3251  }
3252  case TK_UNION:
3253  case TK_STRUCTURE: {
3254  DDS::DynamicData_var temp_dd;
3255  if (dd->get_complex_value(temp_dd, member_id) != DDS::RETCODE_OK) {
3256  return false;
3257  }
3258  if (!print_members(temp_dd, type_string, indent, sequence_like)) {
3259  return false;
3260  }
3261  break;
3262  }
3263  }
3264 
3265  return true;
3266 }
3267 
3268 bool print_dynamic_data(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent)
3269 {
3270  const DDS::DynamicType_var type = dd->type();
3271  const DDS::DynamicType_var base_type = get_base_type(type);
3272 
3273  bool result;
3274  switch (base_type->get_kind()) {
3275  case TK_STRUCTURE:
3276  case TK_UNION:
3277  result = print_members(dd, type_string, indent, true);
3278  break;
3279  default:
3280  result = false;
3281  }
3282  return result;
3283 }
3284 #endif
3285 
3286 } // namespace XTypes
3287 } // namespace OpenDDS
3288 
3290 
3291 #endif // OPENDDS_SAFETY_PROFILE
DDS::ReturnCode_t get_int32_values(DDS::Int32Seq &value, DDS::MemberId id)
ACE_Byte Octet
bool read_delimiter(size_t &size)
Definition: Serializer.inl:912
#define ACE_DEBUG(X)
const TypeKind TK_SEQUENCE
Definition: TypeObject.h:248
bool skip(const char *func_name, const char *description, size_t n, int size=1)
DDS::ReturnCode_t get_uint64_values(DDS::UInt64Seq &value, DDS::MemberId id)
size_t rpos() const
Examine the logical reading position of the stream.
Definition: Serializer.h:475
sequence< unsigned short > UInt16Seq
#define ACE_ERROR(X)
bool skip_collection_member(DDS::DynamicType_ptr coll_type)
bool get_value_from_collection(ElementType &value, MemberId id, TypeKind collection_tk, TypeKind enum_or_bitmask=TK_NONE, LBound lower=0, LBound upper=0)
bool is_complex(TypeKind tk)
sequence< long > Int32Seq
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
ACE_INT64 LongLong
sequence< wchar > WcharSeq
bool struct_has_explicit_keys(AST_Structure *node)
const LogLevel::Value value
Definition: debug.cpp:61
DDS::ReturnCode_t get_int64_values(DDS::Int64Seq &value, DDS::MemberId id)
const TypeKind TK_INT32
Definition: TypeObject.h:217
DDS::ReturnCode_t get_float64_values(DDS::Float64Seq &value, DDS::MemberId id)
std::string String
void release(T x)
const TypeKind TK_STRING16
Definition: TypeObject.h:232
const TypeKind TK_FLOAT128
Definition: TypeObject.h:224
DDS::ReturnCode_t get_float32_value(CORBA::Float &value, DDS::MemberId id)
const TypeKind TK_BYTE
Definition: TypeObject.h:215
Object(TAO_Stub *p, CORBA::Boolean collocated=false, TAO_Abstract_ServantBase *servant=0, TAO_ORB_Core *orb_core=0)
Definition: Object.cpp:21
void wstring_free(WChar *const)
const TypeKind TK_UNION
Definition: TypeObject.h:244
bool get_values_from_union(SequenceType &value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
sequence< char > CharSeq
bool skip(size_t n, int size=1)
Definition: Serializer.inl:443
sequence< long long > Int64Seq
const TypeKind TK_INT16
Definition: TypeObject.h:216
String to_dds_string(unsigned short to_convert)
bool is_type_supported(TypeKind tk, const char *func_name)
Verify that a given type is primitive or string or wstring.
bool skip_to_sequence_element(MemberId id, DDS::DynamicType_ptr coll_type=0)
DDS::DynamicType_var get_base_type(DDS::DynamicType_ptr type)
const ACE_CDR::ULong DISCRIMINATOR_ID
Implementation specific sentinel for a union discriminator used in DynamicData.
Definition: TypeObject.h:913
const TypeKind TK_UINT16
Definition: TypeObject.h:219
ACE_UINT64 ULongLong
DDS::ReturnCode_t get_int8_values(DDS::Int8Seq &value, DDS::MemberId id)
bool print_member(DDS::DynamicData_ptr dd, DCPS::String &type_string, DCPS::String &indent, MemberId member_id)
DDS::TypeDescriptor_var type_desc_
bool read_parameter_id(unsigned &id, size_t &size, bool &must_understand)
Definition: Serializer.cpp:707
DDS::ReturnCode_t get_char16_values(DDS::WcharSeq &value, DDS::MemberId id)
DDS::ReturnCode_t get_single_value(ValueType &value, MemberId id, TypeKind enum_or_bitmask=TK_NONE, LBound lower=0, LBound upper=0)
DDS::ReturnCode_t get_value_from_struct(MemberType &value, MemberId id, TypeKind enum_or_bitmask=TK_NONE, LBound lower=0, LBound upper=0)
bool get_values_from_array(SequenceType &value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
bool is_primitive(TypeKind tk)
const TypeKind TK_INT8
Definition: TypeObject.h:225
size_t strlen(const char *s)
DDS::ReturnCode_t get_complex_value(DDS::DynamicData_ptr &value, DDS::MemberId id)
public unsigned long index
sequence< short > Int16Seq
bool skip_to_array_element(MemberId id, DDS::DynamicType_ptr coll_type=0)
DDS::ReturnCode_t get_uint64_value_impl(CORBA::ULongLong &value, DDS::MemberId id)
DDS::MemberDescriptor * get_from_union_common_checks(MemberId id, const char *func_name)
DDS::ReturnCode_t get_int16_value(CORBA::Short &value, DDS::MemberId id)
DDS::ReturnCode_t get_string_value(char *&value, DDS::MemberId id)
bool is_sequence_like(TypeKind tk)
DDS::MemberId get_member_id_at_index(ACE_CDR::ULong index)
ACE_CDR::Octet TypeKind
Definition: TypeObject.h:210
DDS::ReturnCode_t get_byte_values(DDS::ByteSeq &value, DDS::MemberId id)
bool has_optional_member(bool &has_optional) const
DDS::ReturnCode_t get_sequence_values(SequenceType &value, MemberId id, TypeKind enum_or_bitmask=TK_NONE, LBound lower=0, LBound upper=0)
Common method to read a value sequence of any type (primitive, string, wstring).
LM_DEBUG
ACE_INT16 Short
bool get_primitive_size(DDS::DynamicType_ptr dt, ACE_CDR::ULong &size) const
sequence< unsigned long long > UInt64Seq
DDS::ReturnCode_t get_descriptor(DDS::MemberDescriptor *&value, MemberId id)
sequence< boolean > BooleanSeq
Class to serialize and deserialize data for DDS.
Definition: Serializer.h:369
bool read_discriminator(const DDS::DynamicType_ptr disc_type, DDS::ExtensibilityKind union_ek, ACE_CDR::Long &label)
bool skip_sequence_member(DDS::DynamicType_ptr type)
const TypeKind TK_BOOLEAN
Definition: TypeObject.h:214
const char * typekind_to_string(TypeKind tk)
DDS::ReturnCode_t get_enum_value(DDS::Int32 &value, DDS::DynamicType_ptr enum_type, DDS::DynamicData_ptr src, DDS::MemberId id)
static bool has_explicit_keys(DDS::DynamicType *dt)
DDS::ReturnCode_t get_uint32_value(CORBA::ULong &value, DDS::MemberId id)
sequence< uint8 > UInt8Seq
bool print_members(DDS::DynamicData_ptr dd, DCPS::String &type_string, DCPS::String &indent, bool print_name)
char Char
ACE_CDR::Boolean Boolean
sequence< octet > ByteSeq
const TypeKind TK_BITMASK
Definition: TypeObject.h:239
DDS::ReturnCode_t get_char16_value(CORBA::WChar &value, DDS::MemberId id)
DDS::ReturnCode_t get_boolean_values(DDS::BooleanSeq &value, DDS::MemberId id)
ACE_UINT16 UShort
ACE_Message_Block * current() const
Definition: Serializer.h:480
bool get_values_from_map(SequenceType &value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
DDS::ReturnCode_t get_char8_value(CORBA::Char &value, DDS::MemberId id)
virtual ACE_Message_Block * release(void)
LM_NOTICE
sequence< unsigned long > UInt32Seq
bool get_index_from_id(DDS::MemberId id, ACE_CDR::ULong &index, ACE_CDR::ULong bound) const
virtual ACE_Message_Block * duplicate(void) const
sequence< long double > Float128Seq
DDS::ReturnCode_t get_float128_values(DDS::Float128Seq &value, DDS::MemberId id)
DDS::UInt32 bound_total(DDS::TypeDescriptor_var descriptor)
static bool exclude_member(DCPS::Sample::Extent ext, bool is_key, bool has_explicit_keys)
bool get_values_from_sequence(SequenceType &value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
const TypeKind TK_CHAR8
Definition: TypeObject.h:227
const ACE_CDR::ULong MEMBER_ID_INVALID
Definition: TypeObject.h:911
DDS::DynamicType_var type_
The actual (i.e., non-alias) DynamicType of the associated type.
sequence< float > Float32Seq
bool get_boolean_from_bitmask(ACE_CDR::ULong index, ACE_CDR::Boolean &value)
void string_free(char *)
character_type *& inout(void)
ACE_UINT32 ULong
The End User API.
DDS::ReturnCode_t get_int64_value_impl(CORBA::LongLong &value, DDS::MemberId id)
DDS::ReturnCode_t set_descriptor(MemberId id, DDS::MemberDescriptor *value)
const TypeKind TK_STRUCTURE
Definition: TypeObject.h:243
DDS::ReturnCode_t get_uint16_value(CORBA::UShort &value, DDS::MemberId id)
const char *const name
Definition: debug.cpp:60
DDS::ReturnCode_t get_wstring_value(CORBA::WChar *&value, DDS::MemberId id)
const IntermediateChains & get_intermediate_chains() const
const TypeKind TK_FLOAT32
Definition: TypeObject.h:222
bool exclude_struct_member(MemberId id, DDS::MemberDescriptor_var &md) const
Check if a member with a given id is excluded from struct sample.
ACE_TEXT("TCP_Factory")
bool skip_array_member(DDS::DynamicType_ptr type)
const TypeKind TK_STRING8
Definition: TypeObject.h:231
bool get_from_struct_common_checks(const DDS::MemberDescriptor_var &md, MemberId id, TypeKind kind, bool is_sequence=false)
ACE_INT32 Long
DDS::ReturnCode_t get_values_from_struct(SequenceType &value, MemberId id, TypeKind enum_or_bitmask, LBound lower, LBound upper)
XcdrVersion xcdr_version() const
Definition: Serializer.inl:127
ExtensibilityKind
DDS::ReturnCode_t get_char8_values(DDS::CharSeq &value, DDS::MemberId id)
const ReturnCode_t RETCODE_NO_DATA
CORBA::Boolean equals(DDS::DynamicData_ptr other)
DDS::ReturnCode_t get_value_from_union(MemberType &value, MemberId id, TypeKind enum_or_bitmask=TK_NONE, LBound lower=0, LBound upper=0)
OpenDDS_Dcps_Export unsigned int DCPS_debug_level
Definition: debug.cpp:30
const TypeKind TK_UINT64
Definition: TypeObject.h:221
OpenDDS_Dcps_Export LogLevel log_level
DDS::ReturnCode_t get_int8_value(CORBA::Int8 &value, DDS::MemberId id)
sequence< wstring > WstringSeq
DDS::ReturnCode_t clear_value(DDS::MemberId id)
DDS::DynamicData_ptr loan_value(DDS::MemberId id)
const TypeKind TK_INT64
Definition: TypeObject.h:218
bool check_xcdr1_mutable_i(DDS::DynamicType_ptr dt, DynamicTypeNameSet &dtns)
const TypeKind TK_UINT32
Definition: TypeObject.h:220
const Encoding & encoding() const
Definition: Serializer.inl:199
const ReturnCode_t RETCODE_ERROR
std::ostream & string_helper(std::ostream &o, const CharType *value)
Definition: ValueHelper.h:108
ACE_INT8 Int8
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
DDS::ReturnCode_t get_enumerator_name(DDS::String8_var &name, DDS::Int32 value, DDS::DynamicType_ptr type)
bool read_value(ValueType &value, TypeKind tk)
const TypeKind TK_ENUM
Definition: TypeObject.h:238
DDS::MemberDescriptor * get_union_selected_member()
Return the member descriptor for the selected member from a union data or null.
static DCPS::Sample::Extent nested(DCPS::Sample::Extent ext)
const ReturnCode_t RETCODE_OK
DDS::ReturnCode_t get_int16_values(DDS::Int16Seq &value, DDS::MemberId id)
DDS::ReturnCode_t get_int_value(DDS::Int64 &value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
const ReturnCode_t RETCODE_UNSUPPORTED
bool exclude_union_member(MemberId id) const
Check if a member with a given Id is excluded from a union sample.
DDS::ReturnCode_t get_boolean_value(CORBA::Boolean &value, DDS::MemberId id)
bool read_values(SequenceType &value, TypeKind elem_tk)
DDS::ReturnCode_t get_simple_value(DCPS::Value &value, DDS::MemberId id)
DDS::ReturnCode_t get_uint16_values(DDS::UInt16Seq &value, DDS::MemberId id)
DDS::ReturnCode_t get_uint8_value(CORBA::UInt8 &value, DDS::MemberId id)
DDS::ReturnCode_t get_string_values(DDS::StringSeq &value, DDS::MemberId id)
const TypeKind TK_ARRAY
Definition: TypeObject.h:249
DDS::ReturnCode_t get_uint32_values(DDS::UInt32Seq &value, DDS::MemberId id)
const TypeKind TK_UINT8
Definition: TypeObject.h:226
DDS::ReturnCode_t get_uint_value(DDS::UInt64 &value, DDS::DynamicData_ptr src, DDS::MemberId id, DDS::TypeKind kind)
sequence< int8 > Int8Seq
ACE_WCHAR_T WChar
DDS::ReturnCode_t get_byte_value(CORBA::Octet &value, DDS::MemberId id)
const character_type * in(void) const
ACE_CDR::ULong LBound
Definition: TypeObject.h:312
DDS::ReturnCode_t get_char_common(CharT &value, MemberId id)
Common method to read a single char8 or char16 value.
bool skip_struct_member_at_index(ACE_CDR::ULong index, ACE_CDR::ULong &num_skipped)
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)
DDS::ReturnCode_t get_float128_value(CORBA::LongDouble &value, DDS::MemberId id)
DDS::ReturnCode_t get_uint8_values(DDS::UInt8Seq &value, DDS::MemberId id)
const TypeKind TK_MAP
Definition: TypeObject.h:250
bool Boolean
sequence< double > Float64Seq
LM_ERROR
DDS::ReturnCode_t get_wstring_values(DDS::WstringSeq &value, DDS::MemberId id)
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
ACE_CDR::ULong item_count_
Cache the number of items (i.e., members or elements) in the data it holds.
#define ACE_UINT32_MAX
bool enum_string_helper(char *&strInOut, MemberId id)
DDS::ReturnCode_t get_float32_values(DDS::Float32Seq &value, DDS::MemberId id)
DDS::ReturnCode_t skip_to_struct_member(DDS::MemberDescriptor *member_desc, MemberId id)
DynamicDataXcdrReadImpl & operator=(const DynamicDataXcdrReadImpl &other)
ACE_CDR::ULong length() const
Definition: TypeObject.h:167
bool skip_aggregated_member(DDS::DynamicType_ptr type)
Skip a member which is a structure or a union.
const TypeKind TK_CHAR16
Definition: TypeObject.h:228
DDS::ReturnCode_t get_int32_value(CORBA::Long &value, DDS::MemberId id)
const TypeKind TK_FLOAT64
Definition: TypeObject.h:223
ACE_UINT8 UInt8
void copy(const DynamicDataXcdrReadImpl &other)
const TypeKind TK_BITSET
Definition: TypeObject.h:245
sequence< string > StringSeq
Definition: DdsDcpsCore.idl:50
extensibility(MUTABLE) struct TypeLookup_getTypes_In
Definition: TypeLookup.idl:29
DDS::ReturnCode_t get_float64_value(CORBA::Double &value, DDS::MemberId id)
DDS::ReturnCode_t return_loaned_value(DDS::DynamicData_ptr value)
bool skip_member(DDS::DynamicType_ptr member_type)
bool print_dynamic_data(DDS::DynamicData_ptr dd, DCPS::String &type_string, DCPS::String &indent)
const Encoding & encoding_