LCOV - code coverage report
Current view: top level - DCPS/XTypes - DynamicDataXcdrReadImpl.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 864 1912 45.2 %
Date: 2023-04-30 01:32:43 Functions: 186 310 60.0 %

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

Generated by: LCOV version 1.16