LCOV - code coverage report
Current view: top level - DCPS/XTypes - DynamicDataImpl.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2152 5299 40.6 %
Date: 2023-04-30 01:32:43 Functions: 549 1027 53.5 %

          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 "DynamicDataImpl.h"
      10             : 
      11             : #  include "DynamicTypeMemberImpl.h"
      12             : #  include "Utils.h"
      13             : 
      14             : #  include <dds/DCPS/DisjointSequence.h>
      15             : #  include <dds/DCPS/DCPS_Utils.h>
      16             : 
      17             : #  include <dds/DdsDynamicDataSeqTypeSupportImpl.h>
      18             : #  include <dds/DdsDcpsCoreTypeSupportImpl.h>
      19             : 
      20             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      21             : 
      22             : namespace OpenDDS {
      23             : namespace XTypes {
      24             : 
      25             : using DCPS::LogLevel;
      26             : using DCPS::log_level;
      27             : using DCPS::retcode_to_string;
      28             : 
      29         346 : DynamicDataImpl::DynamicDataImpl(DDS::DynamicType_ptr type)
      30             :   : DynamicDataBase(type)
      31         346 :   , container_(type_, this)
      32             : {
      33         346 : }
      34             : 
      35           0 : DynamicDataImpl::DynamicDataImpl(const DynamicDataImpl& other)
      36             :   : CORBA::Object()
      37             :   , DynamicData()
      38             :   , CORBA::LocalObject()
      39             :   , DCPS::RcObject()
      40             :   , DynamicDataBase(other.type_)
      41           0 :   , container_(other.container_, this)
      42           0 : {}
      43             : 
      44           0 : DDS::ReturnCode_t DynamicDataImpl::set_descriptor(MemberId, DDS::MemberDescriptor*)
      45             : {
      46           0 :   return DDS::RETCODE_UNSUPPORTED;
      47             : }
      48             : 
      49         475 : DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index)
      50             : {
      51         475 :   const TypeKind tk = type_->get_kind();
      52         475 :   switch (tk) {
      53           0 :   case TK_BOOLEAN:
      54             :   case TK_BYTE:
      55             :   case TK_INT16:
      56             :   case TK_INT32:
      57             :   case TK_INT64:
      58             :   case TK_UINT16:
      59             :   case TK_UINT32:
      60             :   case TK_UINT64:
      61             :   case TK_FLOAT32:
      62             :   case TK_FLOAT64:
      63             :   case TK_FLOAT128:
      64             :   case TK_INT8:
      65             :   case TK_UINT8:
      66             :   case TK_CHAR8:
      67             : #ifdef DDS_HAS_WCHAR
      68             :   case TK_CHAR16:
      69             : #endif
      70             :   case TK_ENUM:
      71             :     // Value of enum or primitive types can be indicated by Id MEMBER_ID_INVALID
      72             :     // or by index 0 (Section 7.5.2.11.1).
      73           0 :     if (index != 0 && log_level >= LogLevel::Notice) {
      74           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:"
      75             :                  " Received invalid index (%u) for type %C\n", index, typekind_to_string(tk)));
      76             :     }
      77           0 :     return MEMBER_ID_INVALID;
      78           0 :   case TK_BITMASK:
      79             :     // TODO: Bitmask type needs improvement. See comments in set_single_value method.
      80           0 :     return MEMBER_ID_INVALID;
      81         185 :   case TK_STRING8:
      82             : #ifdef DDS_HAS_WCHAR
      83             :   case TK_STRING16:
      84             : #endif
      85             :   case TK_SEQUENCE: {
      86         185 :     const CORBA::ULong bound = type_desc_->bound()[0];
      87         185 :     if (bound > 0 && index >= bound) {
      88           0 :       if (log_level >= LogLevel::Notice) {
      89           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:"
      90             :                    " Input index (%u) is out-of-bound (bound is %u)\n", index, bound));
      91             :       }
      92           0 :       return MEMBER_ID_INVALID;
      93             :     }
      94         185 :     return index;
      95             :   }
      96         276 :   case TK_ARRAY: {
      97         276 :     const DDS::UInt32 length = bound_total(type_desc_);
      98         276 :     if (index >= length) {
      99           0 :       if (log_level >= LogLevel::Notice) {
     100           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:"
     101             :                    " Input index (%u) is out-of-bound (array length is %u)\n", index, length));
     102             :       }
     103           0 :       return MEMBER_ID_INVALID;
     104             :     }
     105         276 :     return index;
     106             :   }
     107           0 :   case TK_MAP:
     108           0 :     if (log_level >= LogLevel::Notice) {
     109           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:"
     110             :                  " Map is currently not supported\n"));
     111             :     }
     112           0 :     return MEMBER_ID_INVALID;
     113           0 :   case TK_STRUCTURE: {
     114           0 :     DDS::DynamicTypeMember_var dtm;
     115           0 :     if (type_->get_member_by_index(dtm, index) != DDS::RETCODE_OK) {
     116           0 :       return MEMBER_ID_INVALID;
     117             :     }
     118           0 :     return dtm->get_id();
     119           0 :   }
     120          14 :   case TK_UNION: {
     121          14 :     if (index == 0) {
     122           1 :       return DISCRIMINATOR_ID;
     123             :     }
     124             :     bool select_a_member;
     125          13 :     DDS::MemberDescriptor_var selected_md;
     126          13 :     const DDS::ReturnCode_t rc = get_selected_union_branch(select_a_member, selected_md);
     127          13 :     if (rc != DDS::RETCODE_OK) {
     128           0 :       if (log_level >= LogLevel::Warning) {
     129           0 :         ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:"
     130             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
     131             :       }
     132           0 :       return MEMBER_ID_INVALID;
     133             :     }
     134          13 :     if (index == 1 && select_a_member) {
     135          13 :       return selected_md->id();
     136             :     }
     137           0 :     if (log_level >= LogLevel::Warning) {
     138           0 :       ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:"
     139             :                  " invalid index: %u\n", index));
     140             :     }
     141           0 :     return MEMBER_ID_INVALID;
     142          13 :   }
     143             :   }
     144             : 
     145           0 :   if (log_level >= LogLevel::Notice) {
     146           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:"
     147             :                " Calling on an unexpected type %C\n", typekind_to_string(tk)));
     148             :   }
     149           0 :   return MEMBER_ID_INVALID;
     150             : }
     151             : 
     152         121 : CORBA::ULong DynamicDataImpl::get_sequence_size() const
     153             : {
     154         121 :   if (type_->get_kind() != TK_SEQUENCE) {
     155           0 :     return 0;
     156             :   }
     157             : 
     158         121 :   if (!container_.single_map_.empty() || !container_.complex_map_.empty()) {
     159             :     CORBA::ULong largest_index;
     160          70 :     if (!container_.get_largest_index_basic(largest_index)) {
     161           0 :       return 0;
     162             :     }
     163          70 :     if (!container_.sequence_map_.empty()) {
     164             :       CORBA::ULong largest_seq_index;
     165           0 :       if (!container_.get_largest_sequence_index(largest_seq_index)) {
     166           0 :         return 0;
     167             :       }
     168           0 :       largest_index = std::max(largest_index, largest_seq_index);
     169             :     }
     170          70 :     return largest_index + 1;
     171          51 :   } else if (!container_.sequence_map_.empty()) {
     172             :     CORBA::ULong largest_index;
     173           0 :     if (!container_.get_largest_sequence_index(largest_index)) {
     174           0 :       return 0;
     175             :     }
     176           0 :     return largest_index + 1;
     177             :   }
     178          51 :   return 0;
     179             : }
     180             : 
     181           0 : void DynamicDataImpl::erase_member(DDS::MemberId id)
     182             : {
     183           0 :   if (container_.single_map_.erase(id) == 0) {
     184           0 :     if (container_.sequence_map_.erase(id) == 0) {
     185           0 :       container_.complex_map_.erase(id);
     186             :     }
     187             :   }
     188           0 : }
     189             : 
     190         233 : ACE_CDR::ULong DynamicDataImpl::get_item_count()
     191             : {
     192         233 :   const TypeKind tk = type_->get_kind();
     193         233 :   switch (tk) {
     194           0 :   case TK_BOOLEAN:
     195             :   case TK_BYTE:
     196             :   case TK_UINT8:
     197             :   case TK_UINT16:
     198             :   case TK_UINT32:
     199             :   case TK_UINT64:
     200             :   case TK_INT8:
     201             :   case TK_INT16:
     202             :   case TK_INT32:
     203             :   case TK_INT64:
     204             :   case TK_FLOAT32:
     205             :   case TK_FLOAT64:
     206             :   case TK_FLOAT128:
     207             :   case TK_CHAR8:
     208             : #ifdef DDS_HAS_WCHAR
     209             :   case TK_CHAR16:
     210             : #endif
     211             :   case TK_ENUM:
     212           0 :     return 1;
     213           0 :   case TK_STRING8:
     214             : #ifdef DDS_HAS_WCHAR
     215             :   case TK_STRING16:
     216             : #endif
     217             :     {
     218           0 :       if (!container_.single_map_.empty() || !container_.complex_map_.empty()) {
     219             :         CORBA::ULong largest_index;
     220           0 :         if (!container_.get_largest_index_basic(largest_index)) {
     221           0 :           return 0;
     222             :         }
     223           0 :         return largest_index + 1;
     224             :       }
     225           0 :       return 0;
     226             :     }
     227         121 :   case TK_SEQUENCE:
     228         121 :     return get_sequence_size();
     229           0 :   case TK_BITMASK:
     230           0 :     return static_cast<ACE_CDR::ULong>(container_.single_map_.size() +
     231           0 :                                        container_.complex_map_.size());
     232          99 :   case TK_ARRAY:
     233          99 :     return bound_total(type_desc_);
     234           0 :   case TK_STRUCTURE: {
     235           0 :     const CORBA::ULong member_count = type_->get_member_count();
     236           0 :     CORBA::ULong count = member_count;
     237             :     // An optional member that hasn't been set is considered missing.
     238             :     // All non-optional members are counted since they either are set directly
     239             :     // or hold default values (XTypes spec 7.5.2.11.6).
     240           0 :     for (CORBA::ULong i = 0; i < member_count; ++i) {
     241           0 :       DDS::DynamicTypeMember_var dtm;
     242           0 :       if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
     243           0 :         return 0;
     244             :       }
     245           0 :       DDS::MemberDescriptor_var md;
     246           0 :       if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
     247           0 :         return 0;
     248             :       }
     249           0 :       if (md->is_optional()) {
     250           0 :         const DDS::MemberId id = md->id();
     251           0 :         if (container_.single_map_.find(id) == container_.single_map_.end() &&
     252           0 :             container_.sequence_map_.find(id) == container_.sequence_map_.end() &&
     253           0 :             container_.complex_map_.find(id) == container_.complex_map_.end()) {
     254           0 :           --count;
     255             :         }
     256             :       }
     257           0 :     }
     258           0 :     return count;
     259             :   }
     260          13 :   case TK_UNION: {
     261          13 :     CORBA::ULong count = static_cast<CORBA::ULong>(container_.single_map_.size() +
     262          13 :                                                    container_.sequence_map_.size() +
     263          13 :                                                    container_.complex_map_.size());
     264          13 :     if (count > 0) {
     265          12 :       return count;
     266             :     }
     267           1 :     DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type());
     268             :     CORBA::Long disc_val;
     269           1 :     if (!container_.set_default_discriminator_value(disc_val, disc_type)) {
     270           0 :       if (log_level >= LogLevel::Warning) {
     271           0 :         ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_item_count:"
     272             :                    " set_default_discriminator_value failed\n"));
     273             :       }
     274           0 :       return 0;
     275             :     }
     276             :     bool select_a_member;
     277           1 :     DDS::MemberDescriptor_var selected_md;
     278           1 :     const DDS::ReturnCode_t rc = get_selected_union_branch(disc_val, select_a_member, selected_md);
     279           1 :     if (rc != DDS::RETCODE_OK) {
     280           0 :       if (log_level >= LogLevel::Warning) {
     281           0 :         ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_item_count:"
     282             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
     283             :       }
     284           0 :       return 0;
     285             :     }
     286           1 :     return select_a_member ? 2 : 1;
     287           1 :   }
     288           0 :   case TK_MAP:
     289             :   case TK_BITSET:
     290             :   case TK_ALIAS:
     291             :   case TK_ANNOTATION:
     292             :   default:
     293           0 :     if (log_level >= LogLevel::Warning) {
     294           0 :       ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_item_count:"
     295             :                  " Encounter unexpected type kind %C\n", typekind_to_string(tk)));
     296             :     }
     297           0 :     return 0;
     298             :   }
     299             : }
     300             : 
     301           0 : DDS::ReturnCode_t DynamicDataImpl::clear_all_values()
     302             : {
     303           0 :   const TypeKind tk = type_->get_kind();
     304           0 :   if (is_primitive(tk) || tk == TK_ENUM) {
     305           0 :     return clear_value_i(MEMBER_ID_INVALID, type_);
     306             :   }
     307             : 
     308           0 :   switch (tk) {
     309           0 :   case TK_BITMASK:
     310             :   case TK_ARRAY:
     311             :   case TK_STRING8:
     312             : #ifdef DDS_HAS_WCHAR
     313             :   case TK_STRING16:
     314             : #endif
     315             :   case TK_SEQUENCE:
     316             :   case TK_STRUCTURE:
     317             :   case TK_UNION:
     318           0 :     clear_container();
     319           0 :     break;
     320           0 :   case TK_MAP:
     321             :   case TK_BITSET:
     322             :   case TK_ALIAS:
     323             :   case TK_ANNOTATION:
     324             :   default:
     325           0 :     if (log_level >= LogLevel::Notice) {
     326           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::clear_all_values:"
     327             :                  " Encounter unexpected type kind %C\n", typekind_to_string(tk)));
     328             :     }
     329           0 :     return DDS::RETCODE_ERROR;
     330             :   }
     331           0 :   return DDS::RETCODE_OK;
     332             : }
     333             : 
     334         330 : void DynamicDataImpl::clear_container()
     335             : {
     336         330 :   container_.single_map_.clear();
     337         330 :   container_.sequence_map_.clear();
     338         330 :   container_.complex_map_.clear();
     339         330 : }
     340             : 
     341           0 : DDS::ReturnCode_t DynamicDataImpl::clear_nonkey_values()
     342             : {
     343           0 :   return DDS::RETCODE_UNSUPPORTED;
     344             : }
     345             : 
     346           0 : DDS::ReturnCode_t DynamicDataImpl::clear_value(DDS::MemberId id)
     347             : {
     348           0 :   const TypeKind this_tk = type_->get_kind();
     349           0 :   if (is_primitive(this_tk) || this_tk == TK_ENUM) {
     350           0 :     if (id != MEMBER_ID_INVALID) {
     351           0 :       return DDS::RETCODE_BAD_PARAMETER;
     352             :     }
     353           0 :     return clear_value_i(id, type_);
     354             :   }
     355             : 
     356           0 :   switch (this_tk) {
     357           0 :   case TK_BITMASK:
     358           0 :     return set_boolean_value(id, false);
     359           0 :   case TK_ARRAY: {
     360           0 :     const DDS::UInt32 bound = bound_total(type_desc_);
     361           0 :     if (id >= bound) {
     362           0 :       return DDS::RETCODE_BAD_PARAMETER;
     363             :     }
     364           0 :     DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
     365           0 :     return clear_value_i(id, elem_type);
     366           0 :   }
     367           0 :   case TK_STRING8:
     368             : #ifdef DDS_HAS_WCHAR
     369             :   case TK_STRING16:
     370             : #endif
     371             :   case TK_SEQUENCE: {
     372             :     // Shift subsequent elements to the left (XTypes spec 7.5.2.11.3).
     373           0 :     const CORBA::ULong size = get_sequence_size();
     374           0 :     if (id >= size) {
     375           0 :       return DDS::RETCODE_ERROR;
     376             :     }
     377             : 
     378             :     // At the begin of each iterator, member with the current id is not present
     379             :     // in any of the maps. Copy over the next member to the current id.
     380           0 :     erase_member(id);
     381           0 :     for (CORBA::ULong i = id; i < size - 1; ++i) {
     382           0 :       const DDS::MemberId next_id = i + 1;
     383           0 :       DataContainer::const_single_iterator single_it = container_.single_map_.find(next_id);
     384           0 :       if (single_it != container_.single_map_.end()) {
     385           0 :         container_.single_map_.insert(std::make_pair(i, single_it->second));
     386           0 :         container_.single_map_.erase(next_id);
     387           0 :         continue;
     388             :       }
     389           0 :       DataContainer::const_sequence_iterator seq_it = container_.sequence_map_.find(next_id);
     390           0 :       if (seq_it != container_.sequence_map_.end()) {
     391           0 :         container_.sequence_map_.insert(std::make_pair(i, seq_it->second));
     392           0 :         container_.sequence_map_.erase(next_id);
     393           0 :         continue;
     394             :       }
     395           0 :       DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(next_id);
     396           0 :       if (complex_it != container_.complex_map_.end()) {
     397           0 :         container_.complex_map_.insert(std::make_pair(i, complex_it->second));
     398           0 :         container_.complex_map_.erase(next_id);
     399           0 :         continue;
     400             :       }
     401             :     }
     402           0 :     break;
     403             :   }
     404           0 :   case TK_STRUCTURE:
     405             :   case TK_UNION: {
     406           0 :     DDS::DynamicTypeMember_var dtm;
     407           0 :     if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
     408           0 :       return DDS::RETCODE_ERROR;
     409             :     }
     410           0 :     DDS::MemberDescriptor_var md;
     411           0 :     if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
     412           0 :       return DDS::RETCODE_ERROR;
     413             :     }
     414           0 :     if (md->is_optional()) {
     415           0 :       erase_member(id);
     416           0 :       break;
     417             :     }
     418           0 :     DDS::DynamicType_var member_type = get_base_type(md->type());
     419           0 :     return clear_value_i(id, member_type);
     420           0 :   }
     421           0 :   case TK_MAP:
     422             :   case TK_BITSET:
     423             :   case TK_ALIAS:
     424             :   case TK_ANNOTATION:
     425             :   default:
     426           0 :     if (log_level >= LogLevel::Warning) {
     427           0 :       ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::clear_value:"
     428             :                  " Encounter unexpected type kind %C\n", typekind_to_string(this_tk)));
     429             :     }
     430           0 :     return DDS::RETCODE_ERROR;
     431             :   }
     432           0 :   return DDS::RETCODE_OK;
     433             : }
     434             : 
     435           4 : DDS::ReturnCode_t DynamicDataImpl::clear_value_i(DDS::MemberId id, const DDS::DynamicType_var& member_type)
     436             : {
     437           4 :   const TypeKind tk = member_type->get_kind();
     438           4 :   switch (tk) {
     439           0 :   case TK_BOOLEAN: {
     440           0 :     ACE_OutputCDR::from_boolean val(false);
     441           0 :     container_.set_default_basic_value(val);
     442           0 :     insert_single(id, val);
     443           0 :     break;
     444             :   }
     445           0 :   case TK_BYTE: {
     446           0 :     ACE_OutputCDR::from_octet val(0);
     447           0 :     container_.set_default_basic_value(val);
     448           0 :     insert_single(id, val);
     449           0 :     break;
     450             :   }
     451           0 :   case TK_UINT8: {
     452           0 :     ACE_OutputCDR::from_uint8 val(0);
     453           0 :     container_.set_default_basic_value(val);
     454           0 :     insert_single(id, val);
     455           0 :     break;
     456             :   }
     457           0 :   case TK_UINT16: {
     458           0 :     CORBA::UInt16 val(0);
     459           0 :     container_.set_default_basic_value(val);
     460           0 :     insert_single(id, val);
     461           0 :     break;
     462             :   }
     463           0 :   case TK_UINT32: {
     464           0 :     CORBA::UInt32 val(0);
     465           0 :     container_.set_default_basic_value(val);
     466           0 :     insert_single(id, val);
     467           0 :     break;
     468             :   }
     469           0 :   case TK_UINT64: {
     470           0 :     CORBA::UInt64 val(0);
     471           0 :     container_.set_default_basic_value(val);
     472           0 :     insert_single(id, val);
     473           0 :     break;
     474             :   }
     475           0 :   case TK_INT8: {
     476           0 :     ACE_OutputCDR::from_int8 val(0);
     477           0 :     container_.set_default_basic_value(val);
     478           0 :     insert_single(id, val);
     479           0 :     break;
     480             :   }
     481           0 :   case TK_INT16: {
     482           0 :     CORBA::Int16 val(0);
     483           0 :     container_.set_default_basic_value(val);
     484           0 :     insert_single(id, val);
     485           0 :     break;
     486             :   }
     487           4 :   case TK_INT32: {
     488           4 :     CORBA::Int32 val(0);
     489           4 :     container_.set_default_basic_value(val);
     490           4 :     insert_single(id, val);
     491           4 :     break;
     492             :   }
     493           0 :   case TK_INT64: {
     494           0 :     CORBA::Int64 val(0);
     495           0 :     container_.set_default_basic_value(val);
     496           0 :     insert_single(id, val);
     497           0 :     break;
     498             :   }
     499           0 :   case TK_FLOAT32: {
     500           0 :     CORBA::Float val(0.0f);
     501           0 :     container_.set_default_basic_value(val);
     502           0 :     insert_single(id, val);
     503           0 :     break;
     504             :   }
     505           0 :   case TK_FLOAT64: {
     506           0 :     CORBA::Double val(0.0);
     507           0 :     container_.set_default_basic_value(val);
     508           0 :     insert_single(id, val);
     509           0 :     break;
     510             :   }
     511           0 :   case TK_FLOAT128: {
     512             :     CORBA::LongDouble val;
     513           0 :     container_.set_default_basic_value(val);
     514           0 :     insert_single(id, val);
     515           0 :     break;
     516             :   }
     517           0 :   case TK_CHAR8: {
     518           0 :     ACE_OutputCDR::from_char val('\0');
     519           0 :     container_.set_default_basic_value(val);
     520           0 :     insert_single(id, val);
     521           0 :     break;
     522             :   }
     523           0 :   case TK_STRING8: {
     524           0 :     const char* val = 0;
     525           0 :     container_.set_default_basic_value(val);
     526           0 :     insert_single(id, val);
     527           0 :     break;
     528             :   }
     529             : #ifdef DDS_HAS_WCHAR
     530           0 :   case TK_CHAR16: {
     531           0 :     ACE_OutputCDR::from_wchar val(L'\0');
     532           0 :     container_.set_default_basic_value(val);
     533           0 :     insert_single(id, val);
     534           0 :     break;
     535             :   }
     536           0 :   case TK_STRING16: {
     537           0 :     const CORBA::WChar* val = 0;
     538           0 :     container_.set_default_basic_value(val);
     539           0 :     insert_single(id, val);
     540           0 :     break;
     541             :   }
     542             : #endif
     543           0 :   case TK_ENUM: {
     544             :     // Set to first enumerator
     545             :     CORBA::Long value;
     546           0 :     if (!container_.set_default_enum_value(member_type, value)) {
     547           0 :       return DDS::RETCODE_ERROR;
     548             :     }
     549           0 :     TypeKind treat_as = tk;
     550           0 :     if (enum_bound(member_type, treat_as) != DDS::RETCODE_OK) {
     551           0 :       return DDS::RETCODE_ERROR;
     552             :     }
     553           0 :     if (treat_as == TK_INT8) {
     554           0 :       ACE_OutputCDR::from_int8 val(static_cast<CORBA::Int8>(value));
     555           0 :       insert_single(id, val);
     556           0 :     } else if (treat_as == TK_INT16) {
     557           0 :       insert_single(id, static_cast<CORBA::Short>(value));
     558             :     } else {
     559           0 :       insert_single(id, value);
     560             :     }
     561           0 :     break;
     562             :   }
     563           0 :   case TK_BITMASK: {
     564             :     // Set to default bitmask value
     565           0 :     TypeKind treat_as = tk;
     566           0 :     if (bitmask_bound(member_type, treat_as) != DDS::RETCODE_OK) {
     567           0 :       return DDS::RETCODE_ERROR;
     568             :     }
     569           0 :     if (treat_as == TK_UINT8) {
     570           0 :       ACE_OutputCDR::from_uint8 val(0);
     571           0 :       container_.set_default_bitmask_value(val);
     572           0 :       insert_single(id, val);
     573           0 :     } else if (treat_as == TK_UINT16) {
     574             :       CORBA::UShort val;
     575           0 :       container_.set_default_bitmask_value(val);
     576           0 :       insert_single(id, val);
     577           0 :     } else if (treat_as == TK_UINT32) {
     578             :       CORBA::ULong val;
     579           0 :       container_.set_default_bitmask_value(val);
     580           0 :       insert_single(id, val);
     581             :     } else {
     582             :       CORBA::ULongLong val;
     583           0 :       container_.set_default_bitmask_value(val);
     584           0 :       insert_single(id, val);
     585             :     }
     586           0 :     break;
     587             :   }
     588           0 :   case TK_ARRAY:
     589             :   case TK_SEQUENCE:
     590             :   case TK_STRUCTURE:
     591             :   case TK_UNION: {
     592           0 :     DDS::DynamicData_var dd = new DynamicDataImpl(member_type);
     593           0 :     insert_complex(id, dd);
     594           0 :     break;
     595           0 :   }
     596           0 :   case TK_MAP:
     597             :   case TK_BITSET:
     598             :   case TK_ALIAS:
     599             :   case TK_ANNOTATION:
     600             :   default:
     601           0 :     if (log_level >= LogLevel::Warning) {
     602           0 :       ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::clear_value_i:"
     603             :                  " Member %u has unexpected type kind %C\n", id, typekind_to_string(tk)));
     604             :     }
     605           0 :     return DDS::RETCODE_ERROR;
     606             :   }
     607           4 :   return DDS::RETCODE_OK;
     608             : }
     609             : 
     610           0 : DDS::DynamicData_ptr DynamicDataImpl::clone()
     611             : {
     612           0 :   return new DynamicDataImpl(*this);
     613             : }
     614             : 
     615          41 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_int8& value)
     616             : {
     617             :   // The same member might be already written to complex_map_.
     618             :   // Make sure there is only one entry for each member.
     619          41 :   if (container_.complex_map_.erase(id) == 0) {
     620          41 :     container_.single_map_.erase(id);
     621             :   }
     622          41 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     623             : }
     624             : 
     625          31 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_uint8& value)
     626             : {
     627          31 :   if (container_.complex_map_.erase(id) == 0) {
     628          31 :     container_.single_map_.erase(id);
     629             :   }
     630          31 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     631             : }
     632             : 
     633          39 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_char& value)
     634             : {
     635          39 :   if (container_.complex_map_.erase(id) == 0) {
     636          39 :     container_.single_map_.erase(id);
     637             :   }
     638          39 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     639             : }
     640             : 
     641          22 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_octet& value)
     642             : {
     643          22 :   if (container_.complex_map_.erase(id) == 0) {
     644          22 :     container_.single_map_.erase(id);
     645             :   }
     646          22 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     647             : }
     648             : 
     649          25 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_boolean& value)
     650             : {
     651          25 :   if (container_.complex_map_.erase(id) == 0) {
     652          25 :     container_.single_map_.erase(id);
     653             :   }
     654          25 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     655             : }
     656             : 
     657             : #ifdef DDS_HAS_WCHAR
     658          22 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const ACE_OutputCDR::from_wchar& value)
     659             : {
     660          22 :   if (container_.complex_map_.erase(id) == 0) {
     661          22 :     container_.single_map_.erase(id);
     662             :   }
     663          22 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     664             : }
     665             : #endif
     666             : 
     667             : template<typename SingleType>
     668         760 : bool DynamicDataImpl::insert_single(DDS::MemberId id, const SingleType& value)
     669             : {
     670         760 :   if (container_.complex_map_.erase(id) == 0) {
     671         760 :     container_.single_map_.erase(id);
     672             :   }
     673         760 :   return container_.single_map_.insert(std::make_pair(id, value)).second;
     674             : }
     675             : 
     676         185 : bool DynamicDataImpl::insert_complex(DDS::MemberId id, const DDS::DynamicData_var& value)
     677             : {
     678         185 :   if (container_.single_map_.erase(id) == 0) {
     679         168 :     if (container_.sequence_map_.erase(id) == 0) {
     680         144 :       container_.complex_map_.erase(id);
     681             :     }
     682             :   }
     683         185 :   return container_.complex_map_.insert(std::make_pair(id, value)).second;
     684             : }
     685             : 
     686             : // Set a member with the given ID in a struct. The member must have type MemberTypeKind or
     687             : // enum/bitmask. In the latter case, its bit bound must be in the range [lower, upper].
     688             : template<TypeKind MemberTypeKind, typename MemberType>
     689         166 : bool DynamicDataImpl::set_value_to_struct(DDS::MemberId id, const MemberType& value)
     690             : {
     691         166 :   DDS::MemberDescriptor_var md;
     692         166 :   DDS::DynamicType_var member_type;
     693         166 :   const DDS::ReturnCode_t rc = check_member(
     694             :     md, member_type, "DynamicDataImpl::set_value_to_struct", "set", id, MemberTypeKind);
     695         166 :   if (rc != DDS::RETCODE_OK) {
     696           9 :     return false;
     697             :   }
     698         157 :   return insert_single(id, value);
     699         166 : }
     700             : 
     701         113 : bool DynamicDataImpl::is_valid_discriminator_type(TypeKind tk)
     702             : {
     703         113 :   switch (tk) {
     704         113 :   case TK_BOOLEAN:
     705             :   case TK_BYTE:
     706             :   case TK_CHAR8:
     707             : #ifdef DDS_HAS_WCHAR
     708             :   case TK_CHAR16:
     709             : #endif
     710             :   case TK_INT8:
     711             :   case TK_UINT8:
     712             :   case TK_INT16:
     713             :   case TK_UINT16:
     714             :   case TK_INT32:
     715             :   case TK_UINT32:
     716             :   case TK_INT64:
     717             :   case TK_UINT64:
     718             :   case TK_ENUM:
     719         113 :     return true;
     720           0 :   default:
     721           0 :     return false;
     722             :   }
     723             : }
     724             : 
     725             : // Return true if a discriminator value selects the default member of a union.
     726           3 : bool DynamicDataImpl::is_default_member_selected(CORBA::Long disc_val, DDS::MemberId default_id) const
     727             : {
     728           3 :   if (type_->get_kind() != TK_UNION) {
     729           0 :     return false;
     730             :   }
     731             : 
     732           3 :   DDS::DynamicTypeMembersById_var members_var;
     733           3 :   if (type_->get_all_members(members_var) != DDS::RETCODE_OK) {
     734           0 :     return false;
     735             :   }
     736           3 :   DynamicTypeMembersByIdImpl* members = dynamic_cast<DynamicTypeMembersByIdImpl*>(members_var.in());
     737           3 :   if (!members) {
     738           0 :     return false;
     739             :   }
     740             : 
     741          30 :   for (DynamicTypeMembersByIdImpl::const_iterator it = members->begin(); it != members->end(); ++it) {
     742          30 :     if (it->first == default_id) continue;
     743             : 
     744          30 :     DDS::MemberDescriptor_var md;
     745          30 :     if (it->second->get_descriptor(md) != DDS::RETCODE_OK) {
     746           0 :       return false;
     747             :     }
     748          30 :     const DDS::UnionCaseLabelSeq& labels = md->label();
     749          57 :     for (CORBA::ULong i = 0; i < labels.length(); ++i) {
     750          30 :       if (disc_val == labels[i]) {
     751           3 :         return false;
     752             :       }
     753             :     }
     754          30 :   }
     755           0 :   return true;
     756           3 : }
     757             : 
     758         446 : DynamicDataImpl::SingleValue::SingleValue(CORBA::Long int32)
     759         446 :   : kind_(TK_INT32), active_(0), int32_(int32)
     760         446 : {}
     761             : 
     762         103 : DynamicDataImpl::SingleValue::SingleValue(CORBA::ULong uint32)
     763         103 :   : kind_(TK_UINT32), active_(0), uint32_(uint32)
     764         103 : {}
     765             : 
     766          41 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_int8 value)
     767          41 :   : kind_(TK_INT8), active_(new(int8_) ACE_OutputCDR::from_int8(value.val_))
     768          41 : {}
     769             : 
     770          31 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_uint8 value)
     771          31 :   : kind_(TK_UINT8), active_(new(uint8_) ACE_OutputCDR::from_uint8(value.val_))
     772          31 : {}
     773             : 
     774          36 : DynamicDataImpl::SingleValue::SingleValue(CORBA::Short int16)
     775          36 :   : kind_(TK_INT16), active_(0), int16_(int16)
     776          36 : {}
     777             : 
     778          29 : DynamicDataImpl::SingleValue::SingleValue(CORBA::UShort uint16)
     779          29 :   : kind_(TK_UINT16), active_(0), uint16_(uint16)
     780          29 : {}
     781             : 
     782          22 : DynamicDataImpl::SingleValue::SingleValue(CORBA::LongLong int64)
     783          22 :   : kind_(TK_INT64), active_(0), int64_(int64)
     784          22 : {}
     785             : 
     786          25 : DynamicDataImpl::SingleValue::SingleValue(CORBA::ULongLong uint64)
     787          25 :   : kind_(TK_UINT64), active_(0), uint64_(uint64)
     788          25 : {}
     789             : 
     790          21 : DynamicDataImpl::SingleValue::SingleValue(CORBA::Float float32)
     791          21 :   : kind_(TK_FLOAT32), active_(0), float32_(float32)
     792          21 : {}
     793             : 
     794          22 : DynamicDataImpl::SingleValue::SingleValue(CORBA::Double float64)
     795          22 :   : kind_(TK_FLOAT64), active_(0), float64_(float64)
     796          22 : {}
     797             : 
     798          10 : DynamicDataImpl::SingleValue::SingleValue(CORBA::LongDouble float128)
     799          10 :   : kind_(TK_FLOAT128), active_(0), float128_(float128)
     800          10 : {}
     801             : 
     802          39 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_char value)
     803          39 :   : kind_(TK_CHAR8), active_(new(char8_) ACE_OutputCDR::from_char(value.val_))
     804          39 : {}
     805             : 
     806          22 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_octet value)
     807          22 :   : kind_(TK_BYTE), active_(new(byte_) ACE_OutputCDR::from_octet(value.val_))
     808          22 : {}
     809             : 
     810          25 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_boolean value)
     811          25 :   : kind_(TK_BOOLEAN), active_(new(boolean_) ACE_OutputCDR::from_boolean(value.val_))
     812          25 : {}
     813             : 
     814          25 : DynamicDataImpl::SingleValue::SingleValue(const char* str)
     815          25 :   : kind_(TK_STRING8), active_(0), str_(CORBA::string_dup(str))
     816          25 : {}
     817             : 
     818             : #ifdef DDS_HAS_WCHAR
     819          22 : DynamicDataImpl::SingleValue::SingleValue(ACE_OutputCDR::from_wchar value)
     820          22 :   : kind_(TK_CHAR16), active_(new(char16_) ACE_OutputCDR::from_wchar(value.val_))
     821          22 : {}
     822             : 
     823          21 : DynamicDataImpl::SingleValue::SingleValue(const CORBA::WChar* wstr)
     824          21 :   : kind_(TK_STRING16), active_(0), wstr_(CORBA::wstring_dup(wstr))
     825          21 : {}
     826             : #endif
     827             : 
     828         940 : DynamicDataImpl::SingleValue::~SingleValue()
     829             : {
     830             : #define SINGLE_VALUE_DESTRUCT(T) static_cast<ACE_OutputCDR::T*>(active_)->~T(); break
     831         940 :   switch (kind_) {
     832          41 :   case TK_INT8:
     833          41 :     SINGLE_VALUE_DESTRUCT(from_int8);
     834          31 :   case TK_UINT8:
     835          31 :     SINGLE_VALUE_DESTRUCT(from_uint8);
     836          39 :   case TK_CHAR8:
     837          39 :     SINGLE_VALUE_DESTRUCT(from_char);
     838          22 :   case TK_BYTE:
     839          22 :     SINGLE_VALUE_DESTRUCT(from_octet);
     840          25 :   case TK_BOOLEAN:
     841          25 :     SINGLE_VALUE_DESTRUCT(from_boolean);
     842          25 :   case TK_STRING8:
     843          25 :     CORBA::string_free((char*)str_);
     844          25 :     break;
     845             : #ifdef DDS_HAS_WCHAR
     846          22 :   case TK_CHAR16:
     847          22 :     SINGLE_VALUE_DESTRUCT(from_wchar);
     848          21 :   case TK_STRING16:
     849          21 :     CORBA::wstring_free((CORBA::WChar*)wstr_);
     850          21 :     break;
     851             : #endif
     852             :   }
     853             : #undef SINGLE_VALUE_DESTRUCT
     854         940 : }
     855             : 
     856         810 : template<> const CORBA::Long& DynamicDataImpl::SingleValue::get() const { return int32_; }
     857         267 : template<> const CORBA::ULong& DynamicDataImpl::SingleValue::get() const { return uint32_; }
     858             : 
     859         113 : template<> const ACE_OutputCDR::from_int8& DynamicDataImpl::SingleValue::get() const
     860             : {
     861         113 :   return *static_cast<ACE_OutputCDR::from_int8*>(active_);
     862             : }
     863             : 
     864         107 : template<> const ACE_OutputCDR::from_uint8& DynamicDataImpl::SingleValue::get() const
     865             : {
     866         107 :   return *static_cast<ACE_OutputCDR::from_uint8*>(active_);
     867             : }
     868             : 
     869          93 : template<> const CORBA::Short& DynamicDataImpl::SingleValue::get() const { return int16_; }
     870         104 : template<> const CORBA::UShort& DynamicDataImpl::SingleValue::get() const { return uint16_; }
     871          79 : template<> const CORBA::LongLong& DynamicDataImpl::SingleValue::get() const { return int64_; }
     872          95 : template<> const CORBA::ULongLong& DynamicDataImpl::SingleValue::get() const { return uint64_; }
     873          74 : template<> const CORBA::Float& DynamicDataImpl::SingleValue::get() const { return float32_; }
     874          71 : template<> const CORBA::Double& DynamicDataImpl::SingleValue::get() const { return float64_; }
     875          49 : template<> const CORBA::LongDouble& DynamicDataImpl::SingleValue::get() const { return float128_; }
     876             : 
     877          75 : template<> const ACE_OutputCDR::from_char& DynamicDataImpl::SingleValue::get() const
     878             : {
     879          75 :   return *static_cast<ACE_OutputCDR::from_char*>(active_);
     880             : }
     881             : 
     882         115 : template<> const ACE_OutputCDR::from_octet& DynamicDataImpl::SingleValue::get() const
     883             : {
     884         115 :   return *static_cast<ACE_OutputCDR::from_octet*>(active_);
     885             : }
     886             : 
     887         114 : template<> const ACE_OutputCDR::from_boolean& DynamicDataImpl::SingleValue::get() const
     888             : {
     889         114 :   return *static_cast<ACE_OutputCDR::from_boolean*>(active_);
     890             : }
     891             : 
     892          13 : template<> const char* const& DynamicDataImpl::SingleValue::get() const { return str_; }
     893             : 
     894             : #ifdef DDS_HAS_WCHAR
     895          59 : template<> const ACE_OutputCDR::from_wchar& DynamicDataImpl::SingleValue::get() const
     896             : {
     897          59 :   return *static_cast<ACE_OutputCDR::from_wchar*>(active_);
     898             : }
     899             : 
     900          10 : template<> const CORBA::WChar* const& DynamicDataImpl::SingleValue::get() const { return wstr_; }
     901             : #endif
     902             : 
     903          48 : char* DynamicDataImpl::SingleValue::get_string() const { return CORBA::string_dup(str_); }
     904          40 : CORBA::WChar* DynamicDataImpl::SingleValue::get_wstring() const { return CORBA::wstring_dup(wstr_); }
     905             : 
     906             : // Has to be below the get methods, or else there's a template specialization issue.
     907           0 : DynamicDataImpl::SingleValue::SingleValue(const SingleValue& other)
     908           0 :   : kind_(other.kind_)
     909           0 :   , active_(0)
     910             : {
     911           0 :   switch (kind_) {
     912           0 :   case TK_INT8:
     913           0 :     active_ = new(int8_) ACE_OutputCDR::from_int8(other.get<ACE_OutputCDR::from_int8>());
     914           0 :     break;
     915           0 :   case TK_UINT8:
     916           0 :     active_ = new(uint8_) ACE_OutputCDR::from_uint8(other.get<ACE_OutputCDR::from_uint8>());
     917           0 :     break;
     918           0 :   case TK_INT16:
     919           0 :     int16_ = other.int16_;
     920           0 :     break;
     921           0 :   case TK_UINT16:
     922           0 :     uint16_ = other.uint16_;
     923           0 :     break;
     924           0 :   case TK_INT32:
     925           0 :     int32_ = other.int32_;
     926           0 :     break;
     927           0 :   case TK_UINT32:
     928           0 :     uint32_ = other.uint32_;
     929           0 :     break;
     930           0 :   case TK_INT64:
     931           0 :     int64_ = other.int64_;
     932           0 :     break;
     933           0 :   case TK_UINT64:
     934           0 :     uint64_ = other.uint64_;
     935           0 :     break;
     936           0 :   case TK_FLOAT32:
     937           0 :     float32_ = other.float32_;
     938           0 :     break;
     939           0 :   case TK_FLOAT64:
     940           0 :     float64_ = other.float64_;
     941           0 :     break;
     942           0 :   case TK_FLOAT128:
     943           0 :     float128_ = other.float128_;
     944           0 :     break;
     945           0 :   case TK_BOOLEAN:
     946           0 :     active_ = new(boolean_) ACE_OutputCDR::from_boolean(other.get<ACE_OutputCDR::from_boolean>());
     947           0 :     break;
     948           0 :   case TK_BYTE:
     949           0 :     active_ = new(byte_) ACE_OutputCDR::from_octet(other.get<ACE_OutputCDR::from_octet>());
     950           0 :     break;
     951           0 :   case TK_CHAR8:
     952           0 :     active_ = new(char8_) ACE_OutputCDR::from_char(other.get<ACE_OutputCDR::from_char>());
     953           0 :     break;
     954           0 :   case TK_STRING8:
     955           0 :     str_ = CORBA::string_dup(other.str_);
     956           0 :     break;
     957             : #ifdef DDS_HAS_WCHAR
     958           0 :   case TK_CHAR16:
     959           0 :     active_ = new(char16_) ACE_OutputCDR::from_wchar(other.get<ACE_OutputCDR::from_wchar>());
     960           0 :     break;
     961           0 :   case TK_STRING16:
     962           0 :     wstr_ = CORBA::wstring_dup(other.wstr_);
     963           0 :     break;
     964             : #endif
     965             :   }
     966           0 : }
     967             : 
     968          21 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Int32Seq& int32_seq)
     969          21 :   : elem_kind_(TK_INT32), active_(new(int32_seq_) DDS::Int32Seq(int32_seq))
     970          21 : {}
     971             : 
     972          18 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::UInt32Seq& uint32_seq)
     973          18 :   : elem_kind_(TK_UINT32), active_(new(uint32_seq_) DDS::UInt32Seq(uint32_seq))
     974          18 : {}
     975             : 
     976           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Int8Seq& int8_seq)
     977           9 :   : elem_kind_(TK_INT8), active_(new(int8_seq_) DDS::Int8Seq(int8_seq))
     978           9 : {}
     979             : 
     980          15 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::UInt8Seq& uint8_seq)
     981          15 :   : elem_kind_(TK_UINT8), active_(new(uint8_seq_) DDS::UInt8Seq(uint8_seq))
     982          15 : {}
     983             : 
     984          18 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Int16Seq& int16_seq)
     985          18 :   : elem_kind_(TK_INT16), active_(new(int16_seq_) DDS::Int16Seq(int16_seq))
     986          18 : {}
     987             : 
     988           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::UInt16Seq& uint16_seq)
     989           9 :   : elem_kind_(TK_UINT16), active_(new(uint16_seq_) DDS::UInt16Seq(uint16_seq))
     990           9 : {}
     991             : 
     992           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Int64Seq& int64_seq)
     993           9 :   : elem_kind_(TK_INT64), active_(new(int64_seq_) DDS::Int64Seq(int64_seq))
     994           9 : {}
     995             : 
     996           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::UInt64Seq& uint64_seq)
     997           9 :   : elem_kind_(TK_UINT64), active_(new(uint64_seq_) DDS::UInt64Seq(uint64_seq))
     998           9 : {}
     999             : 
    1000          15 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Float32Seq& float32_seq)
    1001          15 :   : elem_kind_(TK_FLOAT32), active_(new(float32_seq_) DDS::Float32Seq(float32_seq))
    1002          15 : {}
    1003             : 
    1004           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Float64Seq& float64_seq)
    1005           9 :   : elem_kind_(TK_FLOAT64), active_(new(float64_seq_) DDS::Float64Seq(float64_seq))
    1006           9 : {}
    1007             : 
    1008           0 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Float128Seq& float128_seq)
    1009           0 :   : elem_kind_(TK_FLOAT128), active_(new(float128_seq_) DDS::Float128Seq(float128_seq))
    1010           0 : {}
    1011             : 
    1012           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::CharSeq& char8_seq)
    1013           9 :   : elem_kind_(TK_CHAR8), active_(new(char8_seq_) DDS::CharSeq(char8_seq))
    1014           9 : {}
    1015             : 
    1016          12 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::ByteSeq& byte_seq)
    1017          12 :   : elem_kind_(TK_BYTE), active_(new(byte_seq_) DDS::ByteSeq(byte_seq))
    1018          12 : {}
    1019             : 
    1020          15 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::BooleanSeq& boolean_seq)
    1021          15 :   : elem_kind_(TK_BOOLEAN), active_(new(boolean_seq_) DDS::BooleanSeq(boolean_seq))
    1022          15 : {}
    1023             : 
    1024           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::StringSeq& str_seq)
    1025           9 :   : elem_kind_(TK_STRING8), active_(new(string_seq_) DDS::StringSeq(str_seq))
    1026           9 : {}
    1027             : 
    1028             : #ifdef DDS_HAS_WCHAR
    1029           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::WcharSeq& char16_seq)
    1030           9 :   : elem_kind_(TK_CHAR16), active_(new(char16_seq_) DDS::WcharSeq(char16_seq))
    1031           9 : {}
    1032             : 
    1033           9 : DynamicDataImpl::SequenceValue::SequenceValue(const DDS::WstringSeq& wstr_seq)
    1034           9 :   : elem_kind_(TK_STRING16), active_(new(wstring_seq_) DDS::WstringSeq(wstr_seq))
    1035           9 : {}
    1036             : #endif
    1037             : 
    1038           0 : DynamicDataImpl::SequenceValue::SequenceValue(const SequenceValue& rhs)
    1039           0 :   : elem_kind_(rhs.elem_kind_), active_(0)
    1040             : {
    1041             : #define SEQUENCE_VALUE_PLACEMENT_NEW(T, N)  active_ = new(N) DDS::T(reinterpret_cast<const DDS::T&>(rhs.N)); break;
    1042           0 :   switch (elem_kind_) {
    1043           0 :   case TK_INT32:
    1044           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Int32Seq, int32_seq_);
    1045           0 :   case TK_UINT32:
    1046           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(UInt32Seq, uint32_seq_);
    1047           0 :   case TK_INT8:
    1048           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Int8Seq, int8_seq_);
    1049           0 :   case TK_UINT8:
    1050           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(UInt8Seq, uint8_seq_);
    1051           0 :   case TK_INT16:
    1052           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Int16Seq, int16_seq_);
    1053           0 :   case TK_UINT16:
    1054           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(UInt16Seq, uint16_seq_);
    1055           0 :   case TK_INT64:
    1056           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Int64Seq, int64_seq_);
    1057           0 :   case TK_UINT64:
    1058           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(UInt64Seq, uint64_seq_);
    1059           0 :   case TK_FLOAT32:
    1060           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Float32Seq, float32_seq_);
    1061           0 :   case TK_FLOAT64:
    1062           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Float64Seq, float64_seq_);
    1063           0 :   case TK_FLOAT128:
    1064           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(Float128Seq, float128_seq_);
    1065           0 :   case TK_CHAR8:
    1066           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(CharSeq, char8_seq_);
    1067           0 :   case TK_BYTE:
    1068           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(ByteSeq, byte_seq_);
    1069           0 :   case TK_BOOLEAN:
    1070           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(BooleanSeq, boolean_seq_);
    1071           0 :   case TK_STRING8:
    1072           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(StringSeq, string_seq_);
    1073             : #ifdef DDS_HAS_WCHAR
    1074           0 :   case TK_CHAR16:
    1075           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(WcharSeq, char16_seq_);
    1076           0 :   case TK_STRING16:
    1077           0 :     SEQUENCE_VALUE_PLACEMENT_NEW(WstringSeq, wstring_seq_);
    1078             : #endif
    1079             :   }
    1080             : #undef SEQUENCE_VALUE_PLACEMENT_NEW
    1081           0 : }
    1082             : 
    1083         195 : DynamicDataImpl::SequenceValue::~SequenceValue()
    1084             : {
    1085             : #define SEQUENCE_VALUE_DESTRUCT(T) static_cast<DDS::T*>(active_)->~T(); break
    1086         195 :   switch (elem_kind_) {
    1087          21 :   case TK_INT32:
    1088          21 :     SEQUENCE_VALUE_DESTRUCT(Int32Seq);
    1089          18 :   case TK_UINT32:
    1090          18 :     SEQUENCE_VALUE_DESTRUCT(UInt32Seq);
    1091           9 :   case TK_INT8:
    1092           9 :     SEQUENCE_VALUE_DESTRUCT(Int8Seq);
    1093          15 :   case TK_UINT8:
    1094          15 :     SEQUENCE_VALUE_DESTRUCT(UInt8Seq);
    1095          18 :   case TK_INT16:
    1096          18 :     SEQUENCE_VALUE_DESTRUCT(Int16Seq);
    1097           9 :   case TK_UINT16:
    1098           9 :     SEQUENCE_VALUE_DESTRUCT(UInt16Seq);
    1099           9 :   case TK_INT64:
    1100           9 :     SEQUENCE_VALUE_DESTRUCT(Int64Seq);
    1101           9 :   case TK_UINT64:
    1102           9 :     SEQUENCE_VALUE_DESTRUCT(UInt64Seq);
    1103          15 :   case TK_FLOAT32:
    1104          15 :     SEQUENCE_VALUE_DESTRUCT(Float32Seq);
    1105           9 :   case TK_FLOAT64:
    1106           9 :     SEQUENCE_VALUE_DESTRUCT(Float64Seq);
    1107           0 :   case TK_FLOAT128:
    1108           0 :     SEQUENCE_VALUE_DESTRUCT(Float128Seq);
    1109           9 :   case TK_CHAR8:
    1110           9 :     SEQUENCE_VALUE_DESTRUCT(CharSeq);
    1111          12 :   case TK_BYTE:
    1112          12 :     SEQUENCE_VALUE_DESTRUCT(ByteSeq);
    1113          15 :   case TK_BOOLEAN:
    1114          15 :     SEQUENCE_VALUE_DESTRUCT(BooleanSeq);
    1115           9 :   case TK_STRING8:
    1116           9 :     SEQUENCE_VALUE_DESTRUCT(StringSeq);
    1117             : #ifdef DDS_HAS_WCHAR
    1118           9 :   case TK_CHAR16:
    1119           9 :     SEQUENCE_VALUE_DESTRUCT(WcharSeq);
    1120           9 :   case TK_STRING16:
    1121           9 :     SEQUENCE_VALUE_DESTRUCT(WstringSeq);
    1122             : #endif
    1123             :   }
    1124             :   #undef SEQUENCE_VALUE_DESTRUCT
    1125         195 : }
    1126             : 
    1127             : #define SEQUENCE_VALUE_GETTERS(T) return *static_cast<DDS::T*>(active_)
    1128          36 : template<> const DDS::Int32Seq& DynamicDataImpl::SequenceValue::get() const
    1129          36 : { SEQUENCE_VALUE_GETTERS(Int32Seq); }
    1130          21 : template<> const DDS::UInt32Seq& DynamicDataImpl::SequenceValue::get() const
    1131          21 : { SEQUENCE_VALUE_GETTERS(UInt32Seq); }
    1132          27 : template<> const DDS::Int8Seq& DynamicDataImpl::SequenceValue::get() const
    1133          27 : { SEQUENCE_VALUE_GETTERS(Int8Seq); }
    1134          24 : template<> const DDS::UInt8Seq& DynamicDataImpl::SequenceValue::get() const
    1135          24 : { SEQUENCE_VALUE_GETTERS(UInt8Seq); }
    1136          24 : template<> const DDS::Int16Seq& DynamicDataImpl::SequenceValue::get() const
    1137          24 : { SEQUENCE_VALUE_GETTERS(Int16Seq); }
    1138          24 : template<> const DDS::UInt16Seq& DynamicDataImpl::SequenceValue::get() const
    1139          24 : { SEQUENCE_VALUE_GETTERS(UInt16Seq); }
    1140          24 : template<> const DDS::Int64Seq& DynamicDataImpl::SequenceValue::get() const
    1141          24 : { SEQUENCE_VALUE_GETTERS(Int64Seq); }
    1142          24 : template<> const DDS::UInt64Seq& DynamicDataImpl::SequenceValue::get() const
    1143          24 : { SEQUENCE_VALUE_GETTERS(UInt64Seq); }
    1144          24 : template<> const DDS::Float32Seq& DynamicDataImpl::SequenceValue::get() const
    1145          24 : { SEQUENCE_VALUE_GETTERS(Float32Seq); }
    1146          24 : template<> const DDS::Float64Seq& DynamicDataImpl::SequenceValue::get() const
    1147          24 : { SEQUENCE_VALUE_GETTERS(Float64Seq); }
    1148           0 : template<> const DDS::Float128Seq& DynamicDataImpl::SequenceValue::get() const
    1149           0 : { SEQUENCE_VALUE_GETTERS(Float128Seq); }
    1150          24 : template<> const DDS::CharSeq& DynamicDataImpl::SequenceValue::get() const
    1151          24 : { SEQUENCE_VALUE_GETTERS(CharSeq); }
    1152          24 : template<> const DDS::ByteSeq& DynamicDataImpl::SequenceValue::get() const
    1153          24 : { SEQUENCE_VALUE_GETTERS(ByteSeq); }
    1154          27 : template<> const DDS::BooleanSeq& DynamicDataImpl::SequenceValue::get() const
    1155          27 : { SEQUENCE_VALUE_GETTERS(BooleanSeq); }
    1156          27 : template<> const DDS::StringSeq& DynamicDataImpl::SequenceValue::get() const
    1157          27 : { SEQUENCE_VALUE_GETTERS(StringSeq); }
    1158             : #ifdef DDS_HAS_WCHAR
    1159          24 : template<> const DDS::WcharSeq& DynamicDataImpl::SequenceValue::get() const
    1160          24 : { SEQUENCE_VALUE_GETTERS(WcharSeq); }
    1161          24 : template<> const DDS::WstringSeq& DynamicDataImpl::SequenceValue::get() const
    1162          24 : { SEQUENCE_VALUE_GETTERS(WstringSeq); }
    1163             : #endif
    1164             : #undef SEQUENCE_VALUE_GETTERS
    1165             : 
    1166         285 : bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val, const DDS::DynamicType_var& disc_type,
    1167             :                                          DataContainer::const_single_iterator it) const
    1168             : {
    1169         285 :   switch (disc_type->get_kind()) {
    1170           0 :   case TK_BOOLEAN: {
    1171           0 :     const ACE_OutputCDR::from_boolean& value = it->second.get<ACE_OutputCDR::from_boolean>();
    1172           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1173           0 :     return true;
    1174             :   }
    1175           0 :   case TK_BYTE: {
    1176           0 :     const ACE_OutputCDR::from_octet& value = it->second.get<ACE_OutputCDR::from_octet>();
    1177           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1178           0 :     return true;
    1179             :   }
    1180           0 :   case TK_CHAR8: {
    1181           0 :     const ACE_OutputCDR::from_char& value = it->second.get<ACE_OutputCDR::from_char>();
    1182           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1183           0 :     return true;
    1184             :   }
    1185             : #ifdef DDS_HAS_WCHAR
    1186           0 :   case TK_CHAR16: {
    1187           0 :     const ACE_OutputCDR::from_wchar& value = it->second.get<ACE_OutputCDR::from_wchar>();
    1188           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1189           0 :     return true;
    1190             :   }
    1191             : #endif
    1192           0 :   case TK_INT8: {
    1193           0 :     const ACE_OutputCDR::from_int8& value = it->second.get<ACE_OutputCDR::from_int8>();
    1194           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1195           0 :     return true;
    1196             :   }
    1197           0 :   case TK_UINT8: {
    1198           0 :     const ACE_OutputCDR::from_uint8& value = it->second.get<ACE_OutputCDR::from_uint8>();
    1199           0 :     disc_val = static_cast<CORBA::Long>(value.val_);
    1200           0 :     return true;
    1201             :   }
    1202           0 :   case TK_INT16: {
    1203           0 :     CORBA::Short value = it->second.get<CORBA::Short>();
    1204           0 :     disc_val = static_cast<CORBA::Long>(value);
    1205           0 :     return true;
    1206             :   }
    1207           0 :   case TK_UINT16: {
    1208           0 :     CORBA::UShort value = it->second.get<CORBA::UShort>();
    1209           0 :     disc_val = static_cast<CORBA::Long>(value);
    1210           0 :     return true;
    1211             :   }
    1212           0 :   case TK_INT32: {
    1213           0 :     disc_val = it->second.get<CORBA::Long>();
    1214           0 :     return true;
    1215             :   }
    1216           0 :   case TK_UINT32: {
    1217           0 :     CORBA::ULong value = it->second.get<CORBA::ULong>();
    1218           0 :     disc_val = static_cast<CORBA::Long>(value);
    1219           0 :     return true;
    1220             :   }
    1221           0 :   case TK_INT64: {
    1222           0 :     CORBA::LongLong value = it->second.get<CORBA::LongLong>();
    1223           0 :     disc_val = static_cast<CORBA::Long>(value);
    1224           0 :     return true;
    1225             :   }
    1226           0 :   case TK_UINT64: {
    1227           0 :     CORBA::ULongLong value = it->second.get<CORBA::ULongLong>();
    1228           0 :     disc_val = static_cast<CORBA::Long>(value);
    1229           0 :     return true;
    1230             :   }
    1231         285 :   case TK_ENUM: {
    1232         285 :     DDS::TypeDescriptor_var td;
    1233         285 :     if (disc_type->get_descriptor(td) != DDS::RETCODE_OK) {
    1234           0 :       return false;
    1235             :     }
    1236         285 :     const CORBA::ULong bitbound = td->bound()[0];
    1237         285 :     if (bitbound >= 1 && bitbound <= 8) {
    1238           0 :       const ACE_OutputCDR::from_int8& value = it->second.get<ACE_OutputCDR::from_int8>();
    1239           0 :       disc_val = static_cast<CORBA::Long>(value.val_);
    1240         285 :     } else if (bitbound >= 9 && bitbound <= 16) {
    1241           0 :       CORBA::Short value = it->second.get<CORBA::Short>();
    1242           0 :       disc_val = static_cast<CORBA::Long>(value);
    1243           0 :     } else {
    1244         285 :       disc_val = it->second.get<CORBA::Long>();
    1245             :     }
    1246         285 :     return true;
    1247         285 :   }
    1248             :   }
    1249           0 :   return false;
    1250             : }
    1251             : 
    1252             : // Read a discriminator value from a DynamicData that represents it.
    1253           0 : bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val) const
    1254             : {
    1255           0 :   if (!is_valid_discriminator_type(type_->get_kind())) {
    1256           0 :     return false;
    1257             :   }
    1258           0 :   DataContainer::const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID);
    1259           0 :   if (it == container_.single_map_.end()) {
    1260           0 :     return false;
    1261             :   }
    1262           0 :   return read_discriminator(disc_val, type_, it);
    1263             : }
    1264             : 
    1265             : // If a selected member of a union is already written, return its ID.
    1266             : // Should only be called for union.
    1267         402 : DDS::MemberId DynamicDataImpl::find_selected_member() const
    1268             : {
    1269             :   // There can be at most 2 entries in total in all three maps,
    1270             :   // one for the discriminator, one for a selected member.
    1271         402 :   for (DataContainer::const_single_iterator single_it = container_.single_map_.begin();
    1272         612 :        single_it != container_.single_map_.end(); ++single_it) {
    1273         393 :     if (single_it->first != DISCRIMINATOR_ID) {
    1274         183 :       return single_it->first;
    1275             :     }
    1276             :   }
    1277             : 
    1278             :   // If there is any entry in sequence_map_, that must be for a selected member
    1279             :   // since discriminator cannot be sequence.
    1280         219 :   if (container_.sequence_map_.size() > 0) {
    1281         208 :     OPENDDS_ASSERT(container_.sequence_map_.size() == 1);
    1282         208 :     return container_.sequence_map_.begin()->first;
    1283             :   }
    1284             : 
    1285          11 :   for (DataContainer::const_complex_iterator cmpl_it = container_.complex_map_.begin();
    1286          11 :        cmpl_it != container_.complex_map_.end(); ++cmpl_it) {
    1287           1 :     if (cmpl_it->first != DISCRIMINATOR_ID) {
    1288           1 :       return cmpl_it->first;
    1289             :     }
    1290             :   }
    1291             : 
    1292             :   // There was no selected member written.
    1293          10 :   return MEMBER_ID_INVALID;
    1294             : }
    1295             : 
    1296             : // Check if a discriminator value would select a member with the given descriptor in a union.
    1297         108 : bool DynamicDataImpl::validate_discriminator(CORBA::Long disc_val,
    1298             :                                              const DDS::MemberDescriptor_var& md) const
    1299             : {
    1300             :   // If the selected member is not default, the discriminator value must equal one of its
    1301             :   // labels. If the selected member is default, the discriminator value must not equal
    1302             :   // any label of the non-default members.
    1303         108 :   if (!md->is_default_label()) {
    1304         105 :     const DDS::UnionCaseLabelSeq& labels = md->label();
    1305         105 :     bool found = false;
    1306         210 :     for (CORBA::ULong i = 0; !found && i < labels.length(); ++i) {
    1307         105 :       if (disc_val == labels[i]) {
    1308          12 :         found = true;
    1309             :       }
    1310             :     }
    1311         105 :     if (!found) {
    1312          93 :       return false;
    1313             :     }
    1314           3 :   } else if (!is_default_member_selected(disc_val, md->id())) {
    1315           3 :     return false;
    1316             :   }
    1317          12 :   return true;
    1318             : }
    1319             : 
    1320           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1321             :                                                   const ACE_OutputCDR::from_boolean& value) const
    1322             : {
    1323           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1324           0 :   return true;
    1325             : }
    1326             : 
    1327           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1328             :                                                   const ACE_OutputCDR::from_octet& value) const
    1329             : {
    1330           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1331           0 :   return true;
    1332             : }
    1333             : 
    1334           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1335             :                                                   const ACE_OutputCDR::from_char& value) const
    1336             : {
    1337           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1338           0 :   return true;
    1339             : }
    1340             : 
    1341             : #ifdef DDS_HAS_WCHAR
    1342           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1343             :                                                   const ACE_OutputCDR::from_wchar& value) const
    1344             : {
    1345           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1346           0 :   return true;
    1347             : }
    1348             : #endif
    1349             : 
    1350           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1351             :                                                   const ACE_OutputCDR::from_int8& value) const
    1352             : {
    1353           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1354           0 :   return true;
    1355             : }
    1356             : 
    1357           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1358             :                                                   const ACE_OutputCDR::from_uint8& value) const
    1359             : {
    1360           0 :   disc_value = static_cast<CORBA::Long>(value.val_);
    1361           0 :   return true;
    1362             : }
    1363             : 
    1364           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1365             :                                                   const CORBA::Short& value) const
    1366             : {
    1367           0 :   disc_value = static_cast<CORBA::Long>(value);
    1368           0 :   return true;
    1369             : }
    1370             : 
    1371           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1372             :                                                   const CORBA::UShort& value) const
    1373             : {
    1374           0 :   disc_value = static_cast<CORBA::Long>(value);
    1375           0 :   return true;
    1376             : }
    1377             : 
    1378         108 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1379             :                                                   const CORBA::Long& value) const
    1380             : {
    1381         108 :   disc_value = value;
    1382         108 :   return true;
    1383             : }
    1384             : 
    1385           9 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1386             :                                                   const CORBA::ULong& value) const
    1387             : {
    1388           9 :   disc_value = static_cast<CORBA::Long>(value);
    1389           9 :   return true;
    1390             : }
    1391             : 
    1392           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1393             :                                                   const CORBA::LongLong& value) const
    1394             : {
    1395           0 :   disc_value = static_cast<CORBA::Long>(value);
    1396           0 :   return true;
    1397             : }
    1398             : 
    1399           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& disc_value,
    1400             :                                                   const CORBA::ULongLong& value) const
    1401             : {
    1402           0 :   disc_value = static_cast<CORBA::Long>(value);
    1403           0 :   return true;
    1404             : }
    1405             : 
    1406             : template<typename MemberType>
    1407           0 : bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& /*disc_value*/,
    1408             :                                                   const MemberType& /*value*/) const
    1409             : {
    1410           0 :   return false;
    1411             : }
    1412             : 
    1413             : template<TypeKind MemberTypeKind, typename MemberType>
    1414         299 : bool DynamicDataImpl::set_value_to_union(DDS::MemberId id, const MemberType& value,
    1415             :                                          TypeKind enum_or_bitmask, LBound lower, LBound upper)
    1416             : {
    1417             :   // This follows the IDL-to-C++ mapping for union.
    1418         299 :   DDS::DynamicType_var member_type;
    1419         299 :   if (id == DISCRIMINATOR_ID) {
    1420             :     // Discriminator can only be of certain types (XTypes spec, 7.2.2.4.4.3)
    1421         113 :     if (!is_valid_discriminator_type(MemberTypeKind)) {
    1422           0 :       if (log_level >= LogLevel::Notice) {
    1423           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:"
    1424             :                    " Type %C cannot be used for union discriminator\n",
    1425             :                    typekind_to_string(MemberTypeKind)));
    1426             :       }
    1427           0 :       return false;
    1428             :     }
    1429             : 
    1430         113 :     member_type = get_base_type(type_desc_->discriminator_type());
    1431             : 
    1432         113 :     const TypeKind member_tk = member_type->get_kind();
    1433         113 :     if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) {
    1434           0 :       return false;
    1435             :     }
    1436             : 
    1437         113 :     if (member_tk == enum_or_bitmask) {
    1438         104 :       DDS::TypeDescriptor_var member_td;
    1439         104 :       if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
    1440           0 :         return false;
    1441             :       }
    1442         104 :       const CORBA::ULong bit_bound = member_td->bound()[0];
    1443         104 :       if (bit_bound < lower || bit_bound > upper) {
    1444           0 :         return false;
    1445             :       }
    1446         104 :     }
    1447             : 
    1448             :     CORBA::Long disc_value;
    1449         113 :     if (!cast_to_discriminator_value(disc_value, value)) {
    1450           0 :       return false;
    1451             :     }
    1452             : 
    1453         113 :     const DDS::MemberId selected_id = find_selected_member();
    1454         113 :     if (selected_id != MEMBER_ID_INVALID) {
    1455         108 :       DDS::DynamicTypeMember_var selected_member;
    1456         108 :       if (type_->get_member(selected_member, selected_id) != DDS::RETCODE_OK) {
    1457           0 :         return false;
    1458             :       }
    1459         108 :       DDS::MemberDescriptor_var selected_md;
    1460         108 :       if (selected_member->get_descriptor(selected_md) != DDS::RETCODE_OK) {
    1461           0 :         return false;
    1462             :       }
    1463             : 
    1464         108 :       if (!validate_discriminator(disc_value, selected_md)) {
    1465          96 :         if (log_level >= LogLevel::Notice) {
    1466           0 :           ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:"
    1467             :                      " Discriminator value %d does not select the activated member (ID %u)\n",
    1468             :                      disc_value, selected_id));
    1469             :         }
    1470          96 :         return false;
    1471             :       }
    1472          12 :       return insert_single(id, value);
    1473         108 :     } else {
    1474             :       // In case the union has implicit default member and the input discriminator value
    1475             :       // selects that implicit default member, store the discriminator value. The semantics
    1476             :       // of this is similar to the _default() method of the IDL-to-C++ mapping for union.
    1477           5 :       if (discriminator_selects_no_member(disc_value)) {
    1478           1 :         return insert_single(id, value);
    1479             :       }
    1480           4 :       if (log_level >= LogLevel::Notice) {
    1481           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:"
    1482             :                    " Can't directly set a discriminator that selects a member."
    1483             :                    " Activate the member first!\n"));
    1484             :       }
    1485           4 :       return false;
    1486             :     }
    1487             :   }
    1488             : 
    1489             :   // Activate a member
    1490         186 :   clear_container();
    1491             : 
    1492         186 :   DDS::DynamicTypeMember_var member;
    1493         186 :   if (type_->get_member(member, id) != DDS::RETCODE_OK) {
    1494           0 :     return false;
    1495             :   }
    1496         186 :   DDS::MemberDescriptor_var md;
    1497         186 :   if (member->get_descriptor(md) != DDS::RETCODE_OK) {
    1498           0 :     return false;
    1499             :   }
    1500         186 :   member_type = get_base_type(md->type());
    1501             : 
    1502         186 :   const TypeKind member_tk = member_type->get_kind();
    1503         186 :   if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) {
    1504           0 :     return false;
    1505             :   }
    1506             : 
    1507         186 :   return insert_valid_discriminator(md) && insert_single(id, value);
    1508         299 : }
    1509             : 
    1510         331 : bool DynamicDataImpl::insert_valid_discriminator(DDS::MemberDescriptor* memberSelected)
    1511             : {
    1512         331 :   if (memberSelected->is_default_label()) {
    1513           8 :     DCPS::DisjointSequence::OrderedRanges<ACE_CDR::Long> used;
    1514           8 :     const ACE_CDR::ULong members = type_->get_member_count();
    1515         152 :     for (ACE_CDR::ULong i = 0; i < members; ++i) {
    1516         144 :       DDS::DynamicTypeMember_var member;
    1517         144 :       if (type_->get_member_by_index(member, i) != DDS::RETCODE_OK) {
    1518           0 :         return false;
    1519             :       }
    1520         144 :       if (member->get_id() == DISCRIMINATOR_ID || member->get_id() == memberSelected->id()) {
    1521          16 :         continue;
    1522             :       }
    1523         128 :       DDS::MemberDescriptor_var mdesc;
    1524         128 :       if (member->get_descriptor(mdesc) != DDS::RETCODE_OK) {
    1525           0 :         return false;
    1526             :       }
    1527         128 :       const DDS::UnionCaseLabelSeq& lseq = mdesc->label();
    1528         256 :       for (ACE_CDR::ULong lbl = 0; lbl < lseq.length(); ++lbl) {
    1529         128 :         used.add(lseq[lbl]);
    1530             :       }
    1531         144 :     }
    1532           8 :     const ACE_CDR::Long disc = used.empty() ? 0 : used.begin()->second + 1;
    1533           8 :     return insert_discriminator(disc);
    1534           8 :   }
    1535         323 :   const DDS::UnionCaseLabelSeq& lseq = memberSelected->label();
    1536         323 :   return lseq.length() && insert_discriminator(lseq[0]);
    1537             : }
    1538             : 
    1539         331 : bool DynamicDataImpl::insert_discriminator(ACE_CDR::Long value)
    1540             : {
    1541         331 :   DDS::DynamicTypeMember_var member;
    1542         331 :   if (type_->get_member(member, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
    1543           0 :     return false;
    1544             :   }
    1545         331 :   DDS::MemberDescriptor_var descriptor;
    1546         331 :   if (member->get_descriptor(descriptor) != DDS::RETCODE_OK) {
    1547           0 :     return false;
    1548             :   }
    1549         331 :   DDS::DynamicType_var discType = get_base_type(descriptor->type());
    1550         331 :   switch (discType ? discType->get_kind() : TK_NONE) {
    1551           0 :   case TK_BOOLEAN:
    1552           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_boolean(value));
    1553           0 :   case TK_BYTE:
    1554           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_octet(value));
    1555           0 :   case TK_CHAR8:
    1556           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_char(value));
    1557             : #ifdef DDS_HAS_WCHAR
    1558           0 :   case TK_CHAR16:
    1559           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_wchar(value));
    1560             : #endif
    1561           0 :   case TK_INT8:
    1562           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_int8(value));
    1563           0 :   case TK_UINT8:
    1564           0 :     return insert_single(DISCRIMINATOR_ID, ACE_OutputCDR::from_uint8(value));
    1565           0 :   case TK_INT16:
    1566           0 :     return insert_single(DISCRIMINATOR_ID, static_cast<ACE_CDR::Short>(value));
    1567           0 :   case TK_UINT16:
    1568           0 :     return insert_single(DISCRIMINATOR_ID, static_cast<ACE_CDR::UShort>(value));
    1569         322 :   case TK_ENUM:
    1570             :   case TK_INT32:
    1571         322 :     return insert_single(DISCRIMINATOR_ID, value);
    1572           9 :   case TK_UINT32:
    1573           9 :     return insert_single(DISCRIMINATOR_ID, static_cast<ACE_CDR::ULong>(value));
    1574           0 :   case TK_INT64:
    1575           0 :     return insert_single(DISCRIMINATOR_ID, static_cast<ACE_CDR::LongLong>(value));
    1576           0 :   case TK_UINT64:
    1577           0 :     return insert_single(DISCRIMINATOR_ID, static_cast<ACE_CDR::ULongLong>(value));
    1578           0 :   default:
    1579           0 :     return false;
    1580             :   }
    1581         331 : }
    1582             : 
    1583             : // Check if a given member ID is valid for a given type with a maximum number of elements.
    1584         175 : bool DynamicDataImpl::check_index_from_id(TypeKind tk, DDS::MemberId id, CORBA::ULong bound) const
    1585             : {
    1586             :   // The given Id is treated as index.
    1587         175 :   switch (tk) {
    1588          91 :   case TK_STRING8:
    1589             :   case TK_STRING16:
    1590             :   case TK_SEQUENCE:
    1591             :   case TK_MAP:
    1592             :     // Bound of 0 means unbounded.
    1593          91 :     if (bound == 0 || id < bound) {
    1594          91 :       return true;
    1595             :     }
    1596           0 :     break;
    1597          84 :   case TK_BITMASK:
    1598             :   case TK_ARRAY:
    1599          84 :     if (id < bound) {
    1600          84 :       return true;
    1601             :     }
    1602           0 :     break;
    1603             :   }
    1604           0 :   return false;
    1605             : }
    1606             : 
    1607             : template<TypeKind ElementTypeKind, typename ElementType>
    1608         173 : bool DynamicDataImpl::set_value_to_collection(DDS::MemberId id, const ElementType& value,
    1609             :   TypeKind collection_tk, TypeKind enum_or_bitmask, LBound lower, LBound upper)
    1610             : {
    1611         173 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    1612         173 :   const TypeKind elem_tk = elem_type->get_kind();
    1613             : 
    1614         173 :   if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
    1615           0 :     if (log_level >= LogLevel::Notice) {
    1616           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_collection:"
    1617             :                  " Could not write a value of type %C to %C with element type %C\n",
    1618             :                  typekind_to_string(ElementTypeKind), typekind_to_string(collection_tk),
    1619             :                  typekind_to_string(elem_tk)));
    1620             :     }
    1621           0 :     return false;
    1622             :   }
    1623             : 
    1624         173 :   if (elem_tk == enum_or_bitmask) {
    1625          14 :     DDS::TypeDescriptor_var elem_td;
    1626          14 :     if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    1627           0 :       return false;
    1628             :     }
    1629          14 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    1630          14 :     if (bit_bound < lower || bit_bound > upper) {
    1631           0 :       return false;
    1632             :     }
    1633          14 :   }
    1634             : 
    1635         173 :   return validate_member_id_collection(id, collection_tk) && insert_single(id, value);
    1636         173 : }
    1637             : 
    1638             : template<TypeKind ValueTypeKind, typename ValueType>
    1639         570 : DDS::ReturnCode_t DynamicDataImpl::set_single_value(DDS::MemberId id, const ValueType& value,
    1640             :   TypeKind enum_or_bitmask, LBound lower, LBound upper)
    1641             : {
    1642         570 :   if (!is_type_supported(ValueTypeKind, "set_single_value")) {
    1643           0 :     return DDS::RETCODE_ERROR;
    1644             :   }
    1645             : 
    1646         570 :   const TypeKind tk = type_->get_kind();
    1647         570 :   bool good = true;
    1648             : 
    1649             :   // TODO: Bitmask can be stored as a whole as a unsigned integer using MEMBER_ID_INVALID
    1650             :   // (this is an extension to the XTypes spec). Elements of the bitmask can also be set
    1651             :   // using the set_boolean_value interface. The two copies of the bitmask value must be
    1652             :   // made consistent. For example, when a bit in the bitmask is updated, either update
    1653             :   // the unsigned integer representation or invalidate it. Similarly, when the unsigned
    1654             :   // integer value is updated, either update the stored elements or invalidate them all.
    1655         570 :   if (tk == enum_or_bitmask) {
    1656           0 :     const CORBA::ULong bit_bound = type_desc_->bound()[0];
    1657           0 :     good = id == MEMBER_ID_INVALID && bit_bound >= lower && bit_bound <= upper &&
    1658           0 :       insert_single(id, value);
    1659             :   } else {
    1660         570 :     switch (tk) {
    1661           6 :     case ValueTypeKind:
    1662           6 :       good = is_primitive(tk) && id == MEMBER_ID_INVALID && insert_single(id, value);
    1663           6 :       break;
    1664         140 :     case TK_STRUCTURE:
    1665         140 :       good = set_value_to_struct<ValueTypeKind>(id, value);
    1666         140 :       break;
    1667         272 :     case TK_UNION:
    1668         272 :       good = set_value_to_union<ValueTypeKind>(id, value, enum_or_bitmask, lower, upper);
    1669         272 :       break;
    1670         149 :     case TK_SEQUENCE:
    1671             :     case TK_ARRAY:
    1672             :     case TK_MAP:
    1673         149 :       good = set_value_to_collection<ValueTypeKind>(id, value, tk, enum_or_bitmask, lower, upper);
    1674         149 :       break;
    1675           3 :     default:
    1676           3 :       good = false;
    1677           3 :       break;
    1678             :     }
    1679             :   }
    1680             : 
    1681         570 :   if (!good && log_level >= LogLevel::Notice) {
    1682           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_single_value: "
    1683             :                "Failed to write a value of %C to DynamicData object of type %C\n",
    1684             :                typekind_to_string(ValueTypeKind), typekind_to_string(tk)));
    1685             :   }
    1686         570 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    1687             : }
    1688             : 
    1689         191 : DDS::ReturnCode_t DynamicDataImpl::set_int32_value(DDS::MemberId id, CORBA::Long value)
    1690             : {
    1691         191 :   return set_single_value<TK_INT32>(id, value, TK_ENUM, 17, 32);
    1692             : }
    1693             : 
    1694          85 : DDS::ReturnCode_t DynamicDataImpl::set_uint32_value(DDS::MemberId id, CORBA::ULong value)
    1695             : {
    1696          85 :   return set_single_value<TK_UINT32>(id, value, TK_BITMASK, 17, 32);
    1697             : }
    1698             : 
    1699          30 : DDS::ReturnCode_t DynamicDataImpl::set_int8_value(DDS::MemberId id, CORBA::Int8 value)
    1700             : {
    1701          30 :   return set_single_value<TK_INT8>(id, ACE_OutputCDR::from_int8(value), TK_ENUM, 1, 8);
    1702             : }
    1703             : 
    1704          31 : DDS::ReturnCode_t DynamicDataImpl::set_uint8_value(DDS::MemberId id, CORBA::UInt8 value)
    1705             : {
    1706          31 :   return set_single_value<TK_UINT8>(id, ACE_OutputCDR::from_uint8(value), TK_BITMASK, 1, 8);
    1707             : }
    1708             : 
    1709          39 : DDS::ReturnCode_t DynamicDataImpl::set_int16_value(DDS::MemberId id, CORBA::Short value)
    1710             : {
    1711          39 :   return set_single_value<TK_INT16>(id, value, TK_ENUM, 9, 16);
    1712             : }
    1713             : 
    1714          29 : DDS::ReturnCode_t DynamicDataImpl::set_uint16_value(DDS::MemberId id, CORBA::UShort value)
    1715             : {
    1716          29 :   return set_single_value<TK_UINT16>(id, value, TK_BITMASK, 9, 16);
    1717             : }
    1718             : 
    1719          22 : DDS::ReturnCode_t DynamicDataImpl::set_int64_value(DDS::MemberId id, CORBA::LongLong value)
    1720             : {
    1721          22 :   return set_single_value<TK_INT64>(id, value);
    1722             : }
    1723             : 
    1724          25 : DDS::ReturnCode_t DynamicDataImpl::set_uint64_value(DDS::MemberId id, CORBA::ULongLong value)
    1725             : {
    1726          25 :   return set_single_value<TK_UINT64>(id, value, TK_BITMASK, 33, 64);
    1727             : }
    1728             : 
    1729          21 : DDS::ReturnCode_t DynamicDataImpl::set_float32_value(DDS::MemberId id, CORBA::Float value)
    1730             : {
    1731          21 :   return set_single_value<TK_FLOAT32>(id, value);
    1732             : }
    1733             : 
    1734          22 : DDS::ReturnCode_t DynamicDataImpl::set_float64_value(DDS::MemberId id, CORBA::Double value)
    1735             : {
    1736          22 :   return set_single_value<TK_FLOAT64>(id, value);
    1737             : }
    1738             : 
    1739          10 : DDS::ReturnCode_t DynamicDataImpl::set_float128_value(DDS::MemberId id, CORBA::LongDouble value)
    1740             : {
    1741          10 :   return set_single_value<TK_FLOAT128>(id, value);
    1742             : }
    1743             : 
    1744             : template<TypeKind CharKind, TypeKind StringKind, typename FromCharT>
    1745          55 : DDS::ReturnCode_t DynamicDataImpl::set_char_common(DDS::MemberId id, const FromCharT& value)
    1746             : {
    1747          55 :   const TypeKind tk = type_->get_kind();
    1748          55 :   bool good = true;
    1749             : 
    1750          55 :   switch (tk) {
    1751           0 :   case CharKind:
    1752           0 :     good = id == MEMBER_ID_INVALID && insert_single(id, value);
    1753           0 :     break;
    1754           0 :   case StringKind: {
    1755           0 :     const CORBA::ULong bound = type_desc_->bound()[0];
    1756           0 :     if (!check_index_from_id(tk, id, bound)) {
    1757           0 :       good = false;
    1758             :     } else {
    1759           0 :       good = insert_single(id, value);
    1760             :     }
    1761           0 :     break;
    1762             :   }
    1763          19 :   case TK_STRUCTURE:
    1764          19 :     good = set_value_to_struct<CharKind>(id, value);
    1765          19 :     break;
    1766          20 :   case TK_UNION:
    1767          20 :     good = set_value_to_union<CharKind>(id, value);
    1768          20 :     break;
    1769          16 :   case TK_SEQUENCE:
    1770             :   case TK_ARRAY:
    1771             :   case TK_MAP:
    1772          16 :     good = set_value_to_collection<CharKind>(id, value, tk);
    1773          16 :     break;
    1774           0 :   default:
    1775           0 :     good = false;
    1776           0 :     break;
    1777             :   }
    1778             : 
    1779          55 :   if (!good && log_level >= LogLevel::Notice) {
    1780           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_char_common:"
    1781             :                " Failed to write DynamicData object of type %C\n", typekind_to_string(tk)));
    1782             :   }
    1783          55 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    1784             : }
    1785             : 
    1786          33 : DDS::ReturnCode_t DynamicDataImpl::set_char8_value(DDS::MemberId id, CORBA::Char value)
    1787             : {
    1788          33 :   return set_char_common<TK_CHAR8, TK_STRING8>(id, ACE_OutputCDR::from_char(value));
    1789             : }
    1790             : 
    1791          22 : DDS::ReturnCode_t DynamicDataImpl::set_char16_value(DDS::MemberId id, CORBA::WChar value)
    1792             : {
    1793             : #ifdef DDS_HAS_WCHAR
    1794          22 :   return set_char_common<TK_CHAR16, TK_STRING16>(id, ACE_OutputCDR::from_wchar(value));
    1795             : #else
    1796             :   return DDS::RETCODE_UNSUPPORTED;
    1797             : #endif
    1798             : }
    1799             : 
    1800          22 : DDS::ReturnCode_t DynamicDataImpl::set_byte_value(DDS::MemberId id, CORBA::Octet value)
    1801             : {
    1802          22 :   return set_single_value<TK_BYTE>(id, ACE_OutputCDR::from_octet(value));
    1803             : }
    1804             : 
    1805          22 : DDS::ReturnCode_t DynamicDataImpl::set_boolean_value(DDS::MemberId id, CORBA::Boolean value)
    1806             : {
    1807          22 :   const TypeKind tk = type_->get_kind();
    1808          22 :   bool good = true;
    1809             : 
    1810          22 :   switch (tk) {
    1811           0 :   case TK_BOOLEAN:
    1812           0 :     good = id == MEMBER_ID_INVALID && insert_single(id, ACE_OutputCDR::from_boolean(value));
    1813           0 :     break;
    1814           0 :   case TK_BITMASK: {
    1815           0 :     const CORBA::ULong bit_bound = type_desc_->bound()[0];
    1816           0 :     if (!check_index_from_id(tk, id, bit_bound)) {
    1817           0 :       good = false;
    1818             :     } else {
    1819           0 :       good = insert_single(id, ACE_OutputCDR::from_boolean(value));
    1820             :     }
    1821           0 :     break;
    1822             :   }
    1823           7 :   case TK_STRUCTURE:
    1824           7 :     good = set_value_to_struct<TK_BOOLEAN>(id, ACE_OutputCDR::from_boolean(value));
    1825           7 :     break;
    1826           7 :   case TK_UNION:
    1827           7 :     good = set_value_to_union<TK_BOOLEAN>(id, ACE_OutputCDR::from_boolean(value));
    1828           7 :     break;
    1829           8 :   case TK_SEQUENCE:
    1830             :   case TK_ARRAY:
    1831             :   case TK_MAP:
    1832           8 :     good = set_value_to_collection<TK_BOOLEAN>(id, ACE_OutputCDR::from_boolean(value), tk);
    1833           8 :     break;
    1834           0 :   default:
    1835           0 :     good = false;
    1836           0 :     break;
    1837             :   }
    1838             : 
    1839          22 :   if (!good && log_level >= LogLevel::Notice) {
    1840           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_boolean_value:"
    1841             :                " Failed to write boolean to DynamicData object of type %C\n",
    1842             :                typekind_to_string(tk)));
    1843             :   }
    1844          22 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    1845             : }
    1846             : 
    1847          23 : DDS::ReturnCode_t DynamicDataImpl::set_string_value(DDS::MemberId id, const char* value)
    1848             : {
    1849          23 :   DDS::DynamicType_var mtype;
    1850          23 :   DDS::ReturnCode_t rc = get_member_type(mtype, type_, id);
    1851          23 :   if (rc != DDS::RETCODE_OK) {
    1852           0 :     return rc;
    1853             :   }
    1854          23 :   if (mtype->get_kind() == TK_ENUM) {
    1855             :     DDS::Int32 intValue;
    1856           1 :     rc = get_enumerator_value(intValue, value, mtype);
    1857           1 :     if (rc != DDS::RETCODE_OK) {
    1858           0 :       return rc;
    1859             :     }
    1860           1 :     return set_enum_value(mtype, this, id, intValue);
    1861             :   }
    1862          22 :   return set_single_value<TK_STRING8>(id, value);
    1863          23 : }
    1864             : 
    1865          21 : DDS::ReturnCode_t DynamicDataImpl::set_wstring_value(DDS::MemberId id, const CORBA::WChar* value)
    1866             : {
    1867             : #ifdef DDS_HAS_WCHAR
    1868          21 :   return set_single_value<TK_STRING16>(id, value);
    1869             : #else
    1870             :   return DDS::RETCODE_UNSUPPORTED;
    1871             : #endif
    1872             : }
    1873             : 
    1874             : #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE
    1875           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value_boolean(DCPS::Value& value,
    1876             :                                                             DDS::MemberId id) const
    1877             : {
    1878           0 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    1879           0 :   if (single_it != container_.single_map_.end()) {
    1880           0 :     value = single_it->second.get<ACE_OutputCDR::from_boolean>().val_;
    1881           0 :     return DDS::RETCODE_OK;
    1882             :   }
    1883           0 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    1884           0 :   if (complex_it != container_.complex_map_.end()) {
    1885           0 :     const DynamicDataImpl* inner_dd = dynamic_cast<DynamicDataImpl*>(complex_it->second.in());
    1886           0 :     if (!inner_dd) {
    1887           0 :       return DDS::RETCODE_ERROR;
    1888             :     }
    1889             :     DataContainer::const_single_iterator inner_it =
    1890           0 :       inner_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    1891           0 :     if (inner_it != inner_dd->container_.single_map_.end()) {
    1892           0 :       value = inner_it->second.get<ACE_OutputCDR::from_boolean>().val_;
    1893           0 :       return DDS::RETCODE_OK;
    1894             :     }
    1895             :   }
    1896           0 :   return DDS::RETCODE_ERROR;
    1897             : }
    1898             : 
    1899           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value_char(DCPS::Value& value,
    1900             :                                                          DDS::MemberId id) const
    1901             : {
    1902           0 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    1903           0 :   if (single_it != container_.single_map_.end()) {
    1904           0 :     value = single_it->second.get<ACE_OutputCDR::from_char>().val_;
    1905           0 :     return DDS::RETCODE_OK;
    1906             :   }
    1907           0 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    1908           0 :   if (complex_it != container_.complex_map_.end()) {
    1909           0 :     const DynamicDataImpl* inner_dd = dynamic_cast<DynamicDataImpl*>(complex_it->second.in());
    1910           0 :     if (!inner_dd) {
    1911           0 :       return DDS::RETCODE_ERROR;
    1912             :     }
    1913             :     DataContainer::const_single_iterator inner_it =
    1914           0 :       inner_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    1915           0 :     if (inner_it != inner_dd->container_.single_map_.end()) {
    1916           0 :       value = inner_it->second.get<ACE_OutputCDR::from_char>().val_;
    1917           0 :       return DDS::RETCODE_OK;
    1918             :     }
    1919             :   }
    1920           0 :   return DDS::RETCODE_ERROR;
    1921             : }
    1922             : 
    1923             : template<typename ValueType>
    1924           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value_primitive(DCPS::Value& value,
    1925             :                                                               DDS::MemberId id) const
    1926             : {
    1927           0 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    1928           0 :   if (single_it != container_.single_map_.end()) {
    1929           0 :     value = single_it->second.get<ValueType>();
    1930           0 :     return DDS::RETCODE_OK;
    1931             :   }
    1932           0 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    1933           0 :   if (complex_it != container_.complex_map_.end()) {
    1934           0 :     const DynamicDataImpl* inner_dd = dynamic_cast<DynamicDataImpl*>(complex_it->second.in());
    1935           0 :     if (!inner_dd) {
    1936           0 :       return DDS::RETCODE_ERROR;
    1937             :     }
    1938             :     DataContainer::const_single_iterator inner_it =
    1939           0 :       inner_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    1940           0 :     if (inner_it != inner_dd->container_.single_map_.end()) {
    1941           0 :       value = inner_it->second.get<ValueType>();
    1942           0 :       return DDS::RETCODE_OK;
    1943             :     }
    1944             :   }
    1945           0 :   return DDS::RETCODE_ERROR;
    1946             : }
    1947             : 
    1948           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value_string(DCPS::Value& value,
    1949             :                                                            DDS::MemberId id) const
    1950             : {
    1951           0 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    1952           0 :   if (single_it != container_.single_map_.end()) {
    1953           0 :     value = single_it->second.get<const char*>();
    1954           0 :     return DDS::RETCODE_OK;
    1955             :   }
    1956             : 
    1957           0 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    1958           0 :   if (complex_it != container_.complex_map_.end()) {
    1959             :     // The string member has its own DynamicData object.
    1960           0 :     const DynamicDataImpl* str_dd = dynamic_cast<DynamicDataImpl*>(complex_it->second.in());
    1961           0 :     char* str = 0;
    1962           0 :     if (!str_dd || !str_dd->read_basic_value(str)) {
    1963           0 :       return DDS::RETCODE_ERROR;
    1964             :     }
    1965           0 :     value = str;
    1966           0 :     return DDS::RETCODE_OK;
    1967             :   }
    1968           0 :   return DDS::RETCODE_ERROR;
    1969             : }
    1970             : 
    1971           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value_enum(DCPS::Value& value,
    1972             :                                                          DDS::MemberId id) const
    1973             : {
    1974           0 :   DDS::DynamicType_var mtype;
    1975           0 :   DDS::ReturnCode_t ret = get_member_type(mtype, type_, id);
    1976           0 :   if (ret != DDS::RETCODE_OK) {
    1977           0 :     return ret;
    1978             :   }
    1979             : 
    1980             :   DDS::Int32 enumAsInteger;
    1981           0 :   ret = get_enum_value(enumAsInteger, mtype, interface_from_this(), id);
    1982           0 :   if (ret != DDS::RETCODE_OK) {
    1983           0 :     return ret;
    1984             :   }
    1985             : 
    1986           0 :   DDS::String8_var str;
    1987           0 :   ret = get_enumerator_name(str, enumAsInteger, mtype);
    1988           0 :   if (ret != DDS::RETCODE_OK) {
    1989           0 :     return ret;
    1990             :   }
    1991             : 
    1992           0 :   value = str.in();
    1993           0 :   return DDS::RETCODE_OK;
    1994           0 : }
    1995             : 
    1996           0 : DDS::ReturnCode_t DynamicDataImpl::get_simple_value(DCPS::Value& value, DDS::MemberId id)
    1997             : {
    1998           0 :   DDS::DynamicTypeMember_var dtm;
    1999           0 :   if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
    2000           0 :     return DDS::RETCODE_ERROR;
    2001             :   }
    2002           0 :   DDS::MemberDescriptor_var md;
    2003           0 :   if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    2004           0 :     return DDS::RETCODE_ERROR;
    2005             :   }
    2006           0 :   DDS::DynamicType_var member_type = get_base_type(md->type());
    2007           0 :   const TypeKind member_kind = member_type->get_kind();
    2008           0 :   switch (member_kind) {
    2009           0 :   case TK_BOOLEAN:
    2010           0 :     return get_simple_value_boolean(value, id);
    2011           0 :   case TK_INT32:
    2012           0 :     return get_simple_value_primitive<CORBA::Long>(value, id);
    2013           0 :   case TK_UINT32:
    2014           0 :     return get_simple_value_primitive<CORBA::ULong>(value, id);
    2015           0 :   case TK_INT64:
    2016           0 :     return get_simple_value_primitive<CORBA::LongLong>(value, id);
    2017           0 :   case TK_UINT64:
    2018           0 :     return get_simple_value_primitive<CORBA::ULongLong>(value, id);
    2019           0 :   case TK_CHAR8:
    2020           0 :     return get_simple_value_char(value, id);
    2021           0 :   case TK_FLOAT64:
    2022           0 :     return get_simple_value_primitive<CORBA::Double>(value, id);
    2023           0 :   case TK_FLOAT128:
    2024           0 :     return get_simple_value_primitive<CORBA::LongDouble>(value, id);
    2025           0 :   case TK_STRING8:
    2026           0 :     return get_simple_value_string(value, id);
    2027           0 :   case TK_ENUM:
    2028           0 :     return get_simple_value_enum(value, id);
    2029           0 :   default:
    2030           0 :     if (log_level >= LogLevel::Notice) {
    2031           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_simple_value:"
    2032             :                  " Member type %C is not supported by DCPS::Value\n",
    2033             :                  typekind_to_string(member_kind)));
    2034             :     }
    2035             :   }
    2036           0 :   return DDS::RETCODE_ERROR;
    2037           0 : }
    2038             : #endif
    2039             : 
    2040          28 : bool DynamicDataImpl::set_complex_to_struct(DDS::MemberId id, DDS::DynamicData_var value)
    2041             : {
    2042          28 :   DDS::DynamicTypeMember_var member;
    2043          28 :   if (type_->get_member(member, id) != DDS::RETCODE_OK) {
    2044           0 :     return false;
    2045             :   }
    2046          28 :   DDS::MemberDescriptor_var md;
    2047          28 :   if (member->get_descriptor(md) != DDS::RETCODE_OK) {
    2048           0 :     return false;
    2049             :   }
    2050             : 
    2051          28 :   const DDS::DynamicType_var member_type = get_base_type(md->type());
    2052          28 :   const DDS::DynamicType_var value_type = value->type();
    2053          28 :   if (!member_type || !value_type || !member_type->equals(value_type)) {
    2054           0 :     return false;
    2055             :   }
    2056          28 :   return insert_complex(id, value);
    2057          28 : }
    2058             : 
    2059           0 : bool DynamicDataImpl::set_complex_to_union(DDS::MemberId id, DDS::DynamicData_var value)
    2060             : {
    2061           0 :   if (id == DISCRIMINATOR_ID) {
    2062           0 :     DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type());
    2063           0 :     const DDS::DynamicType_var value_type = value->type();
    2064           0 :     if (!disc_type->equals(value_type)) {
    2065           0 :       return false;
    2066             :     }
    2067             : 
    2068             :     CORBA::Long disc_val;
    2069           0 :     const DynamicDataImpl* dd_impl = dynamic_cast<const DynamicDataImpl*>(value.in());
    2070           0 :     if (!dd_impl || !dd_impl->read_discriminator(disc_val)) {
    2071           0 :       return false;
    2072             :     }
    2073             : 
    2074           0 :     const DDS::MemberId selected_id = find_selected_member();
    2075           0 :     if (selected_id != MEMBER_ID_INVALID) {
    2076           0 :       DDS::DynamicTypeMember_var selected_member;
    2077           0 :       if (type_->get_member(selected_member, selected_id) != DDS::RETCODE_OK) {
    2078           0 :         return false;
    2079             :       }
    2080           0 :       DDS::MemberDescriptor_var selected_md;
    2081           0 :       if (selected_member->get_descriptor(selected_md) != DDS::RETCODE_OK) {
    2082           0 :         return false;
    2083             :       }
    2084           0 :       if (!validate_discriminator(disc_val, selected_md)) {
    2085           0 :         if (log_level >= LogLevel::Notice) {
    2086           0 :           ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_to_union:"
    2087             :                      " Discriminator value %d does not select the activated member (ID %u)\n",
    2088             :                      disc_val, selected_id));
    2089             :         }
    2090           0 :         return false;
    2091             :       }
    2092           0 :       return insert_complex(id, value);
    2093           0 :     } else {
    2094           0 :       if (discriminator_selects_no_member(disc_val)) {
    2095           0 :         return insert_complex(id, value);
    2096             :       }
    2097           0 :       if (log_level >= LogLevel::Notice) {
    2098           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_to_union:"
    2099             :                    " Can't directly set a discriminator that selects a member."
    2100             :                    " Activate the member first!\n"));
    2101             :       }
    2102           0 :       return false;
    2103             :     }
    2104           0 :   }
    2105             : 
    2106             :   // Activate a member
    2107           0 :   clear_container();
    2108             : 
    2109           0 :   DDS::DynamicTypeMember_var member;
    2110           0 :   if (type_->get_member(member, id) != DDS::RETCODE_OK) {
    2111           0 :     return false;
    2112             :   }
    2113           0 :   DDS::MemberDescriptor_var md;
    2114           0 :   if (member->get_descriptor(md) != DDS::RETCODE_OK) {
    2115           0 :     return false;
    2116             :   }
    2117           0 :   const DDS::DynamicType_var value_type = value->type();
    2118           0 :   if (get_base_type(md->type())->equals(value_type)) {
    2119           0 :     return false;
    2120             :   }
    2121             : 
    2122           0 :   return insert_valid_discriminator(md) && insert_complex(id, value);
    2123           0 : }
    2124             : 
    2125         175 : bool DynamicDataImpl::validate_member_id_collection(DDS::MemberId id, TypeKind tk) const
    2126             : {
    2127         175 :   switch (tk) {
    2128         175 :   case TK_SEQUENCE:
    2129             :   case TK_ARRAY:
    2130         175 :     return check_index_from_id(tk, id, bound_total(type_desc_));
    2131           0 :   case TK_MAP:
    2132           0 :     if (log_level >= LogLevel::Notice) {
    2133           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::validate_member_id_collection::"
    2134             :                  " Map is currently not supported\n"));
    2135             :     }
    2136             :   }
    2137           0 :   return false;
    2138             : }
    2139             : 
    2140           2 : bool DynamicDataImpl::set_complex_to_collection(DDS::MemberId id, DDS::DynamicData_var value,
    2141             :                                                 TypeKind collection_tk)
    2142             : {
    2143           2 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    2144           2 :   const DDS::DynamicType_var value_type = value->type();
    2145           2 :   if (!elem_type->equals(value_type)) {
    2146           0 :     return false;
    2147             :   }
    2148             : 
    2149           2 :   return validate_member_id_collection(id, collection_tk) && insert_complex(id, value);
    2150           2 : }
    2151             : 
    2152          30 : DDS::ReturnCode_t DynamicDataImpl::set_complex_value(DDS::MemberId id, DDS::DynamicData_ptr value)
    2153             : {
    2154          30 :   DDS::DynamicData_var value_var = DDS::DynamicData::_duplicate(value);
    2155          30 :   const TypeKind tk = type_->get_kind();
    2156          30 :   bool good = false;
    2157             : 
    2158          30 :   switch (tk) {
    2159          28 :   case TK_STRUCTURE:
    2160          28 :     good = set_complex_to_struct(id, value_var);
    2161          28 :     break;
    2162           0 :   case TK_UNION:
    2163           0 :     good = set_complex_to_union(id, value_var);
    2164           0 :     break;
    2165           2 :   case TK_SEQUENCE:
    2166             :   case TK_ARRAY:
    2167             :   case TK_MAP:
    2168           2 :     good = set_complex_to_collection(id, value_var, tk);
    2169           2 :     break;
    2170           0 :   default:
    2171           0 :     good = false;
    2172           0 :     break;
    2173             :   }
    2174             : 
    2175          30 :   if (!good && log_level >= LogLevel::Notice) {
    2176           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_value:"
    2177             :                " Failed to write complex value for member with ID %d\n", id));
    2178             :   }
    2179          60 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    2180          30 : }
    2181             : 
    2182             : template<typename SequenceType>
    2183         195 : bool DynamicDataImpl::insert_sequence(DDS::MemberId id, const SequenceType& value)
    2184             : {
    2185         195 :   if (container_.complex_map_.erase(id) == 0) {
    2186         195 :     container_.sequence_map_.erase(id);
    2187             :   }
    2188         195 :   return container_.sequence_map_.insert(std::make_pair(id, value)).second;
    2189             : }
    2190             : 
    2191             : template<TypeKind ElementTypeKind>
    2192         204 : bool DynamicDataImpl::check_seqmem_in_struct_and_union(DDS::MemberId id, TypeKind enum_or_bitmask,
    2193             :                                                        LBound lower, LBound upper) const
    2194             : {
    2195         204 :   DDS::DynamicTypeMember_var member;
    2196         204 :   if (type_->get_member(member, id)) {
    2197           0 :     return false;
    2198             :   }
    2199         204 :   DDS::MemberDescriptor_var md;
    2200         204 :   if (member->get_descriptor(md) != DDS::RETCODE_OK) {
    2201           0 :     return false;
    2202             :   }
    2203             : 
    2204         204 :   const DDS::DynamicType_var member_type = get_base_type(md->type());
    2205         204 :   const TypeKind member_tk = member_type->get_kind();
    2206         204 :   if (member_tk != TK_SEQUENCE) {
    2207           0 :     return false;
    2208             :   }
    2209             : 
    2210         204 :   DDS::TypeDescriptor_var member_td;
    2211         204 :   if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
    2212           0 :     return false;
    2213             :   }
    2214             : 
    2215         204 :   const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type());
    2216         204 :   const TypeKind elem_tk = elem_type->get_kind();
    2217         204 :   if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) {
    2218           9 :     return false;
    2219             :   }
    2220             : 
    2221         195 :   if (elem_tk == enum_or_bitmask) {
    2222           3 :     DDS::TypeDescriptor_var elem_td;
    2223           3 :     if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    2224           0 :       return false;
    2225             :     }
    2226           3 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    2227           3 :     if (bit_bound < lower || bit_bound > upper) {
    2228           0 :       return false;
    2229             :     }
    2230           3 :   }
    2231         195 :   return true;
    2232         204 : }
    2233             : 
    2234             : template<TypeKind ElementTypeKind, typename SequenceType>
    2235          60 : bool DynamicDataImpl::set_values_to_struct(DDS::MemberId id, const SequenceType& value,
    2236             :                                            TypeKind enum_or_bitmask,
    2237             :                                            LBound lower, LBound upper)
    2238             : {
    2239         111 :   return check_seqmem_in_struct_and_union<ElementTypeKind>(id, enum_or_bitmask, lower, upper) &&
    2240         111 :     insert_sequence(id, value);
    2241             : }
    2242             : 
    2243             : template<TypeKind ElementTypeKind, typename SequenceType>
    2244         144 : bool DynamicDataImpl::set_values_to_union(DDS::MemberId id, const SequenceType& value,
    2245             :                                           TypeKind enum_or_bitmask,
    2246             :                                           LBound lower, LBound upper)
    2247             : {
    2248         144 :   if (id == DISCRIMINATOR_ID) {
    2249           0 :     if (log_level >= LogLevel::Notice) {
    2250           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_values_to_union:"
    2251             :                  " Union discriminator cannot be a sequence\n"));
    2252             :     }
    2253           0 :     return false;
    2254             :   }
    2255             : 
    2256             :   // Check the member type against the input type parameters.
    2257         144 :   if (!check_seqmem_in_struct_and_union<ElementTypeKind>(id, enum_or_bitmask, lower, upper)) {
    2258           0 :     return false;
    2259             :   }
    2260             : 
    2261         144 :   clear_container();
    2262             : 
    2263         144 :   DDS::DynamicTypeMember_var member;
    2264         144 :   if (type_->get_member(member, id) != DDS::RETCODE_OK) {
    2265           0 :     return false;
    2266             :   }
    2267         144 :   DDS::MemberDescriptor_var md;
    2268         144 :   if (member->get_descriptor(md) != DDS::RETCODE_OK) {
    2269           0 :     return false;
    2270             :   }
    2271         144 :   return insert_valid_discriminator(md) && insert_sequence(id, value);
    2272         144 : }
    2273             : 
    2274             : template<TypeKind ElementTypeKind>
    2275           0 : bool DynamicDataImpl::check_seqmem_in_sequence_and_array(DDS::MemberId id, CORBA::ULong bound,
    2276             :   TypeKind enum_or_bitmask, LBound lower, LBound upper) const
    2277             : {
    2278           0 :   if (!check_index_from_id(type_->get_kind(), id, bound)) {
    2279           0 :     return false;
    2280             :   }
    2281             : 
    2282           0 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    2283           0 :   const TypeKind elem_tk = elem_type->get_kind();
    2284           0 :   if (elem_tk != TK_SEQUENCE) {
    2285           0 :     return false;
    2286             :   }
    2287             : 
    2288           0 :   DDS::TypeDescriptor_var elem_td;
    2289           0 :   if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    2290           0 :     return false;
    2291             :   }
    2292             : 
    2293           0 :   const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type());
    2294           0 :   const TypeKind nested_elem_tk = nested_elem_type->get_kind();
    2295           0 :   if (nested_elem_tk != ElementTypeKind && nested_elem_tk != enum_or_bitmask) {
    2296           0 :     return false;
    2297             :   }
    2298           0 :   if (nested_elem_tk == enum_or_bitmask) {
    2299           0 :     DDS::TypeDescriptor_var nested_elem_td;
    2300           0 :     if (nested_elem_type->get_descriptor(nested_elem_td) != DDS::RETCODE_OK) {
    2301           0 :       return false;
    2302             :     }
    2303           0 :     const CORBA::ULong bit_bound = nested_elem_td->bound()[0];
    2304           0 :     if (bit_bound < lower || bit_bound > upper) {
    2305           0 :       return false;
    2306             :     }
    2307           0 :   }
    2308           0 :   return true;
    2309           0 : }
    2310             : 
    2311             : template<TypeKind ElementTypeKind, typename SequenceType>
    2312           0 : bool DynamicDataImpl::set_values_to_sequence(DDS::MemberId id, const SequenceType& value,
    2313             :                                              TypeKind enum_or_bitmask,
    2314             :                                              LBound lower, LBound upper)
    2315             : {
    2316           0 :   const DDS::UInt32 bound = type_desc_->bound()[0];
    2317             :   return
    2318           0 :     check_seqmem_in_sequence_and_array<ElementTypeKind>(id, bound, enum_or_bitmask, lower, upper) &&
    2319           0 :     validate_member_id_collection(id, TK_SEQUENCE) &&
    2320           0 :     insert_sequence(id, value);
    2321             : }
    2322             : 
    2323             : template<TypeKind ElementTypeKind, typename SequenceType>
    2324           0 : bool DynamicDataImpl::set_values_to_array(DDS::MemberId id, const SequenceType& value,
    2325             :                                           TypeKind enum_or_bitmask,
    2326             :                                           LBound lower, LBound upper)
    2327             : {
    2328           0 :   const DDS::UInt32 length = bound_total(type_desc_);
    2329             :   return
    2330           0 :     check_seqmem_in_sequence_and_array<ElementTypeKind>(id, length, enum_or_bitmask, lower, upper) &&
    2331           0 :     validate_member_id_collection(id, TK_ARRAY) &&
    2332           0 :     insert_sequence(id, value);
    2333             : }
    2334             : 
    2335             : template<TypeKind ElementTypeKind, typename SequenceType>
    2336         204 : DDS::ReturnCode_t DynamicDataImpl::set_sequence_values(DDS::MemberId id, const SequenceType& value,
    2337             :                                                        TypeKind enum_or_bitmask,
    2338             :                                                        LBound lower, LBound upper)
    2339             : {
    2340         204 :   if (!is_type_supported(ElementTypeKind, "set_sequence_values")) {
    2341           0 :     return DDS::RETCODE_ERROR;
    2342             :   }
    2343             : 
    2344         204 :   const TypeKind tk = type_->get_kind();
    2345         204 :   bool good = true;
    2346             : 
    2347         204 :   switch (tk) {
    2348          60 :   case TK_STRUCTURE:
    2349          60 :     good = set_values_to_struct<ElementTypeKind>(id, value, enum_or_bitmask, lower, upper);
    2350          60 :     break;
    2351         144 :   case TK_UNION:
    2352         144 :     good = set_values_to_union<ElementTypeKind>(id, value, enum_or_bitmask, lower, upper);
    2353         144 :     break;
    2354           0 :   case TK_SEQUENCE:
    2355           0 :     good = set_values_to_sequence<ElementTypeKind>(id, value, enum_or_bitmask, lower, upper);
    2356           0 :     break;
    2357           0 :   case TK_ARRAY:
    2358           0 :     good = set_values_to_array<ElementTypeKind>(id, value, enum_or_bitmask, lower, upper);
    2359           0 :     break;
    2360           0 :   case TK_MAP:
    2361           0 :     if (log_level >= LogLevel::Notice) {
    2362           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_sequence_values:"
    2363             :                  " Map is currently not supported\n"));
    2364             :     }
    2365           0 :     return DDS::RETCODE_ERROR;
    2366           0 :   default:
    2367           0 :     if (log_level >= LogLevel::Notice) {
    2368           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_sequence_values:"
    2369             :                  " Write to unsupported type (%C)\n", typekind_to_string(tk)));
    2370             :     }
    2371           0 :     return DDS::RETCODE_ERROR;
    2372             :   }
    2373             : 
    2374         204 :   if (!good && log_level >= LogLevel::Notice) {
    2375           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_sequence_values:"
    2376             :                " Failed to write sequence of %C to member with ID %d\n",
    2377             :                typekind_to_string(ElementTypeKind), id));
    2378             :   }
    2379         204 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    2380             : }
    2381             : 
    2382          27 : DDS::ReturnCode_t DynamicDataImpl::set_int32_values(DDS::MemberId id, const DDS::Int32Seq& value)
    2383             : {
    2384          27 :   return set_sequence_values<TK_INT32>(id, value, TK_ENUM, 17, 32);
    2385             : }
    2386             : 
    2387          21 : DDS::ReturnCode_t DynamicDataImpl::set_uint32_values(DDS::MemberId id, const DDS::UInt32Seq& value)
    2388             : {
    2389          21 :   return set_sequence_values<TK_UINT32>(id, value, TK_BITMASK, 17, 32);
    2390             : }
    2391             : 
    2392           9 : DDS::ReturnCode_t DynamicDataImpl::set_int8_values(DDS::MemberId id, const DDS::Int8Seq& value)
    2393             : {
    2394           9 :   return set_sequence_values<TK_INT8>(id, value, TK_ENUM, 1, 8);
    2395             : }
    2396             : 
    2397          15 : DDS::ReturnCode_t DynamicDataImpl::set_uint8_values(DDS::MemberId id, const DDS::UInt8Seq& value)
    2398             : {
    2399          15 :   return set_sequence_values<TK_UINT8>(id, value, TK_BITMASK, 1, 8);
    2400             : }
    2401             : 
    2402          18 : DDS::ReturnCode_t DynamicDataImpl::set_int16_values(DDS::MemberId id, const DDS::Int16Seq& value)
    2403             : {
    2404          18 :   return set_sequence_values<TK_INT16>(id, value, TK_ENUM, 9, 16);
    2405             : }
    2406             : 
    2407           9 : DDS::ReturnCode_t DynamicDataImpl::set_uint16_values(DDS::MemberId id, const DDS::UInt16Seq& value)
    2408             : {
    2409           9 :   return set_sequence_values<TK_UINT16>(id, value, TK_BITMASK, 9, 16);
    2410             : }
    2411             : 
    2412           9 : DDS::ReturnCode_t DynamicDataImpl::set_int64_values(DDS::MemberId id, const DDS::Int64Seq& value)
    2413             : {
    2414           9 :   return set_sequence_values<TK_INT64>(id, value);
    2415             : }
    2416             : 
    2417           9 : DDS::ReturnCode_t DynamicDataImpl::set_uint64_values(DDS::MemberId id, const DDS::UInt64Seq& value)
    2418             : {
    2419           9 :   return set_sequence_values<TK_UINT64>(id, value, TK_BITMASK, 33, 64);
    2420             : }
    2421             : 
    2422          15 : DDS::ReturnCode_t DynamicDataImpl::set_float32_values(DDS::MemberId id, const DDS::Float32Seq& value)
    2423             : {
    2424          15 :   return set_sequence_values<TK_FLOAT32>(id, value);
    2425             : }
    2426             : 
    2427           9 : DDS::ReturnCode_t DynamicDataImpl::set_float64_values(DDS::MemberId id, const DDS::Float64Seq& value)
    2428             : {
    2429           9 :   return set_sequence_values<TK_FLOAT64>(id, value);
    2430             : }
    2431             : 
    2432           0 : DDS::ReturnCode_t DynamicDataImpl::set_float128_values(DDS::MemberId id, const DDS::Float128Seq& value)
    2433             : {
    2434           0 :   return set_sequence_values<TK_FLOAT128>(id, value);
    2435             : }
    2436             : 
    2437           9 : DDS::ReturnCode_t DynamicDataImpl::set_char8_values(DDS::MemberId id, const DDS::CharSeq& value)
    2438             : {
    2439           9 :   return set_sequence_values<TK_CHAR8>(id, value);
    2440             : }
    2441             : 
    2442           9 : DDS::ReturnCode_t DynamicDataImpl::set_char16_values(DDS::MemberId id, const DDS::WcharSeq& value)
    2443             : {
    2444             : #ifdef DDS_HAS_WCHAR
    2445           9 :   return set_sequence_values<TK_CHAR16>(id, value);
    2446             : #else
    2447             :   return DDS::RETCODE_UNSUPPORTED;
    2448             : #endif
    2449             : }
    2450             : 
    2451          12 : DDS::ReturnCode_t DynamicDataImpl::set_byte_values(DDS::MemberId id, const DDS::ByteSeq& value)
    2452             : {
    2453          12 :   return set_sequence_values<TK_BYTE>(id, value);
    2454             : }
    2455             : 
    2456          15 : DDS::ReturnCode_t DynamicDataImpl::set_boolean_values(DDS::MemberId id, const DDS::BooleanSeq& value)
    2457             : {
    2458          15 :   return set_sequence_values<TK_BOOLEAN>(id, value);
    2459             : }
    2460             : 
    2461           9 : DDS::ReturnCode_t DynamicDataImpl::set_string_values(DDS::MemberId id, const DDS::StringSeq& value)
    2462             : {
    2463           9 :   return set_sequence_values<TK_STRING8>(id, value);
    2464             : }
    2465             : 
    2466           9 : DDS::ReturnCode_t DynamicDataImpl::set_wstring_values(DDS::MemberId id, const DDS::WstringSeq& value)
    2467             : {
    2468             : #ifdef DDS_HAS_WCHAR
    2469           9 :   return set_sequence_values<TK_STRING16>(id, value);
    2470             : #else
    2471             :   return DDS::RETCODE_UNSUPPORTED;
    2472             : #endif
    2473             : }
    2474             : 
    2475           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_int8& value)
    2476             : {
    2477           0 :   return DDS::RETCODE_OK == get_int8_value(value.val_, MEMBER_ID_INVALID);
    2478             : }
    2479             : 
    2480           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_uint8& value)
    2481             : {
    2482           0 :   return DDS::RETCODE_OK == get_uint8_value(value.val_, MEMBER_ID_INVALID);
    2483             : }
    2484             : 
    2485           3 : bool DynamicDataImpl::read_basic_value(CORBA::Short& value)
    2486             : {
    2487           3 :   return DDS::RETCODE_OK == get_int16_value(value, MEMBER_ID_INVALID);
    2488             : }
    2489             : 
    2490           0 : bool DynamicDataImpl::read_basic_value(CORBA::UShort& value)
    2491             : {
    2492           0 :   return DDS::RETCODE_OK == get_uint16_value(value, MEMBER_ID_INVALID);
    2493             : }
    2494             : 
    2495           0 : bool DynamicDataImpl::read_basic_value(CORBA::Long& value)
    2496             : {
    2497           0 :   return DDS::RETCODE_OK == get_int32_value(value, MEMBER_ID_INVALID);
    2498             : }
    2499             : 
    2500           0 : bool DynamicDataImpl::read_basic_value(CORBA::ULong& value)
    2501             : {
    2502           0 :   return DDS::RETCODE_OK == get_uint32_value(value, MEMBER_ID_INVALID);
    2503             : }
    2504             : 
    2505           0 : bool DynamicDataImpl::read_basic_value(CORBA::LongLong& value)
    2506             : {
    2507           0 :   return DDS::RETCODE_OK == get_int64_value(value, MEMBER_ID_INVALID);
    2508             : }
    2509             : 
    2510           0 : bool DynamicDataImpl::read_basic_value(CORBA::ULongLong& value)
    2511             : {
    2512           0 :   return DDS::RETCODE_OK == get_uint64_value(value, MEMBER_ID_INVALID);
    2513             : }
    2514             : 
    2515           0 : bool DynamicDataImpl::read_basic_value(CORBA::Float& value)
    2516             : {
    2517           0 :   return DDS::RETCODE_OK == get_float32_value(value, MEMBER_ID_INVALID);
    2518             : }
    2519             : 
    2520           0 : bool DynamicDataImpl::read_basic_value(CORBA::Double& value)
    2521             : {
    2522           0 :   return DDS::RETCODE_OK == get_float64_value(value, MEMBER_ID_INVALID);
    2523             : }
    2524             : 
    2525           0 : bool DynamicDataImpl::read_basic_value(CORBA::LongDouble& value)
    2526             : {
    2527           0 :   return DDS::RETCODE_OK == get_float128_value(value, MEMBER_ID_INVALID);
    2528             : }
    2529             : 
    2530           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_char& value)
    2531             : {
    2532           0 :   return DDS::RETCODE_OK == get_char8_value(value.val_, MEMBER_ID_INVALID);
    2533             : }
    2534             : 
    2535             : #ifdef DDS_HAS_WCHAR
    2536           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_wchar& value)
    2537             : {
    2538           0 :   return DDS::RETCODE_OK == get_char16_value(value.val_, MEMBER_ID_INVALID);
    2539             : }
    2540             : #endif
    2541             : 
    2542           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_octet& value)
    2543             : {
    2544           0 :   return DDS::RETCODE_OK == get_byte_value(value.val_, MEMBER_ID_INVALID);
    2545             : }
    2546             : 
    2547           0 : bool DynamicDataImpl::read_basic_value(ACE_OutputCDR::from_boolean& value)
    2548             : {
    2549           0 :   return DDS::RETCODE_OK == get_boolean_value(value.val_, MEMBER_ID_INVALID);
    2550             : }
    2551             : 
    2552           0 : bool DynamicDataImpl::read_basic_value(char*& value) const
    2553             : {
    2554           0 :   const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty();
    2555           0 :   if (!is_empty) {
    2556             :     CORBA::ULong largest_index;
    2557           0 :     if (!container_.get_largest_index_basic(largest_index)) {
    2558           0 :       return false;
    2559             :     }
    2560           0 :     const CORBA::ULong length = largest_index + 2;
    2561           0 :     CORBA::String_var str_var = CORBA::string_alloc(length);
    2562           0 :     ACE_OS::memset(str_var.inout(), 0, length);
    2563           0 :     if (!container_.reconstruct_string_value(str_var.inout())) {
    2564           0 :       return false;
    2565             :     }
    2566           0 :     CORBA::string_free(value);
    2567           0 :     value = str_var._retn();
    2568           0 :   } else {
    2569           0 :     CORBA::string_free(value);
    2570           0 :     value = CORBA::string_dup("");
    2571             :   }
    2572           0 :   return true;
    2573             : }
    2574             : 
    2575             : #ifdef DDS_HAS_WCHAR
    2576           0 : bool DynamicDataImpl::read_basic_value(CORBA::WChar*& value) const
    2577             : {
    2578           0 :   const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty();
    2579           0 :   if (!is_empty) {
    2580             :     CORBA::ULong largest_index;
    2581           0 :     if (!container_.get_largest_index_basic(largest_index)) {
    2582           0 :       return false;
    2583             :     }
    2584           0 :     const CORBA::ULong length = largest_index + 2;
    2585           0 :     CORBA::WString_var wstr_var = CORBA::wstring_alloc(length);
    2586           0 :     ACE_OS::memset(wstr_var.inout(), 0, length * sizeof(CORBA::WChar));
    2587           0 :     if (!container_.reconstruct_wstring_value(wstr_var.inout())) {
    2588           0 :       return false;
    2589             :     }
    2590           0 :     CORBA::wstring_free(value);
    2591           0 :     value = wstr_var._retn();
    2592           0 :   } else {
    2593           0 :     CORBA::wstring_free(value);
    2594           0 :     value = CORBA::wstring_dup(L"");
    2595             :   }
    2596           0 :   return true;
    2597             : }
    2598             : #endif
    2599             : 
    2600             : template<typename ValueType>
    2601        1901 : bool DynamicDataImpl::read_basic_in_single_map(ValueType& value, DDS::MemberId id)
    2602             : {
    2603        1901 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    2604        1901 :   if (single_it != container_.single_map_.end()) {
    2605        1530 :     value = single_it->second.get<ValueType>();
    2606        1530 :     return true;
    2607             :   }
    2608         371 :   return false;
    2609             : }
    2610             : 
    2611             : template<>
    2612          82 : bool DynamicDataImpl::read_basic_in_single_map(char*& value, DDS::MemberId id)
    2613             : {
    2614          82 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    2615          82 :   if (single_it != container_.single_map_.end()) {
    2616          48 :     CORBA::string_free(value);
    2617          48 :     value = single_it->second.get_string();
    2618          48 :     return true;
    2619             :   }
    2620          34 :   return false;
    2621             : }
    2622             : 
    2623             : template<>
    2624          76 : bool DynamicDataImpl::read_basic_in_single_map(CORBA::WChar*& value, DDS::MemberId id)
    2625             : {
    2626          76 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    2627          76 :   if (single_it != container_.single_map_.end()) {
    2628          40 :     CORBA::wstring_free(value);
    2629          40 :     value = single_it->second.get_wstring();
    2630          40 :     return true;
    2631             :   }
    2632          36 :   return false;
    2633             : }
    2634             : 
    2635             : template<typename ValueType>
    2636         441 : bool DynamicDataImpl::read_basic_in_complex_map(ValueType& value, DDS::MemberId id)
    2637             : {
    2638         441 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    2639         441 :   if (complex_it != container_.complex_map_.end()) {
    2640           3 :     DynamicDataImpl* nested_dd = dynamic_cast<DynamicDataImpl*>(complex_it->second.in());
    2641           3 :     return nested_dd && nested_dd->read_basic_value(value);
    2642             :   }
    2643         438 :   return false;
    2644             : }
    2645             : 
    2646             : template<typename ValueType>
    2647        1901 : bool DynamicDataImpl::read_basic_member(ValueType& value, DDS::MemberId id)
    2648             : {
    2649        1901 :   return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id);
    2650             : }
    2651             : 
    2652             : template<>
    2653          82 : bool DynamicDataImpl::read_basic_member(char*& value, DDS::MemberId id)
    2654             : {
    2655          82 :   return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id);
    2656             : }
    2657             : 
    2658             : template<>
    2659          76 : bool DynamicDataImpl::read_basic_member(CORBA::WChar*& value, DDS::MemberId id)
    2660             : {
    2661          76 :   return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id);
    2662             : }
    2663             : 
    2664             : template<typename ValueType>
    2665          11 : bool DynamicDataImpl::get_value_from_self(ValueType& value, DDS::MemberId id)
    2666             : {
    2667             :   // Primitive or enum value can be read using MEMBER_ID_INVALID.
    2668          11 :   if (!is_primitive(type_->get_kind()) || id != MEMBER_ID_INVALID) {
    2669           3 :     return false;
    2670             :   }
    2671           8 :   DataContainer::const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID);
    2672           8 :   if (it != container_.single_map_.end()) {
    2673           8 :     value = it->second.get<ValueType>();
    2674             :   } else {
    2675           0 :     container_.set_default_basic_value(value);
    2676             :   }
    2677           8 :   return true;
    2678             : }
    2679             : 
    2680             : template<>
    2681           0 : bool DynamicDataImpl::get_value_from_self(char*&, DDS::MemberId)
    2682             : {
    2683             :   // Can't read a string from a DynamicData instance representing a string.
    2684           0 :   return false;
    2685             : }
    2686             : 
    2687             : template<>
    2688           0 : bool DynamicDataImpl::get_value_from_self(CORBA::WChar*&, DDS::MemberId)
    2689             : {
    2690             :   // Can't read a wstring from a DynamicData instance representing a wstring.
    2691           0 :   return false;
    2692             : }
    2693             : 
    2694             : template<TypeKind ValueTypeKind, typename ValueType>
    2695           6 : bool DynamicDataImpl::get_value_from_enum(ValueType& value, DDS::MemberId id)
    2696             : {
    2697             :   TypeKind treat_as_tk;
    2698           6 :   const DDS::ReturnCode_t rc = enum_bound(type_, treat_as_tk);
    2699           6 :   if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind || id != MEMBER_ID_INVALID) {
    2700           0 :     return false;
    2701             :   }
    2702           6 :   DataContainer::const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID);
    2703           6 :   if (it != container_.single_map_.end()) {
    2704           6 :     value = it->second.get<ValueType>();
    2705             :   } else {
    2706             :     CORBA::Long enum_default_val;
    2707           0 :     if (!container_.set_default_enum_value(type_, enum_default_val)) {
    2708           0 :       return false;
    2709             :     }
    2710           0 :     cast_to_enum_value(value, enum_default_val);
    2711             :   }
    2712           6 :   return true;
    2713             : }
    2714             : 
    2715             : template<>
    2716           0 : bool DynamicDataImpl::get_value_from_enum<TK_STRING8>(char*&, DDS::MemberId)
    2717             : {
    2718           0 :   return false;
    2719             : }
    2720             : template<>
    2721           0 : bool DynamicDataImpl::get_value_from_enum<TK_STRING16>(CORBA::WChar*&, DDS::MemberId)
    2722             : {
    2723           0 :   return false;
    2724             : }
    2725             : 
    2726             : template<TypeKind ValueTypeKind, typename ValueType>
    2727           0 : bool DynamicDataImpl::get_value_from_bitmask(ValueType& value, DDS::MemberId id)
    2728             : {
    2729             :   // Allow bitmask to be read as an unsigned integer.
    2730             :   TypeKind treat_as_tk;
    2731           0 :   const DDS::ReturnCode_t rc = bitmask_bound(type_, treat_as_tk);
    2732           0 :   if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind || id != MEMBER_ID_INVALID) {
    2733           0 :     return false;
    2734             :   }
    2735           0 :   DataContainer::const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID);
    2736           0 :   if (it != container_.single_map_.end()) {
    2737           0 :     value = it->second.get<ValueType>();
    2738             :   } else {
    2739           0 :     container_.set_default_bitmask_value(value);
    2740             :   }
    2741           0 :   return true;
    2742             : }
    2743             : 
    2744             : template<>
    2745           0 : bool DynamicDataImpl::get_value_from_bitmask<TK_STRING8>(char*&, DDS::MemberId)
    2746             : {
    2747           0 :   return false;
    2748             : }
    2749             : template<>
    2750           0 : bool DynamicDataImpl::get_value_from_bitmask<TK_STRING16>(CORBA::WChar*&, DDS::MemberId)
    2751             : {
    2752           0 :   return false;
    2753             : }
    2754             : 
    2755             : template<TypeKind ValueTypeKind, typename ValueType>
    2756        1517 : bool DynamicDataImpl::get_value_from_struct(ValueType& value, DDS::MemberId id)
    2757             : {
    2758        1517 :   DDS::MemberDescriptor_var md;
    2759        1517 :   DDS::DynamicType_var member_type;
    2760        1517 :   DDS::ReturnCode_t rc = check_member(
    2761             :     md, member_type, "DynamicDataImpl::get_value_from_struct", "get", id, ValueTypeKind);
    2762        1517 :   if (rc != DDS::RETCODE_OK) {
    2763           3 :     return false;
    2764             :   }
    2765        1514 :   if (read_basic_member(value, id)) {
    2766        1097 :     return true;
    2767             :   }
    2768             : 
    2769             :   // Not returning a default value for a missing optional member.
    2770         417 :   if (md->is_optional()) {
    2771           0 :     if (log_level >= LogLevel::Notice) {
    2772           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_struct:"
    2773             :                  " Optional member Id %u is not present\n", id));
    2774             :     }
    2775           0 :     return false;
    2776             :   }
    2777         417 :   container_.set_default_basic_value(value);
    2778         417 :   return true;
    2779        1517 : }
    2780             : 
    2781             : template<TypeKind ValueTypeKind, typename ValueType>
    2782         219 : bool DynamicDataImpl::get_value_from_union(ValueType& value, DDS::MemberId id)
    2783             : {
    2784         219 :   DDS::MemberDescriptor_var md;
    2785         219 :   DDS::DynamicType_var member_type;
    2786         219 :   DDS::ReturnCode_t rc = check_member(
    2787             :     md, member_type, "DynamicDataImpl::get_value_from_union", "get", id, ValueTypeKind);
    2788         219 :   if (rc != DDS::RETCODE_OK) {
    2789           0 :     return false;
    2790             :   }
    2791             : 
    2792             :   // Return the member if it is in the container.
    2793         219 :   if (read_basic_member(value, id)) {
    2794         208 :     return true;
    2795             :   }
    2796             : 
    2797          11 :   if (id == DISCRIMINATOR_ID) {
    2798             :     // Set the discriminator to default value.
    2799             :     // If it selects a branch, set the branch to default value.
    2800           4 :     container_.set_default_basic_value(value);
    2801             :     CORBA::Long disc_value;
    2802           4 :     if (!cast_to_discriminator_value(disc_value, value)) {
    2803           0 :       return false;
    2804             :     }
    2805           4 :     bool found_selected_member = false;
    2806           4 :     DDS::MemberDescriptor_var selected_md;
    2807             :     const DDS::ReturnCode_t rc =
    2808           4 :       get_selected_union_branch(disc_value, found_selected_member, selected_md);
    2809           4 :     if (rc != DDS::RETCODE_OK) {
    2810           0 :       if (log_level >= LogLevel::Notice) {
    2811           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_union:"
    2812             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
    2813             :       }
    2814           0 :       return false;
    2815             :     }
    2816           4 :     insert_single(id, value);
    2817           4 :     if (found_selected_member && !selected_md->is_optional()) {
    2818           4 :       DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    2819           4 :       if (clear_value_i(selected_md->id(), selected_type) != DDS::RETCODE_OK) {
    2820           0 :         return false;
    2821             :       }
    2822           4 :     }
    2823           4 :   } else {
    2824           7 :     DataContainer::const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID);
    2825           7 :     DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID);
    2826           7 :     const bool has_disc = single_it != container_.single_map_.end() ||
    2827           0 :       complex_it != container_.complex_map_.end();
    2828           7 :     if (has_disc) {
    2829           7 :       if (log_level >= LogLevel::Notice) {
    2830           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_union:"
    2831             :                    " Branch Id %u is not the active branch in the union\n", id));
    2832             :       }
    2833           7 :       return false;
    2834             :     }
    2835             :     // Set the branch to default value and set the discriminator to a value that selects this branch.
    2836           0 :     DDS::DynamicTypeMember_var dtm;
    2837           0 :     if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
    2838           0 :       return false;
    2839             :     }
    2840           0 :     DDS::MemberDescriptor_var md;
    2841           0 :     if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    2842           0 :       return false;
    2843             :     }
    2844           0 :     DDS::DynamicType_var dt = get_base_type(md->type());
    2845           0 :     if (clear_value_i(id, dt) != DDS::RETCODE_OK) {
    2846           0 :       return false;
    2847             :     }
    2848           0 :     if (!insert_valid_discriminator(md)) {
    2849           0 :       return false;
    2850             :     }
    2851           0 :     OPENDDS_ASSERT(read_basic_in_single_map(value, id));
    2852           0 :   }
    2853           4 :   return true;
    2854         219 : }
    2855             : 
    2856           0 : void DynamicDataImpl::cast_to_enum_value(ACE_OutputCDR::from_int8& dst, CORBA::Long src) const
    2857             : {
    2858           0 :   dst = ACE_OutputCDR::from_int8(static_cast<CORBA::Int8>(src));
    2859           0 : }
    2860             : 
    2861           0 : void DynamicDataImpl::cast_to_enum_value(CORBA::Short& dst, CORBA::Long src) const
    2862             : {
    2863           0 :   dst = static_cast<CORBA::Short>(src);
    2864           0 : }
    2865             : 
    2866           0 : void DynamicDataImpl::cast_to_enum_value(CORBA::Long& dst, CORBA::Long src) const
    2867             : {
    2868           0 :   dst = src;
    2869           0 : }
    2870             : 
    2871             : template<typename ValueType>
    2872           0 : void DynamicDataImpl::cast_to_enum_value(ValueType&, CORBA::Long) const
    2873           0 : {}
    2874             : 
    2875             : template<TypeKind ValueTypeKind, typename ValueType>
    2876         320 : bool DynamicDataImpl::get_value_from_collection(ValueType& value, DDS::MemberId id)
    2877             : {
    2878         320 :   if (type_->get_kind() == TK_ARRAY && id >= bound_total(type_desc_)) {
    2879           3 :     return false;
    2880             :   }
    2881             : 
    2882         317 :   DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    2883         317 :   const TypeKind elem_tk = elem_type->get_kind();
    2884         317 :   TypeKind treat_as_tk = elem_tk;
    2885         317 :   switch (elem_tk) {
    2886          14 :   case TK_ENUM:
    2887          14 :     if (enum_bound(elem_type, treat_as_tk) != DDS::RETCODE_OK) {
    2888           0 :       return false;
    2889             :     }
    2890          14 :     break;
    2891           0 :   case TK_BITMASK: {
    2892           0 :     if (bitmask_bound(elem_type, treat_as_tk) != DDS::RETCODE_OK) {
    2893           0 :       return false;
    2894             :     }
    2895           0 :     break;
    2896             :   }
    2897             :   }
    2898         317 :   if (treat_as_tk != ValueTypeKind) {
    2899           0 :     return false;
    2900             :   }
    2901         317 :   if (read_basic_member(value, id)) {
    2902         307 :     return true;
    2903             :   }
    2904          10 :   container_.set_default_basic_value(value);
    2905             : 
    2906             :   // Must insert this member in case it's index is larger than the current largest index,
    2907             :   // so that all new members up to this member are serialized. Otherwise, we would be returning
    2908             :   // a value that wouldn't be in the serialized data.
    2909          10 :   insert_single(id, value);
    2910          10 :   return true;
    2911         317 : }
    2912             : 
    2913             : template<TypeKind ValueTypeKind, typename ValueType>
    2914        1800 : DDS::ReturnCode_t DynamicDataImpl::get_single_value(ValueType& value, DDS::MemberId id)
    2915             : {
    2916        1800 :   if (!is_type_supported(ValueTypeKind, "get_single_value")) {
    2917           0 :     return DDS::RETCODE_ERROR;
    2918             :   }
    2919        1800 :   const TypeKind tk = type_->get_kind();
    2920        1800 :   bool good = true;
    2921             : 
    2922        1800 :   switch (tk) {
    2923          11 :   case ValueTypeKind:
    2924          11 :     good = get_value_from_self(value, id);
    2925          11 :     break;
    2926           6 :   case TK_ENUM:
    2927           6 :     good = get_value_from_enum<ValueTypeKind>(value, id);
    2928           6 :     break;
    2929           0 :   case TK_BITMASK:
    2930           0 :     good = get_value_from_bitmask<ValueTypeKind>(value, id);
    2931           0 :     break;
    2932        1281 :   case TK_STRUCTURE:
    2933        1281 :     good = get_value_from_struct<ValueTypeKind>(value, id);
    2934        1281 :     break;
    2935         209 :   case TK_UNION:
    2936         209 :     good = get_value_from_union<ValueTypeKind>(value, id);
    2937         209 :     break;
    2938         293 :   case TK_SEQUENCE:
    2939             :   case TK_ARRAY:
    2940         293 :     good = get_value_from_collection<ValueTypeKind>(value, id);
    2941         293 :     break;
    2942           0 :   case TK_MAP:
    2943           0 :     if (log_level >= LogLevel::Notice) {
    2944           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_single_value:"
    2945             :                  " Map is currently not supported\n"));
    2946             :     }
    2947           0 :     good = false;
    2948           0 :     break;
    2949           0 :   default:
    2950           0 :     good = false;
    2951           0 :     break;
    2952             :   }
    2953             : 
    2954        1800 :   if (!good && log_level >= LogLevel::Notice) {
    2955           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_single_value:"
    2956             :                " Failed to read a value of type %C from a DynamicData object of type %C\n",
    2957             :                typekind_to_string(ValueTypeKind), typekind_to_string(tk)));
    2958             :   }
    2959        1800 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    2960             : }
    2961             : 
    2962         111 : DDS::ReturnCode_t DynamicDataImpl::get_int8_value(CORBA::Int8& value, DDS::MemberId id)
    2963             : {
    2964         111 :   ACE_OutputCDR::from_int8 from_int8(0);
    2965         111 :   const DDS::ReturnCode_t rc = get_single_value<TK_INT8>(from_int8, id);
    2966         111 :   if (rc == DDS::RETCODE_OK) {
    2967         110 :     value = from_int8.val_;
    2968             :   }
    2969         111 :   return rc;
    2970             : }
    2971             : 
    2972         104 : DDS::ReturnCode_t DynamicDataImpl::get_uint8_value(CORBA::UInt8& value, DDS::MemberId id)
    2973             : {
    2974         104 :   ACE_OutputCDR::from_uint8 from_uint8(0);
    2975         104 :   const DDS::ReturnCode_t rc = get_single_value<TK_UINT8>(from_uint8, id);
    2976         104 :   if (rc == DDS::RETCODE_OK) {
    2977         104 :     value = from_uint8.val_;
    2978             :   }
    2979         104 :   return rc;
    2980             : }
    2981             : 
    2982         102 : DDS::ReturnCode_t DynamicDataImpl::get_int16_value(CORBA::Short& value, DDS::MemberId id)
    2983             : {
    2984         102 :   return get_single_value<TK_INT16>(value, id);
    2985             : }
    2986             : 
    2987         102 : DDS::ReturnCode_t DynamicDataImpl::get_uint16_value(CORBA::UShort& value, DDS::MemberId id)
    2988             : {
    2989         102 :   return get_single_value<TK_UINT16>(value, id);
    2990             : }
    2991             : 
    2992         412 : DDS::ReturnCode_t DynamicDataImpl::get_int32_value(CORBA::Long& value, DDS::MemberId id)
    2993             : {
    2994         412 :   return get_single_value<TK_INT32>(value, id);
    2995             : }
    2996             : 
    2997         264 : DDS::ReturnCode_t DynamicDataImpl::get_uint32_value(CORBA::ULong& value, DDS::MemberId id)
    2998             : {
    2999         264 :   return get_single_value<TK_UINT32>(value, id);
    3000             : }
    3001             : 
    3002          90 : DDS::ReturnCode_t DynamicDataImpl::get_int64_value_impl(CORBA::LongLong& value, DDS::MemberId id)
    3003             : {
    3004          90 :   return get_single_value<TK_INT64>(value, id);
    3005             : }
    3006             : 
    3007          98 : DDS::ReturnCode_t DynamicDataImpl::get_uint64_value_impl(CORBA::ULongLong& value, DDS::MemberId id)
    3008             : {
    3009          98 :   return get_single_value<TK_UINT64>(value, id);
    3010             : }
    3011             : 
    3012          88 : DDS::ReturnCode_t DynamicDataImpl::get_float32_value(CORBA::Float& value, DDS::MemberId id)
    3013             : {
    3014          88 :   return get_single_value<TK_FLOAT32>(value, id);
    3015             : }
    3016             : 
    3017          87 : DDS::ReturnCode_t DynamicDataImpl::get_float64_value(CORBA::Double& value, DDS::MemberId id)
    3018             : {
    3019          87 :   return get_single_value<TK_FLOAT64>(value, id);
    3020             : }
    3021             : 
    3022          76 : DDS::ReturnCode_t DynamicDataImpl::get_float128_value(CORBA::LongDouble& value, DDS::MemberId id)
    3023             : {
    3024          76 :   return get_single_value<TK_FLOAT128>(value, id);
    3025             : }
    3026             : 
    3027             : template<TypeKind CharKind, TypeKind StringKind, typename FromCharT, typename CharT>
    3028         172 : DDS::ReturnCode_t DynamicDataImpl::get_char_common(CharT& value, DDS::MemberId id)
    3029             : {
    3030         172 :   const TypeKind tk = type_->get_kind();
    3031         172 :   bool good = true;
    3032         172 :   switch (tk) {
    3033           0 :   case CharKind: {
    3034           0 :     if (id != MEMBER_ID_INVALID) {
    3035           0 :       good = false;
    3036           0 :       break;
    3037             :     }
    3038           0 :     DataContainer::const_single_iterator it = container_.single_map_.find(id);
    3039           0 :     if (it != container_.single_map_.end()) {
    3040           0 :       FromCharT from_char = it->second.get<FromCharT>();
    3041           0 :       value = from_char.val_;
    3042             :     } else {
    3043           0 :       FromCharT from_char('\0');
    3044           0 :       container_.set_default_basic_value(from_char);
    3045           0 :       value = from_char.val_;
    3046             :     }
    3047           0 :     break;
    3048             :   }
    3049           9 :   case StringKind: {
    3050           9 :     FromCharT from_char('\0');
    3051           9 :     good = read_basic_member(from_char, id);
    3052           9 :     if (good) {
    3053           9 :       value = from_char.val_;
    3054             :     }
    3055           9 :     break;
    3056             :   }
    3057         141 :   case TK_STRUCTURE: {
    3058         141 :     FromCharT from_char('\0');
    3059         141 :     good = get_value_from_struct<CharKind>(from_char, id);
    3060         141 :     if (good) {
    3061         141 :       value = from_char.val_;
    3062             :     }
    3063         141 :     break;
    3064             :   }
    3065           6 :   case TK_UNION: {
    3066           6 :     FromCharT from_char('\0');
    3067           6 :     good = get_value_from_union<CharKind>(from_char, id);
    3068           6 :     if (good) {
    3069           6 :       value = from_char.val_;
    3070             :     }
    3071           6 :     break;
    3072             :   }
    3073          16 :   case TK_SEQUENCE:
    3074             :   case TK_ARRAY: {
    3075          16 :     FromCharT from_char('\0');
    3076          16 :     good = get_value_from_collection<CharKind>(from_char, id);
    3077          16 :     if (good) {
    3078          16 :       value = from_char.val_;
    3079             :     }
    3080          16 :     break;
    3081             :   }
    3082           0 :   case TK_MAP:
    3083           0 :     if (log_level >= LogLevel::Notice) {
    3084           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_char_common:"
    3085             :                  " Map is currently not supported\n"));
    3086             :     }
    3087           0 :     good = false;
    3088           0 :     break;
    3089           0 :   default:
    3090           0 :     good = false;
    3091           0 :     break;
    3092             :   }
    3093             : 
    3094         172 :   if (!good && log_level >= LogLevel::Notice) {
    3095           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_char_common::"
    3096             :                " Failed to read a value of type %C from a DynamicData object of type %C\n",
    3097             :                typekind_to_string(CharKind), typekind_to_string(tk)));
    3098             :   }
    3099         172 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    3100             : }
    3101             : 
    3102          92 : DDS::ReturnCode_t DynamicDataImpl::get_char8_value(CORBA::Char& value, DDS::MemberId id)
    3103             : {
    3104          92 :   return get_char_common<TK_CHAR8, TK_STRING8, ACE_OutputCDR::from_char>(value, id);
    3105             : }
    3106             : 
    3107          80 : DDS::ReturnCode_t DynamicDataImpl::get_char16_value(CORBA::WChar& value, DDS::MemberId id)
    3108             : {
    3109             : #ifdef DDS_HAS_WCHAR
    3110          80 :   return get_char_common<TK_CHAR16, TK_STRING16, ACE_OutputCDR::from_wchar>(value, id);
    3111             : #else
    3112             :   return DDS::RETCODE_UNSUPPORTED;
    3113             : #endif
    3114             : }
    3115             : 
    3116         108 : DDS::ReturnCode_t DynamicDataImpl::get_byte_value(CORBA::Octet& value, DDS::MemberId id)
    3117             : {
    3118         108 :   ACE_OutputCDR::from_octet from_octet(0);
    3119         108 :   const DDS::ReturnCode_t rc = get_single_value<TK_BYTE>(from_octet, id);
    3120         108 :   if (rc == DDS::RETCODE_OK) {
    3121         108 :     value = from_octet.val_;
    3122             :   }
    3123         108 :   return rc;
    3124             : }
    3125             : 
    3126             : template<typename UIntType>
    3127           0 : bool DynamicDataImpl::get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value)
    3128             : {
    3129             :   UIntType bitmask;
    3130           0 :   if (!read_basic_value(bitmask)) {
    3131           0 :     return false;
    3132             :   }
    3133           0 :   value = (1ULL << index) & bitmask;
    3134           0 :   return true;
    3135             : }
    3136             : 
    3137             : template<>
    3138           0 : bool DynamicDataImpl::get_boolean_from_bitmask<CORBA::UInt8>(CORBA::ULong index, CORBA::Boolean& value)
    3139             : {
    3140           0 :   ACE_OutputCDR::from_int8 bitmask(0);
    3141           0 :   if (!read_basic_value(bitmask)) {
    3142           0 :     return false;
    3143             :   }
    3144           0 :   value = ((1 << index) & bitmask.val_) ? true : false;
    3145           0 :   return true;
    3146             : }
    3147             : 
    3148         110 : DDS::ReturnCode_t DynamicDataImpl::get_boolean_value(CORBA::Boolean& value, DDS::MemberId id)
    3149             : {
    3150         110 :   const TypeKind tk = type_->get_kind();
    3151         110 :   bool good = true;
    3152         110 :   switch (tk) {
    3153           0 :   case TK_BOOLEAN: {
    3154           0 :     if (id != MEMBER_ID_INVALID) {
    3155           0 :       good = false;
    3156           0 :       break;
    3157             :     }
    3158           0 :     DataContainer::const_single_iterator it = container_.single_map_.find(id);
    3159           0 :     if (it != container_.single_map_.end()) {
    3160           0 :       ACE_OutputCDR::from_boolean from_bool = it->second.get<ACE_OutputCDR::from_boolean>();
    3161           0 :       value = from_bool.val_;
    3162             :     } else {
    3163           0 :       ACE_OutputCDR::from_boolean from_bool(false);
    3164           0 :       container_.set_default_basic_value(from_bool);
    3165           0 :       value = from_bool.val_;
    3166             :     }
    3167           0 :     break;
    3168             :   }
    3169           0 :   case TK_BITMASK: {
    3170           0 :     const LBound bitbound = type_desc_->bound()[0];
    3171             :     ACE_CDR::ULong index;
    3172           0 :     if (!get_index_from_id(id, index, bitbound)) {
    3173           0 :       good = false;
    3174           0 :       break;
    3175             :     }
    3176           0 :     if (bitbound >= 1 && bitbound <= 8) {
    3177           0 :       good = get_boolean_from_bitmask<CORBA::UInt8>(index, value);
    3178           0 :     } else if (bitbound >= 9 && bitbound <= 16) {
    3179           0 :       good = get_boolean_from_bitmask<CORBA::UShort>(index, value);
    3180           0 :     } else if (bitbound >= 17 && bitbound <= 32) {
    3181           0 :       good = get_boolean_from_bitmask<CORBA::ULong>(index, value);
    3182             :     } else {
    3183           0 :       good = get_boolean_from_bitmask<CORBA::ULongLong>(index, value);
    3184             :     }
    3185           0 :     break;
    3186             :   }
    3187          95 :   case TK_STRUCTURE: {
    3188          95 :     ACE_OutputCDR::from_boolean from_bool(false);
    3189          95 :     good = get_value_from_struct<TK_BOOLEAN>(from_bool, id);
    3190          95 :     if (good) {
    3191          95 :       value = from_bool.val_;
    3192             :     }
    3193          95 :     break;
    3194             :   }
    3195           4 :   case TK_UNION: {
    3196           4 :     ACE_OutputCDR::from_boolean from_bool(false);
    3197           4 :     good = get_value_from_union<TK_BOOLEAN>(from_bool, id);
    3198           4 :     if (good) {
    3199           3 :       value = from_bool.val_;
    3200             :     }
    3201           4 :     break;
    3202             :   }
    3203          11 :   case TK_SEQUENCE:
    3204             :   case TK_ARRAY: {
    3205          11 :     ACE_OutputCDR::from_boolean from_bool(false);
    3206          11 :     good = get_value_from_collection<TK_BOOLEAN>(from_bool, id);
    3207          11 :     if (good) {
    3208          11 :       value = from_bool.val_;
    3209             :     }
    3210          11 :     break;
    3211             :   }
    3212           0 :   case TK_MAP:
    3213           0 :     if (log_level >= LogLevel::Notice) {
    3214           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_boolean_value:"
    3215             :                  " Map is currently not supported\n"));
    3216             :     }
    3217           0 :     good = false;
    3218           0 :     break;
    3219           0 :   default:
    3220           0 :     good = false;
    3221           0 :     break;
    3222             :   }
    3223             : 
    3224         110 :   if (!good && log_level >= LogLevel::Notice) {
    3225           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_boolean_value:"
    3226             :                " Failed to read a boolean value from a DynamicData object of type %C\n",
    3227             :                typekind_to_string(tk)));
    3228             :   }
    3229         110 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    3230             : }
    3231             : 
    3232          83 : DDS::ReturnCode_t DynamicDataImpl::get_string_value(char*& value, DDS::MemberId id)
    3233             : {
    3234          83 :   if (enum_string_helper(value, id)) {
    3235           1 :     return DDS::RETCODE_OK;
    3236             :   }
    3237             : 
    3238          82 :   return get_single_value<TK_STRING8>(value, id);
    3239             : }
    3240             : 
    3241          76 : DDS::ReturnCode_t DynamicDataImpl::get_wstring_value(CORBA::WChar*& value, DDS::MemberId id)
    3242             : {
    3243             : #ifdef DDS_HAS_WCHAR
    3244          76 :   return get_single_value<TK_STRING16>(value, id);
    3245             : #else
    3246             :   return DDS::RETCODE_UNSUPPORTED;
    3247             : #endif
    3248             : }
    3249             : 
    3250          14 : bool DynamicDataImpl::move_single_to_complex(const DataContainer::const_single_iterator& it,
    3251             :                                              DynamicDataImpl* data)
    3252             : {
    3253          14 :   DDS::DynamicType_var member_type = data->type();
    3254          14 :   const TypeKind member_tk = member_type->get_kind();
    3255          14 :   TypeKind treat_as = member_tk;
    3256          14 :   if (member_tk == TK_ENUM) {
    3257           6 :     if (enum_bound(member_type, treat_as) != DDS::RETCODE_OK) {
    3258           0 :       return false;
    3259             :     }
    3260             :   }
    3261          14 :   return move_single_to_complex_i(it, data, treat_as);
    3262          14 : }
    3263             : 
    3264          14 : bool DynamicDataImpl::move_single_to_complex_i(const DataContainer::const_single_iterator& it,
    3265             :                                                DynamicDataImpl* data, const TypeKind treat_as)
    3266             : {
    3267          14 :   switch (treat_as) {
    3268           0 :   case TK_INT8: {
    3269           0 :     const ACE_OutputCDR::from_int8& value = it->second.get<ACE_OutputCDR::from_int8>();
    3270           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3271           0 :     break;
    3272             :   }
    3273           0 :   case TK_UINT8: {
    3274           0 :     const ACE_OutputCDR::from_uint8& value = it->second.get<ACE_OutputCDR::from_uint8>();
    3275           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3276           0 :     break;
    3277             :   }
    3278           0 :   case TK_INT16: {
    3279           0 :     const CORBA::Short value = it->second.get<CORBA::Short>();
    3280           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3281           0 :     break;
    3282             :   }
    3283           0 :   case TK_UINT16: {
    3284           0 :     const CORBA::UShort value = it->second.get<CORBA::UShort>();
    3285           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3286           0 :     break;
    3287             :   }
    3288          11 :   case TK_INT32: {
    3289          11 :     const CORBA::Long value = it->second.get<CORBA::Long>();
    3290          11 :     data->insert_single(MEMBER_ID_INVALID, value);
    3291          11 :     break;
    3292             :   }
    3293           0 :   case TK_UINT32: {
    3294           0 :     const CORBA::ULong value = it->second.get<CORBA::ULong>();
    3295           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3296           0 :     break;
    3297             :   }
    3298           0 :   case TK_INT64: {
    3299           0 :     const CORBA::LongLong value = it->second.get<CORBA::LongLong>();
    3300           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3301           0 :     break;
    3302             :   }
    3303           0 :   case TK_UINT64: {
    3304           0 :     const CORBA::ULongLong value = it->second.get<CORBA::ULongLong>();
    3305           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3306           0 :     break;
    3307             :   }
    3308           0 :   case TK_FLOAT32: {
    3309           0 :     const CORBA::Float value = it->second.get<CORBA::Float>();
    3310           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3311           0 :     break;
    3312             :   }
    3313           0 :   case TK_FLOAT64: {
    3314           0 :     const CORBA::Double value = it->second.get<CORBA::Double>();
    3315           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3316           0 :     break;
    3317             :   }
    3318           0 :   case TK_FLOAT128: {
    3319           0 :     const CORBA::LongDouble value = it->second.get<CORBA::LongDouble>();
    3320           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3321           0 :     break;
    3322             :   }
    3323           0 :   case TK_CHAR8: {
    3324           0 :     const ACE_OutputCDR::from_char& value = it->second.get<ACE_OutputCDR::from_char>();
    3325           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3326           0 :     break;
    3327             :   }
    3328             : #ifdef DDS_HAS_WCHAR
    3329           0 :   case TK_CHAR16: {
    3330           0 :     const ACE_OutputCDR::from_wchar& value = it->second.get<ACE_OutputCDR::from_wchar>();
    3331           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3332           0 :     break;
    3333             :   }
    3334             : #endif
    3335           0 :   case TK_BYTE: {
    3336           0 :     const ACE_OutputCDR::from_octet& value = it->second.get<ACE_OutputCDR::from_octet>();
    3337           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3338           0 :     break;
    3339             :   }
    3340           0 :   case TK_BOOLEAN: {
    3341           0 :     const ACE_OutputCDR::from_boolean& value = it->second.get<ACE_OutputCDR::from_boolean>();
    3342           0 :     data->insert_single(MEMBER_ID_INVALID, value);
    3343           0 :     break;
    3344             :   }
    3345           3 :   case TK_STRING8: {
    3346           3 :     const char* str = it->second.get<const char*>();
    3347           3 :     const size_t len = ACE_OS::strlen(str);
    3348          12 :     for (CORBA::ULong i = 0; i < len; ++i) {
    3349           9 :       data->insert_single(i, ACE_OutputCDR::from_char(str[i]));
    3350             :     }
    3351           3 :     break;
    3352             :   }
    3353             : #ifdef DDS_HAS_WCHAR
    3354           0 :   case TK_STRING16: {
    3355           0 :     const CORBA::WChar* wstr = it->second.get<const CORBA::WChar*>();
    3356           0 :     const size_t len = ACE_OS::strlen(wstr);
    3357           0 :     for (CORBA::ULong i = 0; i < len; ++i) {
    3358           0 :       data->insert_single(i, ACE_OutputCDR::from_wchar(wstr[i]));
    3359             :     }
    3360           0 :     break;
    3361             :   }
    3362             : #endif
    3363           0 :   default:
    3364           0 :     return false;
    3365             :   }
    3366          14 :   return true;
    3367             : }
    3368             : 
    3369             : template<typename SequenceType>
    3370           9 : void DynamicDataImpl::move_sequence_helper(const DataContainer::const_sequence_iterator& it,
    3371             :                                            DynamicDataImpl* data)
    3372             : {
    3373           9 :   const SequenceType& values = it->second.get<SequenceType>();
    3374          33 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3375          24 :     data->insert_single(i, values[i]);
    3376             :   }
    3377           9 : }
    3378             : 
    3379             : // Get the inner C-string explicitly
    3380             : template<>
    3381           3 : void DynamicDataImpl::move_sequence_helper<DDS::StringSeq>(const DataContainer::const_sequence_iterator& it,
    3382             :                                                            DynamicDataImpl* data)
    3383             : {
    3384           3 :   const DDS::StringSeq& values = it->second.get<DDS::StringSeq>();
    3385           6 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3386           3 :     data->insert_single(i, values[i].in());
    3387             :   }
    3388           3 : }
    3389             : 
    3390             : #ifdef DDS_HAS_WCHAR
    3391             : template<>
    3392           0 : void DynamicDataImpl::move_sequence_helper<DDS::WstringSeq>(const DataContainer::const_sequence_iterator& it,
    3393             :                                                             DynamicDataImpl* data)
    3394             : {
    3395           0 :   const DDS::WstringSeq& values = it->second.get<DDS::WstringSeq>();
    3396           0 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3397           0 :     data->insert_single(i, values[i].in());
    3398             :   }
    3399           0 : }
    3400             : #endif
    3401             : 
    3402             : template<>
    3403           3 : void DynamicDataImpl::move_sequence_helper<DDS::Int8Seq>(const DataContainer::const_sequence_iterator& it,
    3404             :                                                          DynamicDataImpl* data)
    3405             : {
    3406           3 :   const DDS::Int8Seq& values = it->second.get<DDS::Int8Seq>();
    3407          12 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3408           9 :     data->insert_single(i, ACE_OutputCDR::from_int8(values[i]));
    3409             :   }
    3410           3 : }
    3411             : 
    3412             : template<>
    3413           0 : void DynamicDataImpl::move_sequence_helper<DDS::UInt8Seq>(const DataContainer::const_sequence_iterator& it,
    3414             :                                                           DynamicDataImpl* data)
    3415             : {
    3416           0 :   const DDS::UInt8Seq& values = it->second.get<DDS::UInt8Seq>();
    3417           0 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3418           0 :     data->insert_single(i, ACE_OutputCDR::from_uint8(values[i]));
    3419             :   }
    3420           0 : }
    3421             : 
    3422             : template<>
    3423           0 : void DynamicDataImpl::move_sequence_helper<DDS::CharSeq>(const DataContainer::const_sequence_iterator& it,
    3424             :                                                          DynamicDataImpl* data)
    3425             : {
    3426           0 :   const DDS::CharSeq& values = it->second.get<DDS::CharSeq>();
    3427           0 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3428           0 :     data->insert_single(i, ACE_OutputCDR::from_char(values[i]));
    3429             :   }
    3430           0 : }
    3431             : 
    3432             : template<>
    3433           0 : void DynamicDataImpl::move_sequence_helper<DDS::ByteSeq>(const DataContainer::const_sequence_iterator& it,
    3434             :                                                          DynamicDataImpl* data)
    3435             : {
    3436           0 :   const DDS::ByteSeq& values = it->second.get<DDS::ByteSeq>();
    3437           0 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3438           0 :     data->insert_single(i, ACE_OutputCDR::from_octet(values[i]));
    3439             :   }
    3440           0 : }
    3441             : 
    3442             : template<>
    3443           3 : void DynamicDataImpl::move_sequence_helper<DDS::BooleanSeq>(const DataContainer::const_sequence_iterator& it,
    3444             :                                                             DynamicDataImpl* data)
    3445             : {
    3446           3 :   const DDS::BooleanSeq& values = it->second.get<DDS::BooleanSeq>();
    3447           6 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3448           3 :     data->insert_single(i, ACE_OutputCDR::from_boolean(values[i]));
    3449             :   }
    3450           3 : }
    3451             : 
    3452             : #ifdef DDS_HAS_WCHAR
    3453             : template<>
    3454           0 : void DynamicDataImpl::move_sequence_helper<DDS::WcharSeq>(const DataContainer::const_sequence_iterator& it,
    3455             :                                                           DynamicDataImpl* data)
    3456             : {
    3457           0 :   const DDS::WcharSeq& values = it->second.get<DDS::WcharSeq>();
    3458           0 :   for (CORBA::ULong i = 0; i < values.length(); ++i) {
    3459           0 :     data->insert_single(i, ACE_OutputCDR::from_wchar(values[i]));
    3460             :   }
    3461           0 : }
    3462             : #endif
    3463             : 
    3464          18 : bool DynamicDataImpl::move_sequence_to_complex(const DataContainer::const_sequence_iterator& it,
    3465             :                                                DynamicDataImpl* data)
    3466             : {
    3467          18 :   DDS::DynamicType_var seq_type = data->type();
    3468          18 :   DDS::TypeDescriptor_var seq_td;
    3469          18 :   if (seq_type->get_descriptor(seq_td) != DDS::RETCODE_OK) {
    3470           0 :     return false;
    3471             :   }
    3472          18 :   DDS::DynamicType_var elem_type = get_base_type(seq_td->element_type());
    3473             : 
    3474          18 :   switch (elem_type->get_kind()) {
    3475           3 :   case TK_INT8: {
    3476           3 :     move_sequence_helper<DDS::Int8Seq>(it, data);
    3477           3 :     break;
    3478             :   }
    3479           0 :   case TK_UINT8: {
    3480           0 :     move_sequence_helper<DDS::UInt8Seq>(it, data);
    3481           0 :     break;
    3482             :   }
    3483           0 :   case TK_INT16: {
    3484           0 :     move_sequence_helper<DDS::Int16Seq>(it, data);
    3485           0 :     break;
    3486             :   }
    3487           0 :   case TK_UINT16: {
    3488           0 :     move_sequence_helper<DDS::UInt16Seq>(it, data);
    3489           0 :     break;
    3490             :   }
    3491           6 :   case TK_INT32: {
    3492           6 :     move_sequence_helper<DDS::Int32Seq>(it, data);
    3493           6 :     break;
    3494             :   }
    3495           3 :   case TK_UINT32: {
    3496           3 :     move_sequence_helper<DDS::UInt32Seq>(it, data);
    3497           3 :     break;
    3498             :   }
    3499           0 :   case TK_INT64: {
    3500           0 :     move_sequence_helper<DDS::Int64Seq>(it, data);
    3501           0 :     break;
    3502             :   }
    3503           0 :   case TK_UINT64: {
    3504           0 :     move_sequence_helper<DDS::UInt64Seq>(it, data);
    3505           0 :     break;
    3506             :   }
    3507           0 :   case TK_FLOAT32: {
    3508           0 :     move_sequence_helper<DDS::Float32Seq>(it, data);
    3509           0 :     break;
    3510             :   }
    3511           0 :   case TK_FLOAT64: {
    3512           0 :     move_sequence_helper<DDS::Float64Seq>(it, data);
    3513           0 :     break;
    3514             :   }
    3515           0 :   case TK_FLOAT128: {
    3516           0 :     move_sequence_helper<DDS::Float128Seq>(it, data);
    3517           0 :     break;
    3518             :   }
    3519           0 :   case TK_CHAR8: {
    3520           0 :     move_sequence_helper<DDS::CharSeq>(it, data);
    3521           0 :     break;
    3522             :   }
    3523             : #ifdef DDS_HAS_WCHAR
    3524           0 :   case TK_CHAR16: {
    3525           0 :     move_sequence_helper<DDS::WcharSeq>(it, data);
    3526           0 :     break;
    3527             :   }
    3528             : #endif
    3529           0 :   case TK_BYTE: {
    3530           0 :     move_sequence_helper<DDS::ByteSeq>(it, data);
    3531           0 :     break;
    3532             :   }
    3533           3 :   case TK_BOOLEAN: {
    3534           3 :     move_sequence_helper<DDS::BooleanSeq>(it, data);
    3535           3 :     break;
    3536             :   }
    3537           3 :   case TK_STRING8: {
    3538           3 :     move_sequence_helper<DDS::StringSeq>(it, data);
    3539           3 :     break;
    3540             :   }
    3541             : #ifdef DDS_HAS_WCHAR
    3542           0 :   case TK_STRING16: {
    3543           0 :     move_sequence_helper<DDS::WstringSeq>(it, data);
    3544           0 :     break;
    3545             :   }
    3546             : #endif
    3547           0 :   default:
    3548           0 :     return false;
    3549             :   }
    3550          18 :   return true;
    3551          18 : }
    3552             : 
    3553         444 : bool DynamicDataImpl::get_complex_from_aggregated(DDS::DynamicData_var& value, DDS::MemberId id,
    3554             :                                                   FoundStatus& found_status)
    3555             : {
    3556         444 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    3557         444 :   if (complex_it != container_.complex_map_.end()) {
    3558         316 :     value = DDS::DynamicData::_duplicate(complex_it->second);
    3559         316 :     found_status = FOUND_IN_COMPLEX_MAP;
    3560         316 :     return true;
    3561             :   }
    3562             : 
    3563         128 :   DDS::DynamicTypeMember_var dtm;
    3564         128 :   if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
    3565           0 :     return false;
    3566             :   }
    3567         128 :   DDS::MemberDescriptor_var md;
    3568         128 :   if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    3569           0 :     return false;
    3570             :   }
    3571         128 :   DDS::DynamicType_var member_type = get_base_type(md->type());
    3572         128 :   DynamicDataImpl* dd_impl = new DynamicDataImpl(member_type);
    3573         128 :   DDS::DynamicData_var dd_var = dd_impl;
    3574             : 
    3575         128 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    3576         128 :   if (single_it != container_.single_map_.end()) {
    3577           3 :     if (!move_single_to_complex(single_it, dd_impl)) {
    3578           0 :       return false;
    3579             :     }
    3580           3 :     found_status = FOUND_IN_NON_COMPLEX_MAP;
    3581             :   } else {
    3582         125 :     DataContainer::const_sequence_iterator sequence_it = container_.sequence_map_.find(id);
    3583         125 :     if (sequence_it != container_.sequence_map_.end()) {
    3584          18 :       if (!move_sequence_to_complex(sequence_it, dd_impl)) {
    3585           0 :         return false;
    3586             :       }
    3587          18 :       found_status = FOUND_IN_NON_COMPLEX_MAP;
    3588             :     } else {
    3589         107 :       found_status = NOT_FOUND;
    3590             :     }
    3591             :   }
    3592         128 :   value = dd_var;
    3593         128 :   return true;
    3594         128 : }
    3595             : 
    3596         433 : bool DynamicDataImpl::get_complex_from_struct(DDS::DynamicData_ptr& value, DDS::MemberId id)
    3597             : {
    3598         433 :   FoundStatus found_status = NOT_FOUND;
    3599         433 :   DDS::DynamicData_var dd_var;
    3600         433 :   if (!get_complex_from_aggregated(dd_var, id, found_status)) {
    3601           0 :     return false;
    3602             :   }
    3603             : 
    3604         433 :   if (found_status == FOUND_IN_NON_COMPLEX_MAP || found_status == NOT_FOUND) {
    3605         118 :     insert_complex(id, dd_var);
    3606             :   }
    3607         433 :   CORBA::release(value);
    3608         433 :   value = DDS::DynamicData::_duplicate(dd_var);
    3609         433 :   return true;
    3610         433 : }
    3611             : 
    3612           0 : bool DynamicDataImpl::write_discriminator_helper(CORBA::Long value, TypeKind treat_as)
    3613             : {
    3614           0 :   switch (treat_as) {
    3615           0 :   case TK_BOOLEAN:
    3616           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_boolean(value));
    3617           0 :   case TK_BYTE:
    3618           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_octet(value));
    3619           0 :   case TK_CHAR8:
    3620           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_char(value));
    3621             : #ifdef DDS_HAS_WCHAR
    3622           0 :   case TK_CHAR16:
    3623           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_wchar(value));
    3624             : #endif
    3625           0 :   case TK_INT8:
    3626           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_int8(value));
    3627           0 :   case TK_UINT8:
    3628           0 :     return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_uint8(value));
    3629           0 :   case TK_INT16:
    3630           0 :     return insert_single(MEMBER_ID_INVALID, static_cast<CORBA::Short>(value));
    3631           0 :   case TK_UINT16:
    3632           0 :     return insert_single(MEMBER_ID_INVALID, static_cast<CORBA::UShort>(value));
    3633           0 :   case TK_INT32:
    3634           0 :     return insert_single(MEMBER_ID_INVALID, value);
    3635           0 :   case TK_UINT32:
    3636           0 :     return insert_single(MEMBER_ID_INVALID, static_cast<CORBA::ULong>(value));
    3637           0 :   case TK_INT64:
    3638           0 :     return insert_single(MEMBER_ID_INVALID, static_cast<CORBA::LongLong>(value));
    3639           0 :   case TK_UINT64:
    3640           0 :     return insert_single(MEMBER_ID_INVALID, static_cast<CORBA::ULongLong>(value));
    3641           0 :   default:
    3642           0 :     return false;
    3643             :   }
    3644             : }
    3645             : 
    3646             : // Write value to discriminator represented by a DynamicData instance.
    3647           0 : bool DynamicDataImpl::write_discriminator(CORBA::Long value)
    3648             : {
    3649           0 :   TypeKind treat_as = type_->get_kind();
    3650           0 :   if (treat_as == TK_ENUM) {
    3651           0 :     if (enum_bound(type_, treat_as) != DDS::RETCODE_OK) {
    3652           0 :       return false;
    3653             :     }
    3654             :   }
    3655           0 :   return write_discriminator_helper(value, treat_as);
    3656             : }
    3657             : 
    3658          11 : bool DynamicDataImpl::get_complex_from_union(DDS::DynamicData_ptr& value, DDS::MemberId id)
    3659             : {
    3660          11 :   FoundStatus found_status = NOT_FOUND;
    3661          11 :   DDS::DynamicData_var dd_var;
    3662          11 :   if (!get_complex_from_aggregated(dd_var, id, found_status)) {
    3663           0 :     return false;
    3664             :   }
    3665          11 :   if (found_status != NOT_FOUND) {
    3666          10 :     if (found_status == FOUND_IN_NON_COMPLEX_MAP) {
    3667           9 :       insert_complex(id, dd_var);
    3668             :     }
    3669          10 :     CORBA::release(value);
    3670          10 :     value = DDS::DynamicData::_duplicate(dd_var);
    3671          10 :     return true;
    3672             :   }
    3673             : 
    3674             :   // Requested member with the given Id is not present in the container.
    3675           1 :   if (id == DISCRIMINATOR_ID) {
    3676           0 :     DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type());
    3677             :     CORBA::Long disc_value;
    3678           0 :     if (!container_.set_default_discriminator_value(disc_value, disc_type)) {
    3679           0 :       return false;
    3680             :     }
    3681           0 :     bool found_selected_member = false;
    3682           0 :     DDS::MemberDescriptor_var selected_md;
    3683             :     const DDS::ReturnCode_t rc =
    3684           0 :       get_selected_union_branch(disc_value, found_selected_member, selected_md);
    3685           0 :     if (rc != DDS::RETCODE_OK) {
    3686           0 :       if (log_level >= LogLevel::Notice) {
    3687           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_from_union:"
    3688             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
    3689             :       }
    3690           0 :       return false;
    3691             :     }
    3692           0 :     DynamicDataImpl* dd_impl = new DynamicDataImpl(disc_type);
    3693           0 :     DDS::DynamicData_var dd_var = dd_impl;
    3694           0 :     dd_impl->write_discriminator(disc_value);
    3695           0 :     insert_complex(DISCRIMINATOR_ID, dd_var);
    3696           0 :     if (found_selected_member && !selected_md->is_optional()) {
    3697           0 :       DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    3698           0 :       if (clear_value_i(selected_md->id(), selected_type) != DDS::RETCODE_OK) {
    3699           0 :         return false;
    3700             :       }
    3701           0 :     }
    3702           0 :     CORBA::release(value);
    3703           0 :     value = DDS::DynamicData::_duplicate(dd_var);
    3704           0 :   } else {
    3705           1 :     DataContainer::const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID);
    3706           1 :     DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID);
    3707           2 :     const bool has_disc = single_it != container_.single_map_.end() ||
    3708           1 :       complex_it != container_.complex_map_.end();
    3709           1 :     if (has_disc) {
    3710           0 :       if (log_level >= LogLevel::Notice) {
    3711           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_from_union:"
    3712             :                    " Branch Id %u is not the active branch in the union\n", id));
    3713             :       }
    3714           0 :       return false;
    3715             :     }
    3716           1 :     DDS::DynamicTypeMember_var dtm;
    3717           1 :     if (type_->get_member(dtm, id) != DDS::RETCODE_OK) {
    3718           0 :       return false;
    3719             :     }
    3720           1 :     DDS::MemberDescriptor_var md;
    3721           1 :     if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    3722           0 :       return false;
    3723             :     }
    3724             :     // An empty DynamicData object implicitly contains default value of the associated type.
    3725           1 :     DynamicDataImpl* dd_impl = new DynamicDataImpl(md->type());
    3726           1 :     DDS::DynamicData_var dd_var = dd_impl;
    3727           1 :     if (!insert_valid_discriminator(md)) {
    3728           0 :       return false;
    3729             :     }
    3730           1 :     insert_complex(id, dd_var);
    3731           1 :     CORBA::release(value);
    3732           1 :     value = DDS::DynamicData::_duplicate(dd_var);
    3733           1 :   }
    3734           1 :   return true;
    3735          11 : }
    3736             : 
    3737          44 : bool DynamicDataImpl::get_complex_from_collection(DDS::DynamicData_ptr& value, DDS::MemberId id)
    3738             : {
    3739          44 :   DataContainer::const_complex_iterator complex_it = container_.complex_map_.find(id);
    3740          44 :   if (complex_it != container_.complex_map_.end()) {
    3741          16 :     CORBA::release(value);
    3742          16 :     value = DDS::DynamicData::_duplicate(complex_it->second);
    3743          16 :     return true;
    3744             :   }
    3745             : 
    3746          28 :   if (type_->get_kind() == TK_ARRAY && id >= bound_total(type_desc_)) {
    3747           1 :     return false;
    3748             :   }
    3749             : 
    3750          27 :   DynamicDataImpl* dd_impl = new DynamicDataImpl(type_desc_->element_type());
    3751          27 :   DDS::DynamicData_var dd_var = dd_impl;
    3752             : 
    3753          27 :   DataContainer::const_single_iterator single_it = container_.single_map_.find(id);
    3754          27 :   if (single_it != container_.single_map_.end()) {
    3755          11 :     if (!move_single_to_complex(single_it, dd_impl)) {
    3756           0 :       return false;
    3757             :     }
    3758             :   } else {
    3759          16 :     DataContainer::const_sequence_iterator sequence_it = container_.sequence_map_.find(id);
    3760          16 :     if (sequence_it != container_.sequence_map_.end()) {
    3761           0 :       if (!move_sequence_to_complex(sequence_it, dd_impl)) {
    3762           0 :         return false;
    3763             :       }
    3764             :     }
    3765             :   }
    3766          27 :   insert_complex(id, dd_var);
    3767          27 :   CORBA::release(value);
    3768          27 :   value = DDS::DynamicData::_duplicate(dd_var);
    3769          27 :   return true;
    3770          27 : }
    3771             : 
    3772         488 : DDS::ReturnCode_t DynamicDataImpl::get_complex_value(DDS::DynamicData_ptr& value, DDS::MemberId id)
    3773             : {
    3774         488 :   const TypeKind tk = type_->get_kind();
    3775         488 :   bool good = true;
    3776         488 :   switch (tk) {
    3777         433 :   case TK_STRUCTURE:
    3778         433 :     good = get_complex_from_struct(value, id);
    3779         433 :     break;
    3780          11 :   case TK_UNION:
    3781          11 :     good = get_complex_from_union(value, id);
    3782          11 :     break;
    3783          44 :   case TK_SEQUENCE:
    3784             :   case TK_ARRAY:
    3785          44 :     good = get_complex_from_collection(value, id);
    3786          44 :     break;
    3787           0 :   case TK_MAP:
    3788           0 :     if (log_level >= LogLevel::Notice) {
    3789           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_value:"
    3790             :                  " Map is currently not supported\n"));
    3791             :     }
    3792           0 :     good = false;
    3793           0 :     break;
    3794           0 :   default:
    3795           0 :     good = false;
    3796           0 :     break;
    3797             :   }
    3798             : 
    3799         488 :   if (!good && log_level >= LogLevel::Notice) {
    3800           0 :     ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_value:"
    3801             :                " Failed to read a complex value from a DynamicData object of type %C\n",
    3802             :                typekind_to_string(tk)));
    3803             :   }
    3804         488 :   return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR;
    3805             : }
    3806             : 
    3807           0 : DDS::ReturnCode_t DynamicDataImpl::get_int32_values(DDS::Int32Seq& value, DDS::MemberId id)
    3808             : {
    3809             :   ACE_UNUSED_ARG(value);
    3810             :   ACE_UNUSED_ARG(id);
    3811           0 :   return DDS::RETCODE_UNSUPPORTED;
    3812             : }
    3813             : 
    3814           0 : DDS::ReturnCode_t DynamicDataImpl::get_uint32_values(DDS::UInt32Seq& value, DDS::MemberId id)
    3815             : {
    3816             :   ACE_UNUSED_ARG(value);
    3817             :   ACE_UNUSED_ARG(id);
    3818           0 :   return DDS::RETCODE_UNSUPPORTED;
    3819             : }
    3820             : 
    3821           0 : DDS::ReturnCode_t DynamicDataImpl::get_int8_values(DDS::Int8Seq& value, DDS::MemberId id)
    3822             : {
    3823             :   ACE_UNUSED_ARG(value);
    3824             :   ACE_UNUSED_ARG(id);
    3825           0 :   return DDS::RETCODE_UNSUPPORTED;
    3826             : }
    3827             : 
    3828           0 : DDS::ReturnCode_t DynamicDataImpl::get_uint8_values(DDS::UInt8Seq& value, DDS::MemberId id)
    3829             : {
    3830             :   ACE_UNUSED_ARG(value);
    3831             :   ACE_UNUSED_ARG(id);
    3832           0 :   return DDS::RETCODE_UNSUPPORTED;
    3833             : }
    3834             : 
    3835           0 : DDS::ReturnCode_t DynamicDataImpl::get_int16_values(DDS::Int16Seq& value, DDS::MemberId id)
    3836             : {
    3837             :   ACE_UNUSED_ARG(value);
    3838             :   ACE_UNUSED_ARG(id);
    3839           0 :   return DDS::RETCODE_UNSUPPORTED;
    3840             : }
    3841             : 
    3842           0 : DDS::ReturnCode_t DynamicDataImpl::get_uint16_values(DDS::UInt16Seq& value, DDS::MemberId id)
    3843             : {
    3844             :   ACE_UNUSED_ARG(value);
    3845             :   ACE_UNUSED_ARG(id);
    3846           0 :   return DDS::RETCODE_UNSUPPORTED;
    3847             : }
    3848             : 
    3849           0 : DDS::ReturnCode_t DynamicDataImpl::get_int64_values(DDS::Int64Seq& value, DDS::MemberId id)
    3850             : {
    3851             :   ACE_UNUSED_ARG(value);
    3852             :   ACE_UNUSED_ARG(id);
    3853           0 :   return DDS::RETCODE_UNSUPPORTED;
    3854             : }
    3855             : 
    3856           0 : DDS::ReturnCode_t DynamicDataImpl::get_uint64_values(DDS::UInt64Seq& value, DDS::MemberId id)
    3857             : {
    3858             :   ACE_UNUSED_ARG(value);
    3859             :   ACE_UNUSED_ARG(id);
    3860           0 :   return DDS::RETCODE_UNSUPPORTED;
    3861             : }
    3862             : 
    3863           0 : DDS::ReturnCode_t DynamicDataImpl::get_float32_values(DDS::Float32Seq& value, DDS::MemberId id)
    3864             : {
    3865             :   ACE_UNUSED_ARG(value);
    3866             :   ACE_UNUSED_ARG(id);
    3867           0 :   return DDS::RETCODE_UNSUPPORTED;
    3868             : }
    3869             : 
    3870           0 : DDS::ReturnCode_t DynamicDataImpl::get_float64_values(DDS::Float64Seq& value, DDS::MemberId id)
    3871             : {
    3872             :   ACE_UNUSED_ARG(value);
    3873             :   ACE_UNUSED_ARG(id);
    3874           0 :   return DDS::RETCODE_UNSUPPORTED;
    3875             : }
    3876             : 
    3877           0 : DDS::ReturnCode_t DynamicDataImpl::get_float128_values(DDS::Float128Seq& value, DDS::MemberId id)
    3878             : {
    3879             :   ACE_UNUSED_ARG(value);
    3880             :   ACE_UNUSED_ARG(id);
    3881           0 :   return DDS::RETCODE_UNSUPPORTED;
    3882             : }
    3883             : 
    3884           0 : DDS::ReturnCode_t DynamicDataImpl::get_char8_values(DDS::CharSeq& value, DDS::MemberId id)
    3885             : {
    3886             :   ACE_UNUSED_ARG(value);
    3887             :   ACE_UNUSED_ARG(id);
    3888           0 :   return DDS::RETCODE_UNSUPPORTED;
    3889             : }
    3890             : 
    3891           0 : DDS::ReturnCode_t DynamicDataImpl::get_char16_values(DDS::WcharSeq& value, DDS::MemberId id)
    3892             : {
    3893             :   ACE_UNUSED_ARG(value);
    3894             :   ACE_UNUSED_ARG(id);
    3895           0 :   return DDS::RETCODE_UNSUPPORTED;
    3896             : }
    3897             : 
    3898           0 : DDS::ReturnCode_t DynamicDataImpl::get_byte_values(DDS::ByteSeq& value, DDS::MemberId id)
    3899             : {
    3900             :   ACE_UNUSED_ARG(value);
    3901             :   ACE_UNUSED_ARG(id);
    3902           0 :   return DDS::RETCODE_UNSUPPORTED;
    3903             : }
    3904             : 
    3905           0 : DDS::ReturnCode_t DynamicDataImpl::get_boolean_values(DDS::BooleanSeq& value, DDS::MemberId id)
    3906             : {
    3907             :   ACE_UNUSED_ARG(value);
    3908             :   ACE_UNUSED_ARG(id);
    3909           0 :   return DDS::RETCODE_UNSUPPORTED;
    3910             : }
    3911             : 
    3912           0 : DDS::ReturnCode_t DynamicDataImpl::get_string_values(DDS::StringSeq& value, DDS::MemberId id)
    3913             : {
    3914             :   ACE_UNUSED_ARG(value);
    3915             :   ACE_UNUSED_ARG(id);
    3916           0 :   return DDS::RETCODE_UNSUPPORTED;
    3917             : }
    3918             : 
    3919           0 : DDS::ReturnCode_t DynamicDataImpl::get_wstring_values(DDS::WstringSeq& value, DDS::MemberId id)
    3920             : {
    3921             :   ACE_UNUSED_ARG(value);
    3922             :   ACE_UNUSED_ARG(id);
    3923           0 :   return DDS::RETCODE_UNSUPPORTED;
    3924             : }
    3925             : 
    3926           0 : void DynamicDataImpl::DataContainer::clear()
    3927             : {
    3928           0 :   single_map_.clear();
    3929           0 :   complex_map_.clear();
    3930           0 :   sequence_map_.clear();
    3931           0 : }
    3932             : 
    3933             : // Get largest index among elements of a sequence-like type written to the single map.
    3934          78 : bool DynamicDataImpl::DataContainer::get_largest_single_index(CORBA::ULong& largest_index) const
    3935             : {
    3936          78 :   OPENDDS_ASSERT(is_sequence_like(type_->get_kind()));
    3937          78 :   const DDS::UInt32 bound = bound_total(type_desc_);
    3938             : 
    3939             :   // Since ID is used as index in this implementation, the last element has largest index.
    3940             :   // A different implementation (ID-to-index mapping) may need to iterate through all
    3941             :   // stored elements to find the one with the largest index.
    3942          78 :   return data_->get_index_from_id(single_map_.rbegin()->first, largest_index, bound);
    3943             : }
    3944             : 
    3945             : // Get largest index among elements of a nesting sequence type written to the sequence map.
    3946           0 : bool DynamicDataImpl::DataContainer::get_largest_sequence_index(CORBA::ULong& largest_index) const
    3947             : {
    3948           0 :   OPENDDS_ASSERT(type_->get_kind() == TK_SEQUENCE);
    3949           0 :   const CORBA::ULong bound = type_desc_->bound()[0];
    3950           0 :   return data_->get_index_from_id(sequence_map_.rbegin()->first, largest_index, bound);
    3951             : }
    3952             : 
    3953             : // Get largest index among elements of a sequence-like type written to the complex map.
    3954           7 : bool DynamicDataImpl::DataContainer::get_largest_complex_index(CORBA::ULong& largest_index) const
    3955             : {
    3956           7 :   OPENDDS_ASSERT(is_sequence_like(type_->get_kind()));
    3957           7 :   const DDS::UInt32 bound = bound_total(type_desc_);
    3958           7 :   return data_->get_index_from_id(complex_map_.rbegin()->first, largest_index, bound);
    3959             : }
    3960             : 
    3961          82 : bool DynamicDataImpl::DataContainer::get_largest_index_basic(CORBA::ULong& largest_index) const
    3962             : {
    3963          82 :   largest_index = 0;
    3964          82 :   if (!single_map_.empty() && !get_largest_single_index(largest_index)) {
    3965           0 :     return false;
    3966             :   }
    3967          82 :   if (!complex_map_.empty()) {
    3968             :     CORBA::ULong index;
    3969           4 :     if (!get_largest_complex_index(index)) {
    3970           0 :       return false;
    3971             :     }
    3972           4 :     largest_index = std::max(index, largest_index);
    3973             :   }
    3974          82 :   return true;
    3975             : }
    3976             : 
    3977           0 : bool DynamicDataImpl::DataContainer::get_largest_index_basic_sequence(CORBA::ULong& largest_index) const
    3978             : {
    3979           0 :   largest_index = 0;
    3980           0 :   if (!sequence_map_.empty() && !get_largest_sequence_index(largest_index)) {
    3981           0 :     return false;
    3982             :   }
    3983           0 :   if (!complex_map_.empty()) {
    3984             :     CORBA::ULong index;
    3985           0 :     if (!get_largest_complex_index(index)) {
    3986           0 :       return false;
    3987             :     }
    3988           0 :     largest_index = std::max(index, largest_index);
    3989             :   }
    3990           0 :   return true;
    3991             : }
    3992             : 
    3993         379 : bool DynamicDataImpl::DataContainer::serialize_single_value(DCPS::Serializer& ser,
    3994             :                                                             const SingleValue& sv) const
    3995             : {
    3996         379 :   switch (sv.kind_) {
    3997         203 :   case TK_INT32:
    3998         203 :     return ser << sv.get<CORBA::Long>();
    3999          15 :   case TK_UINT32:
    4000          15 :     return ser << sv.get<CORBA::ULong>();
    4001          15 :   case TK_INT8:
    4002          15 :     return ser << sv.get<ACE_OutputCDR::from_int8>();
    4003          11 :   case TK_UINT8:
    4004          11 :     return ser << sv.get<ACE_OutputCDR::from_uint8>();
    4005          15 :   case TK_INT16:
    4006          15 :     return ser << sv.get<CORBA::Short>();
    4007          12 :   case TK_UINT16:
    4008          12 :     return ser << sv.get<CORBA::UShort>();
    4009          11 :   case TK_INT64:
    4010          11 :     return ser << sv.get<CORBA::LongLong>();
    4011          11 :   case TK_UINT64:
    4012          11 :     return ser << sv.get<CORBA::ULongLong>();
    4013          10 :   case TK_FLOAT32:
    4014          10 :     return ser << sv.get<CORBA::Float>();
    4015          10 :   case TK_FLOAT64:
    4016          10 :     return ser << sv.get<CORBA::Double>();
    4017           0 :   case TK_FLOAT128:
    4018           0 :     return ser << sv.get<CORBA::LongDouble>();
    4019          13 :   case TK_CHAR8:
    4020          13 :     return ser << sv.get<ACE_OutputCDR::from_char>();
    4021          11 :   case TK_BYTE:
    4022          11 :     return ser << sv.get<ACE_OutputCDR::from_octet>();
    4023          11 :   case TK_BOOLEAN:
    4024          11 :     return ser << sv.get<ACE_OutputCDR::from_boolean>();
    4025          10 :   case TK_STRING8:
    4026          10 :     return ser << sv.get<const char*>();
    4027             : #ifdef DDS_HAS_WCHAR
    4028          11 :   case TK_CHAR16:
    4029          11 :     return ser << sv.get<ACE_OutputCDR::from_wchar>();
    4030          10 :   case TK_STRING16:
    4031          10 :     return ser << sv.get<const CORBA::WChar*>();
    4032             : #endif
    4033           0 :   default:
    4034           0 :     return false;
    4035             :   }
    4036             : }
    4037             : 
    4038             : template<typename PrimitiveType>
    4039           5 : bool DynamicDataImpl::DataContainer::serialize_primitive_value(DCPS::Serializer& ser,
    4040             :                                                                PrimitiveType default_value) const
    4041             : {
    4042           5 :   const_single_iterator it = single_map_.find(MEMBER_ID_INVALID);
    4043           5 :   if (it != single_map_.end()) {
    4044           3 :     return serialize_single_value(ser, it->second);
    4045             :   }
    4046             : 
    4047             :   // No data stored. Use default value.
    4048           2 :   set_default_basic_value(default_value);
    4049           2 :   return ser << default_value;
    4050             : }
    4051             : 
    4052         202 : bool DynamicDataImpl::DataContainer::serialized_size_enum(const DCPS::Encoding& encoding,
    4053             :   size_t& size, const DDS::DynamicType_var& enum_type) const
    4054             : {
    4055         202 :   DDS::TypeDescriptor_var enum_td;
    4056         202 :   if (enum_type->get_descriptor(enum_td) != DDS::RETCODE_OK) {
    4057           0 :     return false;
    4058             :   }
    4059         202 :   const CORBA::ULong bit_bound = enum_td->bound()[0];
    4060         202 :   if (bit_bound >= 1 && bit_bound <= 8) {
    4061           0 :     primitive_serialized_size_int8(encoding, size);
    4062           0 :     return true;
    4063         202 :   } else if (bit_bound >= 9 && bit_bound <= 16) {
    4064           0 :     return primitive_serialized_size(encoding, size, CORBA::Short());
    4065         202 :   } else if (bit_bound >= 17 && bit_bound <= 32) {
    4066         202 :     return primitive_serialized_size(encoding, size, CORBA::Long());
    4067             :   }
    4068           0 :   return false;
    4069         202 : }
    4070             : 
    4071           1 : bool DynamicDataImpl::DataContainer::serialize_enum_default_value(DCPS::Serializer& ser,
    4072             :   const DDS::DynamicType_var& enum_type) const
    4073             : {
    4074             :   // The first enumerator is used as the enum's default value (Table 9).
    4075           1 :   DDS::DynamicTypeMember_var first_dtm;
    4076           1 :   if (enum_type->get_member_by_index(first_dtm, 0) != DDS::RETCODE_OK) {
    4077           0 :     return false;
    4078             :   }
    4079           1 :   DDS::MemberDescriptor_var first_md;
    4080           1 :   if (first_dtm->get_descriptor(first_md) != DDS::RETCODE_OK) {
    4081           0 :     return false;
    4082             :   }
    4083           1 :   DDS::TypeDescriptor_var descriptor;
    4084           1 :   if (enum_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
    4085           0 :     return false;
    4086             :   }
    4087           1 :   const CORBA::ULong bit_bound = descriptor->bound()[0];
    4088             : 
    4089           1 :   if (bit_bound >= 1 && bit_bound <= 8) {
    4090           0 :     return ser << static_cast<CORBA::Int8>(first_md->id());
    4091           1 :   } else if (bit_bound >= 9 && bit_bound <= 16) {
    4092           0 :     return ser << static_cast<CORBA::Short>(first_md->id());
    4093           1 :   } else if (bit_bound >= 17 && bit_bound <= 32) {
    4094           1 :     return ser << static_cast<CORBA::Long>(first_md->id());
    4095             :   }
    4096           0 :   return false;
    4097           1 : }
    4098             : 
    4099           0 : bool DynamicDataImpl::DataContainer::serialize_enum_value(DCPS::Serializer& ser) const
    4100             : {
    4101           0 :   const_single_iterator it = single_map_.find(MEMBER_ID_INVALID);
    4102           0 :   if (it != single_map_.end()) {
    4103           0 :     return serialize_single_value(ser, it->second);
    4104             :   }
    4105           0 :   return serialize_enum_default_value(ser, type_);
    4106             : }
    4107             : 
    4108           0 : bool DynamicDataImpl::DataContainer::serialized_size_bitmask(const DCPS::Encoding& encoding,
    4109             :   size_t& size, const DDS::DynamicType_var& bitmask_type) const
    4110             : {
    4111           0 :   DDS::TypeDescriptor_var bitmask_td;
    4112           0 :   if (bitmask_type->get_descriptor(bitmask_td) != DDS::RETCODE_OK) {
    4113           0 :     return false;
    4114             :   }
    4115           0 :   const CORBA::ULong bit_bound = bitmask_td->bound()[0];
    4116           0 :   if (bit_bound >= 1 && bit_bound <= 8) {
    4117           0 :     primitive_serialized_size_uint8(encoding, size);
    4118           0 :     return true;
    4119           0 :   } else if (bit_bound >= 9 && bit_bound <= 16) {
    4120           0 :     return primitive_serialized_size(encoding, size, CORBA::UShort());
    4121           0 :   } else if (bit_bound >= 17 && bit_bound <= 32) {
    4122           0 :     return primitive_serialized_size(encoding, size, CORBA::ULong());
    4123           0 :   } else if (bit_bound >= 33 && bit_bound <= 64) {
    4124           0 :     return primitive_serialized_size(encoding, size, CORBA::ULongLong());
    4125             :   }
    4126           0 :   return false;
    4127           0 : }
    4128             : 
    4129           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_default_value(DCPS::Serializer& ser,
    4130             :   const DDS::DynamicType_var& bitmask_type) const
    4131             : {
    4132           0 :   DDS::TypeDescriptor_var descriptor;
    4133           0 :   if (bitmask_type->get_descriptor(descriptor) != DDS::RETCODE_OK) {
    4134           0 :     return false;
    4135             :   }
    4136           0 :   const CORBA::ULong bit_bound = descriptor->bound()[0];
    4137             : 
    4138             :   // Table 9 doesn't mention default value for bitmask. Use 0 as default here.
    4139           0 :   if (bit_bound >= 1 && bit_bound <= 8) {
    4140           0 :     return ser << static_cast<CORBA::UInt8>(0);
    4141           0 :   } else if (bit_bound >= 9 && bit_bound <= 16) {
    4142           0 :     return ser << static_cast<CORBA::UShort>(0);
    4143           0 :   } else if (bit_bound >= 17 && bit_bound <= 32) {
    4144           0 :     return ser << static_cast<CORBA::ULong>(0);
    4145           0 :   } else if (bit_bound >= 33 && bit_bound <= 64) {
    4146           0 :     return ser << static_cast<CORBA::ULongLong>(0);
    4147             :   }
    4148           0 :   return false;
    4149           0 : }
    4150             : 
    4151           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_value(DCPS::Serializer& ser) const
    4152             : {
    4153           0 :   const_single_iterator it = single_map_.find(MEMBER_ID_INVALID);
    4154           0 :   if (it != single_map_.end()) {
    4155           0 :     return serialize_single_value(ser, it->second);
    4156             :   }
    4157           0 :   return serialize_bitmask_default_value(ser, type_);
    4158             : }
    4159             : 
    4160           0 : bool DynamicDataImpl::DataContainer::reconstruct_string_value(CORBA::Char* str) const
    4161             : {
    4162           0 :   const CORBA::ULong bound = type_desc_->bound()[0];
    4163           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4164             :     CORBA::ULong index;
    4165           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4166           0 :       return false;
    4167             :     }
    4168           0 :     str[index] = it->second.get<ACE_OutputCDR::from_char>().val_;
    4169             :   }
    4170           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4171             :     CORBA::ULong index;
    4172           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4173           0 :       return false;
    4174             :     }
    4175             :     // The DynamicData object for this character may not contain any data.
    4176             :     // Use default value for character if it is the case.
    4177           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4178           0 :     if (!elem_dd) {
    4179           0 :       return false;
    4180             :     }
    4181           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4182           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4183           0 :       str[index] = elem_it->second.get<ACE_OutputCDR::from_char>().val_;
    4184             :     } else {
    4185           0 :       ACE_OutputCDR::from_char from_char('\0');
    4186           0 :       set_default_basic_value(from_char);
    4187           0 :       str[index] = from_char.val_;
    4188             :     }
    4189             :   }
    4190           0 :   return true;
    4191             : }
    4192             : 
    4193           0 : bool DynamicDataImpl::DataContainer::serialized_size_string(const DCPS::Encoding& encoding,
    4194             :                                                             size_t& size) const
    4195             : {
    4196           0 :   const bool is_empty = single_map_.empty() && complex_map_.empty();
    4197           0 :   if (!is_empty) {
    4198             :     CORBA::ULong largest_index;
    4199           0 :     if (!get_largest_index_basic(largest_index)) {
    4200           0 :       return false;
    4201             :     }
    4202           0 :     primitive_serialized_size_ulong(encoding, size);
    4203           0 :     size += largest_index + 2; // Include null
    4204             :   } else {
    4205             :     // Use default value for string, i.e., empty string.
    4206           0 :     primitive_serialized_size_ulong(encoding, size);
    4207           0 :     size += 1; // For the null termination
    4208             :   }
    4209           0 :   return true;
    4210             : }
    4211             : 
    4212           0 : bool DynamicDataImpl::DataContainer::serialize_string_value(DCPS::Serializer& ser) const
    4213             : {
    4214           0 :   char* str = 0;
    4215           0 :   return data_->read_basic_value(str) && (ser << str);
    4216             : }
    4217             : 
    4218             : #ifdef DDS_HAS_WCHAR
    4219           0 : bool DynamicDataImpl::DataContainer::reconstruct_wstring_value(CORBA::WChar* wstr) const
    4220             : {
    4221           0 :   const CORBA::ULong bound = type_desc_->bound()[0];
    4222           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4223             :     CORBA::ULong index;
    4224           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4225           0 :       return false;
    4226             :     }
    4227           0 :     wstr[index] = it->second.get<ACE_OutputCDR::from_wchar>().val_;
    4228             :   }
    4229           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4230             :     CORBA::ULong index;
    4231           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4232           0 :       return false;
    4233             :     }
    4234           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4235           0 :     if (!elem_dd) {
    4236           0 :       return false;
    4237             :     }
    4238           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4239           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4240           0 :       wstr[index] = elem_it->second.get<ACE_OutputCDR::from_wchar>().val_;
    4241             :     } else {
    4242           0 :       ACE_OutputCDR::from_wchar from_wchar('\0');
    4243           0 :       set_default_basic_value(from_wchar);
    4244           0 :       wstr[index] = from_wchar.val_;
    4245             :     }
    4246             :   }
    4247           0 :   return true;
    4248             : }
    4249             : 
    4250           0 : bool DynamicDataImpl::DataContainer::serialized_size_wstring(const DCPS::Encoding& encoding,
    4251             :                                                              size_t& size) const
    4252             : {
    4253           0 :   const bool is_empty = single_map_.empty() && complex_map_.empty();
    4254           0 :   if (!is_empty) {
    4255             :     CORBA::ULong largest_index;
    4256           0 :     if (!get_largest_index_basic(largest_index)) {
    4257           0 :       return false;
    4258             :     }
    4259           0 :     primitive_serialized_size_ulong(encoding, size);
    4260           0 :     size += (largest_index + 1) * DCPS::char16_cdr_size; // Not include null termination
    4261             :   } else {
    4262             :     // Only need length
    4263           0 :     primitive_serialized_size_ulong(encoding, size);
    4264             :   }
    4265           0 :   return true;
    4266             : }
    4267             : 
    4268           0 : bool DynamicDataImpl::DataContainer::serialize_wstring_value(DCPS::Serializer& ser) const
    4269             : {
    4270           0 :   CORBA::WChar* wstr = 0;
    4271           0 :   return data_->read_basic_value(wstr) && (ser << wstr);
    4272             : }
    4273             : #endif
    4274             : 
    4275          11 : void DynamicDataImpl::DataContainer::serialized_size_primitive_sequence(const DCPS::Encoding& encoding,
    4276             :   size_t& size, TypeKind elem_tk, CORBA::ULong length) const
    4277             : {
    4278          11 :   switch (elem_tk) {
    4279           2 :   case TK_INT32:
    4280           2 :     primitive_serialized_size_ulong(encoding, size);
    4281           2 :     if (length == 0) {
    4282           2 :       return;
    4283             :     }
    4284           0 :     primitive_serialized_size(encoding, size, CORBA::Long(), length);
    4285           0 :     return;
    4286           5 :   case TK_UINT32:
    4287           5 :     primitive_serialized_size_ulong(encoding, size);
    4288           5 :     if (length == 0) {
    4289           2 :       return;
    4290             :     }
    4291           3 :     primitive_serialized_size(encoding, size, CORBA::ULong(), length);
    4292           3 :     return;
    4293           0 :   case TK_INT8:
    4294           0 :     primitive_serialized_size_ulong(encoding, size);
    4295           0 :     if (length == 0) {
    4296           0 :       return;
    4297             :     }
    4298           0 :     primitive_serialized_size_int8(encoding, size, length);
    4299           0 :     return;
    4300           0 :   case TK_UINT8:
    4301           0 :     primitive_serialized_size_ulong(encoding, size);
    4302           0 :     if (length == 0) {
    4303           0 :       return;
    4304             :     }
    4305           0 :     primitive_serialized_size_uint8(encoding, size, length);
    4306           0 :     return;
    4307           0 :   case TK_INT16:
    4308           0 :     primitive_serialized_size_ulong(encoding, size);
    4309           0 :     if (length == 0) {
    4310           0 :       return;
    4311             :     }
    4312           0 :     primitive_serialized_size(encoding, size, CORBA::Short(), length);
    4313           0 :     return;
    4314           0 :   case TK_UINT16:
    4315           0 :     primitive_serialized_size_ulong(encoding, size);
    4316           0 :     if (length == 0) {
    4317           0 :       return;
    4318             :     }
    4319           0 :     primitive_serialized_size(encoding, size, CORBA::UShort(), length);
    4320           0 :     return;
    4321           0 :   case TK_INT64:
    4322           0 :     primitive_serialized_size_ulong(encoding, size);
    4323           0 :     if (length == 0) {
    4324           0 :       return;
    4325             :     }
    4326           0 :     primitive_serialized_size(encoding, size, CORBA::LongLong(), length);
    4327           0 :     return;
    4328           0 :   case TK_UINT64:
    4329           0 :     primitive_serialized_size_ulong(encoding, size);
    4330           0 :     if (length == 0) {
    4331           0 :       return;
    4332             :     }
    4333           0 :     primitive_serialized_size(encoding, size, CORBA::ULongLong(), length);
    4334           0 :     return;
    4335           2 :   case TK_FLOAT32:
    4336           2 :     primitive_serialized_size_ulong(encoding, size);
    4337           2 :     if (length == 0) {
    4338           2 :       return;
    4339             :     }
    4340           0 :     primitive_serialized_size(encoding, size, CORBA::Float(), length);
    4341           0 :     return;
    4342           0 :   case TK_FLOAT64:
    4343           0 :     primitive_serialized_size_ulong(encoding, size);
    4344           0 :     if (length == 0) {
    4345           0 :       return;
    4346             :     }
    4347           0 :     primitive_serialized_size(encoding, size, CORBA::Double(), length);
    4348           0 :     return;
    4349           0 :   case TK_FLOAT128:
    4350           0 :     primitive_serialized_size_ulong(encoding, size);
    4351           0 :     if (length == 0) {
    4352           0 :       return;
    4353             :     }
    4354           0 :     primitive_serialized_size(encoding, size, CORBA::LongDouble(), length);
    4355           0 :     return;
    4356           0 :   case TK_CHAR8:
    4357           0 :     primitive_serialized_size_ulong(encoding, size);
    4358           0 :     if (length == 0) {
    4359           0 :       return;
    4360             :     }
    4361           0 :     primitive_serialized_size_char(encoding, size, length);
    4362           0 :     return;
    4363             : #ifdef DDS_HAS_WCHAR
    4364           0 :   case TK_CHAR16:
    4365           0 :     primitive_serialized_size_ulong(encoding, size);
    4366           0 :     if (length == 0) {
    4367           0 :       return;
    4368             :     }
    4369           0 :     primitive_serialized_size_wchar(encoding, size, length);
    4370           0 :     return;
    4371             : #endif
    4372           2 :   case TK_BYTE:
    4373           2 :     primitive_serialized_size_ulong(encoding, size);
    4374           2 :     if (length == 0) {
    4375           2 :       return;
    4376             :     }
    4377           0 :     primitive_serialized_size_octet(encoding, size, length);
    4378           0 :     return;
    4379           0 :   case TK_BOOLEAN:
    4380           0 :     primitive_serialized_size_ulong(encoding, size);
    4381           0 :     if (length == 0) {
    4382           0 :       return;
    4383             :     }
    4384           0 :     primitive_serialized_size_boolean(encoding, size, length);
    4385           0 :     return;
    4386             :   }
    4387             : }
    4388             : 
    4389             : // Group of functions to set default value for a basic type (Table 9).
    4390             : // When MemberDescriptor::default_value is fully supported, it would
    4391             : // have precedence over these default values.
    4392         116 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::Long& value) const
    4393             : {
    4394         116 :   value = 0;
    4395         116 : }
    4396             : 
    4397          28 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::ULong& value) const
    4398             : {
    4399          28 :   value = 0;
    4400          28 : }
    4401             : 
    4402          24 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_int8& value) const
    4403             : {
    4404          24 :   value.val_ = 0;
    4405          24 : }
    4406             : 
    4407           8 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_uint8& value) const
    4408             : {
    4409           8 :   value.val_ = 0;
    4410           8 : }
    4411             : 
    4412          19 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::Short& value) const
    4413             : {
    4414          19 :   value = 0;
    4415          19 : }
    4416             : 
    4417          10 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::UShort& value) const
    4418             : {
    4419          10 :   value = 0;
    4420          10 : }
    4421             : 
    4422          22 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::LongLong& value) const
    4423             : {
    4424          22 :   value = 0;
    4425          22 : }
    4426             : 
    4427          14 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::ULongLong& value) const
    4428             : {
    4429          14 :   value = 0;
    4430          14 : }
    4431             : 
    4432          24 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::Float& value) const
    4433             : {
    4434          24 :   value = 0;
    4435          24 : }
    4436             : 
    4437          26 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::Double& value) const
    4438             : {
    4439          26 :   value = 0;
    4440          26 : }
    4441             : 
    4442          27 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::LongDouble& value) const
    4443             : {
    4444             : #if ACE_SIZEOF_LONG_DOUBLE == 16
    4445          27 :   value = 0;
    4446             : #else
    4447             :   ACE_OS::memset(value.ld, 0, 16);
    4448             : #endif
    4449          27 : }
    4450             : 
    4451          31 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_char& value) const
    4452             : {
    4453          31 :   value.val_ = '\0';
    4454          31 : }
    4455             : 
    4456           5 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_octet& value) const
    4457             : {
    4458           5 :   value.val_ = 0x00;
    4459           5 : }
    4460             : 
    4461           0 : void DynamicDataImpl::DataContainer::set_default_basic_value(const char*& value) const
    4462             : {
    4463           0 :   value = "";
    4464           0 : }
    4465             : 
    4466          34 : void DynamicDataImpl::DataContainer::set_default_basic_value(char*& value) const
    4467             : {
    4468          34 :   CORBA::string_free(value);
    4469          34 :   value = CORBA::string_dup("");
    4470          34 : }
    4471             : 
    4472           7 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_boolean& value) const
    4473             : {
    4474           7 :   value.val_ = false;
    4475           7 : }
    4476             : 
    4477             : #ifdef DDS_HAS_WCHAR
    4478          32 : void DynamicDataImpl::DataContainer::set_default_basic_value(ACE_OutputCDR::from_wchar& value) const
    4479             : {
    4480          32 :   value.val_ = '\0';
    4481          32 : }
    4482             : 
    4483           0 : void DynamicDataImpl::DataContainer::set_default_basic_value(const CORBA::WChar*& value) const
    4484             : {
    4485           0 :   value = L"";
    4486           0 : }
    4487             : 
    4488          36 : void DynamicDataImpl::DataContainer::set_default_basic_value(CORBA::WChar*& value) const
    4489             : {
    4490          36 :   CORBA::wstring_free(value);
    4491          36 :   value = CORBA::wstring_dup(L"");
    4492          36 : }
    4493             : #endif
    4494             : 
    4495           9 : bool DynamicDataImpl::DataContainer::set_default_enum_value(const DDS::DynamicType_var& enum_type,
    4496             :                                                             CORBA::Long& value) const
    4497             : {
    4498             :   // Default enum value is the first enumerator.
    4499           9 :   DDS::DynamicTypeMember_var first_dtm;
    4500           9 :   if (enum_type->get_member_by_index(first_dtm, 0) != DDS::RETCODE_OK) {
    4501           0 :     return false;
    4502             :   }
    4503           9 :   DDS::MemberDescriptor_var first_md;
    4504           9 :   if (first_dtm->get_descriptor(first_md) != DDS::RETCODE_OK) {
    4505           0 :     return false;
    4506             :   }
    4507           9 :   value = static_cast<CORBA::Long>(first_md->id());
    4508           9 :   return true;
    4509           9 : }
    4510             : 
    4511           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_value(ACE_OutputCDR::from_uint8& value) const
    4512             : {
    4513           0 :   value.val_ = 0;
    4514           0 : }
    4515             : 
    4516           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_value(CORBA::UShort& value) const
    4517             : {
    4518           0 :   value = 0;
    4519           0 : }
    4520             : 
    4521           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_value(CORBA::ULong& value) const
    4522             : {
    4523           0 :   value = 0;
    4524           0 : }
    4525             : 
    4526           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_value(CORBA::ULongLong& value) const
    4527             : {
    4528           0 :   value = 0;
    4529           0 : }
    4530             : 
    4531             : template<typename Type>
    4532           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_value(Type&) const
    4533             : {
    4534             :   // No-op. Should never be called.
    4535           0 : }
    4536             : 
    4537           3 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::Int8Seq& collection) const
    4538             : {
    4539           9 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4540           6 :     ACE_OutputCDR::from_int8 value(0);
    4541           6 :     set_default_basic_value(value);
    4542           6 :     collection[i] = value.val_;
    4543             :   }
    4544           3 : }
    4545             : 
    4546           0 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::UInt8Seq& collection) const
    4547             : {
    4548           0 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4549           0 :     ACE_OutputCDR::from_uint8 value(0);
    4550           0 :     set_default_basic_value(value);
    4551           0 :     collection[i] = value.val_;
    4552             :   }
    4553           0 : }
    4554             : 
    4555           0 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::CharSeq& collection) const
    4556             : {
    4557           0 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4558           0 :     ACE_OutputCDR::from_char value('\0');
    4559           0 :     set_default_basic_value(value);
    4560           0 :     collection[i] = value.val_;
    4561             :   }
    4562           0 : }
    4563             : 
    4564           1 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::ByteSeq& collection) const
    4565             : {
    4566           1 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4567           0 :     ACE_OutputCDR::from_octet value(0x00);
    4568           0 :     set_default_basic_value(value);
    4569           0 :     collection[i] = value.val_;
    4570             :   }
    4571           1 : }
    4572             : 
    4573           0 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::BooleanSeq& collection) const
    4574             : {
    4575           0 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4576           0 :     ACE_OutputCDR::from_boolean value(false);
    4577           0 :     set_default_basic_value(value);
    4578           0 :     collection[i] = value.val_;
    4579             :   }
    4580           0 : }
    4581             : 
    4582             : #ifdef DDS_HAS_WCHAR
    4583           0 : void DynamicDataImpl::DataContainer::set_default_primitive_values(DDS::WcharSeq& collection) const
    4584             : {
    4585           0 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4586           0 :     ACE_OutputCDR::from_wchar value(0);
    4587           0 :     set_default_basic_value(value);
    4588           0 :     collection[i] = value.val_;
    4589             :   }
    4590           0 : }
    4591             : #endif
    4592             : 
    4593             : template<typename CollectionType>
    4594          10 : void DynamicDataImpl::DataContainer::set_default_primitive_values(CollectionType& collection) const
    4595             : {
    4596          24 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    4597          14 :     set_default_basic_value(collection[i]);
    4598             :   }
    4599          10 : }
    4600             : 
    4601             : // Set elements for a sequence of primitive type
    4602             : template<>
    4603           0 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::BooleanSeq& collection,
    4604             :   CORBA::ULong bound, const ACE_OutputCDR::from_boolean& /*elem_tag*/) const
    4605             : {
    4606           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4607             :     CORBA::ULong index;
    4608           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4609           0 :       return false;
    4610             :     }
    4611           0 :     collection[index] = it->second.get<ACE_OutputCDR::from_boolean>().val_;
    4612             :   }
    4613             : 
    4614           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4615             :     CORBA::ULong index;
    4616           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4617           0 :       return false;
    4618             :     }
    4619           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4620           0 :     if (!elem_dd) {
    4621           0 :       return false;
    4622             :     }
    4623           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4624           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4625           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_boolean>().val_;
    4626             :     }
    4627             :   }
    4628           0 :   return true;
    4629             : }
    4630             : 
    4631             : template<>
    4632           1 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::ByteSeq& collection,
    4633             :   CORBA::ULong bound, const ACE_OutputCDR::from_octet& /*elem_tag*/) const
    4634             : {
    4635           1 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4636             :     CORBA::ULong index;
    4637           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4638           0 :       return false;
    4639             :     }
    4640           0 :     collection[index] = it->second.get<ACE_OutputCDR::from_octet>().val_;
    4641             :   }
    4642             : 
    4643           1 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4644             :     CORBA::ULong index;
    4645           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4646           0 :       return false;
    4647             :     }
    4648           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4649           0 :     if (!elem_dd) {
    4650           0 :       return false;
    4651             :     }
    4652           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4653           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4654           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_octet>().val_;
    4655             :     }
    4656             :   }
    4657           1 :   return true;
    4658             : }
    4659             : 
    4660             : template<>
    4661           3 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::Int8Seq& collection,
    4662             :   CORBA::ULong bound, const ACE_OutputCDR::from_int8& /*elem_tag*/) const
    4663             : {
    4664           9 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4665             :     CORBA::ULong index;
    4666           6 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4667           0 :       return false;
    4668             :     }
    4669           6 :     collection[index] = it->second.get<ACE_OutputCDR::from_int8>().val_;
    4670             :   }
    4671             : 
    4672           3 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4673             :     CORBA::ULong index;
    4674           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4675           0 :       return false;
    4676             :     }
    4677           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4678           0 :     if (!elem_dd) {
    4679           0 :       return false;
    4680             :     }
    4681           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4682           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4683           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_int8>().val_;
    4684             :     }
    4685             :   }
    4686           3 :   return true;
    4687             : }
    4688             : 
    4689             : template<>
    4690           0 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::UInt8Seq& collection,
    4691             :   CORBA::ULong bound, const ACE_OutputCDR::from_uint8& /*elem_tag*/) const
    4692             : {
    4693           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4694             :     CORBA::ULong index;
    4695           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4696           0 :       return false;
    4697             :     }
    4698           0 :     collection[index] = it->second.get<ACE_OutputCDR::from_uint8>().val_;
    4699             :   }
    4700             : 
    4701           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4702             :     CORBA::ULong index;
    4703           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4704           0 :       return false;
    4705             :     }
    4706           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4707           0 :     if (!elem_dd) {
    4708           0 :       return false;
    4709             :     }
    4710           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4711           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4712           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_uint8>().val_;
    4713             :     }
    4714             :   }
    4715           0 :   return true;
    4716             : }
    4717             : 
    4718             : template<>
    4719           0 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::CharSeq& collection,
    4720             :   CORBA::ULong bound, const ACE_OutputCDR::from_char& /*elem_tag*/) const
    4721             : {
    4722           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4723             :     CORBA::ULong index;
    4724           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4725           0 :       return false;
    4726             :     }
    4727           0 :     collection[index] = it->second.get<ACE_OutputCDR::from_char>().val_;
    4728             :   }
    4729             : 
    4730           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4731             :     CORBA::ULong index;
    4732           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4733           0 :       return false;
    4734             :     }
    4735           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4736           0 :     if (!elem_dd) {
    4737           0 :       return false;
    4738             :     }
    4739           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4740           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4741           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_char>().val_;
    4742             :     }
    4743             :   }
    4744           0 :   return true;
    4745             : }
    4746             : 
    4747             : #ifdef DDS_HAS_WCHAR
    4748             : template<>
    4749           0 : bool DynamicDataImpl::DataContainer::set_primitive_values(DDS::WcharSeq& collection,
    4750             :   CORBA::ULong bound, const ACE_OutputCDR::from_wchar& /*elem_tag*/) const
    4751             : {
    4752           0 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4753             :     CORBA::ULong index;
    4754           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4755           0 :       return false;
    4756             :     }
    4757           0 :     collection[index] = it->second.get<ACE_OutputCDR::from_wchar>().val_;
    4758             :   }
    4759             : 
    4760           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4761             :     CORBA::ULong index;
    4762           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4763           0 :       return false;
    4764             :     }
    4765           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4766           0 :     if (!elem_dd) {
    4767           0 :       return false;
    4768             :     }
    4769           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4770           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4771           0 :       collection[index] = elem_it->second.get<ACE_OutputCDR::from_wchar>().val_;
    4772             :     }
    4773             :   }
    4774           0 :   return true;
    4775             : }
    4776             : #endif
    4777             : 
    4778             : template<typename ElementType, typename CollectionType>
    4779          14 : bool DynamicDataImpl::DataContainer::set_primitive_values(CollectionType& collection,
    4780             :   CORBA::ULong bound, const ElementType& /*elem_tag*/) const
    4781             : {
    4782          34 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    4783             :     CORBA::ULong index;
    4784          20 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4785           0 :       return false;
    4786             :     }
    4787          20 :     collection[index] = it->second.get<ElementType>();
    4788             :   }
    4789             : 
    4790          14 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    4791             :     CORBA::ULong index;
    4792           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    4793           0 :       return false;
    4794             :     }
    4795           0 :     const DynamicDataImpl* elem_dd = dynamic_cast<const DynamicDataImpl*>(it->second.in());
    4796           0 :     if (!elem_dd) {
    4797           0 :       return false;
    4798             :     }
    4799           0 :     const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID);
    4800           0 :     if (elem_it != elem_dd->container_.single_map_.end()) {
    4801           0 :       collection[index] = elem_it->second.get<ElementType>();
    4802             :     }
    4803             :   }
    4804          14 :   return true;
    4805             : }
    4806             : 
    4807             : // Helper function to reconstruct a sequence or array of primitive type.
    4808             : // For array, @a size is equal to @a bound.
    4809             : template<typename ElementType, typename CollectionType>
    4810          14 : bool DynamicDataImpl::DataContainer::reconstruct_primitive_collection(
    4811             :   CollectionType& collection, CORBA::ULong size, CORBA::ULong bound, const ElementType& elem_tag) const
    4812             : {
    4813          14 :   collection.length(size);
    4814          14 :   set_default_primitive_values(collection);
    4815          14 :   return set_primitive_values(collection, bound, elem_tag);
    4816             : }
    4817             : 
    4818             : // Reconstruct the primitive sequence written by the user (elements that are not
    4819             : // explicitly written are set to default value of the corresponding type).
    4820             : // Then serialize the constructed sequence.
    4821           7 : bool DynamicDataImpl::DataContainer::serialize_primitive_sequence(DCPS::Serializer& ser,
    4822             :   TypeKind elem_tk, CORBA::ULong size, CORBA::ULong bound) const
    4823             : {
    4824           7 :   switch (elem_tk) {
    4825           1 :   case TK_INT32: {
    4826           1 :     DDS::Int32Seq int32seq;
    4827           2 :     return reconstruct_primitive_collection(int32seq, size, bound, CORBA::Long()) &&
    4828           1 :       (ser << int32seq);
    4829           1 :   }
    4830           4 :   case TK_UINT32: {
    4831           4 :     DDS::UInt32Seq uint32seq;
    4832           8 :     return reconstruct_primitive_collection(uint32seq, size, bound, CORBA::ULong()) &&
    4833           4 :       (ser << uint32seq);
    4834           4 :   }
    4835           0 :   case TK_INT8: {
    4836           0 :     DDS::Int8Seq int8seq;
    4837           0 :     return reconstruct_primitive_collection(int8seq, size, bound, ACE_OutputCDR::from_int8(0)) &&
    4838           0 :       (ser << int8seq);
    4839           0 :   }
    4840           0 :   case TK_UINT8: {
    4841           0 :     DDS::UInt8Seq uint8seq;
    4842           0 :     return reconstruct_primitive_collection(uint8seq, size, bound, ACE_OutputCDR::from_uint8(0)) &&
    4843           0 :       (ser << uint8seq);
    4844           0 :   }
    4845           0 :   case TK_INT16: {
    4846           0 :     DDS::Int16Seq int16seq;
    4847           0 :     return reconstruct_primitive_collection(int16seq, size, bound, CORBA::Short()) &&
    4848           0 :       (ser << int16seq);
    4849           0 :   }
    4850           0 :   case TK_UINT16: {
    4851           0 :     DDS::UInt16Seq uint16seq;
    4852           0 :     return reconstruct_primitive_collection(uint16seq, size, bound, CORBA::UShort()) &&
    4853           0 :       (ser << uint16seq);
    4854           0 :   }
    4855           0 :   case TK_INT64: {
    4856           0 :     DDS::Int64Seq int64seq;
    4857           0 :     return reconstruct_primitive_collection(int64seq, size, bound, CORBA::LongLong()) &&
    4858           0 :       (ser << int64seq);
    4859           0 :   }
    4860           0 :   case TK_UINT64: {
    4861           0 :     DDS::UInt64Seq uint64seq;
    4862           0 :     return reconstruct_primitive_collection(uint64seq, size, bound, CORBA::ULongLong()) &&
    4863           0 :       (ser << uint64seq);
    4864           0 :   }
    4865           1 :   case TK_FLOAT32: {
    4866           1 :     DDS::Float32Seq float32seq;
    4867           2 :     return reconstruct_primitive_collection(float32seq, size, bound, CORBA::Float()) &&
    4868           1 :       (ser << float32seq);
    4869           1 :   }
    4870           0 :   case TK_FLOAT64: {
    4871           0 :     DDS::Float64Seq float64seq;
    4872           0 :     return reconstruct_primitive_collection(float64seq, size, bound, CORBA::Double()) &&
    4873           0 :       (ser << float64seq);
    4874           0 :   }
    4875           0 :   case TK_FLOAT128: {
    4876           0 :     DDS::Float128Seq float128seq;
    4877           0 :     return reconstruct_primitive_collection(float128seq, size, bound, CORBA::LongDouble()) &&
    4878           0 :       (ser << float128seq);
    4879           0 :   }
    4880           0 :   case TK_CHAR8: {
    4881           0 :     DDS::CharSeq charseq;
    4882           0 :     return reconstruct_primitive_collection(charseq, size, bound, ACE_OutputCDR::from_char('\0')) &&
    4883           0 :       (ser << charseq);
    4884           0 :   }
    4885             : #ifdef DDS_HAS_WCHAR
    4886           0 :   case TK_CHAR16: {
    4887           0 :     DDS::WcharSeq wcharseq;
    4888           0 :     return reconstruct_primitive_collection(wcharseq, size, bound, ACE_OutputCDR::from_wchar(0)) &&
    4889           0 :       (ser << wcharseq);
    4890           0 :   }
    4891             : #endif
    4892           1 :   case TK_BYTE: {
    4893           1 :     DDS::ByteSeq byteseq;
    4894           2 :     return reconstruct_primitive_collection(byteseq, size, bound, ACE_OutputCDR::from_octet(0x00)) &&
    4895           1 :       (ser << byteseq);
    4896           1 :   }
    4897           0 :   case TK_BOOLEAN: {
    4898           0 :     DDS::BooleanSeq boolseq;
    4899           0 :     return reconstruct_primitive_collection(boolseq, size, bound, ACE_OutputCDR::from_boolean(false)) &&
    4900           0 :       (ser << boolseq);
    4901           0 :   }
    4902             :   }
    4903           0 :   return false;
    4904             : }
    4905             : 
    4906             : // Unlike primitive types, string and wstring are not as easy to reconstruct since each
    4907             : // element string may need to be reconstructed individually. Instead, we serialize
    4908             : // the element strings one by one directly.
    4909          11 : void DynamicDataImpl::DataContainer::serialized_size_string_common(const DCPS::Encoding& encoding,
    4910             :   size_t& size, const char* str) const
    4911             : {
    4912          11 :   primitive_serialized_size_ulong(encoding, size);
    4913          11 :   if (str) {
    4914          11 :     size += ACE_OS::strlen(str) + 1; // Include null termination
    4915             :   }
    4916          11 : }
    4917             : 
    4918             : #ifdef DDS_HAS_WCHAR
    4919          11 : void DynamicDataImpl::DataContainer::serialized_size_string_common(const DCPS::Encoding& encoding,
    4920             :   size_t& size, const CORBA::WChar* wstr) const
    4921             : {
    4922          11 :   primitive_serialized_size_ulong(encoding, size);
    4923          11 :   if (wstr) {
    4924          11 :     size += ACE_OS::strlen(wstr) * DCPS::char16_cdr_size; // Not include null termination
    4925             :   }
    4926          11 : }
    4927             : #endif
    4928             : 
    4929          22 : void DynamicDataImpl::DataContainer::serialized_size_string_common(const DCPS::Encoding& encoding,
    4930             :   size_t& size, const SingleValue& sv) const
    4931             : {
    4932          22 :   if (sv.kind_ == TK_STRING8) {
    4933          11 :     serialized_size_string_common(encoding, size, sv.str_);
    4934             :   }
    4935             : #ifdef DDS_HAS_WCHAR
    4936          11 :   else if (sv.kind_ == TK_STRING16) {
    4937          11 :     serialized_size_string_common(encoding, size, sv.wstr_);
    4938             :   }
    4939             : #endif
    4940          22 : }
    4941             : 
    4942             : template<typename StringType>
    4943           0 : bool DynamicDataImpl::DataContainer::serialized_size_generic_string_collection(
    4944             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    4945             : {
    4946           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    4947           0 :     const DDS::MemberId id = index_to_id[i];
    4948           0 :     if (id != MEMBER_ID_INVALID) {
    4949           0 :       const_single_iterator single_it = single_map_.find(id);
    4950           0 :       if (single_it != single_map_.end()) {
    4951           0 :         serialized_size_string_common(encoding, size, single_it->second);
    4952           0 :       } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) {
    4953           0 :         return false;
    4954             :       }
    4955             :     } else {
    4956             :       StringType default_value;
    4957           0 :       set_default_basic_value(default_value);
    4958           0 :       serialized_size_string_common(encoding, size, default_value);
    4959             :     }
    4960             :   }
    4961           0 :   return true;
    4962             : }
    4963             : 
    4964             : template<typename StringType>
    4965           3 : bool DynamicDataImpl::DataContainer::serialized_size_generic_string_sequence(
    4966             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    4967             : {
    4968           3 :   serialized_size_delimiter(encoding, size);
    4969           3 :   primitive_serialized_size_ulong(encoding, size);
    4970           3 :   if (index_to_id.empty()) {
    4971           3 :     return true;
    4972             :   }
    4973           0 :   return serialized_size_generic_string_collection<StringType>(encoding, size, index_to_id);
    4974             : }
    4975             : 
    4976             : // Serialize the individual elements from a sequence or an array of string (or wstring).
    4977             : template<typename StringType>
    4978           0 : bool DynamicDataImpl::DataContainer::serialize_generic_string_collection(DCPS::Serializer& ser,
    4979             :   const IndexToIdMap& index_to_id) const
    4980             : {
    4981           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    4982           0 :     const DDS::MemberId id = index_to_id[i];
    4983           0 :     if (id != MEMBER_ID_INVALID) {
    4984           0 :       const_single_iterator single_it = single_map_.find(id);
    4985           0 :       if (single_it != single_map_.end()) {
    4986           0 :         if (!serialize_single_value(ser, single_it->second)) {
    4987           0 :           return false;
    4988             :         }
    4989           0 :       } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) {
    4990           0 :         return false;
    4991             :       }
    4992             :     } else { // Not set by the user. Use default value.
    4993             :       StringType default_value;
    4994           0 :       set_default_basic_value(default_value);
    4995           0 :       if (!(ser << default_value)) {
    4996           0 :         return false;
    4997             :       }
    4998             :     }
    4999             :   }
    5000           0 :   return true;
    5001             : }
    5002             : 
    5003             : template<typename StringType>
    5004           1 : bool DynamicDataImpl::DataContainer::serialize_generic_string_sequence(DCPS::Serializer& ser,
    5005             :   CORBA::ULong length, CORBA::ULong bound) const
    5006             : {
    5007           1 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    5008           1 :   if (!get_index_to_id_map(index_to_id, bound)) {
    5009           0 :     return false;
    5010             :   }
    5011             : 
    5012           1 :   const DCPS::Encoding& encoding = ser.encoding();
    5013           1 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5014           1 :     size_t total_size = 0;
    5015           2 :     if (!serialized_size_generic_string_sequence<StringType>(encoding, total_size, index_to_id) ||
    5016           1 :         !ser.write_delimiter(total_size)) {
    5017           0 :       return false;
    5018             :     }
    5019             :   }
    5020           1 :   if (!(ser << length)) {
    5021           0 :     return false;
    5022             :   }
    5023           1 :   if (length == 0) {
    5024           1 :     return true;
    5025             :   }
    5026           0 :   return serialize_generic_string_collection<StringType>(ser, index_to_id);
    5027           1 : }
    5028             : 
    5029             : template<typename ElementType, typename CollectionType>
    5030           4 : bool DynamicDataImpl::DataContainer::set_default_enum_values(CollectionType& collection,
    5031             :   const DDS::DynamicType_var& enum_type) const
    5032             : {
    5033             :   CORBA::Long value;
    5034           4 :   if (!set_default_enum_value(enum_type, value)) {
    5035           0 :     return false;
    5036             :   }
    5037          10 :   for (CORBA::ULong i = 0; i < collection.length(); ++i) {
    5038           6 :     collection[i] = static_cast<ElementType>(value);
    5039             :   }
    5040           4 :   return true;
    5041             : }
    5042             : 
    5043             : template<typename ElementType, typename WrapElementType, typename CollectionType>
    5044           4 : bool DynamicDataImpl::DataContainer::reconstruct_enum_collection(CollectionType& collection,
    5045             :   CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type,
    5046             :   const WrapElementType& elem_tag) const
    5047             : {
    5048           4 :   collection.length(size);
    5049           4 :   if (!set_default_enum_values<ElementType>(collection, enum_type)) {
    5050           0 :     return false;
    5051             :   }
    5052           4 :   return set_primitive_values(collection, bound, elem_tag);
    5053             : }
    5054             : 
    5055             : // Serialize enum sequence represented as int8 sequence
    5056           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence_as_int8s(
    5057             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5058             : {
    5059           0 :   serialized_size_delimiter(encoding, size);
    5060           0 :   primitive_serialized_size_ulong(encoding, size);
    5061           0 :   if (length == 0) {
    5062           0 :     return;
    5063             :   }
    5064           0 :   primitive_serialized_size_int8(encoding, size, length);
    5065             : }
    5066             : 
    5067           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence(
    5068             :   const DCPS::Encoding& encoding, size_t& size, const DDS::Int8Seq& seq) const
    5069             : {
    5070           0 :   serialized_size_enum_sequence_as_int8s(encoding, size, seq.length());
    5071           0 : }
    5072             : 
    5073           0 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser,
    5074             :   const DDS::Int8Seq& enumseq) const
    5075             : {
    5076           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5077           0 :   size_t total_size = 0;
    5078           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5079           0 :     serialized_size_enum_sequence_as_int8s(encoding, total_size, enumseq.length());
    5080           0 :     if (!ser.write_delimiter(total_size)) {
    5081           0 :       return false;
    5082             :     }
    5083             :   }
    5084           0 :   const CORBA::ULong length = enumseq.length();
    5085           0 :   if (!(ser << length)) {
    5086           0 :     return false;
    5087             :   }
    5088           0 :   if (length == 0) {
    5089           0 :     return true;
    5090             :   }
    5091           0 :   return ser.write_int8_array(enumseq.get_buffer(), length);
    5092             : }
    5093             : 
    5094           0 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_int8s(DCPS::Serializer& ser,
    5095             :   CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const
    5096             : {
    5097           0 :   DDS::Int8Seq enumseq;
    5098           0 :   return reconstruct_enum_collection<CORBA::Int8>(enumseq, size, bound, enum_type, ACE_OutputCDR::from_int8(0)) &&
    5099           0 :     serialize_enum_sequence_as_ints_i(ser, enumseq);
    5100           0 : }
    5101             : 
    5102             : // Serialize enum sequence represented as int16 sequence
    5103           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence_as_int16s(
    5104             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5105             : {
    5106           0 :   serialized_size_delimiter(encoding, size);
    5107           0 :   primitive_serialized_size_ulong(encoding, size);
    5108           0 :   if (length == 0) {
    5109           0 :     return;
    5110             :   }
    5111           0 :   primitive_serialized_size(encoding, size, CORBA::Short(), length);
    5112             : }
    5113             : 
    5114           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence(
    5115             :   const DCPS::Encoding& encoding, size_t& size, const DDS::Int16Seq& seq) const
    5116             : {
    5117           0 :   serialized_size_enum_sequence_as_int16s(encoding, size, seq.length());
    5118           0 : }
    5119             : 
    5120           0 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser,
    5121             :   const DDS::Int16Seq& enumseq) const
    5122             : {
    5123           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5124           0 :   size_t total_size = 0;
    5125           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5126           0 :     serialized_size_enum_sequence_as_int16s(encoding, total_size, enumseq.length());
    5127           0 :     if (!ser.write_delimiter(total_size)) {
    5128           0 :       return false;
    5129             :     }
    5130             :   }
    5131           0 :   const CORBA::ULong length = enumseq.length();
    5132           0 :   if (!(ser << length)) {
    5133           0 :     return false;
    5134             :   }
    5135           0 :   if (length == 0) {
    5136           0 :     return true;
    5137             :   }
    5138           0 :   return ser.write_short_array(enumseq.get_buffer(), length);
    5139             : }
    5140             : 
    5141           0 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_int16s(DCPS::Serializer& ser,
    5142             :   CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const
    5143             : {
    5144           0 :   DDS::Int16Seq enumseq;
    5145           0 :   return reconstruct_enum_collection<CORBA::Short>(enumseq, size, bound, enum_type, CORBA::Short()) &&
    5146           0 :     serialize_enum_sequence_as_ints_i(ser, enumseq);
    5147           0 : }
    5148             : 
    5149             : // Serialize enum sequence represented as int32 sequence
    5150          15 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence_as_int32s(
    5151             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5152             : {
    5153          15 :   serialized_size_delimiter(encoding, size);
    5154          15 :   primitive_serialized_size_ulong(encoding, size);
    5155          15 :   if (length == 0) {
    5156           3 :     return;
    5157             :   }
    5158          12 :   primitive_serialized_size(encoding, size, CORBA::Long(), length);
    5159             : }
    5160             : 
    5161           3 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence(
    5162             :   const DCPS::Encoding& encoding, size_t& size, const DDS::Int32Seq& seq) const
    5163             : {
    5164           3 :   serialized_size_enum_sequence_as_int32s(encoding, size, seq.length());
    5165           3 : }
    5166             : 
    5167           7 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser,
    5168             :   const DDS::Int32Seq& enumseq) const
    5169             : {
    5170           7 :   const DCPS::Encoding& encoding = ser.encoding();
    5171           7 :   size_t total_size = 0;
    5172           7 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5173           7 :     serialized_size_enum_sequence_as_int32s(encoding, total_size, enumseq.length());
    5174           7 :     if (!ser.write_delimiter(total_size)) {
    5175           0 :       return false;
    5176             :     }
    5177             :   }
    5178           7 :   const CORBA::ULong length = enumseq.length();
    5179           7 :   if (!(ser << length)) {
    5180           0 :     return false;
    5181             :   }
    5182           7 :   if (length == 0) {
    5183           1 :     return true;
    5184             :   }
    5185           6 :   return ser.write_long_array(enumseq.get_buffer(), length);
    5186             : }
    5187             : 
    5188           4 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence_as_int32s(DCPS::Serializer& ser,
    5189             :   CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const
    5190             : {
    5191           4 :   DDS::Int32Seq enumseq;
    5192           8 :   return reconstruct_enum_collection<CORBA::Long>(enumseq, size, bound, enum_type, CORBA::Long()) &&
    5193           8 :     serialize_enum_sequence_as_ints_i(ser, enumseq);
    5194           4 : }
    5195             : 
    5196           5 : void DynamicDataImpl::DataContainer::serialized_size_enum_sequence(const DCPS::Encoding& encoding,
    5197             :   size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const
    5198             : {
    5199           5 :   if (bitbound >= 1 && bitbound <= 8) {
    5200           0 :     serialized_size_enum_sequence_as_int8s(encoding, size, length);
    5201           5 :   } else if (bitbound >= 9 && bitbound <= 16) {
    5202           0 :     serialized_size_enum_sequence_as_int16s(encoding, size, length);
    5203             :   } else { // From 17 to 32
    5204           5 :     serialized_size_enum_sequence_as_int32s(encoding, size, length);
    5205             :   }
    5206           5 : }
    5207             : 
    5208           4 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence(DCPS::Serializer& ser,
    5209             :   CORBA::ULong size, CORBA::ULong bitbound, CORBA::ULong seqbound,
    5210             :   const DDS::DynamicType_var& enum_type) const
    5211             : {
    5212           4 :   if (bitbound >= 1 && bitbound <= 8) {
    5213           0 :     return serialize_enum_sequence_as_int8s(ser, size, seqbound, enum_type);
    5214           4 :   } else if (bitbound >= 9 && bitbound <= 16) {
    5215           0 :     return serialize_enum_sequence_as_int16s(ser, size, seqbound, enum_type);
    5216           4 :   } else if (bitbound >= 17 && bitbound <= 32) {
    5217           4 :     return serialize_enum_sequence_as_int32s(ser, size, seqbound, enum_type);
    5218             :   }
    5219           0 :   return false;
    5220             : }
    5221             : 
    5222             : template<typename CollectionType>
    5223           0 : void DynamicDataImpl::DataContainer::set_default_bitmask_values(CollectionType& col) const
    5224             : {
    5225             :   // Table 9 doesn't mention default value for bitmask. Use 0 as default here.
    5226           0 :   for (CORBA::ULong i = 0; i < col.length(); ++i) {
    5227           0 :     col[i] = 0;
    5228             :   }
    5229           0 : }
    5230             : 
    5231             : template<typename WrapElementType, typename CollectionType>
    5232           0 : bool DynamicDataImpl::DataContainer::reconstruct_bitmask_collection(CollectionType& collection,
    5233             :   CORBA::ULong size, CORBA::ULong bound, const WrapElementType& elem_tag) const
    5234             : {
    5235           0 :   collection.length(size);
    5236           0 :   set_default_bitmask_values(collection);
    5237           0 :   return set_primitive_values(collection, bound, elem_tag);
    5238             : }
    5239             : 
    5240             : // Bitmask sequence represented as uint8 sequence.
    5241           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence_as_uint8s(
    5242             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5243             : {
    5244           0 :   serialized_size_delimiter(encoding, size);
    5245           0 :   primitive_serialized_size_ulong(encoding, size);
    5246           0 :   if (length == 0) {
    5247           0 :     return;
    5248             :   }
    5249           0 :   primitive_serialized_size_uint8(encoding, size, length);
    5250             : }
    5251             : 
    5252           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding,
    5253             :   size_t& size, const DDS::UInt8Seq& seq) const
    5254             : {
    5255           0 :   serialized_size_bitmask_sequence_as_uint8s(encoding, size, seq.length());
    5256           0 : }
    5257             : 
    5258           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser,
    5259             :   const DDS::UInt8Seq& bitmask_seq) const
    5260             : {
    5261           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5262           0 :   size_t total_size = 0;
    5263           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5264           0 :     serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq);
    5265           0 :     if (!ser.write_delimiter(total_size)) {
    5266           0 :       return false;
    5267             :     }
    5268             :   }
    5269           0 :   const CORBA::ULong length = bitmask_seq.length();
    5270           0 :   if (!(ser << length)) {
    5271           0 :     return false;
    5272             :   }
    5273           0 :   if (length == 0) {
    5274           0 :     return true;
    5275             :   }
    5276           0 :   return ser.write_uint8_array(bitmask_seq.get_buffer(), length);
    5277             : }
    5278             : 
    5279           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uint8s(DCPS::Serializer& ser,
    5280             :   CORBA::ULong size, CORBA::ULong bound) const
    5281             : {
    5282           0 :   DDS::UInt8Seq bitmask_seq;
    5283           0 :   return reconstruct_bitmask_collection(bitmask_seq, size, bound, ACE_OutputCDR::from_uint8(0)) &&
    5284           0 :     serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq);
    5285           0 : }
    5286             : 
    5287             : // Bitmask sequence represented as uint16 sequence
    5288           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence_as_uint16s(
    5289             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5290             : {
    5291           0 :   serialized_size_delimiter(encoding, size);
    5292           0 :   primitive_serialized_size_ulong(encoding, size);
    5293           0 :   if (length == 0) {
    5294           0 :     return;
    5295             :   }
    5296           0 :   primitive_serialized_size(encoding, size, CORBA::UShort(), length);
    5297             : }
    5298             : 
    5299           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding,
    5300             :   size_t& size, const DDS::UInt16Seq& seq) const
    5301             : {
    5302           0 :   serialized_size_bitmask_sequence_as_uint16s(encoding, size, seq.length());
    5303           0 : }
    5304             : 
    5305           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser,
    5306             :   const DDS::UInt16Seq& bitmask_seq) const
    5307             : {
    5308           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5309           0 :   size_t total_size = 0;
    5310           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5311           0 :     serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq);
    5312           0 :     if (!ser.write_delimiter(total_size)) {
    5313           0 :       return false;
    5314             :     }
    5315             :   }
    5316           0 :   const CORBA::ULong length = bitmask_seq.length();
    5317           0 :   if (!(ser << length)) {
    5318           0 :     return false;
    5319             :   }
    5320           0 :   if (length == 0) {
    5321           0 :     return true;
    5322             :   }
    5323           0 :   return ser.write_ushort_array(bitmask_seq.get_buffer(), length);
    5324             : }
    5325             : 
    5326           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uint16s(DCPS::Serializer& ser,
    5327             :   CORBA::ULong size, CORBA::ULong bound) const
    5328             : {
    5329           0 :   DDS::UInt16Seq bitmask_seq;
    5330           0 :   return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::UShort()) &&
    5331           0 :     serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq);
    5332           0 : }
    5333             : 
    5334             : // Bitmask sequence represented as uint32 sequence
    5335           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence_as_uint32s(
    5336             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5337             : {
    5338           0 :   serialized_size_delimiter(encoding, size);
    5339           0 :   primitive_serialized_size_ulong(encoding, size);
    5340           0 :   if (length == 0) {
    5341           0 :     return;
    5342             :   }
    5343           0 :   primitive_serialized_size(encoding, size, CORBA::ULong(), length);
    5344             : }
    5345             : 
    5346           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding,
    5347             :   size_t& size, const DDS::UInt32Seq& seq) const
    5348             : {
    5349           0 :   serialized_size_bitmask_sequence_as_uint32s(encoding, size, seq.length());
    5350           0 : }
    5351             : 
    5352           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser,
    5353             :   const DDS::UInt32Seq& bitmask_seq) const
    5354             : {
    5355           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5356           0 :   size_t total_size = 0;
    5357           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5358           0 :     serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq);
    5359           0 :     if (!ser.write_delimiter(total_size)) {
    5360           0 :       return false;
    5361             :     }
    5362             :   }
    5363           0 :   const CORBA::ULong length = bitmask_seq.length();
    5364           0 :   if (!(ser << length)) {
    5365           0 :     return false;
    5366             :   }
    5367           0 :   if (length == 0) {
    5368           0 :     return true;
    5369             :   }
    5370           0 :   return ser.write_ulong_array(bitmask_seq.get_buffer(), length);
    5371             : }
    5372             : 
    5373           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uint32s(DCPS::Serializer& ser,
    5374             :   CORBA::ULong size, CORBA::ULong bound) const
    5375             : {
    5376           0 :   DDS::UInt32Seq bitmask_seq;
    5377           0 :   return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::ULong()) &&
    5378           0 :     serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq);
    5379           0 : }
    5380             : 
    5381             : // Bitmask sequence represented as uint64 sequence
    5382           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence_as_uint64s(
    5383             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    5384             : {
    5385           0 :   serialized_size_delimiter(encoding, size);
    5386           0 :   primitive_serialized_size_ulong(encoding, size);
    5387           0 :   if (length == 0) {
    5388           0 :     return;
    5389             :   }
    5390           0 :   primitive_serialized_size(encoding, size, CORBA::ULongLong(), length);
    5391             : }
    5392             : 
    5393           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding,
    5394             :   size_t& size, const DDS::UInt64Seq& seq) const
    5395             : {
    5396           0 :   serialized_size_bitmask_sequence_as_uint64s(encoding, size, seq.length());
    5397           0 : }
    5398             : 
    5399           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser,
    5400             :   const DDS::UInt64Seq& bitmask_seq) const
    5401             : {
    5402           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5403           0 :   size_t total_size = 0;
    5404           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5405           0 :     serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq);
    5406           0 :     if (!ser.write_delimiter(total_size)) {
    5407           0 :       return false;
    5408             :     }
    5409             :   }
    5410           0 :   const CORBA::ULong length = bitmask_seq.length();
    5411           0 :   if (!(ser << length)) {
    5412           0 :     return false;
    5413             :   }
    5414           0 :   if (length == 0) {
    5415           0 :     return true;
    5416             :   }
    5417           0 :   return ser.write_ulonglong_array(bitmask_seq.get_buffer(), length);
    5418             : }
    5419             : 
    5420           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence_as_uint64s(DCPS::Serializer& ser,
    5421             :   CORBA::ULong size, CORBA::ULong bound) const
    5422             : {
    5423           0 :   DDS::UInt64Seq bitmask_seq;
    5424           0 :   return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::ULongLong()) &&
    5425           0 :     serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq);
    5426           0 : }
    5427             : 
    5428           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(
    5429             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const
    5430             : {
    5431           0 :   if (bitbound >= 1 && bitbound <= 8) {
    5432           0 :     serialized_size_bitmask_sequence_as_uint8s(encoding, size, length);
    5433           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    5434           0 :     serialized_size_bitmask_sequence_as_uint16s(encoding, size, length);
    5435           0 :   } else if (bitbound >= 17 && bitbound <= 32) {
    5436           0 :     serialized_size_bitmask_sequence_as_uint32s(encoding, size, length);
    5437             :   } else { // from 33 to 64
    5438           0 :     serialized_size_bitmask_sequence_as_uint64s(encoding, size, length);
    5439             :   }
    5440           0 : }
    5441             : 
    5442           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence(DCPS::Serializer& ser,
    5443             :   CORBA::ULong size, CORBA::ULong bitbound, CORBA::ULong seqbound) const
    5444             : {
    5445           0 :   if (bitbound >= 1 && bitbound <= 8) {
    5446           0 :     return serialize_bitmask_sequence_as_uint8s(ser, size, seqbound);
    5447           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    5448           0 :     return serialize_bitmask_sequence_as_uint16s(ser, size, seqbound);
    5449           0 :   } else if (bitbound >= 17 && bitbound <= 32) {
    5450           0 :     return serialize_bitmask_sequence_as_uint32s(ser, size, seqbound);
    5451           0 :   } else if (bitbound >= 33 && bitbound <= 64) {
    5452           0 :     return serialize_bitmask_sequence_as_uint64s(ser, size, seqbound);
    5453             :   }
    5454           0 :   return false;
    5455             : }
    5456             : 
    5457             : // Serialize a SequenceValue object
    5458           0 : bool DynamicDataImpl::DataContainer::serialized_size_sequence_value(
    5459             :   const DCPS::Encoding& encoding, size_t& size, const SequenceValue& sv) const
    5460             : {
    5461           0 :   switch (sv.elem_kind_) {
    5462           0 :   case TK_INT32:
    5463           0 :     serialized_size(encoding, size, sv.get<DDS::Int32Seq>());
    5464           0 :     return true;
    5465           0 :   case TK_UINT32:
    5466           0 :     serialized_size(encoding, size, sv.get<DDS::UInt32Seq>());
    5467           0 :     return true;
    5468           0 :   case TK_INT8:
    5469           0 :     serialized_size(encoding, size, sv.get<DDS::Int8Seq>());
    5470           0 :     return true;
    5471           0 :   case TK_UINT8:
    5472           0 :     serialized_size(encoding, size, sv.get<DDS::UInt8Seq>());
    5473           0 :     return true;
    5474           0 :   case TK_INT16:
    5475           0 :     serialized_size(encoding, size, sv.get<DDS::Int16Seq>());
    5476           0 :     return true;
    5477           0 :   case TK_UINT16:
    5478           0 :     serialized_size(encoding, size, sv.get<DDS::UInt16Seq>());
    5479           0 :     return true;
    5480           0 :   case TK_INT64:
    5481           0 :     serialized_size(encoding, size, sv.get<DDS::Int64Seq>());
    5482           0 :     return true;
    5483           0 :   case TK_UINT64:
    5484           0 :     serialized_size(encoding, size, sv.get<DDS::UInt64Seq>());
    5485           0 :     return true;
    5486           0 :   case TK_FLOAT32:
    5487           0 :     serialized_size(encoding, size, sv.get<DDS::Float32Seq>());
    5488           0 :     return true;
    5489           0 :   case TK_FLOAT64:
    5490           0 :     serialized_size(encoding, size, sv.get<DDS::Float64Seq>());
    5491           0 :     return true;
    5492           0 :   case TK_FLOAT128:
    5493           0 :     serialized_size(encoding, size, sv.get<DDS::Float128Seq>());
    5494           0 :     return true;
    5495           0 :   case TK_CHAR8:
    5496           0 :     serialized_size(encoding, size, sv.get<DDS::CharSeq>());
    5497           0 :     return true;
    5498           0 :   case TK_BYTE:
    5499           0 :     serialized_size(encoding, size, sv.get<DDS::ByteSeq>());
    5500           0 :     return true;
    5501           0 :   case TK_BOOLEAN:
    5502           0 :     serialized_size(encoding, size, sv.get<DDS::BooleanSeq>());
    5503           0 :     return true;
    5504           0 :   case TK_STRING8:
    5505           0 :     serialized_size(encoding, size, sv.get<DDS::StringSeq>());
    5506           0 :     return true;
    5507             : #ifdef DDS_HAS_WCHAR
    5508           0 :   case TK_CHAR16:
    5509           0 :     serialized_size(encoding, size, sv.get<DDS::WcharSeq>());
    5510           0 :     return true;
    5511           0 :   case TK_STRING16:
    5512           0 :     serialized_size(encoding, size, sv.get<DDS::WstringSeq>());
    5513           0 :     return true;
    5514             : #endif
    5515           0 :   default:
    5516           0 :     return false;
    5517             :   }
    5518             : }
    5519             : 
    5520           0 : bool DynamicDataImpl::DataContainer::serialize_sequence_value(DCPS::Serializer& ser,
    5521             :                                                               const SequenceValue& sv) const
    5522             : {
    5523           0 :   switch (sv.elem_kind_) {
    5524           0 :   case TK_INT32:
    5525           0 :     return ser << sv.get<DDS::Int32Seq>();
    5526           0 :   case TK_UINT32:
    5527           0 :     return ser << sv.get<DDS::UInt32Seq>();
    5528           0 :   case TK_INT8:
    5529           0 :     return ser << sv.get<DDS::Int8Seq>();
    5530           0 :   case TK_UINT8:
    5531           0 :     return ser << sv.get<DDS::UInt8Seq>();
    5532           0 :   case TK_INT16:
    5533           0 :     return ser << sv.get<DDS::Int16Seq>();
    5534           0 :   case TK_UINT16:
    5535           0 :     return ser << sv.get<DDS::UInt16Seq>();
    5536           0 :   case TK_INT64:
    5537           0 :     return ser << sv.get<DDS::Int64Seq>();
    5538           0 :   case TK_UINT64:
    5539           0 :     return ser << sv.get<DDS::UInt64Seq>();
    5540           0 :   case TK_FLOAT32:
    5541           0 :     return ser << sv.get<DDS::Float32Seq>();
    5542           0 :   case TK_FLOAT64:
    5543           0 :     return ser << sv.get<DDS::Float64Seq>();
    5544           0 :   case TK_FLOAT128:
    5545           0 :     return ser << sv.get<DDS::Float128Seq>();
    5546           0 :   case TK_CHAR8:
    5547           0 :     return ser << sv.get<DDS::CharSeq>();
    5548           0 :   case TK_BYTE:
    5549           0 :     return ser << sv.get<DDS::ByteSeq>();
    5550           0 :   case TK_BOOLEAN:
    5551           0 :     return ser << sv.get<DDS::BooleanSeq>();
    5552           0 :   case TK_STRING8:
    5553           0 :     return ser << sv.get<DDS::StringSeq>();
    5554             : #ifdef DDS_HAS_WCHAR
    5555           0 :   case TK_CHAR16:
    5556           0 :     return ser << sv.get<DDS::WcharSeq>();
    5557           0 :   case TK_STRING16:
    5558           0 :     return ser << sv.get<DDS::WstringSeq>();
    5559             : #endif
    5560           0 :   default:
    5561           0 :     return false;
    5562             :   }
    5563             : }
    5564             : 
    5565             : // Helper function for serializing sequences and arrays
    5566           3 : bool DynamicDataImpl::DataContainer::get_index_to_id_map(IndexToIdMap& index_to_id,
    5567             :                                                          CORBA::ULong bound) const
    5568             : {
    5569           3 :   for (const_single_iterator it = single_map_.begin(); it != single_map_.end(); ++it) {
    5570             :     CORBA::ULong index;
    5571           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    5572           0 :       return false;
    5573             :     }
    5574           0 :     index_to_id[index] = it->first;
    5575             :   }
    5576           3 :   for (const_sequence_iterator it = sequence_map_.begin(); it != sequence_map_.end(); ++it) {
    5577             :     CORBA::ULong index;
    5578           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    5579           0 :       return false;
    5580             :     }
    5581           0 :     index_to_id[index] = it->first;
    5582             :   }
    5583           3 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    5584             :     CORBA::ULong index;
    5585           0 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    5586           0 :       return false;
    5587             :     }
    5588           0 :     index_to_id[index] = it->first;
    5589             :   }
    5590           3 :   return true;
    5591             : }
    5592             : 
    5593           6 : bool DynamicDataImpl::DataContainer::serialized_size_complex_member_i(
    5594             :   const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id, DCPS::Sample::Extent ext) const
    5595             : {
    5596           6 :   const DDS::DynamicData_var& dd_var = complex_map_.at(id);
    5597           6 :   const DynamicDataImpl* data_impl = dynamic_cast<const DynamicDataImpl*>(dd_var.in());
    5598           6 :   if (!data_impl) {
    5599           0 :     return false;
    5600             :   }
    5601           6 :   return data_impl->serialized_size_i(encoding, size, ext);
    5602             : }
    5603             : 
    5604             : template<typename SequenceType>
    5605           0 : bool DynamicDataImpl::DataContainer::serialized_size_nested_basic_sequences(
    5606             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id,
    5607             :   SequenceType protoseq) const
    5608             : {
    5609           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5610           0 :     const CORBA::ULong id = index_to_id[i];
    5611           0 :     if (id != MEMBER_ID_INVALID) {
    5612           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5613           0 :       if (it != sequence_map_.end()) {
    5614           0 :         serialized_size_sequence_value(encoding, size, it->second);
    5615           0 :       } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) {
    5616           0 :         return false;
    5617             :       }
    5618             :     } else { // Empty sequence
    5619           0 :       protoseq.length(0);
    5620           0 :       serialized_size(encoding, size, protoseq);
    5621             :     }
    5622             :   }
    5623           0 :   return true;
    5624             : }
    5625             : 
    5626             : template<typename SequenceType>
    5627           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_basic_sequence(
    5628             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id,
    5629             :   SequenceType protoseq) const
    5630             : {
    5631           0 :   serialized_size_delimiter(encoding, size);
    5632           0 :   primitive_serialized_size_ulong(encoding, size);
    5633           0 :   if (index_to_id.empty()) {
    5634           0 :     return true;
    5635             :   }
    5636           0 :   return serialized_size_nested_basic_sequences(encoding, size, index_to_id, protoseq);
    5637             : }
    5638             : 
    5639           2 : bool DynamicDataImpl::DataContainer::serialize_complex_member_i(DCPS::Serializer& ser,
    5640             :                                                                 DDS::MemberId id,
    5641             :                                                                 DCPS::Sample::Extent ext) const
    5642             : {
    5643           2 :   const DDS::DynamicData_var& dd_var = complex_map_.at(id);
    5644           2 :   const DynamicDataImpl* data_impl = dynamic_cast<const DynamicDataImpl*>(dd_var.in());
    5645           2 :   if (!data_impl) {
    5646           0 :     return false;
    5647             :   }
    5648           2 :   return data_impl->serialize_i(ser, ext);
    5649             : }
    5650             : 
    5651             : template<typename SequenceType>
    5652           0 : bool DynamicDataImpl::DataContainer::serialize_nested_basic_sequences(DCPS::Serializer& ser,
    5653             :   const IndexToIdMap& index_to_id, SequenceType protoseq) const
    5654             : {
    5655           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5656           0 :     const CORBA::ULong id = index_to_id[i];
    5657           0 :     if (id != MEMBER_ID_INVALID) {
    5658           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5659           0 :       if (it != sequence_map_.end()) {
    5660           0 :         if (!serialize_sequence_value(ser, it->second)) {
    5661           0 :           return false;
    5662             :         }
    5663           0 :       } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) {
    5664           0 :         return false;
    5665             :       }
    5666             :     } else {
    5667             :       // Table 9: Use zero-length sequence of the same element type.
    5668           0 :       protoseq.length(0);
    5669           0 :       if (!(ser << protoseq)) {
    5670           0 :         return false;
    5671             :       }
    5672             :     }
    5673             :   }
    5674           0 :   return true;
    5675             : }
    5676             : 
    5677             : template<typename SequenceType>
    5678           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_basic_sequence_i(DCPS::Serializer& ser,
    5679             :   CORBA::ULong size, CORBA::ULong bound, SequenceType protoseq) const
    5680             : {
    5681             :   // Map from index to ID. Use MEMBER_ID_INVALID to indicate there is
    5682             :   // no data for an element at a given index.
    5683           0 :   IndexToIdMap index_to_id(size, MEMBER_ID_INVALID);
    5684           0 :   if (!get_index_to_id_map(index_to_id, bound)) {
    5685           0 :     return false;
    5686             :   }
    5687             : 
    5688           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5689           0 :   size_t total_size = 0;
    5690           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5691           0 :     if (!serialized_size_nesting_basic_sequence(encoding, total_size, index_to_id, protoseq) ||
    5692           0 :         !ser.write_delimiter(total_size)) {
    5693           0 :       return false;
    5694             :     }
    5695             :   }
    5696             : 
    5697             :   // Serialize the top-level sequence's length
    5698           0 :   if (!(ser << size)) {
    5699           0 :     return false;
    5700             :   }
    5701           0 :   if (size == 0) {
    5702           0 :     return true;
    5703             :   }
    5704           0 :   return serialize_nested_basic_sequences(ser, index_to_id, protoseq);
    5705           0 : }
    5706             : 
    5707           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_basic_sequence(
    5708             :   const DCPS::Encoding& encoding, size_t& size, TypeKind nested_elem_tk,
    5709             :   const IndexToIdMap& index_to_id) const
    5710             : {
    5711           0 :   switch (nested_elem_tk) {
    5712           0 :   case TK_INT32:
    5713           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int32Seq());
    5714           0 :   case TK_UINT32:
    5715           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt32Seq());
    5716           0 :   case TK_INT8:
    5717           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int8Seq());
    5718           0 :   case TK_UINT8:
    5719           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt8Seq());
    5720           0 :   case TK_INT16:
    5721           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int16Seq());
    5722           0 :   case TK_UINT16:
    5723           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt16Seq());
    5724           0 :   case TK_INT64:
    5725           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int64Seq());
    5726           0 :   case TK_UINT64:
    5727           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt64Seq());
    5728           0 :   case TK_FLOAT32:
    5729           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float32Seq());
    5730           0 :   case TK_FLOAT64:
    5731           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float64Seq());
    5732           0 :   case TK_FLOAT128:
    5733           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float128Seq());
    5734           0 :   case TK_CHAR8:
    5735           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::CharSeq());
    5736           0 :   case TK_STRING8:
    5737           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::StringSeq());
    5738             : #ifdef DDS_HAS_WCHAR
    5739           0 :   case TK_CHAR16:
    5740           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::WcharSeq());
    5741           0 :   case TK_STRING16:
    5742           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::WstringSeq());
    5743             : #endif
    5744           0 :   case TK_BYTE:
    5745           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::ByteSeq());
    5746           0 :   case TK_BOOLEAN:
    5747           0 :     return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::BooleanSeq());
    5748             :   }
    5749           0 :   return false;
    5750             : }
    5751             : 
    5752           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_basic_sequence(DCPS::Serializer& ser,
    5753             :   TypeKind nested_elem_tk, CORBA::ULong size, CORBA::ULong bound) const
    5754             : {
    5755           0 :   switch (nested_elem_tk) {
    5756           0 :   case TK_INT32:
    5757           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int32Seq());
    5758           0 :   case TK_UINT32:
    5759           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt32Seq());
    5760           0 :   case TK_INT8:
    5761           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int8Seq());
    5762           0 :   case TK_UINT8:
    5763           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt8Seq());
    5764           0 :   case TK_INT16:
    5765           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int16Seq());
    5766           0 :   case TK_UINT16:
    5767           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt16Seq());
    5768           0 :   case TK_INT64:
    5769           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int64Seq());
    5770           0 :   case TK_UINT64:
    5771           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt64Seq());
    5772           0 :   case TK_FLOAT32:
    5773           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float32Seq());
    5774           0 :   case TK_FLOAT64:
    5775           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float64Seq());
    5776           0 :   case TK_FLOAT128:
    5777           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float128Seq());
    5778           0 :   case TK_CHAR8:
    5779           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::CharSeq());
    5780           0 :   case TK_STRING8:
    5781           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::StringSeq());
    5782             : #ifdef DDS_HAS_WCHAR
    5783           0 :   case TK_CHAR16:
    5784           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::WcharSeq());
    5785           0 :   case TK_STRING16:
    5786           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::WstringSeq());
    5787             : #endif
    5788           0 :   case TK_BYTE:
    5789           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::ByteSeq());
    5790           0 :   case TK_BOOLEAN:
    5791           0 :     return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::BooleanSeq());
    5792             :   }
    5793           0 :   return false;
    5794             : }
    5795             : 
    5796           0 : bool DynamicDataImpl::DataContainer::serialized_size_nested_enum_sequences(
    5797             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    5798             : {
    5799           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5800           0 :     const CORBA::ULong id = index_to_id[i];
    5801           0 :     if (id != MEMBER_ID_INVALID) {
    5802           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5803           0 :       if (it != sequence_map_.end()) {
    5804           0 :         serialized_size_enum_sequence(encoding, size, it);
    5805           0 :       } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) {
    5806           0 :         return false;
    5807             :       }
    5808             :     } else {
    5809           0 :       serialized_size_delimiter(encoding, size);
    5810           0 :       primitive_serialized_size_ulong(encoding, size);
    5811             :     }
    5812             :   }
    5813           0 :   return true;
    5814             : }
    5815             : 
    5816           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_enum_sequence(
    5817             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    5818             : {
    5819           0 :   serialized_size_delimiter(encoding, size);
    5820           0 :   primitive_serialized_size_ulong(encoding, size);
    5821           0 :   if (index_to_id.empty()) {
    5822           0 :     return true;
    5823             :   }
    5824           0 :   return serialized_size_nested_enum_sequences(encoding, size, index_to_id);
    5825             : }
    5826             : 
    5827           0 : bool DynamicDataImpl::DataContainer::serialize_nested_enum_sequences(
    5828             :   DCPS::Serializer& ser, const IndexToIdMap& index_to_id) const
    5829             : {
    5830           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5831           0 :     const CORBA::ULong id = index_to_id[i];
    5832           0 :     if (id != MEMBER_ID_INVALID) {
    5833           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5834           0 :       if (it != sequence_map_.end()) {
    5835           0 :         if (!serialize_enum_sequence(ser, it)) {
    5836           0 :           return false;
    5837             :         }
    5838           0 :       } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) {
    5839           0 :         return false;
    5840             :       }
    5841             :     } else { // Empty sequence of enums
    5842           0 :       if (ser.encoding().xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5843           0 :         if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) {
    5844           0 :           return false;
    5845             :         }
    5846             :       }
    5847           0 :       if (!(ser << static_cast<CORBA::ULong>(0))) {
    5848           0 :         return false;
    5849             :       }
    5850             :     }
    5851             :   }
    5852           0 :   return true;
    5853             : }
    5854             : 
    5855           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_enum_sequence(DCPS::Serializer& ser,
    5856             :   CORBA::ULong size, CORBA::ULong bound) const
    5857             : {
    5858           0 :   IndexToIdMap index_to_id(size, MEMBER_ID_INVALID);
    5859           0 :   if (!get_index_to_id_map(index_to_id, bound)) {
    5860           0 :     return false;
    5861             :   }
    5862             : 
    5863           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5864           0 :   size_t total_size = 0;
    5865           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5866           0 :     if (!serialized_size_nesting_enum_sequence(encoding, total_size, index_to_id) ||
    5867           0 :         !ser.write_delimiter(total_size)) {
    5868           0 :       return false;
    5869             :     }
    5870             :   }
    5871             : 
    5872           0 :   if (!(ser << size)) {
    5873           0 :     return false;
    5874             :   }
    5875           0 :   if (size == 0) {
    5876           0 :     return true;
    5877             :   }
    5878           0 :   return serialize_nested_enum_sequences(ser, index_to_id);
    5879           0 : }
    5880             : 
    5881           0 : bool DynamicDataImpl::DataContainer::serialized_size_nested_bitmask_sequences(
    5882             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    5883             : {
    5884           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5885           0 :     const CORBA::ULong id = index_to_id[i];
    5886           0 :     if (id != MEMBER_ID_INVALID) {
    5887           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5888           0 :       if (it != sequence_map_.end()) {
    5889           0 :         serialized_size_bitmask_sequence(encoding, size, it);
    5890           0 :       } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) {
    5891           0 :         return false;
    5892             :       }
    5893             :     } else {
    5894           0 :       serialized_size_delimiter(encoding, size);
    5895           0 :       primitive_serialized_size_ulong(encoding, size);
    5896             :     }
    5897             :   }
    5898           0 :   return true;
    5899             : }
    5900             : 
    5901           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_bitmask_sequence(
    5902             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    5903             : {
    5904           0 :   serialized_size_delimiter(encoding, size);
    5905           0 :   primitive_serialized_size_ulong(encoding, size);
    5906           0 :   if (index_to_id.empty()) {
    5907           0 :     return true;
    5908             :   }
    5909           0 :   return serialized_size_nested_bitmask_sequences(encoding, size, index_to_id);
    5910             : }
    5911             : 
    5912           0 : bool DynamicDataImpl::DataContainer::serialize_nested_bitmask_sequences(DCPS::Serializer& ser,
    5913             :   const IndexToIdMap& index_to_id) const
    5914             : {
    5915           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5916           0 :     const CORBA::ULong id = index_to_id[i];
    5917           0 :     if (id != MEMBER_ID_INVALID) {
    5918           0 :       const_sequence_iterator it = sequence_map_.find(id);
    5919           0 :       if (it != sequence_map_.end()) {
    5920           0 :         if (!serialize_bitmask_sequence(ser, it)) {
    5921           0 :           return false;
    5922             :         }
    5923           0 :       } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) {
    5924           0 :         return false;
    5925             :       }
    5926             :     } else { // Empty sequence of bitmasks
    5927           0 :       if (ser.encoding().xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5928           0 :         if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) {
    5929           0 :           return false;
    5930             :         }
    5931             :       }
    5932           0 :       if (!(ser << static_cast<CORBA::ULong>(0))) {
    5933           0 :         return false;
    5934             :       }
    5935             :     }
    5936             :   }
    5937           0 :   return true;
    5938             : }
    5939             : 
    5940           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_bitmask_sequence(DCPS::Serializer& ser,
    5941             :   CORBA::ULong size, CORBA::ULong bound) const
    5942             : {
    5943           0 :   IndexToIdMap index_to_id(size, MEMBER_ID_INVALID);
    5944           0 :   if (!get_index_to_id_map(index_to_id, bound)) {
    5945           0 :     return false;
    5946             :   }
    5947             : 
    5948           0 :   const DCPS::Encoding& encoding = ser.encoding();
    5949           0 :   size_t total_size = 0;
    5950           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    5951           0 :     if (!serialized_size_nesting_bitmask_sequence(encoding, total_size, index_to_id) ||
    5952           0 :         !ser.write_delimiter(total_size)) {
    5953           0 :       return false;
    5954             :     }
    5955             :   }
    5956             : 
    5957           0 :   if (!(ser << size)) {
    5958           0 :     return false;
    5959             :   }
    5960           0 :   if (size == 0) {
    5961           0 :     return true;
    5962             :   }
    5963           0 :   return serialize_nested_bitmask_sequences(ser, index_to_id);
    5964           0 : }
    5965             : 
    5966           6 : bool DynamicDataImpl::DataContainer::serialized_size_complex_member(const DCPS::Encoding& encoding,
    5967             :   size_t& size, DDS::MemberId id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const
    5968             : {
    5969           6 :   if (id != MEMBER_ID_INVALID) {
    5970           6 :     return serialized_size_complex_member_i(encoding, size, id, ext);
    5971             :   } else {
    5972           0 :     return DynamicDataImpl(elem_type).serialized_size_i(encoding, size, ext);
    5973             :   }
    5974             : }
    5975             : 
    5976          15 : bool DynamicDataImpl::DataContainer::serialized_size_complex_sequence(const DCPS::Encoding& encoding,
    5977             :   size_t& size, const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const
    5978             : {
    5979          15 :   serialized_size_delimiter(encoding, size);
    5980          15 :   primitive_serialized_size_ulong(encoding, size);
    5981          15 :   if (index_to_id.empty()) {
    5982          12 :     return true;
    5983             :   }
    5984           9 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5985           6 :     if (!serialized_size_complex_member(encoding, size, index_to_id[i], elem_type, ext)) {
    5986           0 :       return false;
    5987             :     }
    5988             :   }
    5989           3 :   return true;
    5990             : }
    5991             : 
    5992           1 : bool DynamicDataImpl::DataContainer::serialize_complex_sequence_i(DCPS::Serializer& ser,
    5993             :   const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const
    5994             : {
    5995           3 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    5996           2 :     const CORBA::ULong id = index_to_id[i];
    5997           2 :     if (id != MEMBER_ID_INVALID) {
    5998           2 :       if (!serialize_complex_member_i(ser, id, ext)) {
    5999           0 :         return false;
    6000             :       }
    6001             :     } else {
    6002           0 :       if (!DynamicDataImpl(elem_type).serialize_i(ser, ext)) {
    6003           0 :         return false;
    6004             :       }
    6005             :     }
    6006             :   }
    6007           1 :   return true;
    6008             : }
    6009             : 
    6010           3 : bool DynamicDataImpl::DataContainer::serialize_complex_sequence(DCPS::Serializer& ser,
    6011             :   CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const
    6012             : {
    6013           3 :   IndexToIdMap index_to_id(size, MEMBER_ID_INVALID);
    6014           5 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    6015             :     CORBA::ULong index;
    6016           2 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    6017           0 :       return false;
    6018             :     }
    6019           2 :     index_to_id[index] = it->first;
    6020             :   }
    6021             : 
    6022           3 :   const DCPS::Encoding& encoding = ser.encoding();
    6023           3 :   size_t total_size = 0;
    6024           3 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6025           6 :     if (!serialized_size_complex_sequence(encoding, total_size, index_to_id, elem_type, ext) ||
    6026           3 :         !ser.write_delimiter(total_size)) {
    6027           0 :       return false;
    6028             :     }
    6029             :   }
    6030             : 
    6031           3 :   if (!(ser << size)) {
    6032           0 :     return false;
    6033             :   }
    6034           3 :   if (size == 0) {
    6035           2 :     return true;
    6036             :   }
    6037           1 :   return serialize_complex_sequence_i(ser, index_to_id, elem_type, ext);
    6038           3 : }
    6039             : 
    6040          12 : bool DynamicDataImpl::DataContainer::get_index_to_id_from_complex(IndexToIdMap& index_to_id,
    6041             :                                                                   CORBA::ULong bound) const
    6042             : {
    6043          12 :   CORBA::ULong length = 0;
    6044          12 :   if (!complex_map_.empty()) {
    6045             :     CORBA::ULong largest_index;
    6046           2 :     if (!get_largest_complex_index(largest_index)) {
    6047           0 :       return false;
    6048             :     }
    6049           2 :     length = largest_index + 1;
    6050             :   }
    6051          12 :   index_to_id.resize(length, MEMBER_ID_INVALID);
    6052          16 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    6053             :     CORBA::ULong index;
    6054           4 :     if (!data_->get_index_from_id(it->first, index, bound)) {
    6055           0 :       return false;
    6056             :     }
    6057           4 :     index_to_id[index] = it->first;
    6058             :   }
    6059          12 :   return true;
    6060             : }
    6061             : 
    6062          30 : bool DynamicDataImpl::DataContainer::serialized_size_sequence(const DCPS::Encoding& encoding,
    6063             :                                                               size_t& size,
    6064             :                                                               DCPS::Sample::Extent ext) const
    6065             : {
    6066          30 :   const CORBA::ULong bound = type_desc_->bound()[0];
    6067             : 
    6068          30 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    6069          30 :   const TypeKind elem_tk = elem_type->get_kind();
    6070          30 :   DDS::TypeDescriptor_var elem_td;
    6071          30 :   if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    6072           0 :     return false;
    6073             :   }
    6074             : 
    6075          30 :   if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) {
    6076          18 :     const bool is_empty = single_map_.empty() && complex_map_.empty();
    6077          18 :     CORBA::ULong length = 0;
    6078          18 :     if (!is_empty) {
    6079             :       CORBA::ULong largest_index;
    6080           6 :       if (!get_largest_index_basic(largest_index)) {
    6081           0 :         return false;
    6082             :       }
    6083           6 :       length = largest_index + 1;
    6084             :     }
    6085          18 :     if (is_primitive(elem_tk)) {
    6086          11 :       serialized_size_primitive_sequence(encoding, size, elem_tk, length);
    6087          11 :       return true;
    6088           7 :     } else if (elem_tk == TK_STRING8) {
    6089           2 :       IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6090           2 :       if (!get_index_to_id_map(index_to_id, bound)) {
    6091           0 :         return false;
    6092             :       }
    6093           2 :       return serialized_size_generic_string_sequence<const char*>(encoding, size, index_to_id);
    6094           7 :     } else if (elem_tk == TK_STRING16) {
    6095             : #ifdef DDS_HAS_WCHAR
    6096           0 :       IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6097           0 :       if (!get_index_to_id_map(index_to_id, bound)) {
    6098           0 :         return false;
    6099             :       }
    6100           0 :       return serialized_size_generic_string_sequence<const CORBA::WChar*>(encoding, size, index_to_id);
    6101             : #else
    6102             :       return false;
    6103             : #endif
    6104           5 :     } else if (elem_tk == TK_ENUM) {
    6105           5 :       const CORBA::ULong bit_bound = elem_td->bound()[0];
    6106           5 :       serialized_size_enum_sequence(encoding, size, length, bit_bound);
    6107           5 :       return true;
    6108           0 :     } else if (elem_tk == TK_BITMASK) {
    6109           0 :       const CORBA::ULong bit_bound = elem_td->bound()[0];
    6110           0 :       serialized_size_bitmask_sequence(encoding, size, length, bit_bound);
    6111             :     }
    6112          12 :   } else if (elem_tk == TK_SEQUENCE) {
    6113           0 :     const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type());
    6114           0 :     const TypeKind nested_elem_tk = nested_elem_type->get_kind();
    6115           0 :     if (is_basic(nested_elem_tk) || nested_elem_tk == TK_ENUM ||
    6116             :         nested_elem_tk == TK_BITMASK) {
    6117           0 :       const bool is_empty = sequence_map_.empty() && complex_map_.empty();
    6118           0 :       CORBA::ULong length = 0;
    6119           0 :       if (!is_empty) {
    6120             :         CORBA::ULong largest_index;
    6121           0 :         if (!get_largest_index_basic_sequence(largest_index)) {
    6122           0 :           return false;
    6123             :         }
    6124           0 :         length = largest_index + 1;
    6125             :       }
    6126           0 :       IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6127           0 :       if (!get_index_to_id_map(index_to_id, bound)) {
    6128           0 :         return false;
    6129             :       }
    6130           0 :       if (is_basic(nested_elem_tk)) {
    6131           0 :         return serialized_size_nesting_basic_sequence(encoding, size, nested_elem_tk, index_to_id);
    6132           0 :       } else if (nested_elem_tk == TK_ENUM) {
    6133           0 :         return serialized_size_nesting_enum_sequence(encoding, size, index_to_id);
    6134             :       } else {
    6135           0 :         return serialized_size_nesting_bitmask_sequence(encoding, size, index_to_id);
    6136             :       }
    6137           0 :     }
    6138           0 :   }
    6139             : 
    6140             :   // Elements stored in complex map
    6141          12 :   IndexToIdMap index_to_id;
    6142          12 :   if (!get_index_to_id_from_complex(index_to_id, bound)) {
    6143           0 :     return false;
    6144             :   }
    6145          12 :   return serialized_size_complex_sequence(encoding, size, index_to_id, elem_type, ext);
    6146          30 : }
    6147             : 
    6148          15 : bool DynamicDataImpl::DataContainer::serialize_sequence(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    6149             : {
    6150          15 :   const CORBA::ULong bound = type_desc_->bound()[0];
    6151             : 
    6152          15 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    6153          15 :   const TypeKind elem_tk = elem_type->get_kind();
    6154          15 :   DDS::TypeDescriptor_var elem_td;
    6155          15 :   if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    6156           0 :     return false;
    6157             :   }
    6158             : 
    6159          15 :   if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) {
    6160          12 :     const bool is_empty = single_map_.empty() && complex_map_.empty();
    6161          12 :     CORBA::ULong length = 0;
    6162          12 :     if (!is_empty) {
    6163             :       CORBA::ULong largest_index;
    6164           6 :       if (!get_largest_index_basic(largest_index)) {
    6165           0 :         return false;
    6166             :       }
    6167           6 :       length = largest_index + 1;
    6168             :     }
    6169          12 :     if (is_primitive(elem_tk)) {
    6170           7 :       return serialize_primitive_sequence(ser, elem_tk, length, bound);
    6171           5 :     } else if (elem_tk == TK_STRING8) {
    6172           1 :       return serialize_generic_string_sequence<const char*>(ser, length, bound);
    6173           4 :     } else if (elem_tk == TK_STRING16) {
    6174             : #ifdef DDS_HAS_WCHAR
    6175           0 :       return serialize_generic_string_sequence<const CORBA::WChar*>(ser, length, bound);
    6176             : #else
    6177             :       return false;
    6178             : #endif
    6179           4 :     } else if (elem_tk == TK_ENUM) {
    6180           4 :       const CORBA::ULong bit_bound = elem_td->bound()[0];
    6181           4 :       return serialize_enum_sequence(ser, length, bit_bound, bound, elem_type);
    6182             :     } else {
    6183           0 :       const CORBA::ULong bit_bound = elem_td->bound()[0];
    6184           0 :       return serialize_bitmask_sequence(ser, length, bit_bound, bound);
    6185             :     }
    6186           3 :   } else if (elem_tk == TK_SEQUENCE) {
    6187           0 :     const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type());
    6188           0 :     const TypeKind nested_elem_tk = nested_elem_type->get_kind();
    6189           0 :     if (is_basic(nested_elem_tk) || nested_elem_tk == TK_ENUM ||
    6190             :         nested_elem_tk == TK_BITMASK) {
    6191           0 :       const bool is_empty = sequence_map_.empty() && complex_map_.empty();
    6192           0 :       CORBA::ULong length = 0;
    6193           0 :       if (!is_empty) {
    6194             :         CORBA::ULong largest_index;
    6195           0 :         if (!get_largest_index_basic_sequence(largest_index)) {
    6196           0 :           return false;
    6197             :         }
    6198           0 :         length = largest_index + 1;
    6199             :       }
    6200           0 :       if (is_basic(nested_elem_tk)) {
    6201           0 :         return serialize_nesting_basic_sequence(ser, nested_elem_tk, length, bound);
    6202           0 :       } else if (nested_elem_tk == TK_ENUM) {
    6203           0 :         return serialize_nesting_enum_sequence(ser, length, bound);
    6204             :       } else {
    6205           0 :         return serialize_nesting_bitmask_sequence(ser, length, bound);
    6206             :       }
    6207             :     }
    6208           0 :   }
    6209             : 
    6210             :   // Elements with all the other types are stored in the complex map.
    6211           3 :   CORBA::ULong length = 0;
    6212           3 :   if (!complex_map_.empty()) {
    6213             :     CORBA::ULong largest_index;
    6214           1 :     if (!get_largest_complex_index(largest_index)) {
    6215           0 :       return false;
    6216             :     }
    6217           1 :     length = largest_index + 1;
    6218             :   }
    6219           3 :   return serialize_complex_sequence(ser, length, bound, elem_type, ext);
    6220          15 : }
    6221             : 
    6222          15 : void DynamicDataImpl::DataContainer::serialized_size_primitive_array(const DCPS::Encoding& encoding,
    6223             :   size_t& size, TypeKind elem_tk, CORBA::ULong length) const
    6224             : {
    6225          15 :   switch (elem_tk) {
    6226           4 :   case TK_INT32:
    6227           4 :     primitive_serialized_size(encoding, size, CORBA::Long(), length);
    6228           4 :     return;
    6229           4 :   case TK_UINT32:
    6230           4 :     primitive_serialized_size(encoding, size, CORBA::ULong(), length);
    6231           4 :     return;
    6232           7 :   case TK_INT8:
    6233           7 :     primitive_serialized_size_int8(encoding, size, length);
    6234           7 :     return;
    6235           0 :   case TK_UINT8:
    6236           0 :     primitive_serialized_size_uint8(encoding, size, length);
    6237           0 :     return;
    6238           0 :   case TK_INT16:
    6239           0 :     primitive_serialized_size(encoding, size, CORBA::Short(), length);
    6240           0 :     return;
    6241           0 :   case TK_UINT16:
    6242           0 :     primitive_serialized_size(encoding, size, CORBA::UShort(), length);
    6243           0 :     return;
    6244           0 :   case TK_INT64:
    6245           0 :     primitive_serialized_size(encoding, size, CORBA::LongLong(), length);
    6246           0 :     return;
    6247           0 :   case TK_UINT64:
    6248           0 :     primitive_serialized_size(encoding, size, CORBA::ULongLong(), length);
    6249           0 :     return;
    6250           0 :   case TK_FLOAT32:
    6251           0 :     primitive_serialized_size(encoding, size, CORBA::Float(), length);
    6252           0 :     return;
    6253           0 :   case TK_FLOAT64:
    6254           0 :     primitive_serialized_size(encoding, size, CORBA::Double(), length);
    6255           0 :     return;
    6256           0 :   case TK_FLOAT128:
    6257           0 :     primitive_serialized_size(encoding, size, CORBA::LongDouble(), length);
    6258           0 :     return;
    6259           0 :   case TK_CHAR8:
    6260           0 :     primitive_serialized_size_char(encoding, size, length);
    6261           0 :     return;
    6262             : #ifdef DDS_HAS_WCHAR
    6263           0 :   case TK_CHAR16:
    6264           0 :     primitive_serialized_size_wchar(encoding, size, length);
    6265           0 :     return;
    6266             : #endif
    6267           0 :   case TK_BYTE:
    6268           0 :     primitive_serialized_size_octet(encoding, size, length);
    6269           0 :     return;
    6270           0 :   case TK_BOOLEAN:
    6271           0 :     primitive_serialized_size_boolean(encoding, size, length);
    6272           0 :     return;
    6273             :   }
    6274             : }
    6275             : 
    6276           7 : bool DynamicDataImpl::DataContainer::serialize_primitive_array(DCPS::Serializer& ser,
    6277             :   TypeKind elem_tk, CORBA::ULong length) const
    6278             : {
    6279           7 :   switch (elem_tk) {
    6280           2 :   case TK_INT32: {
    6281           2 :     DDS::Int32Seq int32arr;
    6282           4 :     return reconstruct_primitive_collection(int32arr, length, length, CORBA::Long()) &&
    6283           2 :       ser.write_long_array(int32arr.get_buffer(), length);
    6284           2 :   }
    6285           2 :   case TK_UINT32: {
    6286           2 :     DDS::UInt32Seq uint32arr;
    6287           4 :     return reconstruct_primitive_collection(uint32arr, length, length, CORBA::ULong()) &&
    6288           2 :       ser.write_ulong_array(uint32arr.get_buffer(), length);
    6289           2 :   }
    6290           3 :   case TK_INT8: {
    6291           3 :     DDS::Int8Seq int8arr;
    6292           6 :     return reconstruct_primitive_collection(int8arr, length, length, ACE_OutputCDR::from_int8(0)) &&
    6293           3 :       ser.write_int8_array(int8arr.get_buffer(), length);
    6294           3 :   }
    6295           0 :   case TK_UINT8: {
    6296           0 :     DDS::UInt8Seq uint8arr;
    6297           0 :     return reconstruct_primitive_collection(uint8arr, length, length, ACE_OutputCDR::from_uint8(0)) &&
    6298           0 :       ser.write_uint8_array(uint8arr.get_buffer(), length);
    6299           0 :   }
    6300           0 :   case TK_INT16: {
    6301           0 :     DDS::Int16Seq int16arr;
    6302           0 :     return reconstruct_primitive_collection(int16arr, length, length, CORBA::Short()) &&
    6303           0 :       ser.write_short_array(int16arr.get_buffer(), length);
    6304           0 :   }
    6305           0 :   case TK_UINT16: {
    6306           0 :     DDS::UInt16Seq uint16arr;
    6307           0 :     return reconstruct_primitive_collection(uint16arr, length, length, CORBA::UShort()) &&
    6308           0 :       ser.write_ushort_array(uint16arr.get_buffer(), length);
    6309           0 :   }
    6310           0 :   case TK_INT64: {
    6311           0 :     DDS::Int64Seq int64arr;
    6312           0 :     return reconstruct_primitive_collection(int64arr, length, length, CORBA::LongLong()) &&
    6313           0 :       ser.write_longlong_array(int64arr.get_buffer(), length);
    6314           0 :   }
    6315           0 :   case TK_UINT64: {
    6316           0 :     DDS::UInt64Seq uint64arr;
    6317           0 :     return reconstruct_primitive_collection(uint64arr, length, length, CORBA::ULongLong()) &&
    6318           0 :       ser.write_ulonglong_array(uint64arr.get_buffer(), length);
    6319           0 :   }
    6320           0 :   case TK_FLOAT32: {
    6321           0 :     DDS::Float32Seq float32arr;
    6322           0 :     return reconstruct_primitive_collection(float32arr, length, length, CORBA::Float()) &&
    6323           0 :       ser.write_float_array(float32arr.get_buffer(), length);
    6324           0 :   }
    6325           0 :   case TK_FLOAT64: {
    6326           0 :     DDS::Float64Seq float64arr;
    6327           0 :     return reconstruct_primitive_collection(float64arr, length, length, CORBA::Double()) &&
    6328           0 :       ser.write_double_array(float64arr.get_buffer(), length);
    6329           0 :   }
    6330           0 :   case TK_FLOAT128: {
    6331           0 :     DDS::Float128Seq float128arr;
    6332           0 :     return reconstruct_primitive_collection(float128arr, length, length, CORBA::LongDouble()) &&
    6333           0 :       ser.write_longdouble_array(float128arr.get_buffer(), length);
    6334           0 :   }
    6335           0 :   case TK_CHAR8: {
    6336           0 :     DDS::CharSeq chararr;
    6337           0 :     return reconstruct_primitive_collection(chararr, length, length, ACE_OutputCDR::from_char('\0')) &&
    6338           0 :       ser.write_char_array(chararr.get_buffer(), length);
    6339           0 :   }
    6340             : #ifdef DDS_HAS_WCHAR
    6341           0 :   case TK_CHAR16: {
    6342           0 :     DDS::WcharSeq wchararr;
    6343           0 :     return reconstruct_primitive_collection(wchararr, length, length, ACE_OutputCDR::from_wchar(0)) &&
    6344           0 :       ser.write_wchar_array(wchararr.get_buffer(), length);
    6345           0 :   }
    6346             : #endif
    6347           0 :   case TK_BYTE: {
    6348           0 :     DDS::ByteSeq bytearr;
    6349           0 :     return reconstruct_primitive_collection(bytearr, length, length, ACE_OutputCDR::from_octet(0x00)) &&
    6350           0 :       ser.write_octet_array(bytearr.get_buffer(), length);
    6351           0 :   }
    6352           0 :   case TK_BOOLEAN: {
    6353           0 :     DDS::BooleanSeq boolarr;
    6354           0 :     return reconstruct_primitive_collection(boolarr, length, length, ACE_OutputCDR::from_boolean(false)) &&
    6355           0 :       ser.write_boolean_array(boolarr.get_buffer(), length);
    6356           0 :   }
    6357             :   }
    6358           0 :   return false;
    6359             : }
    6360             : 
    6361             : template<typename StringType>
    6362           0 : bool DynamicDataImpl::DataContainer::serialized_size_generic_string_array(
    6363             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    6364             : {
    6365           0 :   serialized_size_delimiter(encoding, size);
    6366           0 :   return serialized_size_generic_string_collection<StringType>(encoding, size, index_to_id);
    6367             : }
    6368             : 
    6369             : template<typename StringType>
    6370           0 : bool DynamicDataImpl::DataContainer::serialize_generic_string_array(DCPS::Serializer& ser,
    6371             :                                                                     CORBA::ULong length) const
    6372             : {
    6373           0 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6374           0 :   if (!get_index_to_id_map(index_to_id, length)) {
    6375           0 :     return false;
    6376             :   }
    6377             : 
    6378           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6379           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6380           0 :     size_t total_size = 0;
    6381           0 :     if (!serialized_size_generic_string_array<StringType>(encoding, total_size, index_to_id) ||
    6382           0 :         !ser.write_delimiter(total_size)) {
    6383           0 :       return false;
    6384             :     }
    6385             :   }
    6386           0 :   return serialize_generic_string_collection<StringType>(ser, index_to_id);
    6387           0 : }
    6388             : 
    6389             : // Serialize enum array represented as int8 array
    6390           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_array_as_int8s(
    6391             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6392             : {
    6393           0 :   serialized_size_delimiter(encoding, size);
    6394           0 :   primitive_serialized_size_int8(encoding, size, length);
    6395           0 : }
    6396             : 
    6397           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_ints_i(DCPS::Serializer& ser,
    6398             :   const DDS::Int8Seq& enumarr) const
    6399             : {
    6400           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6401           0 :   size_t total_size = 0;
    6402           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6403           0 :     serialized_size_enum_array_as_int8s(encoding, total_size, enumarr.length());
    6404           0 :     if (!ser.write_delimiter(total_size)) {
    6405           0 :       return false;
    6406             :     }
    6407             :   }
    6408           0 :   return ser.write_int8_array(enumarr.get_buffer(), enumarr.length());
    6409             : }
    6410             : 
    6411           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_int8s(DCPS::Serializer& ser,
    6412             :   CORBA::ULong length, const DDS::DynamicType_var& enum_type) const
    6413             : {
    6414           0 :   DDS::Int8Seq enumarr;
    6415           0 :   return reconstruct_enum_collection<CORBA::Int8>(enumarr, length, length, enum_type, ACE_OutputCDR::from_int8(0)) &&
    6416           0 :     serialize_enum_array_as_ints_i(ser, enumarr);
    6417           0 : }
    6418             : 
    6419             : // Serialize enum array represented as int16 array
    6420           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_array_as_int16s(
    6421             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6422             : {
    6423           0 :   serialized_size_delimiter(encoding, size);
    6424           0 :   primitive_serialized_size(encoding, size, CORBA::Short(), length);
    6425           0 : }
    6426             : 
    6427           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_ints_i(DCPS::Serializer& ser,
    6428             :   const DDS::Int16Seq& enumarr) const
    6429             : {
    6430           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6431           0 :   size_t total_size = 0;
    6432           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6433           0 :     serialized_size_enum_array_as_int16s(encoding, total_size, enumarr.length());
    6434           0 :     if (!ser.write_delimiter(total_size)) {
    6435           0 :       return false;
    6436             :     }
    6437             :   }
    6438           0 :   return ser.write_short_array(enumarr.get_buffer(), enumarr.length());
    6439             : }
    6440             : 
    6441           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_int16s(DCPS::Serializer& ser,
    6442             :   CORBA::ULong length, const DDS::DynamicType_var& enum_type) const
    6443             : {
    6444           0 :   DDS::Int16Seq enumarr;
    6445           0 :   return reconstruct_enum_collection<CORBA::Short>(enumarr, length, length, enum_type, CORBA::Short()) &&
    6446           0 :     serialize_enum_array_as_ints_i(ser, enumarr);
    6447           0 : }
    6448             : 
    6449             : // Serialize enum array represented as int32 array
    6450           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_array_as_int32s(
    6451             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6452             : {
    6453           0 :   serialized_size_delimiter(encoding, size);
    6454           0 :   primitive_serialized_size(encoding, size, CORBA::Long(), length);
    6455           0 : }
    6456             : 
    6457           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_ints_i(DCPS::Serializer& ser,
    6458             :   const DDS::Int32Seq& enumarr) const
    6459             : {
    6460           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6461           0 :   size_t total_size = 0;
    6462           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6463           0 :     serialized_size_enum_array_as_int32s(encoding, total_size, enumarr.length());
    6464           0 :     if (!ser.write_delimiter(total_size)) {
    6465           0 :       return false;
    6466             :     }
    6467             :   }
    6468           0 :   return ser.write_long_array(enumarr.get_buffer(), enumarr.length());
    6469             : }
    6470             : 
    6471           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array_as_int32s(DCPS::Serializer& ser,
    6472             :   CORBA::ULong length, const DDS::DynamicType_var& enum_type) const
    6473             : {
    6474           0 :   DDS::Int32Seq enumarr;
    6475           0 :   return reconstruct_enum_collection<CORBA::Long>(enumarr, length, length, enum_type, CORBA::Long()) &&
    6476           0 :     serialize_enum_array_as_ints_i(ser, enumarr);
    6477           0 : }
    6478             : 
    6479           0 : void DynamicDataImpl::DataContainer::serialized_size_enum_array(const DCPS::Encoding& encoding,
    6480             :   size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const
    6481             : {
    6482           0 :   if (bitbound >= 1 && bitbound <= 8) {
    6483           0 :     serialized_size_enum_array_as_int8s(encoding, size, length);
    6484           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    6485           0 :     serialized_size_enum_array_as_int16s(encoding, size, length);
    6486             :   } else { // from 17 to 32
    6487           0 :     serialized_size_enum_array_as_int32s(encoding, size, length);
    6488             :   }
    6489           0 : }
    6490             : 
    6491           0 : bool DynamicDataImpl::DataContainer::serialize_enum_array(DCPS::Serializer& ser,
    6492             :   CORBA::ULong bitbound, CORBA::ULong length, const DDS::DynamicType_var& enum_type) const
    6493             : {
    6494           0 :   if (bitbound >= 1 && bitbound <= 8) {
    6495           0 :     return serialize_enum_array_as_int8s(ser, length, enum_type);
    6496           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    6497           0 :     return serialize_enum_array_as_int16s(ser, length, enum_type);
    6498           0 :   } else if (bitbound >= 17 && bitbound <= 32) {
    6499           0 :     return serialize_enum_array_as_int32s(ser, length, enum_type);
    6500             :   }
    6501           0 :   return false;
    6502             : }
    6503             : 
    6504             : // Bitmask array represented as uint8 array.
    6505           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_array_as_uint8s(
    6506             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6507             : {
    6508           0 :   serialized_size_delimiter(encoding, size);
    6509           0 :   primitive_serialized_size_uint8(encoding, size, length);
    6510           0 : }
    6511             : 
    6512           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser,
    6513             :   const DDS::UInt8Seq& bitmask_arr) const
    6514             : {
    6515           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6516           0 :   size_t total_size = 0;
    6517           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6518           0 :     serialized_size_bitmask_array_as_uint8s(encoding, total_size, bitmask_arr.length());
    6519           0 :     if (!ser.write_delimiter(total_size)) {
    6520           0 :       return false;
    6521             :     }
    6522             :   }
    6523           0 :   return ser.write_uint8_array(bitmask_arr.get_buffer(), bitmask_arr.length());
    6524             : }
    6525             : 
    6526           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uint8s(DCPS::Serializer& ser,
    6527             :                                                                        CORBA::ULong length) const
    6528             : {
    6529           0 :   DDS::UInt8Seq bitmask_arr;
    6530           0 :   return reconstruct_bitmask_collection(bitmask_arr, length, length, ACE_OutputCDR::from_uint8(0)) &&
    6531           0 :     serialize_bitmask_array_as_uints_i(ser, bitmask_arr);
    6532           0 : }
    6533             : 
    6534             : // Bitmask array represented as uint16 array.
    6535           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_array_as_uint16s(
    6536             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6537             : {
    6538           0 :   serialized_size_delimiter(encoding, size);
    6539           0 :   primitive_serialized_size(encoding, size, CORBA::UShort(), length);
    6540           0 : }
    6541             : 
    6542           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser,
    6543             :   const DDS::UInt16Seq& bitmask_arr) const
    6544             : {
    6545           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6546           0 :   size_t total_size = 0;
    6547           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6548           0 :     serialized_size_bitmask_array_as_uint16s(encoding, total_size, bitmask_arr.length());
    6549           0 :     if (!ser.write_delimiter(total_size)) {
    6550           0 :       return false;
    6551             :     }
    6552             :   }
    6553           0 :   return ser.write_ushort_array(bitmask_arr.get_buffer(), bitmask_arr.length());
    6554             : }
    6555             : 
    6556           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uint16s(DCPS::Serializer& ser,
    6557             :                                                                         CORBA::ULong length) const
    6558             : {
    6559           0 :   DDS::UInt16Seq bitmask_arr;
    6560           0 :   return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::UShort()) &&
    6561           0 :     serialize_bitmask_array_as_uints_i(ser, bitmask_arr);
    6562           0 : }
    6563             : 
    6564             : // Bitmask array represented as uint32 array.
    6565           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_array_as_uint32s(
    6566             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6567             : {
    6568           0 :   serialized_size_delimiter(encoding, size);
    6569           0 :   primitive_serialized_size(encoding, size, CORBA::ULong(), length);
    6570           0 : }
    6571             : 
    6572           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser,
    6573             :   const DDS::UInt32Seq& bitmask_arr) const
    6574             : {
    6575           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6576           0 :   size_t total_size = 0;
    6577           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6578           0 :     serialized_size_bitmask_array_as_uint32s(encoding, total_size, bitmask_arr.length());
    6579           0 :     if (!ser.write_delimiter(total_size)) {
    6580           0 :       return false;
    6581             :     }
    6582             :   }
    6583           0 :   return ser.write_ulong_array(bitmask_arr.get_buffer(), bitmask_arr.length());
    6584             : }
    6585             : 
    6586           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uint32s(DCPS::Serializer& ser,
    6587             :                                                                         CORBA::ULong length) const
    6588             : {
    6589           0 :   DDS::UInt32Seq bitmask_arr;
    6590           0 :   return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::ULong()) &&
    6591           0 :     serialize_bitmask_array_as_uints_i(ser, bitmask_arr);
    6592           0 : }
    6593             : 
    6594             : // Bitmask array represented as uint64 array.
    6595           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_array_as_uint64s(
    6596             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const
    6597             : {
    6598           0 :   serialized_size_delimiter(encoding, size);
    6599           0 :   primitive_serialized_size(encoding, size, CORBA::ULongLong(), length);
    6600           0 : }
    6601             : 
    6602           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser,
    6603             :   const DDS::UInt64Seq& bitmask_arr) const
    6604             : {
    6605           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6606           0 :   size_t total_size = 0;
    6607           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6608           0 :     serialized_size_bitmask_array_as_uint64s(encoding, total_size, bitmask_arr.length());
    6609           0 :     if (!ser.write_delimiter(total_size)) {
    6610           0 :       return false;
    6611             :     }
    6612             :   }
    6613           0 :   return ser.write_ulonglong_array(bitmask_arr.get_buffer(), bitmask_arr.length());
    6614             : }
    6615             : 
    6616           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array_as_uint64s(DCPS::Serializer& ser,
    6617             :                                                                         CORBA::ULong length) const
    6618             : {
    6619           0 :   DDS::UInt64Seq bitmask_arr;
    6620           0 :   return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::ULongLong()) &&
    6621           0 :     serialize_bitmask_array_as_uints_i(ser, bitmask_arr);
    6622           0 : }
    6623             : 
    6624           0 : void DynamicDataImpl::DataContainer::serialized_size_bitmask_array(
    6625             :   const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const
    6626             : {
    6627           0 :   if (bitbound >= 1 && bitbound <= 8) {
    6628           0 :     serialized_size_bitmask_array_as_uint8s(encoding, size, length);
    6629           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    6630           0 :     serialized_size_bitmask_array_as_uint16s(encoding, size, length);
    6631           0 :   } else if (bitbound >= 17 && bitbound <= 32) {
    6632           0 :     serialized_size_bitmask_array_as_uint32s(encoding, size, length);
    6633             :   } else { // from 33 to 64
    6634           0 :     serialized_size_bitmask_array_as_uint64s(encoding, size, length);
    6635             :   }
    6636           0 : }
    6637             : 
    6638           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_array(DCPS::Serializer& ser,
    6639             :   CORBA::ULong bitbound, CORBA::ULong length) const
    6640             : {
    6641           0 :   if (bitbound >= 1 && bitbound <= 8) {
    6642           0 :     return serialize_bitmask_array_as_uint8s(ser, length);
    6643           0 :   } else if (bitbound >= 9 && bitbound <= 16) {
    6644           0 :     return serialize_bitmask_array_as_uint16s(ser, length);
    6645           0 :   } else if (bitbound >= 17 && bitbound <= 32) {
    6646           0 :     return serialize_bitmask_array_as_uint32s(ser, length);
    6647           0 :   } else if (bitbound >= 33 && bitbound <= 64) {
    6648           0 :     return serialize_bitmask_array_as_uint64s(ser, length);
    6649             :   }
    6650           0 :   return false;
    6651             : }
    6652             : 
    6653             : template<typename SequenceType>
    6654           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_basic_array(const DCPS::Encoding& encoding,
    6655             :   size_t& size, const IndexToIdMap& index_to_id, SequenceType protoseq) const
    6656             : {
    6657           0 :   serialized_size_delimiter(encoding, size);
    6658           0 :   return serialized_size_nested_basic_sequences(encoding, size, index_to_id, protoseq);
    6659             : }
    6660             : 
    6661             : template<typename SequenceType>
    6662           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_basic_array_i(DCPS::Serializer& ser,
    6663             :   CORBA::ULong length, SequenceType protoseq) const
    6664             : {
    6665           0 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6666           0 :   if (!get_index_to_id_map(index_to_id, length)) {
    6667           0 :     return false;
    6668             :   }
    6669             : 
    6670           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6671           0 :   size_t total_size = 0;
    6672           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6673           0 :     if (!serialized_size_nesting_basic_array(encoding, total_size, index_to_id, protoseq) ||
    6674           0 :         !ser.write_delimiter(total_size)) {
    6675           0 :       return false;
    6676             :     }
    6677             :   }
    6678           0 :   return serialize_nested_basic_sequences(ser, index_to_id, protoseq);
    6679           0 : }
    6680             : 
    6681           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_basic_array(
    6682             :   const DCPS::Encoding& encoding, size_t& size, TypeKind nested_elem_tk,
    6683             :   const IndexToIdMap& index_to_id) const
    6684             : {
    6685           0 :   switch (nested_elem_tk) {
    6686           0 :   case TK_INT32:
    6687           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int32Seq());
    6688           0 :   case TK_UINT32:
    6689           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt32Seq());
    6690           0 :   case TK_INT8:
    6691           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int8Seq());
    6692           0 :   case TK_UINT8:
    6693           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt8Seq());
    6694           0 :   case TK_INT16:
    6695           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int16Seq());
    6696           0 :   case TK_UINT16:
    6697           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt16Seq());
    6698           0 :   case TK_INT64:
    6699           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int64Seq());
    6700           0 :   case TK_UINT64:
    6701           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt64Seq());
    6702           0 :   case TK_FLOAT32:
    6703           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float32Seq());
    6704           0 :   case TK_FLOAT64:
    6705           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float64Seq());
    6706           0 :   case TK_FLOAT128:
    6707           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float128Seq());
    6708           0 :   case TK_CHAR8:
    6709           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::CharSeq());
    6710           0 :   case TK_STRING8:
    6711           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::StringSeq());
    6712             : #ifdef DDS_HAS_WCHAR
    6713           0 :   case TK_CHAR16:
    6714           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::WcharSeq());
    6715           0 :   case TK_STRING16:
    6716           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::WstringSeq());
    6717             : #endif
    6718           0 :   case TK_BYTE:
    6719           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::ByteSeq());
    6720           0 :   case TK_BOOLEAN:
    6721           0 :     return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::BooleanSeq());
    6722             :   }
    6723           0 :   return false;
    6724             : }
    6725             : 
    6726           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_basic_array(DCPS::Serializer& ser,
    6727             :   TypeKind nested_elem_tk, CORBA::ULong length) const
    6728             : {
    6729           0 :   switch (nested_elem_tk) {
    6730           0 :   case TK_INT32:
    6731           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Int32Seq());
    6732           0 :   case TK_UINT32:
    6733           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::UInt32Seq());
    6734           0 :   case TK_INT8:
    6735           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Int8Seq());
    6736           0 :   case TK_UINT8:
    6737           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::UInt8Seq());
    6738           0 :   case TK_INT16:
    6739           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Int16Seq());
    6740           0 :   case TK_UINT16:
    6741           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::UInt16Seq());
    6742           0 :   case TK_INT64:
    6743           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Int64Seq());
    6744           0 :   case TK_UINT64:
    6745           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::UInt64Seq());
    6746           0 :   case TK_FLOAT32:
    6747           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Float32Seq());
    6748           0 :   case TK_FLOAT64:
    6749           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Float64Seq());
    6750           0 :   case TK_FLOAT128:
    6751           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::Float128Seq());
    6752           0 :   case TK_CHAR8:
    6753           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::CharSeq());
    6754           0 :   case TK_STRING8:
    6755           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::StringSeq());
    6756             : #ifdef DDS_HAS_WCHAR
    6757           0 :   case TK_CHAR16:
    6758           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::WcharSeq());
    6759           0 :   case TK_STRING16:
    6760           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::WstringSeq());
    6761             : #endif
    6762           0 :   case TK_BYTE:
    6763           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::ByteSeq());
    6764           0 :   case TK_BOOLEAN:
    6765           0 :     return serialize_nesting_basic_array_i(ser, length, DDS::BooleanSeq());
    6766             :   }
    6767           0 :   return false;
    6768             : }
    6769             : 
    6770           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_enum_array(
    6771             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    6772             : {
    6773           0 :   serialized_size_delimiter(encoding, size);
    6774           0 :   return serialized_size_nested_enum_sequences(encoding, size, index_to_id);
    6775             : }
    6776             : 
    6777           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_enum_array(DCPS::Serializer& ser,
    6778             :                                                                   CORBA::ULong length) const
    6779             : {
    6780           0 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6781           0 :   if (!get_index_to_id_map(index_to_id, length)) {
    6782           0 :     return false;
    6783             :   }
    6784             : 
    6785           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6786           0 :   size_t total_size = 0;
    6787           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6788           0 :     if (!serialized_size_nesting_enum_array(encoding, total_size, index_to_id) ||
    6789           0 :         !ser.write_delimiter(total_size)) {
    6790           0 :       return false;
    6791             :     }
    6792             :   }
    6793           0 :   return serialize_nested_enum_sequences(ser, index_to_id);
    6794           0 : }
    6795             : 
    6796           0 : bool DynamicDataImpl::DataContainer::serialized_size_nesting_bitmask_array(
    6797             :   const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const
    6798             : {
    6799           0 :   serialized_size_delimiter(encoding, size);
    6800           0 :   return serialized_size_nested_bitmask_sequences(encoding, size, index_to_id);
    6801             : }
    6802             : 
    6803           0 : bool DynamicDataImpl::DataContainer::serialize_nesting_bitmask_array(DCPS::Serializer& ser,
    6804             :                                                                      CORBA::ULong length) const
    6805             : {
    6806           0 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6807           0 :   if (!get_index_to_id_map(index_to_id, length)) {
    6808           0 :     return false;
    6809             :   }
    6810             : 
    6811           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6812           0 :   size_t total_size = 0;
    6813           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6814           0 :     if (!serialized_size_nesting_bitmask_array(encoding, total_size, index_to_id) ||
    6815           0 :         !ser.write_delimiter(total_size)) {
    6816           0 :       return false;
    6817             :     }
    6818             :   }
    6819           0 :   return serialize_nested_bitmask_sequences(ser, index_to_id);
    6820           0 : }
    6821             : 
    6822           0 : bool DynamicDataImpl::DataContainer::serialized_size_complex_array(const DCPS::Encoding& encoding,
    6823             :   size_t& size, const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type,
    6824             :   DCPS::Sample::Extent ext) const
    6825             : {
    6826           0 :   serialized_size_delimiter(encoding, size);
    6827           0 :   for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) {
    6828           0 :     if (!serialized_size_complex_member(encoding, size, index_to_id[i], elem_type, ext)) {
    6829           0 :       return false;
    6830             :     }
    6831             :   }
    6832           0 :   return true;
    6833             : }
    6834             : 
    6835           0 : bool DynamicDataImpl::DataContainer::serialize_complex_array(
    6836             :   DCPS::Serializer& ser, CORBA::ULong length, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const
    6837             : {
    6838           0 :   IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6839           0 :   for (const_complex_iterator it = complex_map_.begin(); it != complex_map_.end(); ++it) {
    6840             :     CORBA::ULong index;
    6841           0 :     if (!data_->get_index_from_id(it->first, index, length)) {
    6842           0 :       return false;
    6843             :     }
    6844           0 :     index_to_id[index] = it->first;
    6845             :   }
    6846             : 
    6847           0 :   const DCPS::Encoding& encoding = ser.encoding();
    6848           0 :   size_t total_size = 0;
    6849           0 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    6850           0 :     if (!serialized_size_complex_array(encoding, total_size, index_to_id, elem_type, ext) ||
    6851           0 :         !ser.write_delimiter(total_size)) {
    6852           0 :       return false;
    6853             :     }
    6854             :   }
    6855           0 :   return serialize_complex_sequence_i(ser, index_to_id, elem_type, ext);
    6856           0 : }
    6857             : 
    6858          15 : bool DynamicDataImpl::DataContainer::serialized_size_array(const DCPS::Encoding& encoding,
    6859             :                                                            size_t& size,
    6860             :                                                            DCPS::Sample::Extent ext) const
    6861             : {
    6862          15 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    6863          15 :   const TypeKind elem_tk = elem_type->get_kind();
    6864          15 :   DDS::TypeDescriptor_var elem_td;
    6865          15 :   if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    6866           0 :     return false;
    6867             :   }
    6868             : 
    6869          15 :   const CORBA::ULong length = bound_total(type_desc_);
    6870          15 :   if (is_basic(elem_tk)) {
    6871          15 :     serialized_size_primitive_array(encoding, size, elem_tk, length);
    6872          15 :     return true;
    6873           0 :   } else if (elem_tk == TK_STRING8) {
    6874           0 :     IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6875           0 :     if (!get_index_to_id_map(index_to_id, length)) {
    6876           0 :       return false;
    6877             :     }
    6878           0 :     return serialized_size_generic_string_array<const char*>(encoding, size, index_to_id);
    6879           0 :   } else if (elem_tk == TK_STRING16) {
    6880             : #ifdef DDS_HAS_WCHAR
    6881           0 :     IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6882           0 :     if (!get_index_to_id_map(index_to_id, length)) {
    6883           0 :       return false;
    6884             :     }
    6885           0 :     return serialized_size_generic_string_array<const CORBA::WChar*>(encoding, size, index_to_id);
    6886             : #else
    6887             :     return false;
    6888             : #endif
    6889           0 :   } else if (elem_tk == TK_ENUM) {
    6890           0 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    6891           0 :     serialized_size_enum_array(encoding, size, length, bit_bound);
    6892           0 :     return true;
    6893           0 :   } else if (elem_tk == TK_BITMASK) {
    6894           0 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    6895           0 :     serialized_size_bitmask_array(encoding, size, length, bit_bound);
    6896           0 :     return true;
    6897           0 :   } else if (elem_tk == TK_SEQUENCE) {
    6898           0 :     const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type());
    6899           0 :     const TypeKind nested_elem_tk = nested_elem_type->get_kind();
    6900           0 :     IndexToIdMap index_to_id(length, MEMBER_ID_INVALID);
    6901           0 :     if (!get_index_to_id_map(index_to_id, length)) {
    6902           0 :       return false;
    6903             :     }
    6904           0 :     if (is_basic(nested_elem_tk)) {
    6905           0 :       return serialized_size_nesting_basic_array(encoding, size, nested_elem_tk, index_to_id);
    6906           0 :     } else if (nested_elem_tk == TK_ENUM) {
    6907           0 :       return serialized_size_nesting_enum_array(encoding, size, index_to_id);
    6908           0 :     } else if (nested_elem_tk == TK_BITMASK) {
    6909           0 :       return serialized_size_nesting_bitmask_array(encoding, size, index_to_id);
    6910             :     }
    6911           0 :   }
    6912             : 
    6913             :   // Elements stored in complex map
    6914           0 :   IndexToIdMap index_to_id;
    6915           0 :   if (!get_index_to_id_from_complex(index_to_id, length)) {
    6916           0 :     return false;
    6917             :   }
    6918           0 :   return serialized_size_complex_array(encoding, size, index_to_id, elem_type, ext);
    6919          15 : }
    6920             : 
    6921           7 : bool DynamicDataImpl::DataContainer::serialize_array(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    6922             : {
    6923           7 :   const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type());
    6924           7 :   const TypeKind elem_tk = elem_type->get_kind();
    6925           7 :   DDS::TypeDescriptor_var elem_td;
    6926           7 :   if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) {
    6927           0 :     return false;
    6928             :   }
    6929             : 
    6930           7 :   const CORBA::ULong length = bound_total(type_desc_);
    6931           7 :   if (is_basic(elem_tk)) {
    6932           7 :     return serialize_primitive_array(ser, elem_tk, length);
    6933           0 :   } else if (elem_tk == TK_STRING8) {
    6934           0 :     return serialize_generic_string_array<const char*>(ser, length);
    6935           0 :   } else if (elem_tk == TK_STRING16) {
    6936             : #ifdef DDS_HAS_WCHAR
    6937           0 :     return serialize_generic_string_array<const CORBA::WChar*>(ser, length);
    6938             : #else
    6939             :     return false;
    6940             : #endif
    6941           0 :   } else if (elem_tk == TK_ENUM) {
    6942           0 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    6943           0 :     return serialize_enum_array(ser, bit_bound, length, elem_type);
    6944           0 :   } else if (elem_tk == TK_BITMASK) {
    6945           0 :     const CORBA::ULong bit_bound = elem_td->bound()[0];
    6946           0 :     return serialize_bitmask_array(ser, bit_bound, length);
    6947           0 :   } else if (elem_tk == TK_SEQUENCE) {
    6948           0 :     const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type());
    6949           0 :     const TypeKind nested_elem_tk = nested_elem_type->get_kind();
    6950           0 :     if (is_basic(nested_elem_tk)) {
    6951           0 :       return serialize_nesting_basic_array(ser, nested_elem_tk, length);
    6952           0 :     } else if (nested_elem_tk == TK_ENUM) {
    6953           0 :       return serialize_nesting_enum_array(ser, length);
    6954           0 :     } else if (nested_elem_tk == TK_BITMASK) {
    6955           0 :       return serialize_nesting_bitmask_array(ser, length);
    6956             :     }
    6957           0 :   }
    6958           0 :   return serialize_complex_array(ser, length, elem_type, ext);
    6959           7 : }
    6960             : 
    6961         239 : bool DynamicDataImpl::DataContainer::serialized_size_primitive_member(const DCPS::Encoding& encoding,
    6962             :   size_t& size, TypeKind member_tk) const
    6963             : {
    6964             :   using namespace OpenDDS::DCPS;
    6965             : 
    6966         239 :   switch (member_tk) {
    6967          49 :   case TK_INT32:
    6968          49 :     return primitive_serialized_size(encoding, size, CORBA::Long());
    6969          20 :   case TK_UINT32:
    6970          20 :     return primitive_serialized_size(encoding, size, CORBA::ULong());
    6971          17 :   case TK_INT8:
    6972          17 :     primitive_serialized_size_int8(encoding, size);
    6973          17 :     return true;
    6974          13 :   case TK_UINT8:
    6975          13 :     primitive_serialized_size_uint8(encoding, size);
    6976          13 :     return true;
    6977          17 :   case TK_INT16:
    6978          17 :     return primitive_serialized_size(encoding, size, CORBA::Short());
    6979          14 :   case TK_UINT16:
    6980          14 :     return primitive_serialized_size(encoding, size, CORBA::UShort());
    6981          13 :   case TK_INT64:
    6982          13 :     return primitive_serialized_size(encoding, size, CORBA::LongLong());
    6983          13 :   case TK_UINT64:
    6984          13 :     return primitive_serialized_size(encoding, size, CORBA::ULongLong());
    6985          11 :   case TK_FLOAT32:
    6986          11 :     return primitive_serialized_size(encoding, size, CORBA::Float());
    6987          11 :   case TK_FLOAT64:
    6988          11 :     return primitive_serialized_size(encoding, size, CORBA::Double());
    6989           0 :   case TK_FLOAT128:
    6990           0 :     return primitive_serialized_size(encoding, size, CORBA::LongDouble());
    6991          16 :   case TK_CHAR8:
    6992          16 :     primitive_serialized_size_char(encoding, size);
    6993          16 :     return true;
    6994             : #ifdef DDS_HAS_WCHAR
    6995          13 :   case TK_CHAR16:
    6996          13 :     primitive_serialized_size_wchar(encoding, size);
    6997          13 :     return true;
    6998             : #endif
    6999          16 :   case TK_BYTE:
    7000          16 :     primitive_serialized_size_octet(encoding, size);
    7001          16 :     return true;
    7002          16 :   case TK_BOOLEAN:
    7003          16 :     primitive_serialized_size_boolean(encoding, size);
    7004          16 :     return true;
    7005             :   }
    7006           0 :   return false;
    7007             : }
    7008             : 
    7009          12 : bool DynamicDataImpl::DataContainer::serialized_size_basic_member_default_value(
    7010             :   const DCPS::Encoding& encoding, size_t& size, TypeKind member_tk) const
    7011             : {
    7012          12 :   if (is_primitive(member_tk)) {
    7013          12 :     return serialized_size_primitive_member(encoding, size, member_tk);
    7014           0 :   } else if (member_tk == TK_STRING8) {
    7015             :     const char* str_default;
    7016           0 :     set_default_basic_value(str_default);
    7017           0 :     serialized_size_string_common(encoding, size, str_default);
    7018           0 :     return true;
    7019             :   }
    7020             : #ifdef DDS_HAS_WCHAR
    7021           0 :   else if (member_tk == TK_STRING16) {
    7022             :     const CORBA::WChar* wstr_default;
    7023           0 :     set_default_basic_value(wstr_default);
    7024           0 :     serialized_size_string_common(encoding, size, wstr_default);
    7025           0 :     return true;
    7026             :   }
    7027             : #endif
    7028           0 :   return false;
    7029             : }
    7030             : 
    7031             : // Serialized size of a basic member of an aggregated type. Member header size is not included.
    7032         249 : bool DynamicDataImpl::DataContainer::serialized_size_basic_member(const DCPS::Encoding& encoding,
    7033             :   size_t& size, TypeKind member_tk, const_single_iterator it) const
    7034             : {
    7035         249 :   if (is_primitive(member_tk)) {
    7036         227 :     return serialized_size_primitive_member(encoding, size, member_tk);
    7037          22 :   } else if (member_tk == TK_STRING8 || member_tk == TK_STRING16) {
    7038          22 :     serialized_size_string_common(encoding, size, it->second);
    7039          22 :     return true;
    7040             :   }
    7041           0 :   return false;
    7042             : }
    7043             : 
    7044           6 : bool DynamicDataImpl::DataContainer::serialize_basic_member_default_value(DCPS::Serializer& ser,
    7045             :                                                                           TypeKind member_tk) const
    7046             : {
    7047           6 :   switch (member_tk) {
    7048           2 :   case TK_INT32: {
    7049             :     CORBA::Long value;
    7050           2 :     set_default_basic_value(value);
    7051           2 :     return ser << value;
    7052             :   }
    7053           0 :   case TK_UINT32: {
    7054             :     CORBA::ULong value;
    7055           0 :     set_default_basic_value(value);
    7056           0 :     return ser << value;
    7057             :   }
    7058           0 :   case TK_INT8: {
    7059           0 :     ACE_OutputCDR::from_int8 value(0);
    7060           0 :     set_default_basic_value(value);
    7061           0 :     return ser << value;
    7062             :   }
    7063           0 :   case TK_UINT8: {
    7064           0 :     ACE_OutputCDR::from_uint8 value(0);
    7065           0 :     set_default_basic_value(value);
    7066           0 :     return ser << value;
    7067             :   }
    7068           1 :   case TK_INT16: {
    7069             :     CORBA::Short value;
    7070           1 :     set_default_basic_value(value);
    7071           1 :     return ser << value;
    7072             :   }
    7073           0 :   case TK_UINT16: {
    7074             :     CORBA::UShort value;
    7075           0 :     set_default_basic_value(value);
    7076           0 :     return ser << value;
    7077             :   }
    7078           0 :   case TK_INT64: {
    7079             :     CORBA::LongLong value;
    7080           0 :     set_default_basic_value(value);
    7081           0 :     return ser << value;
    7082             :   }
    7083           0 :   case TK_UINT64: {
    7084             :     CORBA::ULongLong value;
    7085           0 :     set_default_basic_value(value);
    7086           0 :     return ser << value;
    7087             :   }
    7088           0 :   case TK_FLOAT32: {
    7089             :     CORBA::Float value;
    7090           0 :     set_default_basic_value(value);
    7091           0 :     return ser << value;
    7092             :   }
    7093           0 :   case TK_FLOAT64: {
    7094             :     CORBA::Double value;
    7095           0 :     set_default_basic_value(value);
    7096           0 :     return ser << value;
    7097             :   }
    7098           0 :   case TK_FLOAT128: {
    7099             :     CORBA::LongDouble value;
    7100           0 :     set_default_basic_value(value);
    7101           0 :     return ser << value;
    7102             :   }
    7103           1 :   case TK_CHAR8: {
    7104           1 :     ACE_OutputCDR::from_char value('\0');
    7105           1 :     set_default_basic_value(value);
    7106           1 :     return ser << value;
    7107             :   }
    7108           0 :   case TK_STRING8: {
    7109             :     const char* value;
    7110           0 :     set_default_basic_value(value);
    7111           0 :     return ser << value;
    7112             :   }
    7113             : #ifdef DDS_HAS_WCHAR
    7114           0 :   case TK_CHAR16: {
    7115           0 :     ACE_OutputCDR::from_wchar value(0);
    7116           0 :     set_default_basic_value(value);
    7117           0 :     return ser << value;
    7118             :   }
    7119           0 :   case TK_STRING16: {
    7120             :     const CORBA::WChar* value;
    7121           0 :     set_default_basic_value(value);
    7122           0 :     return ser << value;
    7123             :   }
    7124             : #endif
    7125           1 :   case TK_BYTE: {
    7126           1 :     ACE_OutputCDR::from_octet value(0x00);
    7127           1 :     set_default_basic_value(value);
    7128           1 :     return ser << value;
    7129             :   }
    7130           1 :   case TK_BOOLEAN: {
    7131           1 :     ACE_OutputCDR::from_boolean value(false);
    7132           1 :     set_default_basic_value(value);
    7133           1 :     return ser << value;
    7134             :   }
    7135             :   }
    7136           0 :   return false;
    7137             : }
    7138             : 
    7139             : // Serialize an aggregated member stored in the single map.
    7140             : // The member type is basic or enum or bitmask.
    7141         175 : bool DynamicDataImpl::DataContainer::serialized_size_single_aggregated_member_xcdr2(
    7142             :   const DCPS::Encoding& encoding, size_t& size, const_single_iterator it,
    7143             :   const DDS::DynamicType_var& member_type, bool optional,
    7144             :   DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const
    7145             : {
    7146         175 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7147           0 :     primitive_serialized_size_boolean(encoding, size);
    7148         175 :   } else if (extensibility == DDS::MUTABLE) {
    7149          95 :     serialized_size_parameter_id(encoding, size, mutable_running_total);
    7150             :   }
    7151         175 :   const TypeKind member_tk = member_type->get_kind();
    7152         175 :   if (is_basic(member_tk)) {
    7153         168 :     return serialized_size_basic_member(encoding, size, member_tk, it);
    7154           7 :   } else if (member_tk == TK_ENUM) {
    7155           7 :     return serialized_size_enum(encoding, size, member_type);
    7156             :   } else { // Bitmask
    7157           0 :     return serialized_size_bitmask(encoding, size, member_type);
    7158             :   }
    7159             : }
    7160             : 
    7161         210 : bool DynamicDataImpl::DataContainer::serialize_single_aggregated_member_xcdr2(DCPS::Serializer& ser,
    7162             :   const_single_iterator it, const DDS::DynamicType_var& member_type, bool optional,
    7163             :   bool must_understand, DDS::ExtensibilityKind extensibility) const
    7164             : {
    7165         210 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7166           0 :     if (!(ser << ACE_OutputCDR::from_boolean(true))) {
    7167           0 :       return false;
    7168             :     }
    7169         210 :   } else if (extensibility == DDS::MUTABLE) {
    7170          85 :     const DCPS::Encoding& encoding = ser.encoding();
    7171          85 :     const TypeKind member_tk = member_type->get_kind();
    7172          85 :     size_t member_size = 0;
    7173          85 :     if (is_basic(member_tk)) {
    7174          81 :       serialized_size_basic_member(encoding, member_size, member_tk, it);
    7175           4 :     } else if (member_tk == TK_ENUM) {
    7176           4 :       serialized_size_enum(encoding, member_size, member_type);
    7177           0 :     } else if (member_tk == TK_BITMASK) {
    7178           0 :       serialized_size_bitmask(encoding, member_size, member_type);
    7179             :     } else {
    7180           0 :       return false;
    7181             :     }
    7182          85 :     if (!ser.write_parameter_id(it->first, member_size, must_understand)) {
    7183           0 :       return false;
    7184             :     }
    7185             :   }
    7186         210 :   return serialize_single_value(ser, it->second);
    7187             : }
    7188             : 
    7189             : // Serialize a member of an aggregated type whose value must be represented by a DynamicData
    7190             : // object. However, the data for the member is missing from the complex map. So default value
    7191             : // of the corresponding type is used for serialization.
    7192          11 : bool DynamicDataImpl::DataContainer::serialized_size_complex_aggregated_member_xcdr2_default(
    7193             :   const DCPS::Encoding& encoding, size_t& size, const DDS::DynamicType_var& member_type,
    7194             :   bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total,
    7195             :   DCPS::Sample::Extent ext) const
    7196             : {
    7197          11 :   if (optional) {
    7198           0 :     if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7199           0 :       primitive_serialized_size_boolean(encoding, size);
    7200             :     }
    7201           0 :     return true;
    7202             :   }
    7203          11 :   if (extensibility == DDS::MUTABLE) {
    7204          11 :     serialized_size_parameter_id(encoding, size, mutable_running_total);
    7205             :   }
    7206             : 
    7207          11 :   return DynamicDataImpl(member_type).serialized_size_i(encoding, size, ext);
    7208             : }
    7209             : 
    7210           5 : bool DynamicDataImpl::DataContainer::serialize_complex_aggregated_member_xcdr2_default(
    7211             :   DCPS::Serializer& ser, DDS::MemberId id, const DDS::DynamicType_var& member_type,
    7212             :   bool optional, bool must_understand, DDS::ExtensibilityKind extensibility,
    7213             :   DCPS::Sample::Extent ext) const
    7214             : {
    7215           5 :   if (optional) {
    7216           0 :     if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7217           0 :       return ser << ACE_OutputCDR::from_boolean(false);
    7218             :     }
    7219           0 :     return true;
    7220             :   }
    7221             :   // Use default value if the member is not optional.
    7222           5 :   const DynamicDataImpl default_value(member_type);
    7223           5 :   if (extensibility == DDS::MUTABLE) {
    7224           5 :     size_t member_size = 0;
    7225           5 :     default_value.serialized_size_i(ser.encoding(), member_size, ext);
    7226           5 :     if (!ser.write_parameter_id(id, member_size, must_understand)) {
    7227           0 :       return false;
    7228             :     }
    7229             :   }
    7230           5 :   return default_value.serialize_i(ser, ext);
    7231           5 : }
    7232             : 
    7233             : // Serialize a member of an aggregated type stored in the complex map,
    7234             : // i.e., the member value is represented by a DynamicData object.
    7235          37 : bool DynamicDataImpl::DataContainer::serialized_size_complex_aggregated_member_xcdr2(
    7236             :   const DCPS::Encoding& encoding, size_t& size, const_complex_iterator it,
    7237             :   bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total,
    7238             :   DCPS::Sample::Extent ext) const
    7239             : {
    7240          37 :   const DDS::DynamicData_var& data_var = it->second;
    7241          37 :   const DynamicDataImpl* data_impl = dynamic_cast<DynamicDataImpl*>(data_var.in());
    7242          37 :   if (!data_impl) {
    7243           0 :     return false;
    7244             :   }
    7245             : 
    7246          37 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7247           0 :     primitive_serialized_size_boolean(encoding, size);
    7248          37 :   } else if (extensibility == DDS::MUTABLE) {
    7249          26 :     serialized_size_parameter_id(encoding, size, mutable_running_total);
    7250             :   }
    7251          37 :   return data_impl->serialized_size_i(encoding, size, ext);
    7252             : }
    7253             : 
    7254          40 : bool DynamicDataImpl::DataContainer::serialize_complex_aggregated_member_xcdr2(
    7255             :   DCPS::Serializer& ser, const_complex_iterator it, bool optional,
    7256             :   bool must_understand, DDS::ExtensibilityKind extensibility, DCPS::Sample::Extent ext) const
    7257             : {
    7258          40 :   const DDS::DynamicData_var& data_var = it->second;
    7259          40 :   const DynamicDataImpl* data_impl = dynamic_cast<DynamicDataImpl*>(data_var.in());
    7260          40 :   if (!data_impl) {
    7261           0 :     return false;
    7262             :   }
    7263             : 
    7264          40 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7265           0 :     if (!(ser << ACE_OutputCDR::from_boolean(true))) {
    7266           0 :       return false;
    7267             :     }
    7268          40 :   } else if (extensibility == DDS::MUTABLE) {
    7269          23 :     size_t member_size = 0;
    7270          46 :     if (!data_impl->serialized_size_i(ser.encoding(), member_size, ext) ||
    7271          23 :         !ser.write_parameter_id(it->first, member_size, must_understand)) {
    7272           0 :       return false;
    7273             :     }
    7274             :   }
    7275          40 :   return data_impl->serialize_i(ser, ext);
    7276             : }
    7277             : 
    7278             : // Serialize struct member whose type is basic or compatible with a basic type,
    7279             : // that are enum and bitmask types.
    7280         131 : bool DynamicDataImpl::DataContainer::serialized_size_basic_struct_member_xcdr2(
    7281             :   const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id,
    7282             :   const DDS::DynamicType_var& member_type, bool optional,
    7283             :   DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const
    7284             : {
    7285         131 :   const TypeKind member_tk = member_type->get_kind();
    7286         131 :   const_single_iterator single_it = single_map_.find(id);
    7287         131 :   const_complex_iterator complex_it = complex_map_.find(id);
    7288         131 :   if (single_it == single_map_.end() && complex_it == complex_map_.end()) {
    7289           8 :     if (optional) {
    7290           0 :       if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7291           0 :         primitive_serialized_size_boolean(encoding, size);
    7292             :       }
    7293           0 :       return true;
    7294             :     }
    7295           8 :     if (extensibility == DDS::MUTABLE) {
    7296           6 :       serialized_size_parameter_id(encoding, size, mutable_running_total);
    7297             :     }
    7298           8 :     if (is_basic(member_tk)) {
    7299           7 :       return serialized_size_basic_member_default_value(encoding, size, member_tk);
    7300           1 :     } else if (member_tk == TK_ENUM) {
    7301           1 :       return serialized_size_enum(encoding, size, member_type);
    7302             :     } else { // Bitmask
    7303           0 :       return serialized_size_bitmask(encoding, size, member_type);
    7304             :     }
    7305             :   }
    7306             : 
    7307         123 :   if (single_it != single_map_.end()) {
    7308         121 :     return serialized_size_single_aggregated_member_xcdr2(encoding, size, single_it, member_type,
    7309         121 :                                                           optional, extensibility, mutable_running_total);
    7310             :   }
    7311           2 :   return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional,
    7312             :                                                          extensibility, mutable_running_total,
    7313           2 :                                                          DCPS::Sample::Full);
    7314             : }
    7315             : 
    7316         150 : bool DynamicDataImpl::DataContainer::serialize_basic_struct_member_xcdr2(DCPS::Serializer& ser,
    7317             :   DDS::MemberId id, const DDS::DynamicType_var& member_type, bool optional,
    7318             :   bool must_understand, DDS::ExtensibilityKind extensibility) const
    7319             : {
    7320         150 :   const TypeKind member_tk = member_type->get_kind();
    7321         150 :   const DCPS::Encoding& encoding = ser.encoding();
    7322         150 :   const_single_iterator single_it = single_map_.find(id);
    7323         150 :   const_complex_iterator complex_it = complex_map_.find(id);
    7324         150 :   if (single_it == single_map_.end() && complex_it == complex_map_.end()) {
    7325           7 :     if (optional) {
    7326           0 :       if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7327           0 :         return ser << ACE_OutputCDR::from_boolean(false);
    7328             :       }
    7329           0 :       return true;
    7330             :     }
    7331           7 :     if (extensibility == DDS::MUTABLE) {
    7332           6 :       size_t member_size = 0;
    7333           6 :       if (is_basic(member_tk)) {
    7334           5 :         serialized_size_basic_member_default_value(encoding, member_size, member_tk);
    7335           1 :       } else if (member_tk == TK_ENUM) {
    7336           1 :         serialized_size_enum(encoding, member_size, member_type);
    7337           0 :       } else if (member_tk == TK_BITMASK) {
    7338           0 :         serialized_size_bitmask(encoding, member_size, member_type);
    7339             :       } else {
    7340           0 :         return false;
    7341             :       }
    7342           6 :       if (!ser.write_parameter_id(id, member_size, must_understand)) {
    7343           0 :         return false;
    7344             :       }
    7345             :     }
    7346           7 :     if (is_basic(member_tk)) {
    7347           6 :       return serialize_basic_member_default_value(ser, member_tk);
    7348           1 :     } else if (member_tk == TK_ENUM) {
    7349           1 :       return serialize_enum_default_value(ser, member_type);
    7350           0 :     } else if (member_tk == TK_BITMASK) {
    7351           0 :       return serialize_bitmask_default_value(ser, member_type);
    7352             :     }
    7353           0 :     return false;
    7354             :   }
    7355             : 
    7356         143 :   if (single_it != single_map_.end()) {
    7357         140 :     return serialize_single_aggregated_member_xcdr2(ser, single_it, member_type, optional,
    7358         140 :                                                     must_understand, extensibility);
    7359             :   }
    7360           3 :   return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional,
    7361             :                                                    must_understand, extensibility,
    7362           3 :                                                    DCPS::Sample::Full);
    7363             : }
    7364             : 
    7365          22 : void DynamicDataImpl::DataContainer::serialized_size_sequence_member_default_value(
    7366             :   const DCPS::Encoding& encoding, size_t& size, TypeKind elem_tk) const
    7367             : {
    7368             :   // Zero-length sequence
    7369          22 :   if (!is_primitive(elem_tk)) {
    7370           2 :     serialized_size_delimiter(encoding, size);
    7371             :   }
    7372          22 :   primitive_serialized_size_ulong(encoding, size);
    7373          22 : }
    7374             : 
    7375          11 : bool DynamicDataImpl::DataContainer::serialize_sequence_member_default_value(DCPS::Serializer& ser,
    7376             :                                                                              TypeKind elem_tk) const
    7377             : {
    7378             :   // Zero-length sequence
    7379          11 :   const DCPS::Encoding& encoding = ser.encoding();
    7380          11 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2 && !is_primitive(elem_tk)) {
    7381           1 :     if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) {
    7382           0 :       return false;
    7383             :     }
    7384             :   }
    7385          11 :   return ser << static_cast<CORBA::ULong>(0);
    7386             : }
    7387             : 
    7388         189 : bool DynamicDataImpl::DataContainer::serialized_size_basic_sequence(const DCPS::Encoding& encoding,
    7389             :   size_t& size, const_sequence_iterator it) const
    7390             : {
    7391         189 :   switch (it->second.elem_kind_) {
    7392          12 :   case TK_INT32: {
    7393          12 :     const DDS::Int32Seq& seq = it->second.get<DDS::Int32Seq>();
    7394          12 :     serialized_size(encoding, size, seq);
    7395          12 :     return true;
    7396             :   }
    7397           9 :   case TK_UINT32: {
    7398           9 :     const DDS::UInt32Seq& seq = it->second.get<DDS::UInt32Seq>();
    7399           9 :     serialized_size(encoding, size, seq);
    7400           9 :     return true;
    7401             :   }
    7402          12 :   case TK_INT8: {
    7403          12 :     const DDS::Int8Seq& seq = it->second.get<DDS::Int8Seq>();
    7404          12 :     serialized_size(encoding, size, seq);
    7405          12 :     return true;
    7406             :   }
    7407          12 :   case TK_UINT8: {
    7408          12 :     const DDS::UInt8Seq& seq = it->second.get<DDS::UInt8Seq>();
    7409          12 :     serialized_size(encoding, size, seq);
    7410          12 :     return true;
    7411             :   }
    7412          12 :   case TK_INT16: {
    7413          12 :     const DDS::Int16Seq& seq = it->second.get<DDS::Int16Seq>();
    7414          12 :     serialized_size(encoding, size, seq);
    7415          12 :     return true;
    7416             :   }
    7417          12 :   case TK_UINT16: {
    7418          12 :     const DDS::UInt16Seq& seq = it->second.get<DDS::UInt16Seq>();
    7419          12 :     serialized_size(encoding, size, seq);
    7420          12 :     return true;
    7421             :   }
    7422          12 :   case TK_INT64: {
    7423          12 :     const DDS::Int64Seq& seq = it->second.get<DDS::Int64Seq>();
    7424          12 :     serialized_size(encoding, size, seq);
    7425          12 :     return true;
    7426             :   }
    7427          12 :   case TK_UINT64: {
    7428          12 :     const DDS::UInt64Seq& seq = it->second.get<DDS::UInt64Seq>();
    7429          12 :     serialized_size(encoding, size, seq);
    7430          12 :     return true;
    7431             :   }
    7432          12 :   case TK_FLOAT32: {
    7433          12 :     const DDS::Float32Seq& seq = it->second.get<DDS::Float32Seq>();
    7434          12 :     serialized_size(encoding, size, seq);
    7435          12 :     return true;
    7436             :   }
    7437          12 :   case TK_FLOAT64: {
    7438          12 :     const DDS::Float64Seq& seq = it->second.get<DDS::Float64Seq>();
    7439          12 :     serialized_size(encoding, size, seq);
    7440          12 :     return true;
    7441             :   }
    7442           0 :   case TK_FLOAT128: {
    7443           0 :     const DDS::Float128Seq& seq = it->second.get<DDS::Float128Seq>();
    7444           0 :     serialized_size(encoding, size, seq);
    7445           0 :     return true;
    7446             :   }
    7447          12 :   case TK_CHAR8: {
    7448          12 :     const DDS::CharSeq& seq = it->second.get<DDS::CharSeq>();
    7449          12 :     serialized_size(encoding, size, seq);
    7450          12 :     return true;
    7451             :   }
    7452          12 :   case TK_BYTE: {
    7453          12 :     const DDS::ByteSeq& seq = it->second.get<DDS::ByteSeq>();
    7454          12 :     serialized_size(encoding, size, seq);
    7455          12 :     return true;
    7456             :   }
    7457          12 :   case TK_BOOLEAN: {
    7458          12 :     const DDS::BooleanSeq& seq = it->second.get<DDS::BooleanSeq>();
    7459          12 :     serialized_size(encoding, size, seq);
    7460          12 :     return true;
    7461             :   }
    7462          12 :   case TK_STRING8: {
    7463          12 :     const DDS::StringSeq& seq = it->second.get<DDS::StringSeq>();
    7464          12 :     serialized_size(encoding, size, seq);
    7465          12 :     return true;
    7466             :   }
    7467             : #ifdef DDS_HAS_WCHAR
    7468          12 :   case TK_CHAR16: {
    7469          12 :     const DDS::WcharSeq& seq = it->second.get<DDS::WcharSeq>();
    7470          12 :     serialized_size(encoding, size, seq);
    7471          12 :     return true;
    7472             :   }
    7473          12 :   case TK_STRING16: {
    7474          12 :     const DDS::WstringSeq& seq = it->second.get<DDS::WstringSeq>();
    7475          12 :     serialized_size(encoding, size, seq);
    7476          12 :     return true;
    7477             :   }
    7478             : #endif
    7479             :   }
    7480           0 :   return false;
    7481             : }
    7482             : 
    7483         189 : bool DynamicDataImpl::DataContainer::serialize_basic_sequence(DCPS::Serializer& ser,
    7484             :                                                               const_sequence_iterator it) const
    7485             : {
    7486         189 :   switch (it->second.elem_kind_) {
    7487          12 :   case TK_INT32: {
    7488          12 :     const DDS::Int32Seq& seq = it->second.get<DDS::Int32Seq>();
    7489          12 :     return ser << seq;
    7490             :   }
    7491           9 :   case TK_UINT32: {
    7492           9 :     const DDS::UInt32Seq& seq = it->second.get<DDS::UInt32Seq>();
    7493           9 :     return ser << seq;
    7494             :   }
    7495          12 :   case TK_INT8: {
    7496          12 :     const DDS::Int8Seq& seq = it->second.get<DDS::Int8Seq>();
    7497          12 :     return ser << seq;
    7498             :   }
    7499          12 :   case TK_UINT8: {
    7500          12 :     const DDS::UInt8Seq& seq = it->second.get<DDS::UInt8Seq>();
    7501          12 :     return ser << seq;
    7502             :   }
    7503          12 :   case TK_INT16: {
    7504          12 :     const DDS::Int16Seq& seq = it->second.get<DDS::Int16Seq>();
    7505          12 :     return ser << seq;
    7506             :   }
    7507          12 :   case TK_UINT16: {
    7508          12 :     const DDS::UInt16Seq& seq = it->second.get<DDS::UInt16Seq>();
    7509          12 :     return ser << seq;
    7510             :   }
    7511          12 :   case TK_INT64: {
    7512          12 :     const DDS::Int64Seq& seq = it->second.get<DDS::Int64Seq>();
    7513          12 :     return ser << seq;
    7514             :   }
    7515          12 :   case TK_UINT64: {
    7516          12 :     const DDS::UInt64Seq& seq = it->second.get<DDS::UInt64Seq>();
    7517          12 :     return ser << seq;
    7518             :   }
    7519          12 :   case TK_FLOAT32: {
    7520          12 :     const DDS::Float32Seq& seq = it->second.get<DDS::Float32Seq>();
    7521          12 :     return ser << seq;
    7522             :   }
    7523          12 :   case TK_FLOAT64: {
    7524          12 :     const DDS::Float64Seq& seq = it->second.get<DDS::Float64Seq>();
    7525          12 :     return ser << seq;
    7526             :   }
    7527           0 :   case TK_FLOAT128: {
    7528           0 :     const DDS::Float128Seq& seq = it->second.get<DDS::Float128Seq>();
    7529           0 :     return ser << seq;
    7530             :   }
    7531          12 :   case TK_CHAR8: {
    7532          12 :     const DDS::CharSeq& seq = it->second.get<DDS::CharSeq>();
    7533          12 :     return ser << seq;
    7534             :   }
    7535          12 :   case TK_BYTE: {
    7536          12 :     const DDS::ByteSeq& seq = it->second.get<DDS::ByteSeq>();
    7537          12 :     return ser << seq;
    7538             :   }
    7539          12 :   case TK_BOOLEAN: {
    7540          12 :     const DDS::BooleanSeq& seq = it->second.get<DDS::BooleanSeq>();
    7541          12 :     return ser << seq;
    7542             :   }
    7543          12 :   case TK_STRING8: {
    7544          12 :     const DDS::StringSeq& seq = it->second.get<DDS::StringSeq>();
    7545          12 :     return ser << seq;
    7546             :   }
    7547             : #ifdef DDS_HAS_WCHAR
    7548          12 :   case TK_CHAR16: {
    7549          12 :     const DDS::WcharSeq& seq = it->second.get<DDS::WcharSeq>();
    7550          12 :     return ser << seq;
    7551             :   }
    7552          12 :   case TK_STRING16: {
    7553          12 :     const DDS::WstringSeq& seq = it->second.get<DDS::WstringSeq>();
    7554          12 :     return ser << seq;
    7555             :   }
    7556             : #endif
    7557             :   }
    7558           0 :   return false;
    7559             : }
    7560             : 
    7561           3 : bool DynamicDataImpl::DataContainer::serialized_size_enum_sequence(
    7562             :   const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it) const
    7563             : {
    7564           3 :   switch (it->second.elem_kind_) {
    7565           0 :   case TK_INT8: {
    7566           0 :     const DDS::Int8Seq& seq = it->second.get<DDS::Int8Seq>();
    7567           0 :     serialized_size_enum_sequence(encoding, size, seq);
    7568           0 :     return true;
    7569             :   }
    7570           0 :   case TK_INT16: {
    7571           0 :     const DDS::Int16Seq& seq = it->second.get<DDS::Int16Seq>();
    7572           0 :     serialized_size_enum_sequence(encoding, size, seq);
    7573           0 :     return true;
    7574             :   }
    7575           3 :   case TK_INT32: {
    7576           3 :     const DDS::Int32Seq& seq = it->second.get<DDS::Int32Seq>();
    7577           3 :     serialized_size_enum_sequence(encoding, size, seq);
    7578           3 :     return true;
    7579             :   }
    7580             :   }
    7581           0 :   return false;
    7582             : }
    7583             : 
    7584           3 : bool DynamicDataImpl::DataContainer::serialize_enum_sequence(
    7585             :   DCPS::Serializer& ser, const_sequence_iterator it) const
    7586             : {
    7587           3 :   switch (it->second.elem_kind_) {
    7588           0 :   case TK_INT8: {
    7589           0 :     const DDS::Int8Seq& seq = it->second.get<DDS::Int8Seq>();
    7590           0 :     return serialize_enum_sequence_as_ints_i(ser, seq);
    7591             :   }
    7592           0 :   case TK_INT16: {
    7593           0 :     const DDS::Int16Seq& seq = it->second.get<DDS::Int16Seq>();
    7594           0 :     return serialize_enum_sequence_as_ints_i(ser, seq);
    7595             :   }
    7596           3 :   case TK_INT32: {
    7597           3 :     const DDS::Int32Seq& seq = it->second.get<DDS::Int32Seq>();
    7598           3 :     return serialize_enum_sequence_as_ints_i(ser, seq);
    7599             :   }
    7600             :   }
    7601           0 :   return false;
    7602             : }
    7603             : 
    7604           0 : bool DynamicDataImpl::DataContainer::serialized_size_bitmask_sequence(
    7605             :   const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it) const
    7606             : {
    7607           0 :   switch (it->second.elem_kind_) {
    7608           0 :   case TK_UINT8: {
    7609           0 :     const DDS::UInt8Seq& seq = it->second.get<DDS::UInt8Seq>();
    7610           0 :     serialized_size_bitmask_sequence(encoding, size, seq);
    7611           0 :     return true;
    7612             :   }
    7613           0 :   case TK_UINT16: {
    7614           0 :     const DDS::UInt16Seq& seq = it->second.get<DDS::UInt16Seq>();
    7615           0 :     serialized_size_bitmask_sequence(encoding, size, seq);
    7616           0 :     return true;
    7617             :   }
    7618           0 :   case TK_UINT32: {
    7619           0 :     const DDS::UInt32Seq& seq = it->second.get<DDS::UInt32Seq>();
    7620           0 :     serialized_size_bitmask_sequence(encoding, size, seq);
    7621           0 :     return true;
    7622             :   }
    7623           0 :   case TK_UINT64: {
    7624           0 :     const DDS::UInt64Seq& seq = it->second.get<DDS::UInt64Seq>();
    7625           0 :     serialized_size_bitmask_sequence(encoding, size, seq);
    7626           0 :     return true;
    7627             :   }
    7628             :   }
    7629           0 :   return false;
    7630             : }
    7631             : 
    7632           0 : bool DynamicDataImpl::DataContainer::serialize_bitmask_sequence(DCPS::Serializer& ser,
    7633             :                                                                 const_sequence_iterator it) const
    7634             : {
    7635           0 :   switch (it->second.elem_kind_) {
    7636           0 :   case TK_UINT8: {
    7637           0 :     const DDS::UInt8Seq& seq = it->second.get<DDS::UInt8Seq>();
    7638           0 :     return serialize_bitmask_sequence_as_uints_i(ser, seq);
    7639             :   }
    7640           0 :   case TK_UINT16: {
    7641           0 :     const DDS::UInt16Seq& seq = it->second.get<DDS::UInt16Seq>();
    7642           0 :     return serialize_bitmask_sequence_as_uints_i(ser, seq);
    7643             :   }
    7644           0 :   case TK_UINT32: {
    7645           0 :     const DDS::UInt32Seq& seq = it->second.get<DDS::UInt32Seq>();
    7646           0 :     return serialize_bitmask_sequence_as_uints_i(ser, seq);
    7647             :   }
    7648           0 :   case TK_UINT64: {
    7649           0 :     const DDS::UInt64Seq& seq = it->second.get<DDS::UInt64Seq>();
    7650           0 :     return serialize_bitmask_sequence_as_uints_i(ser, seq);
    7651             :   }
    7652             :   }
    7653           0 :   return false;
    7654             : }
    7655             : 
    7656             : // Serialize an aggregated member stored in the sequence map.
    7657             : // The member type is sequence of basic or enum or bitmask type.
    7658         128 : void DynamicDataImpl::DataContainer::serialized_size_sequence_aggregated_member_xcdr2(
    7659             :   const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it, TypeKind elem_tk,
    7660             :   bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const
    7661             : {
    7662         128 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7663           0 :     primitive_serialized_size_boolean(encoding, size);
    7664         128 :   } else if (extensibility == DDS::MUTABLE) {
    7665          64 :     serialized_size_parameter_id(encoding, size, mutable_running_total);
    7666             :   }
    7667         128 :   if (is_basic(elem_tk)) {
    7668         126 :     serialized_size_basic_sequence(encoding, size, it);
    7669           2 :   } else if (elem_tk == TK_ENUM) {
    7670           2 :     serialized_size_enum_sequence(encoding, size, it);
    7671             :   } else { // Bitmask
    7672           0 :     serialized_size_bitmask_sequence(encoding, size, it);
    7673             :   }
    7674         128 : }
    7675             : 
    7676         192 : bool DynamicDataImpl::DataContainer::serialize_sequence_aggregated_member_xcdr2(DCPS::Serializer& ser,
    7677             :   const_sequence_iterator it, TypeKind elem_tk, bool optional,
    7678             :   bool must_understand, DDS::ExtensibilityKind extensibility) const
    7679             : {
    7680         192 :   if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) {
    7681           0 :     if (!(ser << ACE_OutputCDR::from_boolean(true))) {
    7682           0 :       return false;
    7683             :     }
    7684         192 :   } else if (extensibility == DDS::MUTABLE) {
    7685          64 :     const DCPS::Encoding& encoding = ser.encoding();
    7686          64 :     size_t member_size = 0;
    7687          64 :     if (is_basic(elem_tk)) {
    7688          63 :       serialized_size_basic_sequence(encoding, member_size, it);
    7689           1 :     } else if (elem_tk == TK_ENUM) {
    7690           1 :       serialized_size_enum_sequence(encoding, member_size, it);
    7691           0 :     } else if (elem_tk == TK_BITMASK) {
    7692           0 :       serialized_size_bitmask_sequence(encoding, member_size, it);
    7693             :     } else {
    7694           0 :       return false;
    7695             :     }
    7696          64 :     if (!ser.write_parameter_id(it->first, member_size, must_understand)) {
    7697           0 :       return false;
    7698             :     }
    7699             :   }
    7700         192 :   if (is_basic(elem_tk)) {
    7701         189 :     return serialize_basic_sequence(ser, it);
    7702           3 :   } else if (elem_tk == TK_ENUM) {
    7703           3 :     return serialize_enum_sequence(ser, it);
    7704           0 :   } else if (elem_tk == TK_BITMASK) {
    7705           0 :     return serialize_bitmask_sequence(ser, it);
    7706             :   }
    7707           0 :   return false;
    7708             : }
    7709             : 
    7710             : // Serialize a struct member whose type is sequence of basic type or enum or bitmask.
    7711          85 : bool DynamicDataImpl::DataContainer::serialized_size_sequence_struct_member_xcdr2(
    7712             :   const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id, TypeKind elem_tk,
    7713             :   bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total,
    7714             :   DCPS::Sample::Extent) const
    7715             : {
    7716          85 :   const_sequence_iterator seq_it = sequence_map_.find(id);
    7717          85 :   const_complex_iterator complex_it = complex_map_.find(id);
    7718          85 :   if (seq_it == sequence_map_.end() && complex_it == complex_map_.end()) {
    7719          11 :     if (optional) {
    7720           0 :       if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7721           0 :         primitive_serialized_size_boolean(encoding, size);
    7722             :       }
    7723           0 :       return true;
    7724             :     }
    7725          11 :     if (extensibility == DDS::MUTABLE) {
    7726          11 :       serialized_size_parameter_id(encoding, size, mutable_running_total);
    7727             :     }
    7728          11 :     serialized_size_sequence_member_default_value(encoding, size, elem_tk);
    7729          11 :     return true;
    7730             :   }
    7731          74 :   if (seq_it != sequence_map_.end()) {
    7732          64 :     serialized_size_sequence_aggregated_member_xcdr2(encoding, size, seq_it, elem_tk, optional,
    7733             :                                                      extensibility, mutable_running_total);
    7734          64 :     return true;
    7735             :   }
    7736          10 :   return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional,
    7737             :                                                          extensibility, mutable_running_total,
    7738          10 :                                                          DCPS::Sample::Full);
    7739             : }
    7740             : 
    7741         119 : bool DynamicDataImpl::DataContainer::serialize_sequence_struct_member_xcdr2(DCPS::Serializer& ser,
    7742             :   DDS::MemberId id, TypeKind elem_tk, bool optional,
    7743             :   bool must_understand, DDS::ExtensibilityKind extensibility,
    7744             :   DCPS::Sample::Extent ext) const
    7745             : {
    7746         119 :   const DCPS::Encoding& encoding = ser.encoding();
    7747         119 :   const_sequence_iterator seq_it = sequence_map_.find(id);
    7748         119 :   const_complex_iterator complex_it = complex_map_.find(id);
    7749         119 :   if (seq_it == sequence_map_.end() && complex_it == complex_map_.end()) {
    7750          11 :     if (optional) {
    7751           0 :       if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) {
    7752           0 :         return ser << ACE_OutputCDR::from_boolean(false);
    7753             :       }
    7754           0 :       return true;
    7755             :     }
    7756          11 :     if (extensibility == DDS::MUTABLE) {
    7757          11 :       size_t member_size = 0;
    7758          11 :       serialized_size_sequence_member_default_value(encoding, member_size, elem_tk);
    7759          11 :       if (!ser.write_parameter_id(id, member_size, must_understand)) {
    7760           0 :         return false;
    7761             :       }
    7762             :     }
    7763          11 :     return serialize_sequence_member_default_value(ser, elem_tk);
    7764             :   }
    7765             : 
    7766         108 :   if (seq_it != sequence_map_.end()) {
    7767          96 :     return serialize_sequence_aggregated_member_xcdr2(ser, seq_it, elem_tk, optional,
    7768          96 :                                                       must_understand, extensibility);
    7769             :   }
    7770          12 :   return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional,
    7771          12 :                                                    must_understand, extensibility, ext);
    7772             : }
    7773             : 
    7774          54 : bool DynamicDataImpl::DataContainer::serialized_size_structure_xcdr2(
    7775             :   const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const
    7776             : {
    7777          54 :   const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind();
    7778          54 :   const bool struct_has_explicit_keys = has_explicit_keys(type_);
    7779             : 
    7780             :   // Delimiter
    7781          54 :   if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) {
    7782          39 :     serialized_size_delimiter(encoding, size);
    7783             :   }
    7784             : 
    7785             :   // Members
    7786          54 :   size_t mutable_running_total = 0;
    7787          54 :   const CORBA::ULong member_count = type_->get_member_count();
    7788         330 :   for (CORBA::ULong i = 0; i < member_count; ++i) {
    7789         276 :     DDS::DynamicTypeMember_var dtm;
    7790         276 :     if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
    7791           0 :       return false;
    7792             :     }
    7793         276 :     DDS::MemberDescriptor_var md;
    7794         276 :     if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    7795           0 :       return false;
    7796             :     }
    7797             : 
    7798         276 :     if (exclude_member(ext, md->is_key(), struct_has_explicit_keys)) {
    7799          26 :       continue;
    7800             :     }
    7801             : 
    7802         250 :     const DDS::MemberId id = md->id();
    7803         250 :     const CORBA::Boolean optional = md->is_optional();
    7804         250 :     const DDS::DynamicType_var member_type = get_base_type(md->type());
    7805         250 :     const TypeKind member_tk = member_type->get_kind();
    7806             : 
    7807         250 :     if (is_basic(member_tk) || member_tk == TK_ENUM || member_tk == TK_BITMASK) {
    7808         131 :       if (!serialized_size_basic_struct_member_xcdr2(encoding, size, id, member_type, optional,
    7809             :                                                      extensibility, mutable_running_total)) {
    7810           0 :         return false;
    7811             :       }
    7812         131 :       continue;
    7813         119 :     } else if (member_tk == TK_SEQUENCE) {
    7814          94 :       DDS::TypeDescriptor_var member_td;
    7815          94 :       if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
    7816           0 :         return false;
    7817             :       }
    7818          94 :       const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type());
    7819          94 :       const TypeKind elem_tk = elem_type->get_kind();
    7820          94 :       if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) {
    7821          85 :         if (!serialized_size_sequence_struct_member_xcdr2(encoding, size, id, elem_tk, optional,
    7822             :                                                           extensibility, mutable_running_total, nested(ext))) {
    7823           0 :           return false;
    7824             :         }
    7825          85 :         continue;
    7826             :       }
    7827         179 :     }
    7828             : 
    7829          34 :     const_complex_iterator it = complex_map_.find(id);
    7830          34 :     if (it != complex_map_.end()) {
    7831          25 :       if (!serialized_size_complex_aggregated_member_xcdr2(encoding, size, it, optional,
    7832             :                                                            extensibility, mutable_running_total,
    7833             :                                                            nested(ext))) {
    7834           0 :         return false;
    7835             :       }
    7836           9 :     } else if (!serialized_size_complex_aggregated_member_xcdr2_default(encoding, size, member_type, optional,
    7837             :                                                                         extensibility, mutable_running_total,
    7838             :                                                                         nested(ext))) {
    7839           0 :       return false;
    7840             :     }
    7841         734 :   }
    7842             : 
    7843          54 :   if (extensibility == DDS::MUTABLE) {
    7844          26 :     serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);
    7845             :   }
    7846          54 :   return true;
    7847             : }
    7848             : 
    7849          41 : bool DynamicDataImpl::DataContainer::serialize_structure_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    7850             : {
    7851          41 :   const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind();
    7852          41 :   const bool struct_has_explicit_keys = has_explicit_keys(type_);
    7853             : 
    7854             :   // Delimiter
    7855          41 :   const DCPS::Encoding& encoding = ser.encoding();
    7856          41 :   size_t total_size = 0;
    7857          41 :   if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) {
    7858          25 :     if (!data_->serialized_size_i(encoding, total_size, ext) || !ser.write_delimiter(total_size)) {
    7859           0 :       return false;
    7860             :     }
    7861             :   }
    7862             : 
    7863             :   // Members
    7864          41 :   const CORBA::ULong member_count = type_->get_member_count();
    7865         354 :   for (CORBA::ULong i = 0; i < member_count; ++i) {
    7866         313 :     DDS::DynamicTypeMember_var dtm;
    7867         313 :     if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) {
    7868           0 :       return false;
    7869             :     }
    7870         313 :     DDS::MemberDescriptor_var md;
    7871         313 :     if (dtm->get_descriptor(md) != DDS::RETCODE_OK) {
    7872           0 :       return false;
    7873             :     }
    7874             : 
    7875         313 :     if (exclude_member(ext, md->is_key(), struct_has_explicit_keys)) {
    7876          16 :       continue;
    7877             :     }
    7878             : 
    7879         297 :     const DDS::MemberId id = md->id();
    7880         297 :     const CORBA::Boolean optional = md->is_optional();
    7881         297 :     const CORBA::Boolean must_understand = md->is_must_understand() || md->is_key();
    7882         297 :     const DDS::DynamicType_var member_type = get_base_type(md->type());
    7883         297 :     const TypeKind member_tk = member_type->get_kind();
    7884             : 
    7885         297 :     if (is_basic(member_tk) || member_tk == TK_ENUM || member_tk == TK_BITMASK) {
    7886         150 :       if (!serialize_basic_struct_member_xcdr2(ser, id, member_type, optional,
    7887             :                                                must_understand, extensibility)) {
    7888           0 :         return false;
    7889             :       }
    7890         150 :       continue;
    7891         147 :     } else if (member_tk == TK_SEQUENCE) {
    7892         122 :       DDS::TypeDescriptor_var member_td;
    7893         122 :       if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) {
    7894           0 :         return false;
    7895             :       }
    7896         122 :       const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type());
    7897         122 :       const TypeKind elem_tk = elem_type->get_kind();
    7898         122 :       if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) {
    7899         119 :         if (!serialize_sequence_struct_member_xcdr2(ser, id, elem_tk, optional,
    7900             :                                                     must_understand, extensibility, nested(ext))) {
    7901           0 :           return false;
    7902             :         }
    7903         119 :         continue;
    7904             :       }
    7905         241 :     }
    7906             : 
    7907          28 :     const_complex_iterator it = complex_map_.find(id);
    7908          28 :     if (it != complex_map_.end()) {
    7909          25 :       if (!serialize_complex_aggregated_member_xcdr2(ser, it, optional,
    7910             :                                                      must_understand, extensibility, nested(ext))) {
    7911           0 :         return false;
    7912             :       }
    7913           3 :     } else if (!serialize_complex_aggregated_member_xcdr2_default(ser, id, member_type, optional,
    7914             :                                                                   must_understand, extensibility, nested(ext))) {
    7915           0 :       return false;
    7916             :     }
    7917         867 :   }
    7918          41 :   return true;
    7919             : }
    7920             : 
    7921           0 : bool DynamicDataImpl::DataContainer::serialized_size_structure_xcdr1(
    7922             :   const DCPS::Encoding& /*encoding*/, size_t& /*size*/, DCPS::Sample::Extent /*ext*/) const
    7923             : {
    7924             :   // TODO: Support Final & Mutable extensibility?
    7925           0 :   return false;
    7926             : }
    7927             : 
    7928           0 : bool DynamicDataImpl::DataContainer::serialize_structure_xcdr1(DCPS::Serializer& /*ser*/, DCPS::Sample::Extent) const
    7929             : {
    7930             :   // TODO: Support only Final & Mutable extensibility?
    7931           0 :   return false;
    7932             : }
    7933             : 
    7934          54 : bool DynamicDataImpl::DataContainer::serialized_size_structure(const DCPS::Encoding& encoding,
    7935             :                                                                size_t& size,
    7936             :                                                                DCPS::Sample::Extent ext) const
    7937             : {
    7938          54 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    7939          54 :     return serialized_size_structure_xcdr2(encoding, size, ext);
    7940           0 :   } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) {
    7941           0 :     return serialized_size_structure_xcdr1(encoding, size, ext);
    7942             :   }
    7943           0 :   return false;
    7944             : }
    7945             : 
    7946          41 : bool DynamicDataImpl::DataContainer::serialize_structure(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    7947             : {
    7948          41 :   const DCPS::Encoding& encoding = ser.encoding();
    7949          41 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    7950          41 :     return serialize_structure_xcdr2(ser, ext);
    7951           0 :   } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) {
    7952           0 :     return serialize_structure_xcdr1(ser, ext);
    7953             :   }
    7954           0 :   return false;
    7955             : }
    7956             : 
    7957             : // Set discriminator to the default value of the corresponding type.
    7958           5 : bool DynamicDataImpl::DataContainer::set_default_discriminator_value(
    7959             :   CORBA::Long& value, const DDS::DynamicType_var& disc_type) const
    7960             : {
    7961           5 :   const TypeKind disc_tk = disc_type->get_kind();
    7962           5 :   switch (disc_tk) {
    7963           0 :   case TK_BOOLEAN: {
    7964           0 :     ACE_OutputCDR::from_boolean val(false);
    7965           0 :     set_default_basic_value(val);
    7966           0 :     value = static_cast<CORBA::Long>(val.val_);
    7967           0 :     return true;
    7968             :   }
    7969           0 :   case TK_BYTE: {
    7970           0 :     ACE_OutputCDR::from_octet val(0x00);
    7971           0 :     set_default_basic_value(val);
    7972           0 :     value = static_cast<CORBA::Long>(val.val_);
    7973           0 :     return true;
    7974             :   }
    7975           0 :   case TK_CHAR8: {
    7976           0 :     ACE_OutputCDR::from_char val('\0');
    7977           0 :     set_default_basic_value(val);
    7978           0 :     value = static_cast<CORBA::Long>(val.val_);
    7979           0 :     return true;
    7980             :   }
    7981             : #ifdef DDS_HAS_WCHAR
    7982           0 :   case TK_CHAR16: {
    7983           0 :     ACE_OutputCDR::from_wchar val(0);
    7984           0 :     set_default_basic_value(val);
    7985           0 :     value = static_cast<CORBA::Long>(val.val_);
    7986           0 :     return true;
    7987             :   }
    7988             : #endif
    7989           0 :   case TK_INT8: {
    7990           0 :     ACE_OutputCDR::from_int8 val(0);
    7991           0 :     set_default_basic_value(val);
    7992           0 :     value = static_cast<CORBA::Long>(val.val_);
    7993           0 :     return true;
    7994             :   }
    7995           0 :   case TK_UINT8: {
    7996           0 :     ACE_OutputCDR::from_uint8 val(0);
    7997           0 :     set_default_basic_value(val);
    7998           0 :     value = static_cast<CORBA::Long>(val.val_);
    7999           0 :     return true;
    8000             :   }
    8001           0 :   case TK_INT16: {
    8002             :     CORBA::Short val;
    8003           0 :     set_default_basic_value(val);
    8004           0 :     value = static_cast<CORBA::Long>(val);
    8005           0 :     return true;
    8006             :   }
    8007           0 :   case TK_UINT16: {
    8008             :     CORBA::UShort val;
    8009           0 :     set_default_basic_value(val);
    8010           0 :     value = static_cast<CORBA::Long>(val);
    8011           0 :     return true;
    8012             :   }
    8013           0 :   case TK_INT32: {
    8014           0 :     set_default_basic_value(value);
    8015           0 :     return true;
    8016             :   }
    8017           0 :   case TK_UINT32: {
    8018             :     CORBA::ULong val;
    8019           0 :     set_default_basic_value(val);
    8020           0 :     value = static_cast<CORBA::Long>(val);
    8021           0 :     return true;
    8022             :   }
    8023           0 :   case TK_INT64: {
    8024             :     CORBA::LongLong val;
    8025           0 :     set_default_basic_value(val);
    8026           0 :     value = static_cast<CORBA::Long>(val);
    8027           0 :     return true;
    8028             :   }
    8029           0 :   case TK_UINT64: {
    8030             :     CORBA::ULongLong val;
    8031           0 :     set_default_basic_value(val);
    8032           0 :     value = static_cast<CORBA::Long>(val);
    8033           0 :     return true;
    8034             :   }
    8035           5 :   case TK_ENUM: {
    8036           5 :     return set_default_enum_value(disc_type, value);
    8037             :   }
    8038             :   }
    8039           0 :   return false;
    8040             : }
    8041             : 
    8042             : // Get discriminator value from the data container. The discriminator data must present
    8043             : // in either single map or complex map.
    8044         285 : bool DynamicDataImpl::DataContainer::get_discriminator_value(
    8045             :   CORBA::Long& value, const_single_iterator single_it, const_complex_iterator complex_it,
    8046             :   const DDS::DynamicType_var& disc_type) const
    8047             : {
    8048         285 :   if (single_it != single_map_.end()) {
    8049         285 :     data_->read_discriminator(value, disc_type, single_it);
    8050             :   } else { // Find in complex map
    8051           0 :     const DynamicDataImpl* dd_impl = dynamic_cast<const DynamicDataImpl*>(complex_it->second.in());
    8052           0 :     if (!dd_impl) {
    8053           0 :       return false;
    8054             :     }
    8055           0 :     const_single_iterator it = dd_impl->container_.single_map_.find(MEMBER_ID_INVALID);
    8056           0 :     if (it != dd_impl->container_.single_map_.end()) {
    8057           0 :       data_->read_discriminator(value, disc_type, it);
    8058             :     } else {
    8059           0 :       return set_default_discriminator_value(value, disc_type);
    8060             :     }
    8061             :   }
    8062         285 :   return true;
    8063             : }
    8064             : 
    8065         123 : bool DynamicDataImpl::DataContainer::serialized_size_discriminator_member_xcdr2(
    8066             :   const DCPS::Encoding& encoding, size_t& size, const DDS::DynamicType_var& disc_type,
    8067             :   DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const
    8068             : {
    8069         123 :   if (extensibility == DDS::MUTABLE) {
    8070          67 :     serialized_size_parameter_id(encoding, size, mutable_running_total);
    8071             :   }
    8072         123 :   const TypeKind disc_tk = disc_type->get_kind();
    8073         123 :   if (is_primitive(disc_tk)) {
    8074           0 :     return serialized_size_primitive_member(encoding, size, disc_tk);
    8075             :   }
    8076         123 :   return serialized_size_enum(encoding, size, disc_type);
    8077             : }
    8078             : 
    8079           3 : bool DynamicDataImpl::DataContainer::serialize_discriminator_member_xcdr2(
    8080             :   DCPS::Serializer& ser, CORBA::Long value, const DDS::DynamicType_var& disc_type,
    8081             :   DDS::ExtensibilityKind extensibility) const
    8082             : {
    8083           3 :   const DCPS::Encoding& encoding = ser.encoding();
    8084           3 :   const TypeKind disc_tk = disc_type->get_kind();
    8085           3 :   if (extensibility == DDS::MUTABLE) {
    8086           2 :     size_t disc_size = 0;
    8087           2 :     if (is_primitive(disc_tk)) {
    8088           0 :       serialized_size_primitive_member(encoding, disc_size, disc_tk);
    8089             :     } else {
    8090           2 :       serialized_size_enum(encoding, disc_size, disc_type);
    8091             :     }
    8092             :     // Use member Id 0 for discriminator?
    8093           2 :     if (!ser.write_parameter_id(0, disc_size, false)) {
    8094           0 :       return false;
    8095             :     }
    8096             :   }
    8097             : 
    8098           3 :   switch (disc_tk) {
    8099           0 :   case TK_BOOLEAN:
    8100           0 :     return ser << static_cast<CORBA::Boolean>(value);
    8101           0 :   case TK_BYTE:
    8102           0 :     return ser << static_cast<CORBA::Octet>(value);
    8103           0 :   case TK_CHAR8:
    8104           0 :     return ser << static_cast<CORBA::Char>(value);
    8105             : #ifdef DDS_HAS_WCHAR
    8106           0 :   case TK_CHAR16:
    8107           0 :     return ser << static_cast<CORBA::WChar>(value);
    8108             : #endif
    8109           0 :   case TK_INT8:
    8110           0 :     return ser << static_cast<CORBA::Int8>(value);
    8111           0 :   case TK_UINT8:
    8112           0 :     return ser << static_cast<CORBA::UInt8>(value);
    8113           0 :   case TK_INT16:
    8114           0 :     return ser << static_cast<CORBA::Short>(value);
    8115           0 :   case TK_UINT16:
    8116           0 :     return ser << static_cast<CORBA::UShort>(value);
    8117           0 :   case TK_INT32:
    8118           0 :     return ser << value;
    8119           0 :   case TK_UINT32:
    8120           0 :     return ser << static_cast<CORBA::ULong>(value);
    8121           0 :   case TK_INT64:
    8122           0 :     return ser << static_cast<CORBA::LongLong>(value);
    8123           0 :   case TK_UINT64:
    8124           0 :     return ser << static_cast<CORBA::ULongLong>(value);
    8125           3 :   case TK_ENUM: {
    8126           3 :     DDS::TypeDescriptor_var td;
    8127           3 :     if (disc_type->get_descriptor(td) != DDS::RETCODE_OK) {
    8128           0 :       return false;
    8129             :     }
    8130           3 :     const CORBA::ULong bitbound = td->bound()[0];
    8131           3 :     if (bitbound >= 1 && bitbound <= 8) {
    8132           0 :       return ser << static_cast<CORBA::Int8>(value);
    8133           3 :     } else if (bitbound >= 9 && bitbound <= 16) {
    8134           0 :       return ser << static_cast<CORBA::Short>(value);
    8135           3 :     } else if (bitbound >= 17 && bitbound <= 32) {
    8136           3 :       return ser << value;
    8137             :     }
    8138           3 :   }
    8139             :   }
    8140           0 :   return false;
    8141             : }
    8142             : 
    8143         118 : bool DynamicDataImpl::DataContainer::serialized_size_selected_member_xcdr2(
    8144             :   const DCPS::Encoding& encoding, size_t& size, DDS::MemberId selected_id,
    8145             :   DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const
    8146             : {
    8147         118 :   DDS::DynamicTypeMember_var selected_dtm;
    8148         118 :   if (type_->get_member(selected_dtm, selected_id) != DDS::RETCODE_OK) {
    8149           0 :     return false;
    8150             :   }
    8151         118 :   DDS::MemberDescriptor_var selected_md;
    8152         118 :   if (selected_dtm->get_descriptor(selected_md) != DDS::RETCODE_OK) {
    8153           0 :     return false;
    8154             :   }
    8155         118 :   DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    8156         118 :   const bool optional = selected_md->is_optional();
    8157             : 
    8158         118 :   const_single_iterator single_it = single_map_.find(selected_id);
    8159         118 :   if (single_it != single_map_.end()) {
    8160          54 :     return serialized_size_single_aggregated_member_xcdr2(encoding, size, single_it, selected_type, optional,
    8161          54 :                                                           extensibility, mutable_running_total);
    8162             :   }
    8163             : 
    8164          64 :   const_sequence_iterator seq_it = sequence_map_.find(selected_id);
    8165          64 :   if (seq_it != sequence_map_.end()) {
    8166          64 :     DDS::TypeDescriptor_var selected_td;
    8167          64 :     if (selected_type->get_descriptor(selected_td) != DDS::RETCODE_OK) {
    8168           0 :       return false;
    8169             :     }
    8170          64 :     const TypeKind elem_tk = get_base_type(selected_td->element_type())->get_kind();
    8171          64 :     serialized_size_sequence_aggregated_member_xcdr2(encoding, size, seq_it, elem_tk, optional,
    8172             :                                                      extensibility, mutable_running_total);
    8173          64 :     return true;
    8174          64 :   }
    8175             : 
    8176           0 :   const_complex_iterator complex_it = complex_map_.find(selected_id);
    8177           0 :   if (complex_it != complex_map_.end()) {
    8178           0 :     return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional,
    8179             :                                                            extensibility, mutable_running_total,
    8180           0 :                                                            DCPS::Sample::Full);
    8181             :   }
    8182           0 :   return false;
    8183         118 : }
    8184             : 
    8185         166 : bool DynamicDataImpl::DataContainer::serialize_selected_member_xcdr2(DCPS::Serializer& ser,
    8186             :   DDS::MemberId selected_id, DDS::ExtensibilityKind extensibility) const
    8187             : {
    8188         166 :   DDS::DynamicTypeMember_var selected_dtm;
    8189         166 :   if (type_->get_member(selected_dtm, selected_id) != DDS::RETCODE_OK) {
    8190           0 :     return false;
    8191             :   }
    8192         166 :   DDS::MemberDescriptor_var selected_md;
    8193         166 :   if (selected_dtm->get_descriptor(selected_md) != DDS::RETCODE_OK) {
    8194           0 :     return false;
    8195             :   }
    8196         166 :   DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    8197         166 :   const bool optional = selected_md->is_optional();
    8198         166 :   const bool must_understand = selected_md->is_must_understand();
    8199             : 
    8200         166 :   const_single_iterator single_it = single_map_.find(selected_id);
    8201         166 :   if (single_it != single_map_.end()) {
    8202          70 :     return serialize_single_aggregated_member_xcdr2(ser, single_it, selected_type, optional,
    8203          70 :                                                     must_understand, extensibility);
    8204             :   }
    8205             : 
    8206          96 :   const_sequence_iterator seq_it = sequence_map_.find(selected_id);
    8207          96 :   if (seq_it != sequence_map_.end()) {
    8208          96 :     DDS::TypeDescriptor_var selected_td;
    8209          96 :     if (selected_type->get_descriptor(selected_td) != DDS::RETCODE_OK) {
    8210           0 :       return false;
    8211             :     }
    8212          96 :     const TypeKind elem_tk = get_base_type(selected_td->element_type())->get_kind();
    8213          96 :     return serialize_sequence_aggregated_member_xcdr2(ser, seq_it, elem_tk, optional,
    8214          96 :                                                       must_understand, extensibility);
    8215          96 :   }
    8216             : 
    8217           0 :   const_complex_iterator complex_it = complex_map_.find(selected_id);
    8218           0 :   if (complex_it != complex_map_.end()) {
    8219           0 :     return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional,
    8220             :                                                      must_understand, extensibility,
    8221           0 :                                                      DCPS::Sample::Full);
    8222             :   }
    8223           0 :   return false;
    8224         166 : }
    8225             : 
    8226         123 : bool DynamicDataImpl::DataContainer::serialized_size_union_xcdr2(const DCPS::Encoding& encoding,
    8227             :                                                                  size_t& size, DCPS::Sample::Extent ext) const
    8228             : {
    8229         123 :   if (ext == DCPS::Sample::KeyOnly && !has_explicit_keys(type_)) {
    8230             :     // nothing is serialized (not even a delimiter) for key-only serialization when there is no @key
    8231           0 :     return true;
    8232             :   }
    8233             : 
    8234         123 :   const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind();
    8235         123 :   if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) {
    8236         118 :     serialized_size_delimiter(encoding, size);
    8237             :   }
    8238             : 
    8239         123 :   size_t mutable_running_total = 0;
    8240         123 :   DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type());
    8241         123 :   if (ext != DCPS::Sample::Full) {
    8242           3 :     if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type,
    8243             :                                                     extensibility, mutable_running_total)) {
    8244           0 :       return false;
    8245             :     }
    8246           3 :     serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);
    8247           3 :     return true;
    8248             :   }
    8249             : 
    8250         120 :   const_single_iterator single_it = single_map_.find(DISCRIMINATOR_ID);
    8251         120 :   const_complex_iterator complex_it = complex_map_.find(DISCRIMINATOR_ID);
    8252         120 :   const bool has_disc = single_it != single_map_.end() || complex_it != complex_map_.end();
    8253         120 :   const DDS::MemberId selected_id = data_->find_selected_member();
    8254             : 
    8255             :   CORBA::Long disc_value;
    8256         120 :   if (has_disc) {
    8257         118 :     if (!get_discriminator_value(disc_value, single_it, complex_it, disc_type)) {
    8258           0 :       return false;
    8259             :     }
    8260           2 :   } else if (!set_default_discriminator_value(disc_value, disc_type)) {
    8261           0 :     return false;
    8262             :   }
    8263             : 
    8264         120 :   if (selected_id == MEMBER_ID_INVALID) {
    8265           2 :     bool found_selected_member = false;
    8266           2 :     DDS::MemberDescriptor_var selected_md;
    8267             :     const DDS::ReturnCode_t rc =
    8268           2 :       data_->get_selected_union_branch(disc_value, found_selected_member, selected_md);
    8269           2 :     if (rc != DDS::RETCODE_OK) {
    8270           0 :       if (log_level >= LogLevel::Notice) {
    8271           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialized_size_union_xcdr2:"
    8272             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
    8273             :       }
    8274           0 :       return false;
    8275             :     }
    8276           2 :     if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type,
    8277             :                                                     extensibility, mutable_running_total)) {
    8278           0 :       return false;
    8279             :     }
    8280           2 :     if (ext == DCPS::Sample::KeyOnly) {
    8281           0 :       return true;
    8282             :     }
    8283           2 :     if (found_selected_member) {
    8284           2 :       DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    8285           2 :       const bool optional = selected_md->is_optional();
    8286           2 :       if (!serialized_size_complex_aggregated_member_xcdr2_default(encoding, size, selected_type, optional,
    8287             :                                                                    extensibility, mutable_running_total,
    8288             :                                                                    DCPS::Sample::Full)) {
    8289           0 :         return false;
    8290             :       }
    8291           2 :     }
    8292           2 :     serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);
    8293           2 :     return true;
    8294           2 :   }
    8295             : 
    8296         118 :   if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type,
    8297             :                                                   extensibility, mutable_running_total)) {
    8298           0 :     return false;
    8299             :   }
    8300         118 :   if (ext != DCPS::Sample::KeyOnly) {
    8301         118 :     if (!serialized_size_selected_member_xcdr2(
    8302             :         encoding, size, selected_id, extensibility, mutable_running_total)) {
    8303           0 :       return false;
    8304             :     }
    8305             :   }
    8306         118 :   serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);
    8307         118 :   return true;
    8308         123 : }
    8309             : 
    8310         169 : bool DynamicDataImpl::DataContainer::serialize_union_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    8311             : {
    8312         169 :   if (ext == DCPS::Sample::KeyOnly && !has_explicit_keys(type_)) {
    8313             :     // nothing is serialized (not even a delimiter) for key-only serialization when there is no @key
    8314           0 :     return true;
    8315             :   }
    8316             : 
    8317         169 :   const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind();
    8318             : 
    8319             :   // Delimiter
    8320         169 :   const DCPS::Encoding& encoding = ser.encoding();
    8321         169 :   size_t total_size = 0;
    8322         169 :   if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) {
    8323         117 :     if (!data_->serialized_size_i(encoding, total_size, ext) || !ser.write_delimiter(total_size)) {
    8324           0 :       return false;
    8325             :     }
    8326             :   }
    8327             : 
    8328         169 :   const_single_iterator single_it = single_map_.find(DISCRIMINATOR_ID);
    8329         169 :   const_complex_iterator complex_it = complex_map_.find(DISCRIMINATOR_ID);
    8330         169 :   const bool has_disc = single_it != single_map_.end() || complex_it != complex_map_.end();
    8331         169 :   const DDS::MemberId selected_id = data_->find_selected_member();
    8332         169 :   DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type());
    8333         169 :   const TypeKind disc_tk = disc_type->get_kind();
    8334             : 
    8335             :   // Read the discriminator value if the user already set it. Otherwise,
    8336             :   // set it to the default value of the corresponding type.
    8337             :   CORBA::Long disc_value;
    8338         169 :   if (has_disc) {
    8339         167 :     if (!get_discriminator_value(disc_value, single_it, complex_it, disc_type)) {
    8340           0 :       return false;
    8341             :     }
    8342           2 :   } else if (!set_default_discriminator_value(disc_value, disc_type)) {
    8343           0 :     return false;
    8344             :   }
    8345             : 
    8346         169 :   if (selected_id == MEMBER_ID_INVALID) {
    8347             :     // If the defined discriminator value selects a member, serialize the member with
    8348             :     // its default value. Otherwise, serialize only the discriminator.
    8349           3 :     bool found_selected_member = false;
    8350           3 :     DDS::MemberDescriptor_var selected_md;
    8351             :     const DDS::ReturnCode_t rc =
    8352           3 :       data_->get_selected_union_branch(disc_value, found_selected_member, selected_md);
    8353           3 :     if (rc != DDS::RETCODE_OK) {
    8354           0 :       if (log_level >= LogLevel::Notice) {
    8355           0 :         ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialize_union_xcdr2:"
    8356             :                    " get_selected_union_branch failed: %C\n", retcode_to_string(rc)));
    8357             :       }
    8358           0 :       return false;
    8359             :     }
    8360             :     // Discriminator
    8361           3 :     if (!serialize_discriminator_member_xcdr2(ser, disc_value, disc_type, extensibility)) {
    8362           0 :       return false;
    8363             :     }
    8364           3 :     if (ext == DCPS::Sample::KeyOnly) {
    8365           0 :       return true;
    8366             :     }
    8367             :     // Selected member
    8368           3 :     if (found_selected_member) {
    8369           2 :       DDS::DynamicType_var selected_type = get_base_type(selected_md->type());
    8370           2 :       const DDS::MemberId id = selected_md->id();
    8371           2 :       const bool optional = selected_md->is_optional();
    8372           2 :       const bool must_understand = selected_md->is_must_understand();
    8373           2 :       return serialize_complex_aggregated_member_xcdr2_default(ser, id, selected_type, optional,
    8374             :                                                                must_understand, extensibility,
    8375           2 :                                                                DCPS::Sample::Full);
    8376           2 :     }
    8377           1 :     return true;
    8378           3 :   }
    8379             : 
    8380             :   // Both discriminator and a selected member exist in the data container.
    8381         166 :   if (single_it != single_map_.end()) {
    8382         166 :     if (extensibility == DDS::MUTABLE) {
    8383          64 :       size_t disc_size = 0;
    8384          64 :       if (is_primitive(disc_tk)) {
    8385           0 :         serialized_size_primitive_member(encoding, disc_size, disc_tk);
    8386             :       } else { // Enum is the only other type can be used for discriminator
    8387          64 :         serialized_size_enum(encoding, disc_size, disc_type);
    8388             :       }
    8389             :       // Discriminator always has Id 0?
    8390          64 :       if (!ser.write_parameter_id(0, disc_size, false)) {
    8391           0 :         return false;
    8392             :       }
    8393             :     }
    8394         166 :     if (!serialize_single_value(ser, single_it->second)) {
    8395           0 :       return false;
    8396             :     }
    8397             :   } else {
    8398           0 :     if (extensibility == DDS::MUTABLE) {
    8399           0 :       size_t disc_size = 0;
    8400           0 :       serialized_size_complex_member_i(encoding, disc_size, complex_it->first, DCPS::Sample::Full);
    8401           0 :       if (!ser.write_parameter_id(0, disc_size, false)) {
    8402           0 :         return false;
    8403             :       }
    8404             :     }
    8405           0 :     if (!serialize_complex_member_i(ser, complex_it->first, DCPS::Sample::Full)) {
    8406           0 :       return false;
    8407             :     }
    8408             :   }
    8409         332 :   return ext == DCPS::Sample::KeyOnly ||
    8410         332 :     serialize_selected_member_xcdr2(ser, selected_id, extensibility);
    8411         169 : }
    8412             : 
    8413           0 : bool DynamicDataImpl::DataContainer::serialized_size_union_xcdr1(const DCPS::Encoding& /*encoding*/,
    8414             :                                                                  size_t& /*size*/, DCPS::Sample::Extent) const
    8415             : {
    8416             :   // TODO:
    8417           0 :   return false;
    8418             : }
    8419             : 
    8420           0 : bool DynamicDataImpl::DataContainer::serialize_union_xcdr1(DCPS::Serializer& /*ser*/, DCPS::Sample::Extent) const
    8421             : {
    8422             :   // TODO:
    8423           0 :   return false;
    8424             : }
    8425             : 
    8426         123 : bool DynamicDataImpl::DataContainer::serialized_size_union(const DCPS::Encoding& encoding,
    8427             :                                                            size_t& size,
    8428             :                                                            DCPS::Sample::Extent ext) const
    8429             : {
    8430         123 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    8431         123 :     return serialized_size_union_xcdr2(encoding, size, ext);
    8432           0 :   } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) {
    8433           0 :     return serialized_size_union_xcdr1(encoding, size, ext);
    8434             :   }
    8435           0 :   return false;
    8436             : }
    8437             : 
    8438         169 : bool DynamicDataImpl::DataContainer::serialize_union(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    8439             : {
    8440         169 :   const DCPS::Encoding& encoding = ser.encoding();
    8441         169 :   if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) {
    8442         169 :     return serialize_union_xcdr2(ser, ext);
    8443           0 :   } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) {
    8444           0 :     return serialize_union_xcdr1(ser, ext);
    8445             :   }
    8446           0 :   return false;
    8447             : }
    8448             : 
    8449         229 : bool DynamicDataImpl::serialized_size_i(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const
    8450             : {
    8451         229 :   const TypeKind tk = type_->get_kind();
    8452         229 :   switch (tk) {
    8453           4 :   case TK_INT32:
    8454           4 :     return primitive_serialized_size(encoding, size, CORBA::Long());
    8455           0 :   case TK_UINT32:
    8456           0 :     return primitive_serialized_size(encoding, size, CORBA::ULong());
    8457           0 :   case TK_INT8:
    8458           0 :     primitive_serialized_size_int8(encoding, size);
    8459           0 :     return true;
    8460           0 :   case TK_UINT8:
    8461           0 :     primitive_serialized_size_uint8(encoding, size);
    8462           0 :     return true;
    8463           3 :   case TK_INT16:
    8464           3 :     return primitive_serialized_size(encoding, size, CORBA::Short());
    8465           0 :   case TK_UINT16:
    8466           0 :     return primitive_serialized_size(encoding, size, CORBA::UShort());
    8467           0 :   case TK_INT64:
    8468           0 :     return primitive_serialized_size(encoding, size, CORBA::LongLong());
    8469           0 :   case TK_UINT64:
    8470           0 :     return primitive_serialized_size(encoding, size, CORBA::ULongLong());
    8471           0 :   case TK_FLOAT32:
    8472           0 :     return primitive_serialized_size(encoding, size, CORBA::Float());
    8473           0 :   case TK_FLOAT64:
    8474           0 :     return primitive_serialized_size(encoding, size, CORBA::Double());
    8475           0 :   case TK_FLOAT128:
    8476           0 :     return primitive_serialized_size(encoding, size, CORBA::LongDouble());
    8477           0 :   case TK_CHAR8:
    8478           0 :     primitive_serialized_size_char(encoding, size);
    8479           0 :     return true;
    8480             : #ifdef DDS_HAS_WCHAR
    8481           0 :   case TK_CHAR16:
    8482           0 :     primitive_serialized_size_wchar(encoding, size);
    8483           0 :     return true;
    8484             : #endif
    8485           0 :   case TK_BYTE:
    8486           0 :     primitive_serialized_size_octet(encoding, size);
    8487           0 :     return true;
    8488           0 :   case TK_BOOLEAN:
    8489           0 :     primitive_serialized_size_boolean(encoding, size);
    8490           0 :     return true;
    8491           0 :   case TK_ENUM:
    8492           0 :     return container_.serialized_size_enum(encoding, size, type_);
    8493           0 :   case TK_BITMASK:
    8494           0 :     return container_.serialized_size_bitmask(encoding, size, type_);
    8495           0 :   case TK_STRING8:
    8496           0 :     return container_.serialized_size_string(encoding, size);
    8497             : #ifdef DDS_HAS_WCHAR
    8498           0 :   case TK_STRING16:
    8499           0 :     return container_.serialized_size_wstring(encoding, size);
    8500             : #endif
    8501          54 :   case TK_STRUCTURE:
    8502          54 :     return container_.serialized_size_structure(encoding, size, ext);
    8503         123 :   case TK_UNION:
    8504         123 :     return container_.serialized_size_union(encoding, size, ext);
    8505          30 :   case TK_SEQUENCE:
    8506          30 :     return container_.serialized_size_sequence(encoding, size, ext);
    8507          15 :   case TK_ARRAY:
    8508          15 :     return container_.serialized_size_array(encoding, size, ext);
    8509           0 :   case TK_MAP:
    8510           0 :     if (log_level >= LogLevel::Notice) {
    8511           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialized_size_i: Serialization of map types is not supported\n"));
    8512             :     }
    8513             :   }
    8514           0 :   return false;
    8515             : }
    8516             : 
    8517         237 : bool DynamicDataImpl::serialize_i(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const
    8518             : {
    8519         237 :   const TypeKind tk = type_->get_kind();
    8520         237 :   switch (tk) {
    8521           2 :   case TK_INT32:
    8522           2 :     return container_.serialize_primitive_value(ser, CORBA::Long());
    8523           0 :   case TK_UINT32:
    8524           0 :     return container_.serialize_primitive_value(ser, CORBA::ULong());
    8525           0 :   case TK_INT8:
    8526           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_int8(CORBA::Int8()));
    8527           0 :   case TK_UINT8:
    8528           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_uint8(CORBA::UInt8()));
    8529           3 :   case TK_INT16:
    8530           3 :     return container_.serialize_primitive_value(ser, CORBA::Short());
    8531           0 :   case TK_UINT16:
    8532           0 :     return container_.serialize_primitive_value(ser, CORBA::UShort());
    8533           0 :   case TK_INT64:
    8534           0 :     return container_.serialize_primitive_value(ser, CORBA::LongLong());
    8535           0 :   case TK_UINT64:
    8536           0 :     return container_.serialize_primitive_value(ser, CORBA::ULongLong());
    8537           0 :   case TK_FLOAT32:
    8538           0 :     return container_.serialize_primitive_value(ser, CORBA::Float());
    8539           0 :   case TK_FLOAT64:
    8540           0 :     return container_.serialize_primitive_value(ser, CORBA::Double());
    8541           0 :   case TK_FLOAT128:
    8542           0 :     return container_.serialize_primitive_value(ser, CORBA::LongDouble());
    8543           0 :   case TK_CHAR8:
    8544           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_char(CORBA::Char()));
    8545             : #ifdef DDS_HAS_WCHAR
    8546           0 :   case TK_CHAR16:
    8547           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_wchar(CORBA::WChar()));
    8548             : #endif
    8549           0 :   case TK_BYTE:
    8550           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_octet(CORBA::Octet()));
    8551           0 :   case TK_BOOLEAN:
    8552           0 :     return container_.serialize_primitive_value(ser, ACE_OutputCDR::from_boolean(CORBA::Boolean()));
    8553           0 :   case TK_ENUM:
    8554           0 :     return container_.serialize_enum_value(ser);
    8555           0 :   case TK_BITMASK:
    8556           0 :     return container_.serialize_bitmask_value(ser);
    8557           0 :   case TK_STRING8:
    8558           0 :     return container_.serialize_string_value(ser);
    8559             : #ifdef DDS_HAS_WCHAR
    8560           0 :   case TK_STRING16:
    8561           0 :     return container_.serialize_wstring_value(ser);
    8562             : #endif
    8563          41 :   case TK_STRUCTURE:
    8564          41 :     return container_.serialize_structure(ser, ext);
    8565         169 :   case TK_UNION:
    8566         169 :     return container_.serialize_union(ser, ext);
    8567          15 :   case TK_SEQUENCE:
    8568          15 :     return container_.serialize_sequence(ser, ext);
    8569           7 :   case TK_ARRAY:
    8570           7 :     return container_.serialize_array(ser, ext);
    8571           0 :   case TK_MAP:
    8572           0 :     if (log_level >= LogLevel::Notice) {
    8573           0 :       ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialize_i: Serialization of map types is not supported\n"));
    8574             :     }
    8575             :   }
    8576           0 :   return false;
    8577             : }
    8578             : 
    8579             : } // namespace XTypes
    8580             : 
    8581             : namespace DCPS {
    8582             : 
    8583           0 : bool serialized_size(const Encoding& encoding, size_t& size, const XTypes::DynamicDataImpl& data)
    8584             : {
    8585           0 :   return data.serialized_size_i(encoding, size, Sample::Full);
    8586             : }
    8587             : 
    8588         185 : bool operator<<(Serializer& ser, const XTypes::DynamicDataImpl& data)
    8589             : {
    8590         185 :   return data.serialize_i(ser, Sample::Full);
    8591             : }
    8592             : 
    8593           5 : bool serialized_size(const Encoding& encoding, size_t& size, const KeyOnly<const XTypes::DynamicDataImpl>& key)
    8594             : {
    8595           5 :   return key.value.serialized_size_i(encoding, size, Sample::KeyOnly);
    8596             : }
    8597             : 
    8598           5 : bool operator<<(Serializer& ser, const KeyOnly<const XTypes::DynamicDataImpl>& key)
    8599             : {
    8600           5 :   return key.value.serialize_i(ser, Sample::KeyOnly);
    8601             : }
    8602             : 
    8603             : } // namespace DCPS
    8604             : } // namespace OpenDDS
    8605             : 
    8606             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
    8607             : 
    8608             : #endif // OPENDDS_SAFETY_PROFILE

Generated by: LCOV version 1.16