diff --git a/dds/DCPS/XTypes/DynamicDataBase.cpp b/dds/DCPS/XTypes/DynamicDataBase.cpp index 55c73a3c22..4699ad18cc 100644 --- a/dds/DCPS/XTypes/DynamicDataBase.cpp +++ b/dds/DCPS/XTypes/DynamicDataBase.cpp @@ -301,51 +301,6 @@ DDS::MemberId DynamicDataBase::get_union_default_member(DDS::DynamicType* type) return default_branch; } -DDS::ReturnCode_t DynamicDataBase::get_selected_union_branch(DDS::Int32 disc, - bool& found_selected_member, DDS::MemberDescriptor_var& selected_md) const -{ - found_selected_member = false; - bool has_default = false; - DDS::ReturnCode_t rc = DDS::RETCODE_OK; - DDS::MemberDescriptor_var default_md; - for (DDS::UInt32 i = 0; i < type_->get_member_count(); ++i) { - DDS::DynamicTypeMember_var dtm; - rc = type_->get_member_by_index(dtm, i); - if (rc != DDS::RETCODE_OK) { - return rc; - } - if (dtm->get_id() == DISCRIMINATOR_ID) { - continue; - } - DDS::MemberDescriptor_var md; - rc = dtm->get_descriptor(md); - if (rc != DDS::RETCODE_OK) { - return rc; - } - bool found_matched_label = false; - const DDS::UnionCaseLabelSeq labels = md->label(); - for (DDS::UInt32 j = 0; !found_matched_label && j < labels.length(); ++j) { - if (disc == labels[j]) { - found_matched_label = true; - } - } - if (found_matched_label) { - selected_md = md; - found_selected_member = true; - break; - } - if (md->is_default_label()) { - default_md = md; - has_default = true; - } - } - if (!found_selected_member && has_default) { - selected_md = default_md; - found_selected_member = true; - } - return rc; -} - DDS::ReturnCode_t DynamicDataBase::get_selected_union_branch( bool& found_selected_member, DDS::MemberDescriptor_var& selected_md) { @@ -362,14 +317,15 @@ DDS::ReturnCode_t DynamicDataBase::get_selected_union_branch( } return DDS::RETCODE_ERROR; } - return get_selected_union_branch(static_cast(i64_disc), found_selected_member, selected_md); + return XTypes::get_selected_union_branch(type_, static_cast(i64_disc), + found_selected_member, selected_md); } bool DynamicDataBase::discriminator_selects_no_member(DDS::Int32 disc) const { bool found_selected_member; DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = get_selected_union_branch(disc, found_selected_member, selected_md); + const DDS::ReturnCode_t rc = XTypes::get_selected_union_branch(type_, disc, found_selected_member, selected_md); if (rc != DDS::RETCODE_OK) { if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataBase::discriminator_selects_no_member: " @@ -380,37 +336,6 @@ bool DynamicDataBase::discriminator_selects_no_member(DDS::Int32 disc) const return !found_selected_member; } -bool DynamicDataBase::has_explicit_keys(DDS::DynamicType* dt) -{ - // see dds_generator.h struct_has_explicit_keys() in opendds_idl - DDS::TypeDescriptor_var type_descriptor; - DDS::ReturnCode_t ret = dt->get_descriptor(type_descriptor); - if (ret != DDS::RETCODE_OK) { - return false; - } - DDS::DynamicType* const base = type_descriptor->base_type(); - if (base && has_explicit_keys(base)) { - return true; - } - - for (ACE_CDR::ULong i = 0; i < dt->get_member_count(); ++i) { - DDS::DynamicTypeMember_var member; - ret = dt->get_member_by_index(member, i); - if (ret != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var descriptor; - ret = member->get_descriptor(descriptor); - if (ret != DDS::RETCODE_OK) { - return false; - } - if (descriptor->is_key()) { - return true; - } - } - return false; -} - DDS::ReturnCode_t DynamicDataBase::unsupported_method(const char* method_name, bool warning) const { if (log_level >= (warning ? LogLevel::Warning : LogLevel::Notice)) { diff --git a/dds/DCPS/XTypes/DynamicDataBase.h b/dds/DCPS/XTypes/DynamicDataBase.h index 92c0455507..048cb164b7 100644 --- a/dds/DCPS/XTypes/DynamicDataBase.h +++ b/dds/DCPS/XTypes/DynamicDataBase.h @@ -41,10 +41,6 @@ class OpenDDS_Dcps_Export DynamicDataBase : public virtual DCPS::LocalObject= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:" + if (index != 0 && log_level >= LogLevel::Warning) { + ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:" " Received invalid index (%u) for type %C\n", index, typekind_to_string(tk))); } return MEMBER_ID_INVALID; @@ -85,8 +89,8 @@ DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index) case TK_SEQUENCE: { const CORBA::ULong bound = type_desc_->bound()[0]; if (bound > 0 && index >= bound) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:" + if (log_level >= LogLevel::Warning) { + ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:" " Input index (%u) is out-of-bound (bound is %u)\n", index, bound)); } return MEMBER_ID_INVALID; @@ -96,21 +100,16 @@ DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index) case TK_ARRAY: { const DDS::UInt32 length = bound_total(type_desc_); if (index >= length) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:" + if (log_level >= LogLevel::Warning) { + ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:" " Input index (%u) is out-of-bound (array length is %u)\n", index, length)); } return MEMBER_ID_INVALID; } return index; } - case TK_MAP: - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:" - " Map is currently not supported\n")); - } - return MEMBER_ID_INVALID; case TK_STRUCTURE: { + // Use the member order defined in the type since it's the order used for serialization. DDS::DynamicTypeMember_var dtm; if (type_->get_member_by_index(dtm, index) != DDS::RETCODE_OK) { return MEMBER_ID_INVALID; @@ -121,9 +120,10 @@ DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index) if (index == 0) { return DISCRIMINATOR_ID; } - bool select_a_member; + + bool has_selected_branch; DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = get_selected_union_branch(select_a_member, selected_md); + const DDS::ReturnCode_t rc = get_selected_union_branch(has_selected_branch, selected_md); if (rc != DDS::RETCODE_OK) { if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:" @@ -131,7 +131,7 @@ DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index) } return MEMBER_ID_INVALID; } - if (index == 1 && select_a_member) { + if (index == 1 && has_selected_branch) { return selected_md->id(); } if (log_level >= LogLevel::Warning) { @@ -142,49 +142,84 @@ DDS::MemberId DynamicDataImpl::get_member_id_at_index(ACE_CDR::ULong index) } } - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_member_id_at_index:" - " Calling on an unexpected type %C\n", typekind_to_string(tk))); + if (log_level >= LogLevel::Warning) { + ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_member_id_at_index:" + " Called on an unexpected type %C\n", typekind_to_string(tk))); } return MEMBER_ID_INVALID; } -CORBA::ULong DynamicDataImpl::get_sequence_size() const +void DynamicDataImpl::erase_member(DDS::MemberId id) { - if (type_->get_kind() != TK_SEQUENCE) { - return 0; + if (container_.single_map_.erase(id) == 0) { + if (container_.sequence_map_.erase(id) == 0) { + container_.complex_map_.erase(id); + } + } +} + +CORBA::ULong DynamicDataImpl::get_string_item_count() const +{ + CORBA::ULong bs_item_count = 0; + if (backing_store_) { + bs_item_count = backing_store_->get_item_count(); } + CORBA::ULong container_item_count = 0; if (!container_.single_map_.empty() || !container_.complex_map_.empty()) { CORBA::ULong largest_index; if (!container_.get_largest_index_basic(largest_index)) { return 0; } - if (!container_.sequence_map_.empty()) { - CORBA::ULong largest_seq_index; - if (!container_.get_largest_sequence_index(largest_seq_index)) { - return 0; - } - largest_index = std::max(largest_index, largest_seq_index); + container_item_count = largest_index + 1; + } + return std::max(bs_item_count, container_item_count); +} + +CORBA::ULong DynamicDataImpl::get_sequence_item_count() const +{ + CORBA::ULong bs_item_count = 0; + if (backing_store_) { + bs_item_count = backing_store_->get_item_count(); + } + + CORBA::ULong container_item_count = 0; + if (!container_.single_map_.empty() + || !container_.sequence_map_.empty() + || !container_.complex_map_.empty()) { + CORBA::ULong largest_single_index = 0; + if (!container_.single_map_.empty() && + !container_.get_largest_single_index(largest_single_index)) { + return 0; } - return largest_index + 1; - } else if (!container_.sequence_map_.empty()) { - CORBA::ULong largest_index; - if (!container_.get_largest_sequence_index(largest_index)) { + CORBA::ULong largest_sequence_index = 0; + if (!container_.sequence_map_.empty() && + !container_.get_largest_sequence_index(largest_sequence_index)) { + return 0; + } + CORBA::ULong largest_complex_index = 0; + if (!container_.complex_map_.empty() && + !container_.get_largest_complex_index(largest_complex_index)) { return 0; } - return largest_index + 1; + container_item_count = std::max(largest_single_index, + std::max(largest_sequence_index, + largest_complex_index)) + 1; } - return 0; + + return std::max(bs_item_count, container_item_count); } -void DynamicDataImpl::erase_member(DDS::MemberId id) +bool DynamicDataImpl::has_member(DDS::MemberId id) const { - if (container_.single_map_.erase(id) == 0) { - if (container_.sequence_map_.erase(id) == 0) { - container_.complex_map_.erase(id); - } + if (container_.single_map_.find(id) != container_.single_map_.end() || + container_.sequence_map_.find(id) != container_.sequence_map_.end() || + container_.complex_map_.find(id) != container_.complex_map_.end()) { + return true; } + + DDS::DynamicData_var member_dd; + return backing_store_ && backing_store_->get_complex_value(member_dd, id) == DDS::RETCODE_OK; } ACE_CDR::ULong DynamicDataImpl::get_item_count() @@ -214,18 +249,9 @@ ACE_CDR::ULong DynamicDataImpl::get_item_count() #ifdef DDS_HAS_WCHAR case TK_STRING16: #endif - { - if (!container_.single_map_.empty() || !container_.complex_map_.empty()) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic(largest_index)) { - return 0; - } - return largest_index + 1; - } - return 0; - } + return get_string_item_count(); case TK_SEQUENCE: - return get_sequence_size(); + return get_sequence_item_count(); case TK_BITMASK: return static_cast(container_.single_map_.size() + container_.complex_map_.size()); @@ -234,7 +260,7 @@ ACE_CDR::ULong DynamicDataImpl::get_item_count() case TK_STRUCTURE: { const CORBA::ULong member_count = type_->get_member_count(); CORBA::ULong count = member_count; - // An optional member that hasn't been set is considered missing. + // An optional member that hasn't been set is not counted. // All non-optional members are counted since they either are set directly // or hold default values (XTypes spec 7.5.2.11.6). for (CORBA::ULong i = 0; i < member_count; ++i) { @@ -246,44 +272,31 @@ ACE_CDR::ULong DynamicDataImpl::get_item_count() if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { return 0; } - if (md->is_optional()) { - const DDS::MemberId id = md->id(); - if (container_.single_map_.find(id) == container_.single_map_.end() && - container_.sequence_map_.find(id) == container_.sequence_map_.end() && - container_.complex_map_.find(id) == container_.complex_map_.end()) { - --count; - } + if (md->is_optional() && !has_member(md->id())) { + --count; } } return count; } case TK_UNION: { - CORBA::ULong count = static_cast(container_.single_map_.size() + - container_.sequence_map_.size() + - container_.complex_map_.size()); - if (count > 0) { - return count; - } - DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); - CORBA::Long disc_val; - if (!set_default_discriminator_value(disc_val, disc_type)) { - if (log_level >= LogLevel::Warning) { - ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_item_count:" - " set_default_discriminator_value failed\n")); - } - return 0; - } - bool select_a_member; + bool has_selected_branch; DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = get_selected_union_branch(disc_val, select_a_member, selected_md); + const DDS::ReturnCode_t rc = get_selected_union_branch(has_selected_branch, selected_md); if (rc != DDS::RETCODE_OK) { if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: DynamicDataImpl::get_item_count:" - " get_selected_union_branch failed: %C\n", retcode_to_string(rc))); + " get_selected_union_branch returned %C\n", retcode_to_string(rc))); } return 0; } - return select_a_member ? 2 : 1; + if (has_selected_branch) { + DDS::UInt32 count = 2; + if (selected_md->is_optional() && !has_member(selected_md->id())) { + --count; + } + return count; + } + return 1; } case TK_MAP: case TK_BITSET: @@ -316,6 +329,7 @@ DDS::ReturnCode_t DynamicDataImpl::clear_all_values() case TK_STRUCTURE: case TK_UNION: clear_container(); + set_backing_store(0); break; case TK_MAP: case TK_BITSET: @@ -356,7 +370,7 @@ DDS::ReturnCode_t DynamicDataImpl::clear_value(DDS::MemberId id) return set_boolean_value(id, false); case TK_ARRAY: { const DDS::UInt32 bound = bound_total(type_desc_); - if (id >= bound) { + if (!check_index_from_id(this_tk, id, bound)) { return DDS::RETCODE_BAD_PARAMETER; } DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); @@ -368,35 +382,49 @@ DDS::ReturnCode_t DynamicDataImpl::clear_value(DDS::MemberId id) #endif case TK_SEQUENCE: { // Shift subsequent elements to the left (XTypes spec 7.5.2.11.3). - const CORBA::ULong size = get_sequence_size(); + const CORBA::ULong size = get_sequence_item_count(); if (id >= size) { - return DDS::RETCODE_ERROR; + return DDS::RETCODE_BAD_PARAMETER; } - // At the begin of each iterator, member with the current id is not present - // in any of the maps. Copy over the next member to the current id. + DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); erase_member(id); - for (CORBA::ULong i = id; i < size - 1; ++i) { - const DDS::MemberId next_id = i + 1; - const_single_iterator single_it = container_.single_map_.find(next_id); + for (CORBA::ULong i = id_to_index(id) + 1; i < size; ++i) { + const DDS::MemberId curr_id = index_to_id(i); + const DDS::MemberId prev_id = index_to_id(i - 1); + const_single_iterator single_it = container_.single_map_.find(curr_id); if (single_it != container_.single_map_.end()) { - container_.single_map_.insert(std::make_pair(i, single_it->second)); - container_.single_map_.erase(next_id); + container_.single_map_.insert(std::make_pair(prev_id, single_it->second)); + container_.single_map_.erase(curr_id); continue; } - const_sequence_iterator seq_it = container_.sequence_map_.find(next_id); + const_sequence_iterator seq_it = container_.sequence_map_.find(curr_id); if (seq_it != container_.sequence_map_.end()) { - container_.sequence_map_.insert(std::make_pair(i, seq_it->second)); - container_.sequence_map_.erase(next_id); + container_.sequence_map_.insert(std::make_pair(prev_id, seq_it->second)); + container_.sequence_map_.erase(curr_id); continue; } - const_complex_iterator complex_it = container_.complex_map_.find(next_id); + const_complex_iterator complex_it = container_.complex_map_.find(curr_id); if (complex_it != container_.complex_map_.end()) { - container_.complex_map_.insert(std::make_pair(i, complex_it->second)); - container_.complex_map_.erase(next_id); + container_.complex_map_.insert(std::make_pair(prev_id, complex_it->second)); + container_.complex_map_.erase(curr_id); continue; } + // Since the backing store is read-only, we can't shift its elements. Instead, + // copy (and shift) the elements that are missing in the container from the backing store. + if (backing_store_) { + DynamicDataImpl* elem_ddi = new DynamicDataImpl(elem_type); + DDS::DynamicData_var elem_dd = elem_ddi; + const DDS::ReturnCode_t rc = set_member_backing_store(elem_ddi, curr_id); + if (rc != DDS::RETCODE_OK && rc != DDS::RETCODE_NO_DATA) { + return DDS::RETCODE_ERROR; + } + container_.complex_map_.insert(std::make_pair(prev_id, elem_dd)); + } } + + // Then disable the backing store. + set_backing_store(0); break; } case TK_STRUCTURE: @@ -411,6 +439,45 @@ DDS::ReturnCode_t DynamicDataImpl::clear_value(DDS::MemberId id) } if (md->is_optional()) { erase_member(id); + DDS::DynamicData_var opt_val; + if (backing_store_ && backing_store_->get_complex_value(opt_val, id) == DDS::RETCODE_OK) { + // The backing store is read-only, so to remove the optional member we need to + // invalidate the backing store. Save all the members that are in the backing store + // but not in the container. + DDS::DynamicTypeMembersById_var members_var; + if (type_->get_all_members(members_var) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + DynamicTypeMembersByIdImpl* members = dynamic_cast(members_var.in()); + if (!members) { + return DDS::RETCODE_ERROR; + } + for (DynamicTypeMembersByIdImpl::const_iterator it = members->begin(); it != members->end(); ++it) { + const DDS::MemberId mid = it->first; + if (mid == id) { + continue; + } + const bool container_has_it = + container_.single_map_.find(mid) != container_.single_map_.end() || + container_.sequence_map_.find(mid) != container_.sequence_map_.end() || + container_.complex_map_.find(mid) != container_.complex_map_.end(); + if (!container_has_it) { + DDS::MemberDescriptor_var mem_desc; + if (it->second->get_descriptor(mem_desc) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + DDS::DynamicType_var mem_dt = get_base_type(mem_desc->type()); + DynamicDataImpl* mem_ddi = new DynamicDataImpl(mem_dt); + DDS::DynamicData_var mem_dd = mem_ddi; + const DDS::ReturnCode_t rc = set_member_backing_store(mem_ddi, mid); + if (rc != DDS::RETCODE_OK && rc != DDS::RETCODE_NO_DATA) { + return DDS::RETCODE_ERROR; + } + container_.complex_map_.insert(std::make_pair(mid, mem_dd)); + } + } + set_backing_store(0); + } break; } DDS::DynamicType_var member_type = get_base_type(md->type()); @@ -684,16 +751,17 @@ bool DynamicDataImpl::insert_complex(DDS::MemberId id, const DDS::DynamicData_va // Set a member with the given ID in a struct. The member must have type MemberTypeKind or // enum/bitmask. In the latter case, its bit bound must be in the range [lower, upper]. template -bool DynamicDataImpl::set_value_to_struct(DDS::MemberId id, const MemberType& value) +DDS::ReturnCode_t DynamicDataImpl::set_value_to_struct(DDS::MemberId id, const MemberType& value) { DDS::MemberDescriptor_var md; DDS::DynamicType_var member_type; const DDS::ReturnCode_t rc = check_member( md, member_type, "DynamicDataImpl::set_value_to_struct", "set", id, MemberTypeKind); if (rc != DDS::RETCODE_OK) { - return false; + return rc; } - return insert_single(id, value); + insert_single(id, value); + return DDS::RETCODE_OK; } bool DynamicDataImpl::is_valid_discriminator_type(TypeKind tk) @@ -753,6 +821,10 @@ bool DynamicDataImpl::is_default_member_selected(CORBA::Long disc_val, DDS::Memb return true; } +DynamicDataImpl::SingleValue::SingleValue() + : kind_(TK_NONE), active_(0) +{} + DynamicDataImpl::SingleValue::SingleValue(CORBA::Long int32) : kind_(TK_INT32), active_(0), int32_(int32) {} @@ -901,10 +973,7 @@ template<> const CORBA::WChar* const& DynamicDataImpl::SingleValue::get() const char* DynamicDataImpl::SingleValue::get_string() const { return CORBA::string_dup(str_); } CORBA::WChar* DynamicDataImpl::SingleValue::get_wstring() const { return CORBA::wstring_dup(wstr_); } -// Has to be below the get methods, or else there's a template specialization issue. -DynamicDataImpl::SingleValue::SingleValue(const SingleValue& other) - : kind_(other.kind_) - , active_(0) +void DynamicDataImpl::SingleValue::copy(const SingleValue& other) { switch (kind_) { case TK_INT8: @@ -963,6 +1032,22 @@ DynamicDataImpl::SingleValue::SingleValue(const SingleValue& other) } } +// Has to be below the get methods, or else there's a template specialization issue. +DynamicDataImpl::SingleValue::SingleValue(const SingleValue& other) + : kind_(other.kind_) + , active_(0) +{ + copy(other); +} + +DynamicDataImpl::SingleValue& DynamicDataImpl::SingleValue::operator=(const SingleValue& other) +{ + kind_ = other.kind_; + active_ = 0; + copy(other); + return *this; +} + DynamicDataImpl::SequenceValue::SequenceValue(const DDS::Int32Seq& int32_seq) : elem_kind_(TK_INT32), active_(new(int32_seq_) DDS::Int32Seq(int32_seq)) {} @@ -1161,10 +1246,17 @@ template<> const DDS::WstringSeq& DynamicDataImpl::SequenceValue::get() const #endif #undef SEQUENCE_VALUE_GETTERS -bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val, const DDS::DynamicType_var& disc_type, - const_single_iterator it) const +bool DynamicDataImpl::read_disc_from_single_map(CORBA::Long& disc_val, + const DDS::DynamicType_var& disc_type, + const const_single_iterator& it) const { - switch (disc_type->get_kind()) { + const TypeKind disc_tk = disc_type->get_kind(); + TypeKind treat_as_tk = disc_tk; + if (disc_tk == TK_ENUM && enum_bound(disc_type, treat_as_tk) != DDS::RETCODE_OK) { + return false; + } + + switch (treat_as_tk) { case TK_BOOLEAN: { const ACE_OutputCDR::from_boolean& value = it->second.get(); disc_val = static_cast(value.val_); @@ -1199,7 +1291,7 @@ bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val, const DDS::Dynam } case TK_INT16: { CORBA::Short value = it->second.get(); - disc_val = static_cast(value); + disc_val = value; return true; } case TK_UINT16: { @@ -1226,21 +1318,112 @@ bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val, const DDS::Dynam disc_val = static_cast(value); return true; } - case TK_ENUM: { - DDS::TypeDescriptor_var td; - if (disc_type->get_descriptor(td) != DDS::RETCODE_OK) { + } + return false; +} + +// Read discriminator, identified by a given id, from the backing store. +bool DynamicDataImpl::read_disc_from_backing_store(CORBA::Long& disc_val, + DDS::MemberId id, + const DDS::DynamicType_var& disc_type) +{ + const TypeKind disc_tk = disc_type->get_kind(); + TypeKind treat_as_tk = disc_tk; + if (disc_tk == TK_ENUM && enum_bound(disc_type, treat_as_tk) != DDS::RETCODE_OK) { + return false; + } + + switch (treat_as_tk) { + case TK_BOOLEAN: { + ACE_OutputCDR::from_boolean val(false); + if (!get_value_from_backing_store(val, id)) { return false; } - const CORBA::ULong bitbound = td->bound()[0]; - if (bitbound >= 1 && bitbound <= 8) { - const ACE_OutputCDR::from_int8& value = it->second.get(); - disc_val = static_cast(value.val_); - } else if (bitbound >= 9 && bitbound <= 16) { - CORBA::Short value = it->second.get(); - disc_val = static_cast(value); - } else { - disc_val = it->second.get(); + disc_val = static_cast(val.val_); + return true; + } + case TK_BYTE: { + ACE_OutputCDR::from_octet val(0x00); + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val.val_); + return true; + } + case TK_CHAR8: { + ACE_OutputCDR::from_char val('\0'); + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val.val_); + return true; + } +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: { + ACE_OutputCDR::from_wchar val(0); + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val.val_); + return true; + } +#endif + case TK_INT8: { + ACE_OutputCDR::from_int8 val(0); + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val.val_); + return true; + } + case TK_UINT8: { + ACE_OutputCDR::from_uint8 val(0); + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val.val_); + return true; + } + case TK_INT16: { + CORBA::Short val; + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = val; + return true; + } + case TK_UINT16: { + CORBA::UShort val; + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val); + return true; + } + case TK_INT32: + return get_value_from_backing_store(disc_val, id); + case TK_UINT32: { + CORBA::ULong val; + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val); + return true; + } + case TK_INT64: { + CORBA::LongLong val; + if (!get_value_from_backing_store(val, id)) { + return false; + } + disc_val = static_cast(val); + return true; + } + case TK_UINT64: { + CORBA::ULongLong val; + if (!get_value_from_backing_store(val, id)) { + return false; } + disc_val = static_cast(val); return true; } } @@ -1248,47 +1431,19 @@ bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val, const DDS::Dynam } // Read a discriminator value from a DynamicData that represents it. -bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val) const +bool DynamicDataImpl::read_discriminator(CORBA::Long& disc_val) { if (!is_valid_discriminator_type(type_->get_kind())) { return false; } const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); - if (it == container_.single_map_.end()) { - return false; - } - return read_discriminator(disc_val, type_, it); -} - -// If a selected member of a union is already written, return its ID. -// Should only be called for union. -DDS::MemberId DynamicDataImpl::find_selected_member() const -{ - // There can be at most 2 entries in total in all three maps, - // one for the discriminator, one for a selected member. - for (const_single_iterator single_it = container_.single_map_.begin(); - single_it != container_.single_map_.end(); ++single_it) { - if (single_it->first != DISCRIMINATOR_ID) { - return single_it->first; - } - } - - // If there is any entry in sequence_map_, that must be for a selected member - // since discriminator cannot be sequence. - if (container_.sequence_map_.size() > 0) { - OPENDDS_ASSERT(container_.sequence_map_.size() == 1); - return container_.sequence_map_.begin()->first; + if (it != container_.single_map_.end()) { + return read_disc_from_single_map(disc_val, type_, it); } - - for (const_complex_iterator cmpl_it = container_.complex_map_.begin(); - cmpl_it != container_.complex_map_.end(); ++cmpl_it) { - if (cmpl_it->first != DISCRIMINATOR_ID) { - return cmpl_it->first; - } + if (read_disc_from_backing_store(disc_val, MEMBER_ID_INVALID, type_)) { + return true; } - - // There was no selected member written. - return MEMBER_ID_INVALID; + return set_default_discriminator_value(disc_val, type_); } // Check if a discriminator value would select a member with the given descriptor in a union. @@ -1408,111 +1563,207 @@ bool DynamicDataImpl::cast_to_discriminator_value(CORBA::Long& /*disc_value*/, return false; } -template -bool DynamicDataImpl::set_value_to_union(DDS::MemberId id, const MemberType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper) +// Return true if the DynamicData instance contains a value for the discriminator. +bool DynamicDataImpl::has_discriminator_value(const_single_iterator& single_it, + const_complex_iterator& complex_it) const { - // This follows the IDL-to-C++ mapping for union. - DDS::DynamicType_var member_type; - if (id == DISCRIMINATOR_ID) { - // Discriminator can only be of certain types (XTypes spec, 7.2.2.4.4.3) - if (!is_valid_discriminator_type(MemberTypeKind)) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:" - " Type %C cannot be used for union discriminator\n", - typekind_to_string(MemberTypeKind))); - } - return false; - } - - member_type = get_base_type(type_desc_->discriminator_type()); - - const TypeKind member_tk = member_type->get_kind(); - if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) { - return false; - } + single_it = container_.single_map_.find(DISCRIMINATOR_ID); + complex_it = container_.complex_map_.find(DISCRIMINATOR_ID); - if (member_tk == enum_or_bitmask) { - DDS::TypeDescriptor_var member_td; - if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = member_td->bound()[0]; - if (bit_bound < lower || bit_bound > upper) { - return false; - } - } + // A backing store, if present, must have valid data (for union in this case), + // meaning it must have at least data for discriminator. + return single_it != container_.single_map_.end() + || complex_it != container_.complex_map_.end() + || backing_store_; +} - CORBA::Long disc_value; - if (!cast_to_discriminator_value(disc_value, value)) { +// Get discriminator value from the data container or the backing store. +// Call only when the instance has data for discriminator. +bool DynamicDataImpl::get_discriminator_value(CORBA::Long& value, + const const_single_iterator& single_it, + const const_complex_iterator& complex_it, + const DDS::DynamicType_var& disc_type) +{ + if (single_it != container_.single_map_.end()) { + read_disc_from_single_map(value, disc_type, single_it); + } else if (complex_it != container_.complex_map_.end()) { + const DynamicDataImpl* dd_impl = dynamic_cast(complex_it->second.in()); + if (!dd_impl) { return false; } - - const DDS::MemberId selected_id = find_selected_member(); - if (selected_id != MEMBER_ID_INVALID) { - DDS::DynamicTypeMember_var selected_member; - if (type_->get_member(selected_member, selected_id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var selected_md; - if (selected_member->get_descriptor(selected_md) != DDS::RETCODE_OK) { - return false; - } - - if (!validate_discriminator(disc_value, selected_md)) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:" - " Discriminator value %d does not select the activated member (ID %u)\n", - disc_value, selected_id)); - } - return false; - } - return insert_single(id, value); + const_single_iterator it = dd_impl->container_.single_map_.find(MEMBER_ID_INVALID); + if (it != dd_impl->container_.single_map_.end()) { + read_disc_from_single_map(value, disc_type, it); } else { - // In case the union has implicit default member and the input discriminator value - // selects that implicit default member, store the discriminator value. The semantics - // of this is similar to the _default() method of the IDL-to-C++ mapping for union. - if (discriminator_selects_no_member(disc_value)) { - return insert_single(id, value); - } - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_union:" - " Can't directly set a discriminator that selects a member." - " Activate the member first!\n")); - } - return false; + return set_default_discriminator_value(value, disc_type); } + } else { + return read_disc_from_backing_store(value, DISCRIMINATOR_ID, disc_type); } + return true; +} - // Activate a member - clear_container(); - - DDS::DynamicTypeMember_var member; - if (type_->get_member(member, id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var md; - if (member->get_descriptor(md) != DDS::RETCODE_OK) { - return false; +// The following cases will succeed: +// (1) If the current state of the union has a branch, including the implicit default branch, +// the new discriminator value must selects the same branch. +// (2) When the union is empty, the discriminator has its default value and if it +// selects a branch, that branch will also have the default value. In this case, if +// the new discriminator selects the same branch, the operation succeeds. +// (3) The new discriminator selects the implicit default member, if there is one. This +// is equivalent to the _default() method of the IDL-to-C++ mappings. +// +// For all other cases, the operation returns PRECONDITION_NOT_MET. +DDS::ReturnCode_t DynamicDataImpl::set_union_discriminator_helper(CORBA::Long new_disc_value, + const char* func_name) +{ + bool has_existing_branch; + DDS::MemberDescriptor_var existing_md; + const DDS::ReturnCode_t rc = get_selected_union_branch(has_existing_branch, existing_md); + if (rc != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; } - member_type = get_base_type(md->type()); - const TypeKind member_tk = member_type->get_kind(); - if (member_tk != MemberTypeKind && member_tk != enum_or_bitmask) { - return false; + // Always allow setting discriminator that selects the implicit default member. + if (discriminator_selects_no_member(new_disc_value)) { + return DDS::RETCODE_OK; } - return insert_valid_discriminator(md) && insert_single(id, value); + // The new discriminator selects a different branch than the current one. + if (!has_existing_branch || !validate_discriminator(new_disc_value, existing_md)) { + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::%C:" + " Discriminator value %d does not select the same activated branch!\n", + func_name, new_disc_value)); + } + return DDS::RETCODE_PRECONDITION_NOT_MET; + } + return DDS::RETCODE_OK; } -bool DynamicDataImpl::insert_valid_discriminator(DDS::MemberDescriptor* memberSelected) +bool DynamicDataImpl::get_union_member_type(DDS::MemberId id, DDS::DynamicType_var& member_type, + DDS::MemberDescriptor_var& md) const { - if (memberSelected->is_default_label()) { - DCPS::DisjointSequence::OrderedRanges used; - const ACE_CDR::ULong members = type_->get_member_count(); - for (ACE_CDR::ULong i = 0; i < members; ++i) { - DDS::DynamicTypeMember_var member; - if (type_->get_member_by_index(member, i) != DDS::RETCODE_OK) { + if (id == DISCRIMINATOR_ID) { + member_type = get_base_type(type_desc_->discriminator_type()); + } else { + DDS::DynamicTypeMember_var member; + if (type_->get_member(member, id) != DDS::RETCODE_OK) { + return false; + } + if (member->get_descriptor(md) != DDS::RETCODE_OK) { + return false; + } + member_type = get_base_type(md->type()); + } + return true; +} + +// Only call on union. +// Check if there is a selected branch and return its information if so. +bool DynamicDataImpl::find_selected_union_branch(bool& has_existing_branch, + DDS::MemberDescriptor_var& existing_md) +{ + const_single_iterator single_it; + const_complex_iterator complex_it; + has_existing_branch = false; + + if (has_discriminator_value(single_it, complex_it)) { + DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); + CORBA::Long existing_disc; + if (!get_discriminator_value(existing_disc, single_it, complex_it, disc_type)) { + return false; + } + if (XTypes::get_selected_union_branch(type_, existing_disc, has_existing_branch, existing_md) != DDS::RETCODE_OK) { + return false; + } + } + return true; +} + +// With backing store, data for union (the discriminator and a selected branch) can +// scatter across the container and the backing store. E.g., the discriminator can be +// in the container but a branch selected by it is in the backing store, and vice versa. +// In any case, the container and backing store as a whole must represent a valid state +// of the union data. The union data can be in the following states: +// (a) It contains no data at all. +// (b) It contains a value for the discriminator and a value for the selected branch, +// including the implicit default branch, if exists. +// +// In the case of (b), the data for the discriminator and the selected branch can be +// found at either the container or the backing store, if present: +// (i) Both the discriminator and the selected branch are in the container +// (the backing store contains obsolete data) +// (ii) Both the discriminator and the selected branch are in the backing store +// (the container is empty) +// (iii) The discriminator is in the container, the selected branch is in the backing store +// (iv) The discrininator is in the backing store, the selected branch is in the container +// +// Note also that the container have priority over the backing store when reading data. +template +DDS::ReturnCode_t DynamicDataImpl::set_value_to_union(DDS::MemberId id, const MemberType& value) +{ + DDS::DynamicType_var member_type; + DDS::MemberDescriptor_var md; + if (!get_union_member_type(id, member_type, md)) { + return DDS::RETCODE_ERROR; + } + + const TypeKind member_tk = member_type->get_kind(); + TypeKind treat_member_as = member_tk; + if (member_tk == TK_ENUM && enum_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + if (member_tk == TK_BITMASK && bitmask_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + + if (treat_member_as != ValueTypeKind) { + return DDS::RETCODE_BAD_PARAMETER; + } + + // This follows the IDL-to-C++ mapping for union. + if (id == DISCRIMINATOR_ID) { + CORBA::Long disc_value; + if (!cast_to_discriminator_value(disc_value, value)) { + return DDS::RETCODE_ERROR; + } + const DDS::ReturnCode_t rc = set_union_discriminator_helper(disc_value, "set_value_to_union"); + if (rc != DDS::RETCODE_OK) { + return rc; + } + insert_single(id, value); + return DDS::RETCODE_OK; + } + + bool has_existing_branch = false; + DDS::MemberDescriptor_var existing_md; + if (!find_selected_union_branch(has_existing_branch, existing_md)) { + return DDS::RETCODE_ERROR; + } + + // Update the value of the branch, but keep the existing discriminator value. + if (has_existing_branch && existing_md->id() == id) { + insert_single(id, value); + return DDS::RETCODE_OK; + } + + // Store both the selected branch and a matching discriminator to the container. + clear_container(); + + if (!insert_valid_discriminator(md) || !insert_single(id, value)) { + return DDS::RETCODE_ERROR; + } + return DDS::RETCODE_OK; +} + +bool DynamicDataImpl::insert_valid_discriminator(DDS::MemberDescriptor* memberSelected) +{ + if (memberSelected->is_default_label()) { + DCPS::DisjointSequence::OrderedRanges used; + const ACE_CDR::ULong members = type_->get_member_count(); + for (ACE_CDR::ULong i = 0; i < members; ++i) { + DDS::DynamicTypeMember_var member; + if (type_->get_member_by_index(member, i) != DDS::RETCODE_OK) { return false; } if (member->get_id() == DISCRIMINATOR_ID || member->get_id() == memberSelected->id()) { @@ -1581,20 +1832,20 @@ bool DynamicDataImpl::insert_discriminator(ACE_CDR::Long value) // Check if a given member ID is valid for a given type with a maximum number of elements. bool DynamicDataImpl::check_index_from_id(TypeKind tk, DDS::MemberId id, CORBA::ULong bound) const { - // The given Id is treated as index. + const CORBA::ULong index = id_to_index(id); switch (tk) { case TK_STRING8: case TK_STRING16: case TK_SEQUENCE: case TK_MAP: // Bound of 0 means unbounded. - if (bound == 0 || id < bound) { + if (bound == 0 || index < bound) { return true; } break; case TK_BITMASK: case TK_ARRAY: - if (id < bound) { + if (index < bound) { return true; } break; @@ -1602,47 +1853,71 @@ bool DynamicDataImpl::check_index_from_id(TypeKind tk, DDS::MemberId id, CORBA:: return false; } +bool DynamicDataImpl::check_out_of_bound_write(DDS::MemberId id) +{ + const TypeKind tk = type_->get_kind(); + CORBA::ULong bound = bound_total(type_desc_); + const CORBA::ULong item_count = get_item_count(); + if (tk == TK_SEQUENCE || tk == TK_STRING8 || tk == TK_STRING16) { + // Allow setting an existing element or appending a new one + if (bound == 0) { // The sequence has no hard bound + bound = item_count + 1; + } else { + bound = bound > item_count ? item_count + 1 : bound; + } + } + if (!check_index_from_id(tk, id, bound)) { + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) DynamicDataImpl::check_out_of_bound_write:" + " Invalid ID: %u. Total number of elements: %u\n", id, item_count)); + } + return false; + } + return true; +} + template -bool DynamicDataImpl::set_value_to_collection(DDS::MemberId id, const ElementType& value, - TypeKind collection_tk, TypeKind enum_or_bitmask, LBound lower, LBound upper) +DDS::ReturnCode_t DynamicDataImpl::set_value_to_collection(DDS::MemberId id, const ElementType& value) { + if (!check_out_of_bound_write(id)) { + return DDS::RETCODE_BAD_PARAMETER; + } + + // Check the compatibility of the element type. const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); const TypeKind elem_tk = elem_type->get_kind(); + TypeKind treat_elem_as = elem_tk; + if (elem_tk == TK_ENUM && enum_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + if (elem_tk == TK_BITMASK && bitmask_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } - if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) { + if (treat_elem_as != ElementTypeKind) { if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_value_to_collection:" - " Could not write a value of type %C to %C with element type %C\n", - typekind_to_string(ElementTypeKind), typekind_to_string(collection_tk), - typekind_to_string(elem_tk))); - } - return false; - } - - if (elem_tk == enum_or_bitmask) { - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = elem_td->bound()[0]; - if (bit_bound < lower || bit_bound > upper) { - return false; + " Can't write a value of type %C to a collection with element type %C\n", + typekind_to_string(ElementTypeKind), typekind_to_string(elem_tk))); } + return DDS::RETCODE_BAD_PARAMETER; } - - return validate_member_id_collection(id, collection_tk) && insert_single(id, value); + insert_single(id, value); + return DDS::RETCODE_OK; } template -DDS::ReturnCode_t DynamicDataImpl::set_single_value(DDS::MemberId id, const ValueType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper) +DDS::ReturnCode_t DynamicDataImpl::set_single_value(DDS::MemberId id, const ValueType& value) { if (!is_type_supported(ValueTypeKind, "set_single_value")) { return DDS::RETCODE_ERROR; } const TypeKind tk = type_->get_kind(); - bool good = true; + TypeKind treat_as = tk; + if (tk == TK_ENUM && enum_bound(type_, treat_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } // TODO: Bitmask can be stored as a whole as a unsigned integer using MEMBER_ID_INVALID // (this is an extension to the XTypes spec). Elements of the bitmask can also be set @@ -1650,68 +1925,61 @@ DDS::ReturnCode_t DynamicDataImpl::set_single_value(DDS::MemberId id, const Valu // made consistent. For example, when a bit in the bitmask is updated, either update // the unsigned integer representation or invalidate it. Similarly, when the unsigned // integer value is updated, either update the stored elements or invalidate them all. - if (tk == enum_or_bitmask) { - const CORBA::ULong bit_bound = type_desc_->bound()[0]; - good = id == MEMBER_ID_INVALID && bit_bound >= lower && bit_bound <= upper && - insert_single(id, value); - } else { - switch (tk) { - case ValueTypeKind: - good = is_primitive(tk) && id == MEMBER_ID_INVALID && insert_single(id, value); - break; - case TK_STRUCTURE: - good = set_value_to_struct(id, value); - break; - case TK_UNION: - good = set_value_to_union(id, value, enum_or_bitmask, lower, upper); - break; - case TK_SEQUENCE: - case TK_ARRAY: - case TK_MAP: - good = set_value_to_collection(id, value, tk, enum_or_bitmask, lower, upper); - break; - default: - good = false; - break; - } + if (tk == TK_BITMASK && bitmask_bound(type_, treat_as) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; } - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_single_value: " - "Failed to write a value of %C to DynamicData object of type %C\n", - typekind_to_string(ValueTypeKind), typekind_to_string(tk))); + switch (treat_as) { + case ValueTypeKind: + if (!is_primitive(treat_as) || id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; + } + insert_single(id, value); + return DDS::RETCODE_OK; + case TK_STRUCTURE: + return set_value_to_struct(id, value); + case TK_UNION: + return set_value_to_union(id, value); + case TK_SEQUENCE: + case TK_ARRAY: + return set_value_to_collection(id, value); + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_single_value:" + " Called on unexpected type %C\n", typekind_to_string(tk))); + } } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::set_int32_value(DDS::MemberId id, CORBA::Long value) { - return set_single_value(id, value, TK_ENUM, 17, 32); + return set_single_value(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_uint32_value(DDS::MemberId id, CORBA::ULong value) { - return set_single_value(id, value, TK_BITMASK, 17, 32); + return set_single_value(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_int8_value(DDS::MemberId id, CORBA::Int8 value) { - return set_single_value(id, ACE_OutputCDR::from_int8(value), TK_ENUM, 1, 8); + return set_single_value(id, ACE_OutputCDR::from_int8(value)); } DDS::ReturnCode_t DynamicDataImpl::set_uint8_value(DDS::MemberId id, CORBA::UInt8 value) { - return set_single_value(id, ACE_OutputCDR::from_uint8(value), TK_BITMASK, 1, 8); + return set_single_value(id, ACE_OutputCDR::from_uint8(value)); } DDS::ReturnCode_t DynamicDataImpl::set_int16_value(DDS::MemberId id, CORBA::Short value) { - return set_single_value(id, value, TK_ENUM, 9, 16); + return set_single_value(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_uint16_value(DDS::MemberId id, CORBA::UShort value) { - return set_single_value(id, value, TK_BITMASK, 9, 16); + return set_single_value(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_int64_value(DDS::MemberId id, CORBA::LongLong value) @@ -1721,7 +1989,7 @@ DDS::ReturnCode_t DynamicDataImpl::set_int64_value(DDS::MemberId id, CORBA::Long DDS::ReturnCode_t DynamicDataImpl::set_uint64_value(DDS::MemberId id, CORBA::ULongLong value) { - return set_single_value(id, value, TK_BITMASK, 33, 64); + return set_single_value(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_float32_value(DDS::MemberId id, CORBA::Float value) @@ -1743,42 +2011,29 @@ template DDS::ReturnCode_t DynamicDataImpl::set_char_common(DDS::MemberId id, const FromCharT& value) { const TypeKind tk = type_->get_kind(); - bool good = true; switch (tk) { case CharKind: - good = id == MEMBER_ID_INVALID && insert_single(id, value); - break; - case StringKind: { - const CORBA::ULong bound = type_desc_->bound()[0]; - if (!check_index_from_id(tk, id, bound)) { - good = false; - } else { - good = insert_single(id, value); + if (id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; } - break; - } + insert_single(id, value); + return DDS::RETCODE_OK; case TK_STRUCTURE: - good = set_value_to_struct(id, value); - break; + return set_value_to_struct(id, value); case TK_UNION: - good = set_value_to_union(id, value); - break; + return set_value_to_union(id, value); + case StringKind: case TK_SEQUENCE: case TK_ARRAY: - case TK_MAP: - good = set_value_to_collection(id, value, tk); - break; + return set_value_to_collection(id, value); default: - good = false; - break; - } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_char_common:" - " Failed to write DynamicData object of type %C\n", typekind_to_string(tk))); + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_char_common:" + " Called on unexpected type %C\n", typekind_to_string(tk))); + } } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::set_char8_value(DDS::MemberId id, CORBA::Char value) @@ -1803,43 +2058,36 @@ DDS::ReturnCode_t DynamicDataImpl::set_byte_value(DDS::MemberId id, CORBA::Octet DDS::ReturnCode_t DynamicDataImpl::set_boolean_value(DDS::MemberId id, CORBA::Boolean value) { const TypeKind tk = type_->get_kind(); - bool good = true; switch (tk) { case TK_BOOLEAN: - good = id == MEMBER_ID_INVALID && insert_single(id, ACE_OutputCDR::from_boolean(value)); - break; + if (id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; + } + insert_single(id, ACE_OutputCDR::from_boolean(value)); + return DDS::RETCODE_OK; case TK_BITMASK: { const CORBA::ULong bit_bound = type_desc_->bound()[0]; if (!check_index_from_id(tk, id, bit_bound)) { - good = false; - } else { - good = insert_single(id, ACE_OutputCDR::from_boolean(value)); + return DDS::RETCODE_BAD_PARAMETER; } - break; + insert_single(id, ACE_OutputCDR::from_boolean(value)); + return DDS::RETCODE_OK; } case TK_STRUCTURE: - good = set_value_to_struct(id, ACE_OutputCDR::from_boolean(value)); - break; + return set_value_to_struct(id, ACE_OutputCDR::from_boolean(value)); case TK_UNION: - good = set_value_to_union(id, ACE_OutputCDR::from_boolean(value)); - break; + return set_value_to_union(id, ACE_OutputCDR::from_boolean(value)); case TK_SEQUENCE: case TK_ARRAY: - case TK_MAP: - good = set_value_to_collection(id, ACE_OutputCDR::from_boolean(value), tk); - break; + return set_value_to_collection(id, ACE_OutputCDR::from_boolean(value)); default: - good = false; - break; - } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_boolean_value:" - " Failed to write boolean to DynamicData object of type %C\n", - typekind_to_string(tk))); + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_boolean_value:" + " Called on unexpected type %C\n", typekind_to_string(tk))); + } } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::set_string_value(DDS::MemberId id, const char* value) @@ -2034,154 +2282,132 @@ DDS::ReturnCode_t DynamicDataImpl::get_simple_value(DCPS::Value& value, DDS::Mem bool DynamicDataImpl::serialized_size(const DCPS::Encoding& enc, size_t& size, DCPS::Sample::Extent ext) const { - return serialized_size_i(enc, size, ext); + DynamicDataImpl* non_const_this = const_cast(this); + if (ext == DCPS::Sample::Full) { + return DCPS::serialized_size(enc, size, non_const_this); + } else if (ext == DCPS::Sample::KeyOnly) { + DDS::DynamicData_ptr tmp = non_const_this; + return DCPS::serialized_size(enc, size, DCPS::KeyOnly(tmp)); + } + return false; } bool DynamicDataImpl::serialize(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const { - return serialize_i(ser, ext); + DynamicDataImpl* non_const_this = const_cast(this); + if (ext == DCPS::Sample::Full) { + return ser << non_const_this; + } else if (ext == DCPS::Sample::KeyOnly) { + DDS::DynamicData_ptr tmp = non_const_this; + return ser << DCPS::KeyOnly(tmp); + } + return false; } -bool DynamicDataImpl::set_complex_to_struct(DDS::MemberId id, DDS::DynamicData_var value) +DDS::ReturnCode_t DynamicDataImpl::set_complex_to_struct(DDS::MemberId id, DDS::DynamicData_var value) { DDS::DynamicTypeMember_var member; if (type_->get_member(member, id) != DDS::RETCODE_OK) { - return false; + return DDS::RETCODE_ERROR; } DDS::MemberDescriptor_var md; if (member->get_descriptor(md) != DDS::RETCODE_OK) { - return false; + return DDS::RETCODE_ERROR; } const DDS::DynamicType_var member_type = get_base_type(md->type()); const DDS::DynamicType_var value_type = value->type(); if (!member_type || !value_type || !member_type->equals(value_type)) { - return false; + return DDS::RETCODE_BAD_PARAMETER; } - return insert_complex(id, value); + insert_complex(id, value); + return DDS::RETCODE_OK; } -bool DynamicDataImpl::set_complex_to_union(DDS::MemberId id, DDS::DynamicData_var value) +DDS::ReturnCode_t DynamicDataImpl::set_complex_to_union(DDS::MemberId id, DDS::DynamicData_var value) { - if (id == DISCRIMINATOR_ID) { - DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); - const DDS::DynamicType_var value_type = value->type(); - if (!disc_type->equals(value_type)) { - return false; - } + DDS::DynamicType_var member_type; + DDS::MemberDescriptor_var md; + if (!get_union_member_type(id, member_type, md)) { + return DDS::RETCODE_ERROR; + } + + const DDS::DynamicType_var value_type = value->type(); + if (!member_type->equals(value_type)) { + return DDS::RETCODE_BAD_PARAMETER; + } + if (id == DISCRIMINATOR_ID) { CORBA::Long disc_val; - const DynamicDataImpl* dd_impl = dynamic_cast(value.in()); + DynamicDataImpl* dd_impl = dynamic_cast(value.in()); if (!dd_impl || !dd_impl->read_discriminator(disc_val)) { - return false; + return DDS::RETCODE_ERROR; } - - const DDS::MemberId selected_id = find_selected_member(); - if (selected_id != MEMBER_ID_INVALID) { - DDS::DynamicTypeMember_var selected_member; - if (type_->get_member(selected_member, selected_id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var selected_md; - if (selected_member->get_descriptor(selected_md) != DDS::RETCODE_OK) { - return false; - } - if (!validate_discriminator(disc_val, selected_md)) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_to_union:" - " Discriminator value %d does not select the activated member (ID %u)\n", - disc_val, selected_id)); - } - return false; - } - return insert_complex(id, value); - } else { - if (discriminator_selects_no_member(disc_val)) { - return insert_complex(id, value); - } - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_to_union:" - " Can't directly set a discriminator that selects a member." - " Activate the member first!\n")); - } - return false; + const DDS::ReturnCode_t rc = set_union_discriminator_helper(disc_val, "set_complex_to_union"); + if (rc != DDS::RETCODE_OK) { + return rc; } + insert_complex(id, value); + return DDS::RETCODE_OK; } - // Activate a member - clear_container(); - - DDS::DynamicTypeMember_var member; - if (type_->get_member(member, id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var md; - if (member->get_descriptor(md) != DDS::RETCODE_OK) { - return false; + bool has_existing_branch = false; + DDS::MemberDescriptor_var existing_md; + if (!find_selected_union_branch(has_existing_branch, existing_md)) { + return DDS::RETCODE_ERROR; } - const DDS::DynamicType_var value_type = value->type(); - if (!get_base_type(md->type())->equals(value_type)) { - return false; + + // Update the value for the existing branch. + if (has_existing_branch && existing_md->id() == id) { + insert_complex(id, value); + return DDS::RETCODE_OK; } - return insert_valid_discriminator(md) && insert_complex(id, value); -} + // Set the union to the new branch. + clear_container(); -bool DynamicDataImpl::validate_member_id_collection(DDS::MemberId id, TypeKind tk) const -{ - switch (tk) { - case TK_SEQUENCE: - case TK_ARRAY: - return check_index_from_id(tk, id, bound_total(type_desc_)); - case TK_MAP: - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::validate_member_id_collection::" - " Map is currently not supported\n")); - } + if (!insert_valid_discriminator(md) || !insert_complex(id, value)) { + return DDS::RETCODE_ERROR; } - return false; + return DDS::RETCODE_OK; } -bool DynamicDataImpl::set_complex_to_collection(DDS::MemberId id, DDS::DynamicData_var value, - TypeKind collection_tk) +DDS::ReturnCode_t DynamicDataImpl::set_complex_to_collection(DDS::MemberId id, DDS::DynamicData_var value) { + if (!check_out_of_bound_write(id)) { + return DDS::RETCODE_BAD_PARAMETER; + } + const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); const DDS::DynamicType_var value_type = value->type(); if (!elem_type->equals(value_type)) { - return false; + return DDS::RETCODE_BAD_PARAMETER; } - return validate_member_id_collection(id, collection_tk) && insert_complex(id, value); + insert_complex(id, value); + return DDS::RETCODE_OK; } DDS::ReturnCode_t DynamicDataImpl::set_complex_value(DDS::MemberId id, DDS::DynamicData_ptr value) { DDS::DynamicData_var value_var = DDS::DynamicData::_duplicate(value); const TypeKind tk = type_->get_kind(); - bool good = false; switch (tk) { case TK_STRUCTURE: - good = set_complex_to_struct(id, value_var); - break; + return set_complex_to_struct(id, value_var); case TK_UNION: - good = set_complex_to_union(id, value_var); - break; + return set_complex_to_union(id, value_var); case TK_SEQUENCE: case TK_ARRAY: - case TK_MAP: - good = set_complex_to_collection(id, value_var, tk); - break; + return set_complex_to_collection(id, value_var); default: - good = false; - break; - } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_value:" - " Failed to write complex value for member with ID %d\n", id)); + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_complex_value:" + " Called on unexpected type %C\n", typekind_to_string(tk))); + } } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } template @@ -2193,15 +2419,14 @@ bool DynamicDataImpl::insert_sequence(DDS::MemberId id, const SequenceType& valu return container_.sequence_map_.insert(std::make_pair(id, value)).second; } +// Check that the member at the given Id has a compatible type. template -bool DynamicDataImpl::check_seqmem_in_struct_and_union(DDS::MemberId id, TypeKind enum_or_bitmask, - LBound lower, LBound upper) const +bool DynamicDataImpl::check_seqmem_in_struct_and_union(DDS::MemberId id, DDS::MemberDescriptor_var& md) const { DDS::DynamicTypeMember_var member; - if (type_->get_member(member, id)) { + if (type_->get_member(member, id) != DDS::RETCODE_OK) { return false; } - DDS::MemberDescriptor_var md; if (member->get_descriptor(md) != DDS::RETCODE_OK) { return false; } @@ -2219,74 +2444,58 @@ bool DynamicDataImpl::check_seqmem_in_struct_and_union(DDS::MemberId id, TypeKin const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type()); const TypeKind elem_tk = elem_type->get_kind(); - if (elem_tk != ElementTypeKind && elem_tk != enum_or_bitmask) { + TypeKind treat_elem_as = elem_tk; + if (elem_tk == TK_ENUM && enum_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } + if (elem_tk == TK_BITMASK && bitmask_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { return false; } - if (elem_tk == enum_or_bitmask) { - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = elem_td->bound()[0]; - if (bit_bound < lower || bit_bound > upper) { - return false; - } - } - return true; + return treat_elem_as == ElementTypeKind; } template -bool DynamicDataImpl::set_values_to_struct(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, - LBound lower, LBound upper) +bool DynamicDataImpl::set_values_to_struct(DDS::MemberId id, const SequenceType& value) { - return check_seqmem_in_struct_and_union(id, enum_or_bitmask, lower, upper) && - insert_sequence(id, value); + DDS::MemberDescriptor_var md; + return check_seqmem_in_struct_and_union(id, md) + && insert_sequence(id, value); } template -bool DynamicDataImpl::set_values_to_union(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, - LBound lower, LBound upper) +bool DynamicDataImpl::set_values_to_union(DDS::MemberId id, const SequenceType& value) { - if (id == DISCRIMINATOR_ID) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_values_to_union:" - " Union discriminator cannot be a sequence\n")); - } + DDS::MemberDescriptor_var md; + if (!check_seqmem_in_struct_and_union(id, md)) { return false; } - // Check the member type against the input type parameters. - if (!check_seqmem_in_struct_and_union(id, enum_or_bitmask, lower, upper)) { + bool has_existing_branch = false; + DDS::MemberDescriptor_var existing_md; + if (!find_selected_union_branch(has_existing_branch, existing_md)) { return false; } + if (has_existing_branch && existing_md->id() == id) { + return insert_sequence(id, value); + } + clear_container(); - DDS::DynamicTypeMember_var member; - if (type_->get_member(member, id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var md; - if (member->get_descriptor(md) != DDS::RETCODE_OK) { - return false; - } return insert_valid_discriminator(md) && insert_sequence(id, value); } -template -bool DynamicDataImpl::check_seqmem_in_sequence_and_array(DDS::MemberId id, CORBA::ULong bound, - TypeKind enum_or_bitmask, LBound lower, LBound upper) const +template +bool DynamicDataImpl::set_values_to_collection(DDS::MemberId id, const SequenceType& value) { - if (!check_index_from_id(type_->get_kind(), id, bound)) { + if (!check_out_of_bound_write(id)) { return false; } + // Check that the element type is compatible with the input sequence. const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - if (elem_tk != TK_SEQUENCE) { + if (elem_type->get_kind() != TK_SEQUENCE) { return false; } @@ -2294,86 +2503,54 @@ bool DynamicDataImpl::check_seqmem_in_sequence_and_array(DDS::MemberId id, CORBA if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { return false; } - const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type()); const TypeKind nested_elem_tk = nested_elem_type->get_kind(); - if (nested_elem_tk != ElementTypeKind && nested_elem_tk != enum_or_bitmask) { + TypeKind treat_nested_as = nested_elem_tk; + if (nested_elem_tk == TK_ENUM && enum_bound(nested_elem_type, treat_nested_as) != DDS::RETCODE_OK) { return false; } - if (nested_elem_tk == enum_or_bitmask) { - DDS::TypeDescriptor_var nested_elem_td; - if (nested_elem_type->get_descriptor(nested_elem_td) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = nested_elem_td->bound()[0]; - if (bit_bound < lower || bit_bound > upper) { - return false; - } + if (nested_elem_tk == TK_BITMASK && bitmask_bound(nested_elem_type, treat_nested_as) != DDS::RETCODE_OK) { + return false; + } + if (nested_elem_tk != ElementTypeKind) { + return false; } - return true; -} -template -bool DynamicDataImpl::set_values_to_sequence(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, - LBound lower, LBound upper) -{ - const DDS::UInt32 bound = type_desc_->bound()[0]; - return - check_seqmem_in_sequence_and_array(id, bound, enum_or_bitmask, lower, upper) && - validate_member_id_collection(id, TK_SEQUENCE) && - insert_sequence(id, value); -} + // The length must be at most the bound of the element sequence type. + const CORBA::ULong bound = bound_total(elem_td); + if (bound > 0 && bound < value.length()) { + return false; + } -template -bool DynamicDataImpl::set_values_to_array(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, - LBound lower, LBound upper) -{ - const DDS::UInt32 length = bound_total(type_desc_); - return - check_seqmem_in_sequence_and_array(id, length, enum_or_bitmask, lower, upper) && - validate_member_id_collection(id, TK_ARRAY) && - insert_sequence(id, value); + return insert_sequence(id, value); } template -DDS::ReturnCode_t DynamicDataImpl::set_sequence_values(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, - LBound lower, LBound upper) +DDS::ReturnCode_t DynamicDataImpl::set_sequence_values(DDS::MemberId id, const SequenceType& value) { if (!is_type_supported(ElementTypeKind, "set_sequence_values")) { return DDS::RETCODE_ERROR; } const TypeKind tk = type_->get_kind(); - bool good = true; + bool good = false; switch (tk) { case TK_STRUCTURE: - good = set_values_to_struct(id, value, enum_or_bitmask, lower, upper); + good = set_values_to_struct(id, value); break; case TK_UNION: - good = set_values_to_union(id, value, enum_or_bitmask, lower, upper); + good = set_values_to_union(id, value); break; case TK_SEQUENCE: - good = set_values_to_sequence(id, value, enum_or_bitmask, lower, upper); - break; case TK_ARRAY: - good = set_values_to_array(id, value, enum_or_bitmask, lower, upper); + good = set_values_to_collection(id, value); break; - case TK_MAP: - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_sequence_values:" - " Map is currently not supported\n")); - } - return DDS::RETCODE_ERROR; default: if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_sequence_values:" " Write to unsupported type (%C)\n", typekind_to_string(tk))); } - return DDS::RETCODE_ERROR; } if (!good && log_level >= LogLevel::Notice) { @@ -2386,32 +2563,32 @@ DDS::ReturnCode_t DynamicDataImpl::set_sequence_values(DDS::MemberId id, const S DDS::ReturnCode_t DynamicDataImpl::set_int32_values(DDS::MemberId id, const DDS::Int32Seq& value) { - return set_sequence_values(id, value, TK_ENUM, 17, 32); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_uint32_values(DDS::MemberId id, const DDS::UInt32Seq& value) { - return set_sequence_values(id, value, TK_BITMASK, 17, 32); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_int8_values(DDS::MemberId id, const DDS::Int8Seq& value) { - return set_sequence_values(id, value, TK_ENUM, 1, 8); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_uint8_values(DDS::MemberId id, const DDS::UInt8Seq& value) { - return set_sequence_values(id, value, TK_BITMASK, 1, 8); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_int16_values(DDS::MemberId id, const DDS::Int16Seq& value) { - return set_sequence_values(id, value, TK_ENUM, 9, 16); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_uint16_values(DDS::MemberId id, const DDS::UInt16Seq& value) { - return set_sequence_values(id, value, TK_BITMASK, 9, 16); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_int64_values(DDS::MemberId id, const DDS::Int64Seq& value) @@ -2421,7 +2598,7 @@ DDS::ReturnCode_t DynamicDataImpl::set_int64_values(DDS::MemberId id, const DDS: DDS::ReturnCode_t DynamicDataImpl::set_uint64_values(DDS::MemberId id, const DDS::UInt64Seq& value) { - return set_sequence_values(id, value, TK_BITMASK, 33, 64); + return set_sequence_values(id, value); } DDS::ReturnCode_t DynamicDataImpl::set_float32_values(DDS::MemberId id, const DDS::Float32Seq& value) @@ -2618,7 +2795,6 @@ bool DynamicDataImpl::read_basic_in_single_map(char*& value, DDS::MemberId id) { const_single_iterator single_it = container_.single_map_.find(id); if (single_it != container_.single_map_.end()) { - CORBA::string_free(value); value = single_it->second.get_string(); return true; } @@ -2630,7 +2806,6 @@ bool DynamicDataImpl::read_basic_in_single_map(CORBA::WChar*& value, DDS::Member { const_single_iterator single_it = container_.single_map_.find(id); if (single_it != container_.single_map_.end()) { - CORBA::wstring_free(value); value = single_it->second.get_wstring(); return true; } @@ -2648,127 +2823,243 @@ bool DynamicDataImpl::read_basic_in_complex_map(ValueType& value, DDS::MemberId return false; } -template -bool DynamicDataImpl::read_basic_member(ValueType& value, DDS::MemberId id) +void DynamicDataImpl::set_backing_store(DDS::DynamicData_ptr backing_store) { - return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id); + backing_store_ = backing_store; } -template<> -bool DynamicDataImpl::read_basic_member(char*& value, DDS::MemberId id) +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_int8& value, + DDS::MemberId id) { - return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id); + return backing_store_ && backing_store_->get_int8_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); } -template<> -bool DynamicDataImpl::read_basic_member(CORBA::WChar*& value, DDS::MemberId id) +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_uint8& value, + DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_uint8_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::Short& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_int16_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::UShort& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_uint16_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::Long& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_int32_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::ULong& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_uint32_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::LongLong& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_int64_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::ULongLong& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_uint64_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::Float& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_float32_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::Double& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_float64_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::LongDouble& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_float128_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_octet& value, + DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_byte_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(char*& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_string_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(CORBA::WChar*& value, DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_wstring_value(value, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_char& value, + DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_char8_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_wchar& value, + DDS::MemberId id) { - return read_basic_in_single_map(value, id) || read_basic_in_complex_map(value, id); + return backing_store_ && backing_store_->get_char16_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +bool DynamicDataImpl::get_value_from_backing_store(ACE_OutputCDR::from_boolean& value, + DDS::MemberId id) +{ + return backing_store_ && backing_store_->get_boolean_value(value.val_, id) == DDS::RETCODE_OK + && insert_single(id, value); +} + +template +bool DynamicDataImpl::read_basic_member(ValueType& value, DDS::MemberId id) +{ + return read_basic_in_single_map(value, id) + || read_basic_in_complex_map(value, id) + || get_value_from_backing_store(value, id); } template -bool DynamicDataImpl::get_value_from_self(ValueType& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_self(ValueType& value, DDS::MemberId id) { // Primitive or enum value can be read using MEMBER_ID_INVALID. - if (!is_primitive(type_->get_kind()) || id != MEMBER_ID_INVALID) { - return false; + if (!is_primitive(type_->get_kind())) { + return DDS::RETCODE_ERROR; + } + if (id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; } + const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); if (it != container_.single_map_.end()) { value = it->second.get(); - } else { + } else if (!get_value_from_backing_store(value, id)) { set_default_basic_value(value); } - return true; + return DDS::RETCODE_OK; } template<> -bool DynamicDataImpl::get_value_from_self(char*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_self(char*&, DDS::MemberId) { // Can't read a string from a DynamicData instance representing a string. - return false; + return DDS::RETCODE_ERROR; } template<> -bool DynamicDataImpl::get_value_from_self(CORBA::WChar*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_self(CORBA::WChar*&, DDS::MemberId) { // Can't read a wstring from a DynamicData instance representing a wstring. - return false; + return DDS::RETCODE_ERROR; } template -bool DynamicDataImpl::get_value_from_enum(ValueType& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_enum(ValueType& value, DDS::MemberId id) { TypeKind treat_as_tk; const DDS::ReturnCode_t rc = enum_bound(type_, treat_as_tk); - if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind || id != MEMBER_ID_INVALID) { - return false; + if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind) { + return DDS::RETCODE_ERROR; + } + if (id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; } + const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); if (it != container_.single_map_.end()) { value = it->second.get(); - } else { + } else if (!get_value_from_backing_store(value, id)) { CORBA::Long enum_default_val; if (!set_default_enum_value(type_, enum_default_val)) { - return false; + return DDS::RETCODE_ERROR; } cast_to_enum_value(value, enum_default_val); } - return true; + + return DDS::RETCODE_OK; } template<> -bool DynamicDataImpl::get_value_from_enum(char*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_enum(char*&, DDS::MemberId) { - return false; + return DDS::RETCODE_ERROR; } template<> -bool DynamicDataImpl::get_value_from_enum(CORBA::WChar*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_enum(CORBA::WChar*&, DDS::MemberId) { - return false; + return DDS::RETCODE_ERROR; } template -bool DynamicDataImpl::get_value_from_bitmask(ValueType& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_bitmask(ValueType& value, DDS::MemberId id) { // Allow bitmask to be read as an unsigned integer. TypeKind treat_as_tk; const DDS::ReturnCode_t rc = bitmask_bound(type_, treat_as_tk); - if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind || id != MEMBER_ID_INVALID) { - return false; + if (rc != DDS::RETCODE_OK || treat_as_tk != ValueTypeKind) { + return DDS::RETCODE_ERROR; + } + if (id != MEMBER_ID_INVALID) { + return DDS::RETCODE_BAD_PARAMETER; } + const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); if (it != container_.single_map_.end()) { value = it->second.get(); - } else { + } else if (!get_value_from_backing_store(value, id)) { set_default_bitmask_value(value); } - return true; + return DDS::RETCODE_OK; } template<> -bool DynamicDataImpl::get_value_from_bitmask(char*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_bitmask(char*&, DDS::MemberId) { - return false; + return DDS::RETCODE_ERROR; } template<> -bool DynamicDataImpl::get_value_from_bitmask(CORBA::WChar*&, DDS::MemberId) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_bitmask(CORBA::WChar*&, DDS::MemberId) { - return false; + return DDS::RETCODE_ERROR; } template -bool DynamicDataImpl::get_value_from_struct(ValueType& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_struct(ValueType& value, DDS::MemberId id) { DDS::MemberDescriptor_var md; DDS::DynamicType_var member_type; DDS::ReturnCode_t rc = check_member( md, member_type, "DynamicDataImpl::get_value_from_struct", "get", id, ValueTypeKind); if (rc != DDS::RETCODE_OK) { - return false; + return rc; } if (read_basic_member(value, id)) { - return true; + return DDS::RETCODE_OK; } // Not returning a default value for a missing optional member. @@ -2777,85 +3068,54 @@ bool DynamicDataImpl::get_value_from_struct(ValueType& value, DDS::MemberId id) ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_struct:" " Optional member Id %u is not present\n", id)); } - return false; + return DDS::RETCODE_NO_DATA; } + set_default_basic_value(value); - return true; + return DDS::RETCODE_OK; } template -bool DynamicDataImpl::get_value_from_union(ValueType& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_value_from_union(ValueType& value, DDS::MemberId id) { DDS::MemberDescriptor_var md; DDS::DynamicType_var member_type; DDS::ReturnCode_t rc = check_member( md, member_type, "DynamicDataImpl::get_value_from_union", "get", id, ValueTypeKind); if (rc != DDS::RETCODE_OK) { - return false; + return rc; + } + + if (id == DISCRIMINATOR_ID) { + if (!read_basic_member(value, id)) { + set_default_basic_value(value); + } + return DDS::RETCODE_OK; + } + + // Branch + bool has_selected_branch; + DDS::MemberDescriptor_var selected_md; + if (get_selected_union_branch(has_selected_branch, selected_md) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + + // Requesting a branch that is not selected. + if (!has_selected_branch || selected_md->id() != id) { + return DDS::RETCODE_PRECONDITION_NOT_MET; } - // Return the member if it is in the container. if (read_basic_member(value, id)) { - return true; + return DDS::RETCODE_OK; } - if (id == DISCRIMINATOR_ID) { - // Set the discriminator to default value. - // If it selects a branch, set the branch to default value. - set_default_basic_value(value); - CORBA::Long disc_value; - if (!cast_to_discriminator_value(disc_value, value)) { - return false; - } - bool found_selected_member = false; - DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = - get_selected_union_branch(disc_value, found_selected_member, selected_md); - if (rc != DDS::RETCODE_OK) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_union:" - " get_selected_union_branch failed: %C\n", retcode_to_string(rc))); - } - return false; - } - insert_single(id, value); - if (found_selected_member && !selected_md->is_optional()) { - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - if (clear_value_i(selected_md->id(), selected_type) != DDS::RETCODE_OK) { - return false; - } - } - } else { - const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID); - const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID); - const bool has_disc = single_it != container_.single_map_.end() || - complex_it != container_.complex_map_.end(); - if (has_disc) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_value_from_union:" - " Branch Id %u is not the active branch in the union\n", id)); - } - return false; - } - // Set the branch to default value and set the discriminator to a value that selects this branch. - DDS::DynamicTypeMember_var dtm; - if (type_->get_member(dtm, id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var md; - if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { - return false; - } - DDS::DynamicType_var dt = get_base_type(md->type()); - if (clear_value_i(id, dt) != DDS::RETCODE_OK) { - return false; - } - if (!insert_valid_discriminator(md)) { - return false; - } - OPENDDS_ASSERT(read_basic_in_single_map(value, id)); + // The selected branch has not been set explicitly, either because the union data + // is completely empty, or the selected branch is optional and hasn't been set. + if (selected_md->is_optional()) { + return DDS::RETCODE_NO_DATA; } - return true; + set_default_basic_value(value); + return DDS::RETCODE_OK; } void DynamicDataImpl::cast_to_enum_value(ACE_OutputCDR::from_int8& dst, CORBA::Long src) const @@ -2877,42 +3137,62 @@ template void DynamicDataImpl::cast_to_enum_value(ValueType&, CORBA::Long) const {} -template -bool DynamicDataImpl::get_value_from_collection(ValueType& value, DDS::MemberId id) +// Check for out-of-bound read to a collection-like type (sequence, array, string) +bool DynamicDataImpl::check_out_of_bound_read(DDS::MemberId id) { - if (type_->get_kind() == TK_ARRAY && id >= bound_total(type_desc_)) { + const TypeKind tk = type_->get_kind(); + CORBA::ULong bound = bound_total(type_desc_); + const CORBA::ULong item_count = get_item_count(); + if (tk == TK_SEQUENCE || tk == TK_STRING8 || tk == TK_STRING16) { + if (bound > 0) { + bound = item_count; + } + } + if (!check_index_from_id(tk, id, bound)) { + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) DynamicDataImpl::check_out_of_bound_read:" + " Invalid ID: %u. Total number of elements: %u\n", id, item_count)); + } return false; } + return true; +} + +template +DDS::ReturnCode_t DynamicDataImpl::get_value_from_collection(ValueType& value, DDS::MemberId id) +{ + if (!check_out_of_bound_read(id)) { + return DDS::RETCODE_BAD_PARAMETER; + } + // Check the element type DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); const TypeKind elem_tk = elem_type->get_kind(); TypeKind treat_as_tk = elem_tk; switch (elem_tk) { case TK_ENUM: if (enum_bound(elem_type, treat_as_tk) != DDS::RETCODE_OK) { - return false; + return DDS::RETCODE_ERROR; } break; case TK_BITMASK: { if (bitmask_bound(elem_type, treat_as_tk) != DDS::RETCODE_OK) { - return false; + return DDS::RETCODE_ERROR; } break; } } if (treat_as_tk != ValueTypeKind) { - return false; - } - if (read_basic_member(value, id)) { - return true; + return DDS::RETCODE_ERROR; } - set_default_basic_value(value); - // Must insert this member in case it's index is larger than the current largest index, - // so that all new members up to this member are serialized. Otherwise, we would be returning - // a value that wouldn't be in the serialized data. - insert_single(id, value); - return true; + // For sequence or string, as long as there is no out-of-range access, + // it'll read successfully from the container or the backing store. + if (!read_basic_member(value, id)) { + // This may only happen for array. + set_default_basic_value(value); + } + return DDS::RETCODE_OK; } template @@ -2922,65 +3202,44 @@ DDS::ReturnCode_t DynamicDataImpl::get_single_value(ValueType& value, DDS::Membe return DDS::RETCODE_ERROR; } const TypeKind tk = type_->get_kind(); - bool good = true; switch (tk) { case ValueTypeKind: - good = get_value_from_self(value, id); - break; + return get_value_from_self(value, id); case TK_ENUM: - good = get_value_from_enum(value, id); - break; + return get_value_from_enum(value, id); case TK_BITMASK: - good = get_value_from_bitmask(value, id); - break; + return get_value_from_bitmask(value, id); case TK_STRUCTURE: - good = get_value_from_struct(value, id); - break; + return get_value_from_struct(value, id); case TK_UNION: - good = get_value_from_union(value, id); - break; + return get_value_from_union(value, id); case TK_SEQUENCE: case TK_ARRAY: - good = get_value_from_collection(value, id); - break; - case TK_MAP: + return get_value_from_collection(value, id); + default: if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_single_value:" - " Map is currently not supported\n")); + " Called on unexpected type %C\n", typekind_to_string(tk))); } - good = false; break; - default: - good = false; - break; - } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_single_value:" - " Failed to read a value of type %C from a DynamicData object of type %C\n", - typekind_to_string(ValueTypeKind), typekind_to_string(tk))); } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::get_int8_value(CORBA::Int8& value, DDS::MemberId id) { - ACE_OutputCDR::from_int8 from_int8(0); + ACE_OutputCDR::from_int8 from_int8(value); const DDS::ReturnCode_t rc = get_single_value(from_int8, id); - if (rc == DDS::RETCODE_OK) { - value = from_int8.val_; - } + value = from_int8.val_; return rc; } DDS::ReturnCode_t DynamicDataImpl::get_uint8_value(CORBA::UInt8& value, DDS::MemberId id) { - ACE_OutputCDR::from_uint8 from_uint8(0); + ACE_OutputCDR::from_uint8 from_uint8(value); const DDS::ReturnCode_t rc = get_single_value(from_uint8, id); - if (rc == DDS::RETCODE_OK) { - value = from_uint8.val_; - } + value = from_uint8.val_; return rc; } @@ -3033,75 +3292,41 @@ templateget_kind(); - bool good = true; switch (tk) { case CharKind: { - if (id != MEMBER_ID_INVALID) { - good = false; - break; - } - const_single_iterator it = container_.single_map_.find(id); - if (it != container_.single_map_.end()) { - FromCharT from_char = it->second.get(); - value = from_char.val_; - } else { - FromCharT from_char('\0'); - set_default_basic_value(from_char); - value = from_char.val_; - } - break; - } - case StringKind: { - FromCharT from_char('\0'); - good = read_basic_member(from_char, id); - if (good) { - value = from_char.val_; - } - break; + FromCharT from_char(value); + const DDS::ReturnCode_t rc = get_value_from_self(from_char, id); + value = from_char.val_; + return rc; } case TK_STRUCTURE: { - FromCharT from_char('\0'); - good = get_value_from_struct(from_char, id); - if (good) { - value = from_char.val_; - } - break; + FromCharT from_char(value); + const DDS::ReturnCode_t rc = get_value_from_struct(from_char, id); + value = from_char.val_; + return rc; } case TK_UNION: { - FromCharT from_char('\0'); - good = get_value_from_union(from_char, id); - if (good) { - value = from_char.val_; - } - break; + FromCharT from_char(value); + const DDS::ReturnCode_t rc = get_value_from_union(from_char, id); + value = from_char.val_; + return rc; } + case StringKind: case TK_SEQUENCE: case TK_ARRAY: { - FromCharT from_char('\0'); - good = get_value_from_collection(from_char, id); - if (good) { - value = from_char.val_; - } - break; + FromCharT from_char(value); + const DDS::ReturnCode_t rc = get_value_from_collection(from_char, id); + value = from_char.val_; + return rc; } - case TK_MAP: + default: if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_char_common:" - " Map is currently not supported\n")); + " Called on unexpected type %C\n", typekind_to_string(tk))); } - good = false; - break; - default: - good = false; break; } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_char_common::" - " Failed to read a value of type %C from a DynamicData object of type %C\n", - typekind_to_string(CharKind), typekind_to_string(tk))); - } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::get_char8_value(CORBA::Char& value, DDS::MemberId id) @@ -3120,118 +3345,86 @@ DDS::ReturnCode_t DynamicDataImpl::get_char16_value(CORBA::WChar& value, DDS::Me DDS::ReturnCode_t DynamicDataImpl::get_byte_value(CORBA::Octet& value, DDS::MemberId id) { - ACE_OutputCDR::from_octet from_octet(0); + ACE_OutputCDR::from_octet from_octet(value); const DDS::ReturnCode_t rc = get_single_value(from_octet, id); - if (rc == DDS::RETCODE_OK) { - value = from_octet.val_; - } + value = from_octet.val_; return rc; } template -bool DynamicDataImpl::get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value) +DDS::ReturnCode_t DynamicDataImpl::get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value) { UIntType bitmask; if (!read_basic_value(bitmask)) { - return false; + return DDS::RETCODE_ERROR; } value = (1ULL << index) & bitmask; - return true; + return DDS::RETCODE_OK; } template<> -bool DynamicDataImpl::get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value) +DDS::ReturnCode_t DynamicDataImpl::get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value) { - ACE_OutputCDR::from_int8 bitmask(0); + ACE_OutputCDR::from_uint8 bitmask(0); if (!read_basic_value(bitmask)) { - return false; + return DDS::RETCODE_ERROR; } value = ((1 << index) & bitmask.val_) ? true : false; - return true; + return DDS::RETCODE_OK; } DDS::ReturnCode_t DynamicDataImpl::get_boolean_value(CORBA::Boolean& value, DDS::MemberId id) { const TypeKind tk = type_->get_kind(); - bool good = true; switch (tk) { case TK_BOOLEAN: { - if (id != MEMBER_ID_INVALID) { - good = false; - break; - } - const_single_iterator it = container_.single_map_.find(id); - if (it != container_.single_map_.end()) { - ACE_OutputCDR::from_boolean from_bool = it->second.get(); - value = from_bool.val_; - } else { - ACE_OutputCDR::from_boolean from_bool(false); - set_default_basic_value(from_bool); - value = from_bool.val_; - } - break; + ACE_OutputCDR::from_boolean from_bool(value); + const DDS::ReturnCode_t rc = get_value_from_self(from_bool, id); + value = from_bool.val_; + return rc; } case TK_BITMASK: { const LBound bitbound = type_desc_->bound()[0]; ACE_CDR::ULong index; if (!get_index_from_id(id, index, bitbound)) { - good = false; - break; + return DDS::RETCODE_BAD_PARAMETER; } if (bitbound >= 1 && bitbound <= 8) { - good = get_boolean_from_bitmask(index, value); + return get_boolean_from_bitmask(index, value); } else if (bitbound >= 9 && bitbound <= 16) { - good = get_boolean_from_bitmask(index, value); + return get_boolean_from_bitmask(index, value); } else if (bitbound >= 17 && bitbound <= 32) { - good = get_boolean_from_bitmask(index, value); - } else { - good = get_boolean_from_bitmask(index, value); + return get_boolean_from_bitmask(index, value); } - break; + return get_boolean_from_bitmask(index, value); } case TK_STRUCTURE: { - ACE_OutputCDR::from_boolean from_bool(false); - good = get_value_from_struct(from_bool, id); - if (good) { - value = from_bool.val_; - } - break; + ACE_OutputCDR::from_boolean from_bool(value); + const DDS::ReturnCode_t rc = get_value_from_struct(from_bool, id); + value = from_bool.val_; + return rc; } case TK_UNION: { - ACE_OutputCDR::from_boolean from_bool(false); - good = get_value_from_union(from_bool, id); - if (good) { - value = from_bool.val_; - } - break; + ACE_OutputCDR::from_boolean from_bool(value); + const DDS::ReturnCode_t rc = get_value_from_union(from_bool, id); + value = from_bool.val_; + return rc; } case TK_SEQUENCE: case TK_ARRAY: { - ACE_OutputCDR::from_boolean from_bool(false); - good = get_value_from_collection(from_bool, id); - if (good) { - value = from_bool.val_; - } - break; + ACE_OutputCDR::from_boolean from_bool(value); + const DDS::ReturnCode_t rc = get_value_from_collection(from_bool, id); + value = from_bool.val_; + return rc; } - case TK_MAP: + default: if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_boolean_value:" - " Map is currently not supported\n")); + " Called on unexpected type %C\n", typekind_to_string(tk))); } - good = false; - break; - default: - good = false; break; } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_boolean_value:" - " Failed to read a boolean value from a DynamicData object of type %C\n", - typekind_to_string(tk))); - } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::get_string_value(char*& value, DDS::MemberId id) @@ -3240,12 +3433,18 @@ DDS::ReturnCode_t DynamicDataImpl::get_string_value(char*& value, DDS::MemberId return DDS::RETCODE_OK; } + CORBA::string_free(value); + // Set to nil since get_string_value of the backing store may be called which + // also releases the memory pointed to by value, causing double-free error. + value = 0; return get_single_value(value, id); } DDS::ReturnCode_t DynamicDataImpl::get_wstring_value(CORBA::WChar*& value, DDS::MemberId id) { #ifdef DDS_HAS_WCHAR + CORBA::wstring_free(value); + value = 0; return get_single_value(value, id); #else return DDS::RETCODE_UNSUPPORTED; @@ -3375,7 +3574,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_iterator& it, Dy { const SequenceType& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, values[i]); + data->insert_single(index_to_id(i), values[i]); } } @@ -3386,7 +3585,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_ { const DDS::StringSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, values[i].in()); + data->insert_single(index_to_id(i), values[i].in()); } } @@ -3397,7 +3596,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence { const DDS::WstringSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, values[i].in()); + data->insert_single(index_to_id(i), values[i].in()); } } #endif @@ -3408,7 +3607,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_it { const DDS::Int8Seq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_int8(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_int8(values[i])); } } @@ -3418,7 +3617,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_i { const DDS::UInt8Seq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_uint8(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_uint8(values[i])); } } @@ -3428,7 +3627,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_it { const DDS::CharSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_char(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_char(values[i])); } } @@ -3438,7 +3637,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_it { const DDS::ByteSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_octet(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_octet(values[i])); } } @@ -3448,7 +3647,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence { const DDS::BooleanSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_boolean(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_boolean(values[i])); } } @@ -3459,7 +3658,7 @@ void DynamicDataImpl::move_sequence_helper(const const_sequence_i { const DDS::WcharSeq& values = it->second.get(); for (CORBA::ULong i = 0; i < values.length(); ++i) { - data->insert_single(i, ACE_OutputCDR::from_wchar(values[i])); + data->insert_single(index_to_id(i), ACE_OutputCDR::from_wchar(values[i])); } } #endif @@ -3473,8 +3672,16 @@ bool DynamicDataImpl::move_sequence_to_complex(const const_sequence_iterator& it return false; } DDS::DynamicType_var elem_type = get_base_type(seq_td->element_type()); + const TypeKind elem_tk = elem_type->get_kind(); + TypeKind treat_elem_as = elem_tk; + if (elem_tk == TK_ENUM && enum_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } + if (elem_tk == TK_BITMASK && bitmask_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } - switch (elem_type->get_kind()) { + switch (treat_elem_as) { case TK_INT8: { move_sequence_helper(it, data); break; @@ -3553,12 +3760,12 @@ bool DynamicDataImpl::move_sequence_to_complex(const const_sequence_iterator& it return true; } -bool DynamicDataImpl::get_complex_from_aggregated(DDS::DynamicData_var& value, DDS::MemberId id, - FoundStatus& found_status) +bool DynamicDataImpl::get_complex_from_container(DDS::DynamicData_var& value, DDS::MemberId id, + FoundStatus& found_status) { const_complex_iterator complex_it = container_.complex_map_.find(id); if (complex_it != container_.complex_map_.end()) { - value = DDS::DynamicData::_duplicate(complex_it->second); + value = complex_it->second; found_status = FOUND_IN_COMPLEX_MAP; return true; } @@ -3596,215 +3803,199 @@ bool DynamicDataImpl::get_complex_from_aggregated(DDS::DynamicData_var& value, D return true; } -bool DynamicDataImpl::get_complex_from_struct(DDS::DynamicData_ptr& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::set_member_backing_store(DynamicDataImpl* member_ddi, + DDS::MemberId id) { - FoundStatus found_status = NOT_FOUND; - DDS::DynamicData_var dd_var; - if (!get_complex_from_aggregated(dd_var, id, found_status)) { - return false; + if (!backing_store_) { + return DDS::RETCODE_NO_DATA; } - if (found_status == FOUND_IN_NON_COMPLEX_MAP || found_status == NOT_FOUND) { - insert_complex(id, dd_var); + DDS::DynamicData_var member_dd; + const DDS::ReturnCode_t rc = backing_store_->get_complex_value(member_dd, id); + if (rc != DDS::RETCODE_OK) { + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::set_member_backing_store:" + " Get complex value for member ID: %u failed: %C\n", id, retcode_to_string(rc))); + } + return DDS::RETCODE_NO_DATA; } - CORBA::release(value); - value = DDS::DynamicData::_duplicate(dd_var); - return true; + + member_ddi->set_backing_store(DDS::DynamicData::_duplicate(member_dd)); + return DDS::RETCODE_OK; } -bool DynamicDataImpl::write_discriminator_helper(CORBA::Long value, TypeKind treat_as) +// Get complex value for a member of a struct or a branch of a union. +DDS::ReturnCode_t DynamicDataImpl::get_complex_from_aggregated(DDS::DynamicData_var& dd_var, + DDS::MemberId id) { - switch (treat_as) { - case TK_BOOLEAN: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_boolean(value)); - case TK_BYTE: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_octet(value)); - case TK_CHAR8: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_char(value)); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_wchar(value)); -#endif - case TK_INT8: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_int8(value)); - case TK_UINT8: - return insert_single(MEMBER_ID_INVALID, ACE_OutputCDR::from_uint8(value)); - case TK_INT16: - return insert_single(MEMBER_ID_INVALID, static_cast(value)); - case TK_UINT16: - return insert_single(MEMBER_ID_INVALID, static_cast(value)); - case TK_INT32: - return insert_single(MEMBER_ID_INVALID, value); - case TK_UINT32: - return insert_single(MEMBER_ID_INVALID, static_cast(value)); - case TK_INT64: - return insert_single(MEMBER_ID_INVALID, static_cast(value)); - case TK_UINT64: - return insert_single(MEMBER_ID_INVALID, static_cast(value)); - default: - return false; + // Whether the member is found in the container. + FoundStatus found_status = NOT_FOUND; + if (!get_complex_from_container(dd_var, id, found_status)) { + return DDS::RETCODE_ERROR; } -} -// Write value to discriminator represented by a DynamicData instance. -bool DynamicDataImpl::write_discriminator(CORBA::Long value) -{ - TypeKind treat_as = type_->get_kind(); - if (treat_as == TK_ENUM) { - if (enum_bound(type_, treat_as) != DDS::RETCODE_OK) { - return false; + if (found_status == NOT_FOUND) { + DynamicDataImpl* ddi = dynamic_cast(dd_var.in()); + if (!ddi) { + return DDS::RETCODE_ERROR; + } + if (set_member_backing_store(ddi, id) != DDS::RETCODE_OK) { + DDS::DynamicTypeMember_var dtm; + if (type_->get_member(dtm, id) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + DDS::MemberDescriptor_var md; + if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; + } + if (md->is_optional()) { + return DDS::RETCODE_NO_DATA; + } } } - return write_discriminator_helper(value, treat_as); + + if (found_status == NOT_FOUND || found_status == FOUND_IN_NON_COMPLEX_MAP) { + insert_complex(id, dd_var); + } + return DDS::RETCODE_OK; } -bool DynamicDataImpl::get_complex_from_union(DDS::DynamicData_ptr& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_complex_from_struct(DDS::DynamicData_ptr& value, DDS::MemberId id) { - FoundStatus found_status = NOT_FOUND; + DDS::MemberDescriptor_var md; + if (get_descriptor(md, id) != DDS::RETCODE_OK) { + return DDS::RETCODE_BAD_PARAMETER; + } + DDS::DynamicData_var dd_var; - if (!get_complex_from_aggregated(dd_var, id, found_status)) { - return false; + const DDS::ReturnCode_t rc = get_complex_from_aggregated(dd_var, id); + if (rc != DDS::RETCODE_OK) { + return rc; } - if (found_status != NOT_FOUND) { - if (found_status == FOUND_IN_NON_COMPLEX_MAP) { - insert_complex(id, dd_var); - } - CORBA::release(value); - value = DDS::DynamicData::_duplicate(dd_var); - return true; + + CORBA::release(value); + value = DDS::DynamicData::_duplicate(dd_var); + return DDS::RETCODE_OK; +} + +DDS::ReturnCode_t DynamicDataImpl::get_complex_from_union(DDS::DynamicData_ptr& value, DDS::MemberId id) +{ + DDS::MemberDescriptor_var md; + if (get_descriptor(md, id) != DDS::RETCODE_OK) { + return DDS::RETCODE_BAD_PARAMETER; } - // Requested member with the given Id is not present in the container. + // Whether it is found in the container. + FoundStatus found_status = NOT_FOUND; + DDS::DynamicData_var dd_var; + if (id == DISCRIMINATOR_ID) { - DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); - CORBA::Long disc_value; - if (!set_default_discriminator_value(disc_value, disc_type)) { - return false; + if (!get_complex_from_container(dd_var, id, found_status)) { + return DDS::RETCODE_ERROR; } - bool found_selected_member = false; - DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = - get_selected_union_branch(disc_value, found_selected_member, selected_md); - if (rc != DDS::RETCODE_OK) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_from_union:" - " get_selected_union_branch failed: %C\n", retcode_to_string(rc))); + if (found_status == NOT_FOUND) { + DynamicDataImpl* ddi = dynamic_cast(dd_var.in()); + if (!ddi) { + return DDS::RETCODE_ERROR; } - return false; - } - DynamicDataImpl* dd_impl = new DynamicDataImpl(disc_type); - DDS::DynamicData_var dd_var = dd_impl; - dd_impl->write_discriminator(disc_value); - insert_complex(DISCRIMINATOR_ID, dd_var); - if (found_selected_member && !selected_md->is_optional()) { - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - if (clear_value_i(selected_md->id(), selected_type) != DDS::RETCODE_OK) { - return false; + const DDS::ReturnCode_t rc = set_member_backing_store(ddi, id); + if (rc != DDS::RETCODE_OK && rc != DDS::RETCODE_NO_DATA) { + return DDS::RETCODE_ERROR; } } - CORBA::release(value); - value = DDS::DynamicData::_duplicate(dd_var); - } else { - const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID); - const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID); - const bool has_disc = single_it != container_.single_map_.end() || - complex_it != container_.complex_map_.end(); - if (has_disc) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_from_union:" - " Branch Id %u is not the active branch in the union\n", id)); - } - return false; + + if (found_status == NOT_FOUND || found_status == FOUND_IN_NON_COMPLEX_MAP) { + insert_complex(id, dd_var); } - DDS::DynamicTypeMember_var dtm; - if (type_->get_member(dtm, id) != DDS::RETCODE_OK) { - return false; + } else { // Branch + bool has_selected_branch; + DDS::MemberDescriptor_var selected_md; + if (get_selected_union_branch(has_selected_branch, selected_md) != DDS::RETCODE_OK) { + return DDS::RETCODE_ERROR; } - DDS::MemberDescriptor_var md; - if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { - return false; + + // Requesting a branch that is not selected. + if (!has_selected_branch || selected_md->id() != id) { + return DDS::RETCODE_PRECONDITION_NOT_MET; } - // An empty DynamicData object implicitly contains default value of the associated type. - DynamicDataImpl* dd_impl = new DynamicDataImpl(md->type()); - DDS::DynamicData_var dd_var = dd_impl; - if (!insert_valid_discriminator(md)) { - return false; + + const DDS::ReturnCode_t rc = get_complex_from_aggregated(dd_var, id); + if (rc != DDS::RETCODE_OK) { + return rc; } - insert_complex(id, dd_var); - CORBA::release(value); - value = DDS::DynamicData::_duplicate(dd_var); } - return true; + + CORBA::release(value); + value = DDS::DynamicData::_duplicate(dd_var); + return DDS::RETCODE_OK; } -bool DynamicDataImpl::get_complex_from_collection(DDS::DynamicData_ptr& value, DDS::MemberId id) +DDS::ReturnCode_t DynamicDataImpl::get_complex_from_collection(DDS::DynamicData_ptr& value, DDS::MemberId id) { + if (!check_out_of_bound_read(id)) { + return DDS::RETCODE_BAD_PARAMETER; + } + const_complex_iterator complex_it = container_.complex_map_.find(id); if (complex_it != container_.complex_map_.end()) { CORBA::release(value); value = DDS::DynamicData::_duplicate(complex_it->second); - return true; - } - - if (type_->get_kind() == TK_ARRAY && id >= bound_total(type_desc_)) { - return false; + return DDS::RETCODE_OK; } - DynamicDataImpl* dd_impl = new DynamicDataImpl(type_desc_->element_type()); + DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); + DynamicDataImpl* dd_impl = new DynamicDataImpl(elem_type); DDS::DynamicData_var dd_var = dd_impl; const_single_iterator single_it = container_.single_map_.find(id); + bool found_in_maps = false; if (single_it != container_.single_map_.end()) { if (!move_single_to_complex(single_it, dd_impl)) { - return false; + return DDS::RETCODE_ERROR; } + found_in_maps = true; } else { const_sequence_iterator sequence_it = container_.sequence_map_.find(id); if (sequence_it != container_.sequence_map_.end()) { if (!move_sequence_to_complex(sequence_it, dd_impl)) { - return false; + return DDS::RETCODE_ERROR; } + found_in_maps = true; + } + } + + if (!found_in_maps) { + const DDS::ReturnCode_t rc = set_member_backing_store(dd_impl, id); + if (rc != DDS::RETCODE_OK && rc != DDS::RETCODE_NO_DATA) { + return DDS::RETCODE_ERROR; } } insert_complex(id, dd_var); + CORBA::release(value); value = DDS::DynamicData::_duplicate(dd_var); - return true; + return DDS::RETCODE_OK; } DDS::ReturnCode_t DynamicDataImpl::get_complex_value(DDS::DynamicData_ptr& value, DDS::MemberId id) { const TypeKind tk = type_->get_kind(); - bool good = true; switch (tk) { case TK_STRUCTURE: - good = get_complex_from_struct(value, id); - break; + return get_complex_from_struct(value, id); case TK_UNION: - good = get_complex_from_union(value, id); - break; + return get_complex_from_union(value, id); case TK_SEQUENCE: case TK_ARRAY: - good = get_complex_from_collection(value, id); - break; - case TK_MAP: + return get_complex_from_collection(value, id); + default: if (log_level >= LogLevel::Notice) { ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_value:" - " Map is currently not supported\n")); + " Called on unexpected type %C\n", typekind_to_string(tk))); } - good = false; - break; - default: - good = false; break; } - - if (!good && log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_complex_value:" - " Failed to read a complex value from a DynamicData object of type %C\n", - typekind_to_string(tk))); - } - return good ? DDS::RETCODE_OK : DDS::RETCODE_ERROR; + return DDS::RETCODE_ERROR; } DDS::ReturnCode_t DynamicDataImpl::get_int32_values(DDS::Int32Seq& value, DDS::MemberId id) @@ -3993,195 +4184,49 @@ bool DynamicDataImpl::DataContainer::get_largest_index_basic_sequence(CORBA::ULo return true; } -template -bool DynamicDataImpl::serialize_primitive_value(DCPS::Serializer& ser, - PrimitiveType default_value) const -{ - const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); - if (it != container_.single_map_.end()) { - return serialize_single_value(ser, it->second); - } - - // No data stored. Use default value. - set_default_basic_value(default_value); - return ser << default_value; -} - -bool DynamicDataImpl::serialized_size_enum(const DCPS::Encoding& encoding, - size_t& size, const DDS::DynamicType_var& enum_type) const +bool DynamicDataImpl::reconstruct_string_value(CORBA::Char* str) const { - DDS::TypeDescriptor_var enum_td; - if (enum_type->get_descriptor(enum_td) != DDS::RETCODE_OK) { - return false; + const CORBA::ULong bound = type_desc_->bound()[0]; + for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { + CORBA::ULong index; + if (!get_index_from_id(it->first, index, bound)) { + return false; + } + str[index] = it->second.get().val_; } - const CORBA::ULong bit_bound = enum_td->bound()[0]; - if (bit_bound >= 1 && bit_bound <= 8) { - primitive_serialized_size_int8(encoding, size); - return true; - } else if (bit_bound >= 9 && bit_bound <= 16) { - return primitive_serialized_size(encoding, size, CORBA::Short()); - } else if (bit_bound >= 17 && bit_bound <= 32) { - return primitive_serialized_size(encoding, size, CORBA::Long()); + for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { + CORBA::ULong index; + if (!get_index_from_id(it->first, index, bound)) { + return false; + } + // The DynamicData object for this character may not contain any data. + // Use default value for character if it is the case. + const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); + if (!elem_dd) { + return false; + } + const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); + if (elem_it != elem_dd->container_.single_map_.end()) { + str[index] = elem_it->second.get().val_; + } else { + ACE_OutputCDR::from_char from_char('\0'); + set_default_basic_value(from_char); + str[index] = from_char.val_; + } } - return false; + return true; } -bool DynamicDataImpl::serialize_enum_default_value(DCPS::Serializer& ser, - const DDS::DynamicType_var& enum_type) const +#ifdef DDS_HAS_WCHAR +bool DynamicDataImpl::reconstruct_wstring_value(CORBA::WChar* wstr) const { - // The first enumerator is used as the enum's default value (Table 9). - DDS::DynamicTypeMember_var first_dtm; - if (enum_type->get_member_by_index(first_dtm, 0) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var first_md; - if (first_dtm->get_descriptor(first_md) != DDS::RETCODE_OK) { - return false; - } - DDS::TypeDescriptor_var descriptor; - if (enum_type->get_descriptor(descriptor) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = descriptor->bound()[0]; - - if (bit_bound >= 1 && bit_bound <= 8) { - return ser << static_cast(first_md->id()); - } else if (bit_bound >= 9 && bit_bound <= 16) { - return ser << static_cast(first_md->id()); - } else if (bit_bound >= 17 && bit_bound <= 32) { - return ser << static_cast(first_md->id()); - } - return false; -} - -bool DynamicDataImpl::serialize_enum_value(DCPS::Serializer& ser) const -{ - const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); - if (it != container_.single_map_.end()) { - return serialize_single_value(ser, it->second); - } - return serialize_enum_default_value(ser, type_); -} - -bool DynamicDataImpl::serialized_size_bitmask(const DCPS::Encoding& encoding, - size_t& size, const DDS::DynamicType_var& bitmask_type) const -{ - DDS::TypeDescriptor_var bitmask_td; - if (bitmask_type->get_descriptor(bitmask_td) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = bitmask_td->bound()[0]; - if (bit_bound >= 1 && bit_bound <= 8) { - primitive_serialized_size_uint8(encoding, size); - return true; - } else if (bit_bound >= 9 && bit_bound <= 16) { - return primitive_serialized_size(encoding, size, CORBA::UShort()); - } else if (bit_bound >= 17 && bit_bound <= 32) { - return primitive_serialized_size(encoding, size, CORBA::ULong()); - } else if (bit_bound >= 33 && bit_bound <= 64) { - return primitive_serialized_size(encoding, size, CORBA::ULongLong()); - } - return false; -} - -bool DynamicDataImpl::serialize_bitmask_default_value(DCPS::Serializer& ser, - const DDS::DynamicType_var& bitmask_type) const -{ - DDS::TypeDescriptor_var descriptor; - if (bitmask_type->get_descriptor(descriptor) != DDS::RETCODE_OK) { - return false; - } - const CORBA::ULong bit_bound = descriptor->bound()[0]; - - // Table 9 doesn't mention default value for bitmask. Use 0 as default here. - if (bit_bound >= 1 && bit_bound <= 8) { - return ser << static_cast(0); - } else if (bit_bound >= 9 && bit_bound <= 16) { - return ser << static_cast(0); - } else if (bit_bound >= 17 && bit_bound <= 32) { - return ser << static_cast(0); - } else if (bit_bound >= 33 && bit_bound <= 64) { - return ser << static_cast(0); - } - return false; -} - -bool DynamicDataImpl::serialize_bitmask_value(DCPS::Serializer& ser) const -{ - const_single_iterator it = container_.single_map_.find(MEMBER_ID_INVALID); - if (it != container_.single_map_.end()) { - return serialize_single_value(ser, it->second); - } - return serialize_bitmask_default_value(ser, type_); -} - -bool DynamicDataImpl::reconstruct_string_value(CORBA::Char* str) const -{ - const CORBA::ULong bound = type_desc_->bound()[0]; - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - str[index] = it->second.get().val_; - } - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - // The DynamicData object for this character may not contain any data. - // Use default value for character if it is the case. - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - str[index] = elem_it->second.get().val_; - } else { - ACE_OutputCDR::from_char from_char('\0'); - set_default_basic_value(from_char); - str[index] = from_char.val_; - } - } - return true; -} - -bool DynamicDataImpl::serialized_size_string(const DCPS::Encoding& encoding, size_t& size) const -{ - const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty(); - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic(largest_index)) { - return false; - } - primitive_serialized_size_ulong(encoding, size); - size += largest_index + 2; // Include null - } else { - // Use default value for string, i.e., empty string. - primitive_serialized_size_ulong(encoding, size); - size += 1; // For the null termination - } - return true; -} - -bool DynamicDataImpl::serialize_string_value(DCPS::Serializer& ser) const -{ - char* str = 0; - return read_basic_value(str) && (ser << str); -} - -#ifdef DDS_HAS_WCHAR -bool DynamicDataImpl::reconstruct_wstring_value(CORBA::WChar* wstr) const -{ - const CORBA::ULong bound = type_desc_->bound()[0]; - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - wstr[index] = it->second.get().val_; + const CORBA::ULong bound = type_desc_->bound()[0]; + for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { + CORBA::ULong index; + if (!get_index_from_id(it->first, index, bound)) { + return false; + } + wstr[index] = it->second.get().val_; } for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { CORBA::ULong index; @@ -4203,144 +4248,7 @@ bool DynamicDataImpl::reconstruct_wstring_value(CORBA::WChar* wstr) const } return true; } - -bool DynamicDataImpl::serialized_size_wstring(const DCPS::Encoding& encoding, size_t& size) const -{ - const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty(); - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic(largest_index)) { - return false; - } - primitive_serialized_size_ulong(encoding, size); - size += (largest_index + 1) * DCPS::char16_cdr_size; // Not include null termination - } else { - // Only need length - primitive_serialized_size_ulong(encoding, size); - } - return true; -} - -bool DynamicDataImpl::serialize_wstring_value(DCPS::Serializer& ser) const -{ - CORBA::WChar* wstr = 0; - return read_basic_value(wstr) && (ser << wstr); -} -#endif - -void DynamicDataImpl::serialized_size_primitive_sequence(const DCPS::Encoding& encoding, - size_t& size, TypeKind elem_tk, CORBA::ULong length) const -{ - switch (elem_tk) { - case TK_INT32: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Long(), length); - return; - case TK_UINT32: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::ULong(), length); - return; - case TK_INT8: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_int8(encoding, size, length); - return; - case TK_UINT8: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_uint8(encoding, size, length); - return; - case TK_INT16: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Short(), length); - return; - case TK_UINT16: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::UShort(), length); - return; - case TK_INT64: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::LongLong(), length); - return; - case TK_UINT64: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::ULongLong(), length); - return; - case TK_FLOAT32: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Float(), length); - return; - case TK_FLOAT64: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Double(), length); - return; - case TK_FLOAT128: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::LongDouble(), length); - return; - case TK_CHAR8: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_char(encoding, size, length); - return; -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_wchar(encoding, size, length); - return; #endif - case TK_BYTE: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_octet(encoding, size, length); - return; - case TK_BOOLEAN: - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_boolean(encoding, size, length); - return; - } -} // Group of functions to set default value for a basic type (Table 9). // When MemberDescriptor::default_value is fully supported, it would @@ -4554,2370 +4462,137 @@ void DynamicDataImpl::set_default_primitive_values(CollectionType& collection) c } } -// Set elements for a sequence of primitive type -template<> -bool DynamicDataImpl::set_primitive_values(DDS::BooleanSeq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_boolean& /*elem_tag*/) const +// Set discriminator to the default value of the corresponding type. +bool DynamicDataImpl::set_default_discriminator_value(CORBA::Long& value, + const DDS::DynamicType_var& disc_type) const { - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; + const TypeKind disc_tk = disc_type->get_kind(); + switch (disc_tk) { + case TK_BOOLEAN: { + ACE_OutputCDR::from_boolean val(false); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } + case TK_BYTE: { + ACE_OutputCDR::from_octet val(0x00); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } - return true; -} - -template<> -bool DynamicDataImpl::set_primitive_values(DDS::ByteSeq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_octet& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; + case TK_CHAR8: { + ACE_OutputCDR::from_char val('\0'); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: { + ACE_OutputCDR::from_wchar val(0); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } - return true; -} - -template<> -bool DynamicDataImpl::set_primitive_values(DDS::Int8Seq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_int8& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; - } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } - } - return true; -} - -template<> -bool DynamicDataImpl::set_primitive_values(DDS::UInt8Seq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_uint8& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; - } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } - } - return true; -} - -template<> -bool DynamicDataImpl::set_primitive_values(DDS::CharSeq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_char& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; - } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } - } - return true; -} - -#ifdef DDS_HAS_WCHAR -template<> -bool DynamicDataImpl::set_primitive_values(DDS::WcharSeq& collection, - CORBA::ULong bound, const ACE_OutputCDR::from_wchar& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get().val_; - } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get().val_; - } - } - return true; -} #endif - -template -bool DynamicDataImpl::set_primitive_values(CollectionType& collection, - CORBA::ULong bound, const ElementType& /*elem_tag*/) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - collection[index] = it->second.get(); - } - - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - const DynamicDataImpl* elem_dd = dynamic_cast(it->second.in()); - if (!elem_dd) { - return false; - } - const_single_iterator elem_it = elem_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (elem_it != elem_dd->container_.single_map_.end()) { - collection[index] = elem_it->second.get(); - } - } - return true; -} - -// Helper function to reconstruct a sequence or array of primitive type. -// For array, @a size is equal to @a bound. -template -bool DynamicDataImpl::reconstruct_primitive_collection(CollectionType& collection, - CORBA::ULong size, CORBA::ULong bound, const ElementType& elem_tag) const -{ - collection.length(size); - set_default_primitive_values(collection); - return set_primitive_values(collection, bound, elem_tag); -} - -// Reconstruct the primitive sequence written by the user (elements that are not -// explicitly written are set to default value of the corresponding type). -// Then serialize the constructed sequence. -bool DynamicDataImpl::serialize_primitive_sequence(DCPS::Serializer& ser, - TypeKind elem_tk, CORBA::ULong size, CORBA::ULong bound) const -{ - switch (elem_tk) { - case TK_INT32: { - DDS::Int32Seq int32seq; - return reconstruct_primitive_collection(int32seq, size, bound, CORBA::Long()) && - (ser << int32seq); - } - case TK_UINT32: { - DDS::UInt32Seq uint32seq; - return reconstruct_primitive_collection(uint32seq, size, bound, CORBA::ULong()) && - (ser << uint32seq); - } case TK_INT8: { - DDS::Int8Seq int8seq; - return reconstruct_primitive_collection(int8seq, size, bound, ACE_OutputCDR::from_int8(0)) && - (ser << int8seq); + ACE_OutputCDR::from_int8 val(0); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } case TK_UINT8: { - DDS::UInt8Seq uint8seq; - return reconstruct_primitive_collection(uint8seq, size, bound, ACE_OutputCDR::from_uint8(0)) && - (ser << uint8seq); + ACE_OutputCDR::from_uint8 val(0); + set_default_basic_value(val); + value = static_cast(val.val_); + return true; } case TK_INT16: { - DDS::Int16Seq int16seq; - return reconstruct_primitive_collection(int16seq, size, bound, CORBA::Short()) && - (ser << int16seq); - } - case TK_UINT16: { - DDS::UInt16Seq uint16seq; - return reconstruct_primitive_collection(uint16seq, size, bound, CORBA::UShort()) && - (ser << uint16seq); - } - case TK_INT64: { - DDS::Int64Seq int64seq; - return reconstruct_primitive_collection(int64seq, size, bound, CORBA::LongLong()) && - (ser << int64seq); - } - case TK_UINT64: { - DDS::UInt64Seq uint64seq; - return reconstruct_primitive_collection(uint64seq, size, bound, CORBA::ULongLong()) && - (ser << uint64seq); - } - case TK_FLOAT32: { - DDS::Float32Seq float32seq; - return reconstruct_primitive_collection(float32seq, size, bound, CORBA::Float()) && - (ser << float32seq); - } - case TK_FLOAT64: { - DDS::Float64Seq float64seq; - return reconstruct_primitive_collection(float64seq, size, bound, CORBA::Double()) && - (ser << float64seq); - } - case TK_FLOAT128: { - DDS::Float128Seq float128seq; - return reconstruct_primitive_collection(float128seq, size, bound, CORBA::LongDouble()) && - (ser << float128seq); - } - case TK_CHAR8: { - DDS::CharSeq charseq; - return reconstruct_primitive_collection(charseq, size, bound, ACE_OutputCDR::from_char('\0')) && - (ser << charseq); - } -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - DDS::WcharSeq wcharseq; - return reconstruct_primitive_collection(wcharseq, size, bound, ACE_OutputCDR::from_wchar(0)) && - (ser << wcharseq); - } -#endif - case TK_BYTE: { - DDS::ByteSeq byteseq; - return reconstruct_primitive_collection(byteseq, size, bound, ACE_OutputCDR::from_octet(0x00)) && - (ser << byteseq); - } - case TK_BOOLEAN: { - DDS::BooleanSeq boolseq; - return reconstruct_primitive_collection(boolseq, size, bound, ACE_OutputCDR::from_boolean(false)) && - (ser << boolseq); - } - } - return false; -} - -// Unlike primitive types, string and wstring are not as easy to reconstruct since each -// element string may need to be reconstructed individually. Instead, we serialize -// the element strings one by one directly. -void DynamicDataImpl::serialized_size_string_common(const DCPS::Encoding& encoding, - size_t& size, const char* str) const -{ - primitive_serialized_size_ulong(encoding, size); - if (str) { - size += ACE_OS::strlen(str) + 1; // Include null termination - } -} - -#ifdef DDS_HAS_WCHAR -void DynamicDataImpl::serialized_size_string_common(const DCPS::Encoding& encoding, - size_t& size, const CORBA::WChar* wstr) const -{ - primitive_serialized_size_ulong(encoding, size); - if (wstr) { - size += ACE_OS::strlen(wstr) * DCPS::char16_cdr_size; // Not include null termination - } -} -#endif - -void DynamicDataImpl::serialized_size_string_common(const DCPS::Encoding& encoding, - size_t& size, const SingleValue& sv) const -{ - if (sv.kind_ == TK_STRING8) { - serialized_size_string_common(encoding, size, sv.str_); - } -#ifdef DDS_HAS_WCHAR - else if (sv.kind_ == TK_STRING16) { - serialized_size_string_common(encoding, size, sv.wstr_); - } -#endif -} - -template -bool DynamicDataImpl::serialized_size_generic_string_collection( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const DDS::MemberId id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - serialized_size_string_common(encoding, size, single_it->second); - } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) { - return false; - } - } else { - StringType default_value; - set_default_basic_value(default_value); - serialized_size_string_common(encoding, size, default_value); - } - } - return true; -} - -template -bool DynamicDataImpl::serialized_size_generic_string_sequence( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (index_to_id.empty()) { + CORBA::Short val; + set_default_basic_value(val); + value = static_cast(val); return true; } - return serialized_size_generic_string_collection(encoding, size, index_to_id); -} - -// Serialize the individual elements from a sequence or an array of string (or wstring). -template -bool DynamicDataImpl::serialize_generic_string_collection(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const DDS::MemberId id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - if (!serialize_single_value(ser, single_it->second)) { - return false; - } - } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) { - return false; - } - } else { // Not set by the user. Use default value. - StringType default_value; - set_default_basic_value(default_value); - if (!(ser << default_value)) { - return false; - } - } - } - return true; -} - -template -bool DynamicDataImpl::serialize_generic_string_sequence(DCPS::Serializer& ser, - CORBA::ULong length, CORBA::ULong bound) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - - const DCPS::Encoding& encoding = ser.encoding(); - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - size_t total_size = 0; - if (!serialized_size_generic_string_sequence(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } - } - if (!(ser << length)) { - return false; - } - if (length == 0) { + case TK_UINT16: { + CORBA::UShort val; + set_default_basic_value(val); + value = static_cast(val); return true; } - return serialize_generic_string_collection(ser, index_to_id); -} - -template -bool DynamicDataImpl::set_default_enum_values(CollectionType& collection, - const DDS::DynamicType_var& enum_type) const -{ - CORBA::Long value; - if (!set_default_enum_value(enum_type, value)) { - return false; - } - for (CORBA::ULong i = 0; i < collection.length(); ++i) { - collection[i] = static_cast(value); - } - return true; -} - -template -bool DynamicDataImpl::reconstruct_enum_collection(CollectionType& collection, - CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type, - const WrapElementType& elem_tag) const -{ - collection.length(size); - if (!set_default_enum_values(collection, enum_type)) { - return false; - } - return set_primitive_values(collection, bound, elem_tag); -} - -// Serialize enum sequence represented as int8 sequence -void DynamicDataImpl::serialized_size_enum_sequence_as_int8s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_int8(encoding, size, length); -} - -void DynamicDataImpl::serialized_size_enum_sequence( - const DCPS::Encoding& encoding, size_t& size, const DDS::Int8Seq& seq) const -{ - serialized_size_enum_sequence_as_int8s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, - const DDS::Int8Seq& enumseq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_sequence_as_int8s(encoding, total_size, enumseq.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = enumseq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_int8_array(enumseq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_int8s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int8Seq enumseq; - return reconstruct_enum_collection(enumseq, size, bound, enum_type, ACE_OutputCDR::from_int8(0)) && - serialize_enum_sequence_as_ints_i(ser, enumseq); -} - -// Serialize enum sequence represented as int16 sequence -void DynamicDataImpl::serialized_size_enum_sequence_as_int16s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Short(), length); -} - -void DynamicDataImpl::serialized_size_enum_sequence( - const DCPS::Encoding& encoding, size_t& size, const DDS::Int16Seq& seq) const -{ - serialized_size_enum_sequence_as_int16s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, - const DDS::Int16Seq& enumseq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_sequence_as_int16s(encoding, total_size, enumseq.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = enumseq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_short_array(enumseq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_int16s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int16Seq enumseq; - return reconstruct_enum_collection(enumseq, size, bound, enum_type, CORBA::Short()) && - serialize_enum_sequence_as_ints_i(ser, enumseq); -} - -// Serialize enum sequence represented as int32 sequence -void DynamicDataImpl::serialized_size_enum_sequence_as_int32s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::Long(), length); -} - -void DynamicDataImpl::serialized_size_enum_sequence( - const DCPS::Encoding& encoding, size_t& size, const DDS::Int32Seq& seq) const -{ - serialized_size_enum_sequence_as_int32s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, - const DDS::Int32Seq& enumseq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_sequence_as_int32s(encoding, total_size, enumseq.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = enumseq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_long_array(enumseq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_enum_sequence_as_int32s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int32Seq enumseq; - return reconstruct_enum_collection(enumseq, size, bound, enum_type, CORBA::Long()) && - serialize_enum_sequence_as_ints_i(ser, enumseq); -} - -void DynamicDataImpl::serialized_size_enum_sequence(const DCPS::Encoding& encoding, - size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const -{ - if (bitbound >= 1 && bitbound <= 8) { - serialized_size_enum_sequence_as_int8s(encoding, size, length); - } else if (bitbound >= 9 && bitbound <= 16) { - serialized_size_enum_sequence_as_int16s(encoding, size, length); - } else { // From 17 to 32 - serialized_size_enum_sequence_as_int32s(encoding, size, length); - } -} - -bool DynamicDataImpl::serialize_enum_sequence(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bitbound, CORBA::ULong seqbound, - const DDS::DynamicType_var& enum_type) const -{ - if (bitbound >= 1 && bitbound <= 8) { - return serialize_enum_sequence_as_int8s(ser, size, seqbound, enum_type); - } else if (bitbound >= 9 && bitbound <= 16) { - return serialize_enum_sequence_as_int16s(ser, size, seqbound, enum_type); - } else if (bitbound >= 17 && bitbound <= 32) { - return serialize_enum_sequence_as_int32s(ser, size, seqbound, enum_type); - } - return false; -} - -template -void DynamicDataImpl::set_default_bitmask_values(CollectionType& col) const -{ - // Table 9 doesn't mention default value for bitmask. Use 0 as default here. - for (CORBA::ULong i = 0; i < col.length(); ++i) { - col[i] = 0; - } -} - -template -bool DynamicDataImpl::reconstruct_bitmask_collection(CollectionType& collection, - CORBA::ULong size, CORBA::ULong bound, const WrapElementType& elem_tag) const -{ - collection.length(size); - set_default_bitmask_values(collection); - return set_primitive_values(collection, bound, elem_tag); -} - -// Bitmask sequence represented as uint8 sequence. -void DynamicDataImpl::serialized_size_bitmask_sequence_as_uint8s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size_uint8(encoding, size, length); -} - -void DynamicDataImpl::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, - size_t& size, const DDS::UInt8Seq& seq) const -{ - serialized_size_bitmask_sequence_as_uint8s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt8Seq& bitmask_seq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = bitmask_seq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_uint8_array(bitmask_seq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uint8s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - DDS::UInt8Seq bitmask_seq; - return reconstruct_bitmask_collection(bitmask_seq, size, bound, ACE_OutputCDR::from_uint8(0)) && - serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq); -} - -// Bitmask sequence represented as uint16 sequence -void DynamicDataImpl::serialized_size_bitmask_sequence_as_uint16s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::UShort(), length); -} - -void DynamicDataImpl::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, - size_t& size, const DDS::UInt16Seq& seq) const -{ - serialized_size_bitmask_sequence_as_uint16s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt16Seq& bitmask_seq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = bitmask_seq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_ushort_array(bitmask_seq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uint16s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - DDS::UInt16Seq bitmask_seq; - return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::UShort()) && - serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq); -} - -// Bitmask sequence represented as uint32 sequence -void DynamicDataImpl::serialized_size_bitmask_sequence_as_uint32s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::ULong(), length); -} - -void DynamicDataImpl::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, - size_t& size, const DDS::UInt32Seq& seq) const -{ - serialized_size_bitmask_sequence_as_uint32s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt32Seq& bitmask_seq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = bitmask_seq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_ulong_array(bitmask_seq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uint32s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - DDS::UInt32Seq bitmask_seq; - return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::ULong()) && - serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq); -} - -// Bitmask sequence represented as uint64 sequence -void DynamicDataImpl::serialized_size_bitmask_sequence_as_uint64s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (length == 0) { - return; - } - primitive_serialized_size(encoding, size, CORBA::ULongLong(), length); -} - -void DynamicDataImpl::serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, - size_t& size, const DDS::UInt64Seq& seq) const -{ - serialized_size_bitmask_sequence_as_uint64s(encoding, size, seq.length()); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt64Seq& bitmask_seq) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_sequence(encoding, total_size, bitmask_seq); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - const CORBA::ULong length = bitmask_seq.length(); - if (!(ser << length)) { - return false; - } - if (length == 0) { - return true; - } - return ser.write_ulonglong_array(bitmask_seq.get_buffer(), length); -} - -bool DynamicDataImpl::serialize_bitmask_sequence_as_uint64s(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - DDS::UInt64Seq bitmask_seq; - return reconstruct_bitmask_collection(bitmask_seq, size, bound, CORBA::ULongLong()) && - serialize_bitmask_sequence_as_uints_i(ser, bitmask_seq); -} - -void DynamicDataImpl::serialized_size_bitmask_sequence( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const -{ - if (bitbound >= 1 && bitbound <= 8) { - serialized_size_bitmask_sequence_as_uint8s(encoding, size, length); - } else if (bitbound >= 9 && bitbound <= 16) { - serialized_size_bitmask_sequence_as_uint16s(encoding, size, length); - } else if (bitbound >= 17 && bitbound <= 32) { - serialized_size_bitmask_sequence_as_uint32s(encoding, size, length); - } else { // from 33 to 64 - serialized_size_bitmask_sequence_as_uint64s(encoding, size, length); - } -} - -bool DynamicDataImpl::serialize_bitmask_sequence(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bitbound, CORBA::ULong seqbound) const -{ - if (bitbound >= 1 && bitbound <= 8) { - return serialize_bitmask_sequence_as_uint8s(ser, size, seqbound); - } else if (bitbound >= 9 && bitbound <= 16) { - return serialize_bitmask_sequence_as_uint16s(ser, size, seqbound); - } else if (bitbound >= 17 && bitbound <= 32) { - return serialize_bitmask_sequence_as_uint32s(ser, size, seqbound); - } else if (bitbound >= 33 && bitbound <= 64) { - return serialize_bitmask_sequence_as_uint64s(ser, size, seqbound); - } - return false; -} - -// Serialize a SequenceValue object -bool DynamicDataImpl::serialized_size_sequence_value( - const DCPS::Encoding& encoding, size_t& size, const SequenceValue& sv) const -{ - switch (sv.elem_kind_) { - case TK_INT32: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_UINT32: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_INT8: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_UINT8: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_INT16: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_UINT16: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_INT64: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_UINT64: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_FLOAT32: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_FLOAT64: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_FLOAT128: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_CHAR8: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_BYTE: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_BOOLEAN: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_STRING8: - DCPS::serialized_size(encoding, size, sv.get()); - return true; -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - DCPS::serialized_size(encoding, size, sv.get()); - return true; - case TK_STRING16: - DCPS::serialized_size(encoding, size, sv.get()); - return true; -#endif - default: - return false; - } -} - -bool DynamicDataImpl::serialize_sequence_value(DCPS::Serializer& ser, - const SequenceValue& sv) const -{ - switch (sv.elem_kind_) { - case TK_INT32: - return ser << sv.get(); - case TK_UINT32: - return ser << sv.get(); - case TK_INT8: - return ser << sv.get(); - case TK_UINT8: - return ser << sv.get(); - case TK_INT16: - return ser << sv.get(); - case TK_UINT16: - return ser << sv.get(); - case TK_INT64: - return ser << sv.get(); - case TK_UINT64: - return ser << sv.get(); - case TK_FLOAT32: - return ser << sv.get(); - case TK_FLOAT64: - return ser << sv.get(); - case TK_FLOAT128: - return ser << sv.get(); - case TK_CHAR8: - return ser << sv.get(); - case TK_BYTE: - return ser << sv.get(); - case TK_BOOLEAN: - return ser << sv.get(); - case TK_STRING8: - return ser << sv.get(); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return ser << sv.get(); - case TK_STRING16: - return ser << sv.get(); -#endif - default: - return false; - } -} - -// Helper function for serializing sequences and arrays -bool DynamicDataImpl::get_index_to_id_map(IndexToIdMap& index_to_id, - CORBA::ULong bound) const -{ - for (const_single_iterator it = container_.single_map_.begin(); it != container_.single_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - index_to_id[index] = it->first; - } - for (const_sequence_iterator it = container_.sequence_map_.begin(); it != container_.sequence_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - index_to_id[index] = it->first; - } - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - index_to_id[index] = it->first; - } - return true; -} - -bool DynamicDataImpl::serialized_size_complex_member_i( - const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id, DCPS::Sample::Extent ext) const -{ - const DDS::DynamicData_var& dd_var = container_.complex_map_.at(id); - const DynamicDataImpl* data_impl = dynamic_cast(dd_var.in()); - if (!data_impl) { - return false; - } - return data_impl->serialized_size_i(encoding, size, ext); -} - -template -bool DynamicDataImpl::serialized_size_nested_basic_sequences( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id, - SequenceType protoseq) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - serialized_size_sequence_value(encoding, size, it->second); - } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) { - return false; - } - } else { // Empty sequence - protoseq.length(0); - DCPS::serialized_size(encoding, size, protoseq); - } - } - return true; -} - -template -bool DynamicDataImpl::serialized_size_nesting_basic_sequence( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id, - SequenceType protoseq) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (index_to_id.empty()) { - return true; - } - return serialized_size_nested_basic_sequences(encoding, size, index_to_id, protoseq); -} - -bool DynamicDataImpl::serialize_complex_member_i(DCPS::Serializer& ser, - DDS::MemberId id, DCPS::Sample::Extent ext) const -{ - const DDS::DynamicData_var& dd_var = container_.complex_map_.at(id); - const DynamicDataImpl* data_impl = dynamic_cast(dd_var.in()); - if (!data_impl) { - return false; - } - return data_impl->serialize_i(ser, ext); -} - -template -bool DynamicDataImpl::serialize_nested_basic_sequences(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id, SequenceType protoseq) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - if (!serialize_sequence_value(ser, it->second)) { - return false; - } - } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) { - return false; - } - } else { - // Table 9: Use zero-length sequence of the same element type. - protoseq.length(0); - if (!(ser << protoseq)) { - return false; - } - } - } - return true; -} - -template -bool DynamicDataImpl::serialize_nesting_basic_sequence_i(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound, SequenceType protoseq) const -{ - // Map from index to ID. Use MEMBER_ID_INVALID to indicate there is - // no data for an element at a given index. - IndexToIdMap index_to_id(size, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_basic_sequence(encoding, total_size, index_to_id, protoseq) || - !ser.write_delimiter(total_size)) { - return false; - } - } - - // Serialize the top-level sequence's length - if (!(ser << size)) { - return false; - } - if (size == 0) { - return true; - } - return serialize_nested_basic_sequences(ser, index_to_id, protoseq); -} - -bool DynamicDataImpl::serialized_size_nesting_basic_sequence( - const DCPS::Encoding& encoding, size_t& size, TypeKind nested_elem_tk, - const IndexToIdMap& index_to_id) const -{ - switch (nested_elem_tk) { - case TK_INT32: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int32Seq()); - case TK_UINT32: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt32Seq()); - case TK_INT8: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int8Seq()); - case TK_UINT8: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt8Seq()); - case TK_INT16: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int16Seq()); - case TK_UINT16: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt16Seq()); - case TK_INT64: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Int64Seq()); - case TK_UINT64: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::UInt64Seq()); - case TK_FLOAT32: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float32Seq()); - case TK_FLOAT64: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float64Seq()); - case TK_FLOAT128: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::Float128Seq()); - case TK_CHAR8: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::CharSeq()); - case TK_STRING8: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::StringSeq()); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::WcharSeq()); - case TK_STRING16: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::WstringSeq()); -#endif - case TK_BYTE: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::ByteSeq()); - case TK_BOOLEAN: - return serialized_size_nesting_basic_sequence(encoding, size, index_to_id, DDS::BooleanSeq()); - } - return false; -} - -bool DynamicDataImpl::serialize_nesting_basic_sequence(DCPS::Serializer& ser, - TypeKind nested_elem_tk, CORBA::ULong size, CORBA::ULong bound) const -{ - switch (nested_elem_tk) { - case TK_INT32: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int32Seq()); - case TK_UINT32: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt32Seq()); - case TK_INT8: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int8Seq()); - case TK_UINT8: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt8Seq()); - case TK_INT16: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int16Seq()); - case TK_UINT16: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt16Seq()); - case TK_INT64: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Int64Seq()); - case TK_UINT64: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::UInt64Seq()); - case TK_FLOAT32: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float32Seq()); - case TK_FLOAT64: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float64Seq()); - case TK_FLOAT128: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::Float128Seq()); - case TK_CHAR8: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::CharSeq()); - case TK_STRING8: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::StringSeq()); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::WcharSeq()); - case TK_STRING16: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::WstringSeq()); -#endif - case TK_BYTE: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::ByteSeq()); - case TK_BOOLEAN: - return serialize_nesting_basic_sequence_i(ser, size, bound, DDS::BooleanSeq()); - } - return false; -} - -bool DynamicDataImpl::serialized_size_nested_enum_sequences( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - serialized_size_enum_sequence(encoding, size, it); - } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) { - return false; - } - } else { - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - } - } - return true; -} - -bool DynamicDataImpl::serialized_size_nesting_enum_sequence( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (index_to_id.empty()) { - return true; - } - return serialized_size_nested_enum_sequences(encoding, size, index_to_id); -} - -bool DynamicDataImpl::serialize_nested_enum_sequences( - DCPS::Serializer& ser, const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - if (!serialize_enum_sequence(ser, it)) { - return false; - } - } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) { - return false; - } - } else { // Empty sequence of enums - if (ser.encoding().xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) { - return false; - } - } - if (!(ser << static_cast(0))) { - return false; - } - } - } - return true; -} - -bool DynamicDataImpl::serialize_nesting_enum_sequence(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - IndexToIdMap index_to_id(size, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_enum_sequence(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } - } - - if (!(ser << size)) { - return false; - } - if (size == 0) { - return true; - } - return serialize_nested_enum_sequences(ser, index_to_id); -} - -bool DynamicDataImpl::serialized_size_nested_bitmask_sequences( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - serialized_size_bitmask_sequence(encoding, size, it); - } else if (!serialized_size_complex_member_i(encoding, size, id, DCPS::Sample::Full)) { - return false; - } - } else { - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - } - } - return true; -} - -bool DynamicDataImpl::serialized_size_nesting_bitmask_sequence( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (index_to_id.empty()) { - return true; - } - return serialized_size_nested_bitmask_sequences(encoding, size, index_to_id); -} - -bool DynamicDataImpl::serialize_nested_bitmask_sequences(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - const_sequence_iterator it = container_.sequence_map_.find(id); - if (it != container_.sequence_map_.end()) { - if (!serialize_bitmask_sequence(ser, it)) { - return false; - } - } else if (!serialize_complex_member_i(ser, id, DCPS::Sample::Full)) { - return false; - } - } else { // Empty sequence of bitmasks - if (ser.encoding().xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) { - return false; - } - } - if (!(ser << static_cast(0))) { - return false; - } - } - } - return true; -} - -bool DynamicDataImpl::serialize_nesting_bitmask_sequence(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound) const -{ - IndexToIdMap index_to_id(size, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_bitmask_sequence(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } - } - - if (!(ser << size)) { - return false; - } - if (size == 0) { - return true; - } - return serialize_nested_bitmask_sequences(ser, index_to_id); -} - -bool DynamicDataImpl::serialized_size_complex_member(const DCPS::Encoding& encoding, - size_t& size, DDS::MemberId id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const -{ - if (id != MEMBER_ID_INVALID) { - return serialized_size_complex_member_i(encoding, size, id, ext); - } else { - return DynamicDataImpl(elem_type).serialized_size_i(encoding, size, ext); - } -} - -bool DynamicDataImpl::serialized_size_complex_sequence(const DCPS::Encoding& encoding, - size_t& size, const IndexToIdMap& index_to_id, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_ulong(encoding, size); - if (index_to_id.empty()) { - return true; - } - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - if (!serialized_size_complex_member(encoding, size, index_to_id[i], elem_type, ext)) { - return false; - } - } - return true; -} - -bool DynamicDataImpl::serialize_complex_sequence_i(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const -{ - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - const CORBA::ULong id = index_to_id[i]; - if (id != MEMBER_ID_INVALID) { - if (!serialize_complex_member_i(ser, id, ext)) { - return false; - } - } else { - if (!DynamicDataImpl(elem_type).serialize_i(ser, ext)) { - return false; - } - } - } - return true; -} - -bool DynamicDataImpl::serialize_complex_sequence(DCPS::Serializer& ser, - CORBA::ULong size, CORBA::ULong bound, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const -{ - IndexToIdMap index_to_id(size, MEMBER_ID_INVALID); - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - index_to_id[index] = it->first; - } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_complex_sequence(encoding, total_size, index_to_id, elem_type, ext) || - !ser.write_delimiter(total_size)) { - return false; - } - } - - if (!(ser << size)) { - return false; - } - if (size == 0) { - return true; - } - return serialize_complex_sequence_i(ser, index_to_id, elem_type, ext); -} - -bool DynamicDataImpl::get_index_to_id_from_complex(IndexToIdMap& index_to_id, - CORBA::ULong bound) const -{ - CORBA::ULong length = 0; - if (!container_.complex_map_.empty()) { - CORBA::ULong largest_index; - if (!container_.get_largest_complex_index(largest_index)) { - return false; - } - length = largest_index + 1; - } - index_to_id.resize(length, MEMBER_ID_INVALID); - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, bound)) { - return false; - } - index_to_id[index] = it->first; - } - return true; -} - -bool DynamicDataImpl::serialized_size_sequence(const DCPS::Encoding& encoding, - size_t& size, DCPS::Sample::Extent ext) const -{ - const CORBA::ULong bound = type_desc_->bound()[0]; - - const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; - } - - if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) { - const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty(); - CORBA::ULong length = 0; - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic(largest_index)) { - return false; - } - length = largest_index + 1; - } - if (is_primitive(elem_tk)) { - serialized_size_primitive_sequence(encoding, size, elem_tk, length); - return true; - } else if (elem_tk == TK_STRING8) { - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - return serialized_size_generic_string_sequence(encoding, size, index_to_id); - } else if (elem_tk == TK_STRING16) { -#ifdef DDS_HAS_WCHAR - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - return serialized_size_generic_string_sequence(encoding, size, index_to_id); -#else - return false; -#endif - } else if (elem_tk == TK_ENUM) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - serialized_size_enum_sequence(encoding, size, length, bit_bound); - return true; - } else if (elem_tk == TK_BITMASK) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - serialized_size_bitmask_sequence(encoding, size, length, bit_bound); - } - } else if (elem_tk == TK_SEQUENCE) { - const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type()); - const TypeKind nested_elem_tk = nested_elem_type->get_kind(); - if (is_basic(nested_elem_tk) || nested_elem_tk == TK_ENUM || - nested_elem_tk == TK_BITMASK) { - const bool is_empty = container_.sequence_map_.empty() && container_.complex_map_.empty(); - CORBA::ULong length = 0; - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic_sequence(largest_index)) { - return false; - } - length = largest_index + 1; - } - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, bound)) { - return false; - } - if (is_basic(nested_elem_tk)) { - return serialized_size_nesting_basic_sequence(encoding, size, nested_elem_tk, index_to_id); - } else if (nested_elem_tk == TK_ENUM) { - return serialized_size_nesting_enum_sequence(encoding, size, index_to_id); - } else { - return serialized_size_nesting_bitmask_sequence(encoding, size, index_to_id); - } - } - } - - // Elements stored in complex map - IndexToIdMap index_to_id; - if (!get_index_to_id_from_complex(index_to_id, bound)) { - return false; - } - return serialized_size_complex_sequence(encoding, size, index_to_id, elem_type, ext); -} - -bool DynamicDataImpl::serialize_sequence(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const -{ - const CORBA::ULong bound = type_desc_->bound()[0]; - - const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; - } - - if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) { - const bool is_empty = container_.single_map_.empty() && container_.complex_map_.empty(); - CORBA::ULong length = 0; - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic(largest_index)) { - return false; - } - length = largest_index + 1; - } - if (is_primitive(elem_tk)) { - return serialize_primitive_sequence(ser, elem_tk, length, bound); - } else if (elem_tk == TK_STRING8) { - return serialize_generic_string_sequence(ser, length, bound); - } else if (elem_tk == TK_STRING16) { -#ifdef DDS_HAS_WCHAR - return serialize_generic_string_sequence(ser, length, bound); -#else - return false; -#endif - } else if (elem_tk == TK_ENUM) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - return serialize_enum_sequence(ser, length, bit_bound, bound, elem_type); - } else { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - return serialize_bitmask_sequence(ser, length, bit_bound, bound); - } - } else if (elem_tk == TK_SEQUENCE) { - const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type()); - const TypeKind nested_elem_tk = nested_elem_type->get_kind(); - if (is_basic(nested_elem_tk) || nested_elem_tk == TK_ENUM || - nested_elem_tk == TK_BITMASK) { - const bool is_empty = container_.sequence_map_.empty() && container_.complex_map_.empty(); - CORBA::ULong length = 0; - if (!is_empty) { - CORBA::ULong largest_index; - if (!container_.get_largest_index_basic_sequence(largest_index)) { - return false; - } - length = largest_index + 1; - } - if (is_basic(nested_elem_tk)) { - return serialize_nesting_basic_sequence(ser, nested_elem_tk, length, bound); - } else if (nested_elem_tk == TK_ENUM) { - return serialize_nesting_enum_sequence(ser, length, bound); - } else { - return serialize_nesting_bitmask_sequence(ser, length, bound); - } - } - } - - // Elements with all the other types are stored in the complex map. - CORBA::ULong length = 0; - if (!container_.complex_map_.empty()) { - CORBA::ULong largest_index; - if (!container_.get_largest_complex_index(largest_index)) { - return false; - } - length = largest_index + 1; - } - return serialize_complex_sequence(ser, length, bound, elem_type, ext); -} - -void DynamicDataImpl::serialized_size_primitive_array(const DCPS::Encoding& encoding, - size_t& size, TypeKind elem_tk, CORBA::ULong length) const -{ - switch (elem_tk) { - case TK_INT32: - primitive_serialized_size(encoding, size, CORBA::Long(), length); - return; - case TK_UINT32: - primitive_serialized_size(encoding, size, CORBA::ULong(), length); - return; - case TK_INT8: - primitive_serialized_size_int8(encoding, size, length); - return; - case TK_UINT8: - primitive_serialized_size_uint8(encoding, size, length); - return; - case TK_INT16: - primitive_serialized_size(encoding, size, CORBA::Short(), length); - return; - case TK_UINT16: - primitive_serialized_size(encoding, size, CORBA::UShort(), length); - return; - case TK_INT64: - primitive_serialized_size(encoding, size, CORBA::LongLong(), length); - return; - case TK_UINT64: - primitive_serialized_size(encoding, size, CORBA::ULongLong(), length); - return; - case TK_FLOAT32: - primitive_serialized_size(encoding, size, CORBA::Float(), length); - return; - case TK_FLOAT64: - primitive_serialized_size(encoding, size, CORBA::Double(), length); - return; - case TK_FLOAT128: - primitive_serialized_size(encoding, size, CORBA::LongDouble(), length); - return; - case TK_CHAR8: - primitive_serialized_size_char(encoding, size, length); - return; -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - primitive_serialized_size_wchar(encoding, size, length); - return; -#endif - case TK_BYTE: - primitive_serialized_size_octet(encoding, size, length); - return; - case TK_BOOLEAN: - primitive_serialized_size_boolean(encoding, size, length); - return; - } -} - -bool DynamicDataImpl::serialize_primitive_array(DCPS::Serializer& ser, - TypeKind elem_tk, CORBA::ULong length) const -{ - switch (elem_tk) { - case TK_INT32: { - DDS::Int32Seq int32arr; - return reconstruct_primitive_collection(int32arr, length, length, CORBA::Long()) && - ser.write_long_array(int32arr.get_buffer(), length); - } - case TK_UINT32: { - DDS::UInt32Seq uint32arr; - return reconstruct_primitive_collection(uint32arr, length, length, CORBA::ULong()) && - ser.write_ulong_array(uint32arr.get_buffer(), length); - } - case TK_INT8: { - DDS::Int8Seq int8arr; - return reconstruct_primitive_collection(int8arr, length, length, ACE_OutputCDR::from_int8(0)) && - ser.write_int8_array(int8arr.get_buffer(), length); - } - case TK_UINT8: { - DDS::UInt8Seq uint8arr; - return reconstruct_primitive_collection(uint8arr, length, length, ACE_OutputCDR::from_uint8(0)) && - ser.write_uint8_array(uint8arr.get_buffer(), length); - } - case TK_INT16: { - DDS::Int16Seq int16arr; - return reconstruct_primitive_collection(int16arr, length, length, CORBA::Short()) && - ser.write_short_array(int16arr.get_buffer(), length); - } - case TK_UINT16: { - DDS::UInt16Seq uint16arr; - return reconstruct_primitive_collection(uint16arr, length, length, CORBA::UShort()) && - ser.write_ushort_array(uint16arr.get_buffer(), length); - } - case TK_INT64: { - DDS::Int64Seq int64arr; - return reconstruct_primitive_collection(int64arr, length, length, CORBA::LongLong()) && - ser.write_longlong_array(int64arr.get_buffer(), length); - } - case TK_UINT64: { - DDS::UInt64Seq uint64arr; - return reconstruct_primitive_collection(uint64arr, length, length, CORBA::ULongLong()) && - ser.write_ulonglong_array(uint64arr.get_buffer(), length); - } - case TK_FLOAT32: { - DDS::Float32Seq float32arr; - return reconstruct_primitive_collection(float32arr, length, length, CORBA::Float()) && - ser.write_float_array(float32arr.get_buffer(), length); - } - case TK_FLOAT64: { - DDS::Float64Seq float64arr; - return reconstruct_primitive_collection(float64arr, length, length, CORBA::Double()) && - ser.write_double_array(float64arr.get_buffer(), length); - } - case TK_FLOAT128: { - DDS::Float128Seq float128arr; - return reconstruct_primitive_collection(float128arr, length, length, CORBA::LongDouble()) && - ser.write_longdouble_array(float128arr.get_buffer(), length); - } - case TK_CHAR8: { - DDS::CharSeq chararr; - return reconstruct_primitive_collection(chararr, length, length, ACE_OutputCDR::from_char('\0')) && - ser.write_char_array(chararr.get_buffer(), length); - } -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - DDS::WcharSeq wchararr; - return reconstruct_primitive_collection(wchararr, length, length, ACE_OutputCDR::from_wchar(0)) && - ser.write_wchar_array(wchararr.get_buffer(), length); - } -#endif - case TK_BYTE: { - DDS::ByteSeq bytearr; - return reconstruct_primitive_collection(bytearr, length, length, ACE_OutputCDR::from_octet(0x00)) && - ser.write_octet_array(bytearr.get_buffer(), length); - } - case TK_BOOLEAN: { - DDS::BooleanSeq boolarr; - return reconstruct_primitive_collection(boolarr, length, length, ACE_OutputCDR::from_boolean(false)) && - ser.write_boolean_array(boolarr.get_buffer(), length); - } - } - return false; -} - -template -bool DynamicDataImpl::serialized_size_generic_string_array( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - return serialized_size_generic_string_collection(encoding, size, index_to_id); -} - -template -bool DynamicDataImpl::serialize_generic_string_array(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; - } - - const DCPS::Encoding& encoding = ser.encoding(); - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - size_t total_size = 0; - if (!serialized_size_generic_string_array(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } - } - return serialize_generic_string_collection(ser, index_to_id); -} - -// Serialize enum array represented as int8 array -void DynamicDataImpl::serialized_size_enum_array_as_int8s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_int8(encoding, size, length); -} - -bool DynamicDataImpl::serialize_enum_array_as_ints_i(DCPS::Serializer& ser, - const DDS::Int8Seq& enumarr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_array_as_int8s(encoding, total_size, enumarr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_int8_array(enumarr.get_buffer(), enumarr.length()); -} - -bool DynamicDataImpl::serialize_enum_array_as_int8s(DCPS::Serializer& ser, - CORBA::ULong length, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int8Seq enumarr; - return reconstruct_enum_collection(enumarr, length, length, enum_type, ACE_OutputCDR::from_int8(0)) && - serialize_enum_array_as_ints_i(ser, enumarr); -} - -// Serialize enum array represented as int16 array -void DynamicDataImpl::serialized_size_enum_array_as_int16s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size(encoding, size, CORBA::Short(), length); -} - -bool DynamicDataImpl::serialize_enum_array_as_ints_i(DCPS::Serializer& ser, - const DDS::Int16Seq& enumarr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_array_as_int16s(encoding, total_size, enumarr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_short_array(enumarr.get_buffer(), enumarr.length()); -} - -bool DynamicDataImpl::serialize_enum_array_as_int16s(DCPS::Serializer& ser, - CORBA::ULong length, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int16Seq enumarr; - return reconstruct_enum_collection(enumarr, length, length, enum_type, CORBA::Short()) && - serialize_enum_array_as_ints_i(ser, enumarr); -} - -// Serialize enum array represented as int32 array -void DynamicDataImpl::serialized_size_enum_array_as_int32s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size(encoding, size, CORBA::Long(), length); -} - -bool DynamicDataImpl::serialize_enum_array_as_ints_i(DCPS::Serializer& ser, - const DDS::Int32Seq& enumarr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_enum_array_as_int32s(encoding, total_size, enumarr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_long_array(enumarr.get_buffer(), enumarr.length()); -} - -bool DynamicDataImpl::serialize_enum_array_as_int32s(DCPS::Serializer& ser, - CORBA::ULong length, const DDS::DynamicType_var& enum_type) const -{ - DDS::Int32Seq enumarr; - return reconstruct_enum_collection(enumarr, length, length, enum_type, CORBA::Long()) && - serialize_enum_array_as_ints_i(ser, enumarr); -} - -void DynamicDataImpl::serialized_size_enum_array(const DCPS::Encoding& encoding, - size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const -{ - if (bitbound >= 1 && bitbound <= 8) { - serialized_size_enum_array_as_int8s(encoding, size, length); - } else if (bitbound >= 9 && bitbound <= 16) { - serialized_size_enum_array_as_int16s(encoding, size, length); - } else { // from 17 to 32 - serialized_size_enum_array_as_int32s(encoding, size, length); - } -} - -bool DynamicDataImpl::serialize_enum_array(DCPS::Serializer& ser, - CORBA::ULong bitbound, CORBA::ULong length, const DDS::DynamicType_var& enum_type) const -{ - if (bitbound >= 1 && bitbound <= 8) { - return serialize_enum_array_as_int8s(ser, length, enum_type); - } else if (bitbound >= 9 && bitbound <= 16) { - return serialize_enum_array_as_int16s(ser, length, enum_type); - } else if (bitbound >= 17 && bitbound <= 32) { - return serialize_enum_array_as_int32s(ser, length, enum_type); - } - return false; -} - -// Bitmask array represented as uint8 array. -void DynamicDataImpl::serialized_size_bitmask_array_as_uint8s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size_uint8(encoding, size, length); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt8Seq& bitmask_arr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_array_as_uint8s(encoding, total_size, bitmask_arr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_uint8_array(bitmask_arr.get_buffer(), bitmask_arr.length()); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uint8s(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - DDS::UInt8Seq bitmask_arr; - return reconstruct_bitmask_collection(bitmask_arr, length, length, ACE_OutputCDR::from_uint8(0)) && - serialize_bitmask_array_as_uints_i(ser, bitmask_arr); -} - -// Bitmask array represented as uint16 array. -void DynamicDataImpl::serialized_size_bitmask_array_as_uint16s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size(encoding, size, CORBA::UShort(), length); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt16Seq& bitmask_arr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_array_as_uint16s(encoding, total_size, bitmask_arr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_ushort_array(bitmask_arr.get_buffer(), bitmask_arr.length()); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uint16s(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - DDS::UInt16Seq bitmask_arr; - return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::UShort()) && - serialize_bitmask_array_as_uints_i(ser, bitmask_arr); -} - -// Bitmask array represented as uint32 array. -void DynamicDataImpl::serialized_size_bitmask_array_as_uint32s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size(encoding, size, CORBA::ULong(), length); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt32Seq& bitmask_arr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_array_as_uint32s(encoding, total_size, bitmask_arr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_ulong_array(bitmask_arr.get_buffer(), bitmask_arr.length()); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uint32s(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - DDS::UInt32Seq bitmask_arr; - return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::ULong()) && - serialize_bitmask_array_as_uints_i(ser, bitmask_arr); -} - -// Bitmask array represented as uint64 array. -void DynamicDataImpl::serialized_size_bitmask_array_as_uint64s( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length) const -{ - serialized_size_delimiter(encoding, size); - primitive_serialized_size(encoding, size, CORBA::ULongLong(), length); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt64Seq& bitmask_arr) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - serialized_size_bitmask_array_as_uint64s(encoding, total_size, bitmask_arr.length()); - if (!ser.write_delimiter(total_size)) { - return false; - } - } - return ser.write_ulonglong_array(bitmask_arr.get_buffer(), bitmask_arr.length()); -} - -bool DynamicDataImpl::serialize_bitmask_array_as_uint64s(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - DDS::UInt64Seq bitmask_arr; - return reconstruct_bitmask_collection(bitmask_arr, length, length, CORBA::ULongLong()) && - serialize_bitmask_array_as_uints_i(ser, bitmask_arr); -} - -void DynamicDataImpl::serialized_size_bitmask_array( - const DCPS::Encoding& encoding, size_t& size, CORBA::ULong length, CORBA::ULong bitbound) const -{ - if (bitbound >= 1 && bitbound <= 8) { - serialized_size_bitmask_array_as_uint8s(encoding, size, length); - } else if (bitbound >= 9 && bitbound <= 16) { - serialized_size_bitmask_array_as_uint16s(encoding, size, length); - } else if (bitbound >= 17 && bitbound <= 32) { - serialized_size_bitmask_array_as_uint32s(encoding, size, length); - } else { // from 33 to 64 - serialized_size_bitmask_array_as_uint64s(encoding, size, length); - } -} - -bool DynamicDataImpl::serialize_bitmask_array(DCPS::Serializer& ser, - CORBA::ULong bitbound, CORBA::ULong length) const -{ - if (bitbound >= 1 && bitbound <= 8) { - return serialize_bitmask_array_as_uint8s(ser, length); - } else if (bitbound >= 9 && bitbound <= 16) { - return serialize_bitmask_array_as_uint16s(ser, length); - } else if (bitbound >= 17 && bitbound <= 32) { - return serialize_bitmask_array_as_uint32s(ser, length); - } else if (bitbound >= 33 && bitbound <= 64) { - return serialize_bitmask_array_as_uint64s(ser, length); - } - return false; -} - -template -bool DynamicDataImpl::serialized_size_nesting_basic_array(const DCPS::Encoding& encoding, - size_t& size, const IndexToIdMap& index_to_id, SequenceType protoseq) const -{ - serialized_size_delimiter(encoding, size); - return serialized_size_nested_basic_sequences(encoding, size, index_to_id, protoseq); -} - -template -bool DynamicDataImpl::serialize_nesting_basic_array_i(DCPS::Serializer& ser, - CORBA::ULong length, SequenceType protoseq) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; + case TK_INT32: { + set_default_basic_value(value); + return true; } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_basic_array(encoding, total_size, index_to_id, protoseq) || - !ser.write_delimiter(total_size)) { - return false; - } + case TK_UINT32: { + CORBA::ULong val; + set_default_basic_value(val); + value = static_cast(val); + return true; } - return serialize_nested_basic_sequences(ser, index_to_id, protoseq); -} - -bool DynamicDataImpl::serialized_size_nesting_basic_array(const DCPS::Encoding& encoding, - size_t& size, TypeKind nested_elem_tk, const IndexToIdMap& index_to_id) const -{ - switch (nested_elem_tk) { - case TK_INT32: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int32Seq()); - case TK_UINT32: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt32Seq()); - case TK_INT8: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int8Seq()); - case TK_UINT8: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt8Seq()); - case TK_INT16: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int16Seq()); - case TK_UINT16: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt16Seq()); - case TK_INT64: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Int64Seq()); - case TK_UINT64: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::UInt64Seq()); - case TK_FLOAT32: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float32Seq()); - case TK_FLOAT64: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float64Seq()); - case TK_FLOAT128: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::Float128Seq()); - case TK_CHAR8: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::CharSeq()); - case TK_STRING8: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::StringSeq()); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::WcharSeq()); - case TK_STRING16: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::WstringSeq()); -#endif - case TK_BYTE: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::ByteSeq()); - case TK_BOOLEAN: - return serialized_size_nesting_basic_array(encoding, size, index_to_id, DDS::BooleanSeq()); + case TK_INT64: { + CORBA::LongLong val; + set_default_basic_value(val); + value = static_cast(val); + return true; } - return false; -} - -bool DynamicDataImpl::serialize_nesting_basic_array(DCPS::Serializer& ser, - TypeKind nested_elem_tk, CORBA::ULong length) const -{ - switch (nested_elem_tk) { - case TK_INT32: - return serialize_nesting_basic_array_i(ser, length, DDS::Int32Seq()); - case TK_UINT32: - return serialize_nesting_basic_array_i(ser, length, DDS::UInt32Seq()); - case TK_INT8: - return serialize_nesting_basic_array_i(ser, length, DDS::Int8Seq()); - case TK_UINT8: - return serialize_nesting_basic_array_i(ser, length, DDS::UInt8Seq()); - case TK_INT16: - return serialize_nesting_basic_array_i(ser, length, DDS::Int16Seq()); - case TK_UINT16: - return serialize_nesting_basic_array_i(ser, length, DDS::UInt16Seq()); - case TK_INT64: - return serialize_nesting_basic_array_i(ser, length, DDS::Int64Seq()); - case TK_UINT64: - return serialize_nesting_basic_array_i(ser, length, DDS::UInt64Seq()); - case TK_FLOAT32: - return serialize_nesting_basic_array_i(ser, length, DDS::Float32Seq()); - case TK_FLOAT64: - return serialize_nesting_basic_array_i(ser, length, DDS::Float64Seq()); - case TK_FLOAT128: - return serialize_nesting_basic_array_i(ser, length, DDS::Float128Seq()); - case TK_CHAR8: - return serialize_nesting_basic_array_i(ser, length, DDS::CharSeq()); - case TK_STRING8: - return serialize_nesting_basic_array_i(ser, length, DDS::StringSeq()); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return serialize_nesting_basic_array_i(ser, length, DDS::WcharSeq()); - case TK_STRING16: - return serialize_nesting_basic_array_i(ser, length, DDS::WstringSeq()); -#endif - case TK_BYTE: - return serialize_nesting_basic_array_i(ser, length, DDS::ByteSeq()); - case TK_BOOLEAN: - return serialize_nesting_basic_array_i(ser, length, DDS::BooleanSeq()); + case TK_UINT64: { + CORBA::ULongLong val; + set_default_basic_value(val); + value = static_cast(val); + return true; } - return false; -} - -bool DynamicDataImpl::serialized_size_nesting_enum_array( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - return serialized_size_nested_enum_sequences(encoding, size, index_to_id); -} - -bool DynamicDataImpl::serialize_nesting_enum_array(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; + case TK_ENUM: { + return set_default_enum_value(disc_type, value); } - - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_enum_array(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } } - return serialize_nested_enum_sequences(ser, index_to_id); -} - -bool DynamicDataImpl::serialized_size_nesting_bitmask_array( - const DCPS::Encoding& encoding, size_t& size, const IndexToIdMap& index_to_id) const -{ - serialized_size_delimiter(encoding, size); - return serialized_size_nested_bitmask_sequences(encoding, size, index_to_id); + return false; } -bool DynamicDataImpl::serialize_nesting_bitmask_array(DCPS::Serializer& ser, - CORBA::ULong length) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; - } +} // namespace XTypes - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_nesting_bitmask_array(encoding, total_size, index_to_id) || - !ser.write_delimiter(total_size)) { - return false; - } - } - return serialize_nested_bitmask_sequences(ser, index_to_id); -} -bool DynamicDataImpl::serialized_size_complex_array(const DCPS::Encoding& encoding, - size_t& size, const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, - DCPS::Sample::Extent ext) const -{ - serialized_size_delimiter(encoding, size); - for (CORBA::ULong i = 0; i < index_to_id.size(); ++i) { - if (!serialized_size_complex_member(encoding, size, index_to_id[i], elem_type, ext)) { - return false; - } - } - return true; -} +namespace DCPS { -bool DynamicDataImpl::serialize_complex_array( - DCPS::Serializer& ser, CORBA::ULong length, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const -{ - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - for (const_complex_iterator it = container_.complex_map_.begin(); it != container_.complex_map_.end(); ++it) { - CORBA::ULong index; - if (!get_index_from_id(it->first, index, length)) { - return false; - } - index_to_id[index] = it->first; - } +// XCDR2 serialization using the DynamicData API (intended to work with any implementation). +// The get functions must already handle try-construct behavior (in case of reading from +// a XCDR backing store) or returning default value (in case the member data is missing +// from the internal container). So it's guaranteed that some data for each valid +// member is available for serialization. - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - if (!serialized_size_complex_array(encoding, total_size, index_to_id, elem_type, ext) || - !ser.write_delimiter(total_size)) { - return false; - } - } - return serialize_complex_sequence_i(ser, index_to_id, elem_type, ext); -} +bool serialized_size_i( + const Encoding& encoding, size_t& size, DDS::DynamicData_ptr data, Sample::Extent ext); +bool serialize(Serializer& ser, DDS::DynamicData_ptr data, Sample::Extent ext); -bool DynamicDataImpl::serialized_size_array(const DCPS::Encoding& encoding, - size_t& size, DCPS::Sample::Extent ext) const +bool get_type_descriptor(const DDS::DynamicType_var& type, DDS::TypeDescriptor_var& td) { - const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; - } - - const CORBA::ULong length = bound_total(type_desc_); - if (is_basic(elem_tk)) { - serialized_size_primitive_array(encoding, size, elem_tk, length); - return true; - } else if (elem_tk == TK_STRING8) { - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; - } - return serialized_size_generic_string_array(encoding, size, index_to_id); - } else if (elem_tk == TK_STRING16) { -#ifdef DDS_HAS_WCHAR - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; - } - return serialized_size_generic_string_array(encoding, size, index_to_id); -#else - return false; -#endif - } else if (elem_tk == TK_ENUM) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - serialized_size_enum_array(encoding, size, length, bit_bound); - return true; - } else if (elem_tk == TK_BITMASK) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - serialized_size_bitmask_array(encoding, size, length, bit_bound); - return true; - } else if (elem_tk == TK_SEQUENCE) { - const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type()); - const TypeKind nested_elem_tk = nested_elem_type->get_kind(); - IndexToIdMap index_to_id(length, MEMBER_ID_INVALID); - if (!get_index_to_id_map(index_to_id, length)) { - return false; - } - if (is_basic(nested_elem_tk)) { - return serialized_size_nesting_basic_array(encoding, size, nested_elem_tk, index_to_id); - } else if (nested_elem_tk == TK_ENUM) { - return serialized_size_nesting_enum_array(encoding, size, index_to_id); - } else if (nested_elem_tk == TK_BITMASK) { - return serialized_size_nesting_bitmask_array(encoding, size, index_to_id); + if (type->get_descriptor(td) != DDS::RETCODE_OK) { + if (log_level >= LogLevel::Notice) { + const CORBA::String_var type_name = type->get_name(); + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: get_type_descriptor:" + " Failed to get type descriptor for type %C\n", type_name.in())); } - } - - // Elements stored in complex map - IndexToIdMap index_to_id; - if (!get_index_to_id_from_complex(index_to_id, length)) { return false; } - return serialized_size_complex_array(encoding, size, index_to_id, elem_type, ext); + return true; } -bool DynamicDataImpl::serialize_array(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const +void serialized_size_dynamic_member_header( + const Encoding& encoding, size_t& size, size_t& mutable_running_total, + DDS::ReturnCode_t rc, DDS::ExtensibilityKind extensibility, CORBA::Boolean optional) { - const DDS::DynamicType_var elem_type = get_base_type(type_desc_->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - DDS::TypeDescriptor_var elem_td; - if (elem_type->get_descriptor(elem_td) != DDS::RETCODE_OK) { - return false; + if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { + primitive_serialized_size_boolean(encoding, size); + return; } - - const CORBA::ULong length = bound_total(type_desc_); - if (is_basic(elem_tk)) { - return serialize_primitive_array(ser, elem_tk, length); - } else if (elem_tk == TK_STRING8) { - return serialize_generic_string_array(ser, length); - } else if (elem_tk == TK_STRING16) { -#ifdef DDS_HAS_WCHAR - return serialize_generic_string_array(ser, length); -#else - return false; -#endif - } else if (elem_tk == TK_ENUM) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - return serialize_enum_array(ser, bit_bound, length, elem_type); - } else if (elem_tk == TK_BITMASK) { - const CORBA::ULong bit_bound = elem_td->bound()[0]; - return serialize_bitmask_array(ser, bit_bound, length); - } else if (elem_tk == TK_SEQUENCE) { - const DDS::DynamicType_var nested_elem_type = get_base_type(elem_td->element_type()); - const TypeKind nested_elem_tk = nested_elem_type->get_kind(); - if (is_basic(nested_elem_tk)) { - return serialize_nesting_basic_array(ser, nested_elem_tk, length); - } else if (nested_elem_tk == TK_ENUM) { - return serialize_nesting_enum_array(ser, length); - } else if (nested_elem_tk == TK_BITMASK) { - return serialize_nesting_bitmask_array(ser, length); + if (extensibility == DDS::MUTABLE) { + if (!optional || rc == DDS::RETCODE_OK) { + serialized_size_parameter_id(encoding, size, mutable_running_total); } } - return serialize_complex_array(ser, length, elem_type, ext); } -bool DynamicDataImpl::serialized_size_primitive_member(const DCPS::Encoding& encoding, - size_t& size, TypeKind member_tk) const +bool serialized_size_primitive_value(const Encoding& encoding, size_t& size, DDS::TypeKind member_tk) { - using namespace OpenDDS::DCPS; - + using namespace OpenDDS::XTypes; switch (member_tk) { case TK_INT32: return primitive_serialized_size(encoding, size, CORBA::Long()); @@ -6948,849 +4623,464 @@ bool DynamicDataImpl::serialized_size_primitive_member(const DCPS::Encoding& enc return true; #ifdef DDS_HAS_WCHAR case TK_CHAR16: - primitive_serialized_size_wchar(encoding, size); - return true; -#endif - case TK_BYTE: - primitive_serialized_size_octet(encoding, size); - return true; - case TK_BOOLEAN: - primitive_serialized_size_boolean(encoding, size); - return true; - } - return false; -} - -bool DynamicDataImpl::serialized_size_basic_member_default_value( - const DCPS::Encoding& encoding, size_t& size, TypeKind member_tk) const -{ - if (is_primitive(member_tk)) { - return serialized_size_primitive_member(encoding, size, member_tk); - } else if (member_tk == TK_STRING8) { - const char* str_default; - set_default_basic_value(str_default); - serialized_size_string_common(encoding, size, str_default); - return true; - } -#ifdef DDS_HAS_WCHAR - else if (member_tk == TK_STRING16) { - const CORBA::WChar* wstr_default; - set_default_basic_value(wstr_default); - serialized_size_string_common(encoding, size, wstr_default); - return true; - } -#endif - return false; -} - -// Serialized size of a basic member of an aggregated type. Member header size is not included. -bool DynamicDataImpl::serialized_size_basic_member(const DCPS::Encoding& encoding, - size_t& size, TypeKind member_tk, const_single_iterator it) const -{ - if (is_primitive(member_tk)) { - return serialized_size_primitive_member(encoding, size, member_tk); - } else if (member_tk == TK_STRING8 || member_tk == TK_STRING16) { - serialized_size_string_common(encoding, size, it->second); - return true; - } - return false; -} - -bool DynamicDataImpl::serialize_basic_member_default_value(DCPS::Serializer& ser, - TypeKind member_tk) const -{ - switch (member_tk) { - case TK_INT32: { - CORBA::Long value; - set_default_basic_value(value); - return ser << value; - } - case TK_UINT32: { - CORBA::ULong value; - set_default_basic_value(value); - return ser << value; - } - case TK_INT8: { - ACE_OutputCDR::from_int8 value(0); - set_default_basic_value(value); - return ser << value; - } - case TK_UINT8: { - ACE_OutputCDR::from_uint8 value(0); - set_default_basic_value(value); - return ser << value; - } - case TK_INT16: { - CORBA::Short value; - set_default_basic_value(value); - return ser << value; - } - case TK_UINT16: { - CORBA::UShort value; - set_default_basic_value(value); - return ser << value; - } - case TK_INT64: { - CORBA::LongLong value; - set_default_basic_value(value); - return ser << value; - } - case TK_UINT64: { - CORBA::ULongLong value; - set_default_basic_value(value); - return ser << value; - } - case TK_FLOAT32: { - CORBA::Float value; - set_default_basic_value(value); - return ser << value; - } - case TK_FLOAT64: { - CORBA::Double value; - set_default_basic_value(value); - return ser << value; - } - case TK_FLOAT128: { - CORBA::LongDouble value; - set_default_basic_value(value); - return ser << value; - } - case TK_CHAR8: { - ACE_OutputCDR::from_char value('\0'); - set_default_basic_value(value); - return ser << value; - } - case TK_STRING8: { - const char* value; - set_default_basic_value(value); - return ser << value; - } -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - ACE_OutputCDR::from_wchar value(0); - set_default_basic_value(value); - return ser << value; - } - case TK_STRING16: { - const CORBA::WChar* value; - set_default_basic_value(value); - return ser << value; - } -#endif - case TK_BYTE: { - ACE_OutputCDR::from_octet value(0x00); - set_default_basic_value(value); - return ser << value; - } - case TK_BOOLEAN: { - ACE_OutputCDR::from_boolean value(false); - set_default_basic_value(value); - return ser << value; - } + primitive_serialized_size_wchar(encoding, size); + return true; +#endif + case TK_BYTE: + primitive_serialized_size_octet(encoding, size); + return true; + case TK_BOOLEAN: + primitive_serialized_size_boolean(encoding, size); + return true; } return false; } -// Serialize an aggregated member stored in the single map. -// The member type is basic or enum or bitmask. -bool DynamicDataImpl::serialized_size_single_aggregated_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, const_single_iterator it, - const DDS::DynamicType_var& member_type, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const +void serialized_size_string_value(const Encoding& encoding, size_t& size, const char* str) { - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - primitive_serialized_size_boolean(encoding, size); - } else if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); - } - const TypeKind member_tk = member_type->get_kind(); - if (is_basic(member_tk)) { - return serialized_size_basic_member(encoding, size, member_tk, it); - } else if (member_tk == TK_ENUM) { - return serialized_size_enum(encoding, size, member_type); - } else { // Bitmask - return serialized_size_bitmask(encoding, size, member_type); + primitive_serialized_size_ulong(encoding, size); + if (str) { + size += ACE_OS::strlen(str) + 1; // Include null termination } } -bool DynamicDataImpl::serialize_single_aggregated_member_xcdr2(DCPS::Serializer& ser, - const_single_iterator it, const DDS::DynamicType_var& member_type, bool optional, - bool must_understand, DDS::ExtensibilityKind extensibility) const +#ifdef DDS_HAS_WCHAR +void serialized_size_wstring_value(const Encoding& encoding, size_t& size, const CORBA::WChar* wstr) { - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - if (!(ser << ACE_OutputCDR::from_boolean(true))) { - return false; - } - } else if (extensibility == DDS::MUTABLE) { - const DCPS::Encoding& encoding = ser.encoding(); - const TypeKind member_tk = member_type->get_kind(); - size_t member_size = 0; - if (is_basic(member_tk)) { - serialized_size_basic_member(encoding, member_size, member_tk, it); - } else if (member_tk == TK_ENUM) { - serialized_size_enum(encoding, member_size, member_type); - } else if (member_tk == TK_BITMASK) { - serialized_size_bitmask(encoding, member_size, member_type); - } else { - return false; - } - if (!ser.write_parameter_id(it->first, member_size, must_understand)) { - return false; - } + primitive_serialized_size_ulong(encoding, size); + if (wstr) { + size += ACE_OS::strlen(wstr) * char16_cdr_size; // Not include null termination } - return serialize_single_value(ser, it->second); } +#endif -// Serialize a member of an aggregated type whose value must be represented by a DynamicData -// object. However, the data for the member is missing from the complex map. So default value -// of the corresponding type is used for serialization. -bool DynamicDataImpl::serialized_size_complex_aggregated_member_xcdr2_default( - const DCPS::Encoding& encoding, size_t& size, const DDS::DynamicType_var& member_type, - bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total, - DCPS::Sample::Extent ext) const +bool check_rc_from_get(DDS::ReturnCode_t rc, DDS::MemberId id, DDS::TypeKind tk, const char* fn_name) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - primitive_serialized_size_boolean(encoding, size); + if (rc != DDS::RETCODE_OK && rc != DDS::RETCODE_NO_DATA) { + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|t) NOTICE: %C: Failed to get %C member ID %u: %C\n", + fn_name, XTypes::typekind_to_string(tk), id, retcode_to_string(rc))); } - return true; - } - if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); + return false; } - - return DynamicDataImpl(member_type).serialized_size_i(encoding, size, ext); + return true; } -bool DynamicDataImpl::serialize_complex_aggregated_member_xcdr2_default( - DCPS::Serializer& ser, DDS::MemberId id, const DDS::DynamicType_var& member_type, - bool optional, bool must_understand, DDS::ExtensibilityKind extensibility, - DCPS::Sample::Extent ext) const +bool serialized_size_dynamic_member(DDS::DynamicData_ptr data, const Encoding& encoding, + size_t& size, const DDS::MemberDescriptor_var& md, DDS::ExtensibilityKind extensibility, + size_t& mutable_running_total, Sample::Extent ext) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - return ser << ACE_OutputCDR::from_boolean(false); - } - return true; - } - // Use default value if the member is not optional. - const DynamicDataImpl default_value(member_type); - if (extensibility == DDS::MUTABLE) { - size_t member_size = 0; - default_value.serialized_size_i(ser.encoding(), member_size, ext); - if (!ser.write_parameter_id(id, member_size, must_understand)) { - return false; - } - } - return default_value.serialize_i(ser, ext); -} + using namespace OpenDDS::XTypes; + const DDS::MemberId member_id = md->id(); + const CORBA::Boolean optional = md->is_optional(); + const DDS::DynamicType_var member_type = get_base_type(md->type()); + const DDS::TypeKind member_tk = member_type->get_kind(); + DDS::TypeKind treat_member_as = member_tk; -// Serialize a member of an aggregated type stored in the complex map, -// i.e., the member value is represented by a DynamicData object. -bool DynamicDataImpl::serialized_size_complex_aggregated_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, const_complex_iterator it, - bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total, - DCPS::Sample::Extent ext) const -{ - const DDS::DynamicData_var& data_var = it->second; - const DynamicDataImpl* data_impl = dynamic_cast(data_var.in()); - if (!data_impl) { + if (member_tk == TK_ENUM && enum_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { return false; } - - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - primitive_serialized_size_boolean(encoding, size); - } else if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); - } - return data_impl->serialized_size_i(encoding, size, ext); -} - -bool DynamicDataImpl::serialize_complex_aggregated_member_xcdr2( - DCPS::Serializer& ser, const_complex_iterator it, bool optional, - bool must_understand, DDS::ExtensibilityKind extensibility, DCPS::Sample::Extent ext) const -{ - const DDS::DynamicData_var& data_var = it->second; - const DynamicDataImpl* data_impl = dynamic_cast(data_var.in()); - if (!data_impl) { + if (member_tk == TK_BITMASK && bitmask_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { return false; } - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - if (!(ser << ACE_OutputCDR::from_boolean(true))) { - return false; + DDS::ReturnCode_t rc = DDS::RETCODE_OK; + if (is_primitive(treat_member_as)) { + switch (treat_member_as) { + case TK_INT8: { + CORBA::Int8 val; + rc = data->get_int8_value(val, member_id); + break; } - } else if (extensibility == DDS::MUTABLE) { - size_t member_size = 0; - if (!data_impl->serialized_size_i(ser.encoding(), member_size, ext) || - !ser.write_parameter_id(it->first, member_size, must_understand)) { - return false; + case TK_UINT8: { + CORBA::UInt8 val; + rc = data->get_uint8_value(val, member_id); + break; } - } - return data_impl->serialize_i(ser, ext); -} - -// Serialize struct member whose type is basic or compatible with a basic type, -// that are enum and bitmask types. -bool DynamicDataImpl::serialized_size_basic_struct_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id, - const DDS::DynamicType_var& member_type, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const -{ - const TypeKind member_tk = member_type->get_kind(); - const_single_iterator single_it = container_.single_map_.find(id); - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (single_it == container_.single_map_.end() && complex_it == container_.complex_map_.end()) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - primitive_serialized_size_boolean(encoding, size); - } - return true; + case TK_INT16: { + CORBA::Short val; + rc = data->get_int16_value(val, member_id); + break; } - if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); + case TK_UINT16: { + CORBA::UShort val; + rc = data->get_uint16_value(val, member_id); + break; } - if (is_basic(member_tk)) { - return serialized_size_basic_member_default_value(encoding, size, member_tk); - } else if (member_tk == TK_ENUM) { - return serialized_size_enum(encoding, size, member_type); - } else { // Bitmask - return serialized_size_bitmask(encoding, size, member_type); + case TK_INT32: { + CORBA::Long val; + rc = data->get_int32_value(val, member_id); + break; } - } - - if (single_it != container_.single_map_.end()) { - return serialized_size_single_aggregated_member_xcdr2(encoding, size, single_it, member_type, - optional, extensibility, mutable_running_total); - } - return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional, - extensibility, mutable_running_total, - DCPS::Sample::Full); -} - -bool DynamicDataImpl::serialize_basic_struct_member_xcdr2(DCPS::Serializer& ser, - DDS::MemberId id, const DDS::DynamicType_var& member_type, bool optional, - bool must_understand, DDS::ExtensibilityKind extensibility) const -{ - const TypeKind member_tk = member_type->get_kind(); - const DCPS::Encoding& encoding = ser.encoding(); - const_single_iterator single_it = container_.single_map_.find(id); - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (single_it == container_.single_map_.end() && complex_it == container_.complex_map_.end()) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - return ser << ACE_OutputCDR::from_boolean(false); - } - return true; + case TK_UINT32: { + CORBA::ULong val; + rc = data->get_uint32_value(val, member_id); + break; } - if (extensibility == DDS::MUTABLE) { - size_t member_size = 0; - if (is_basic(member_tk)) { - serialized_size_basic_member_default_value(encoding, member_size, member_tk); - } else if (member_tk == TK_ENUM) { - serialized_size_enum(encoding, member_size, member_type); - } else if (member_tk == TK_BITMASK) { - serialized_size_bitmask(encoding, member_size, member_type); - } else { - return false; - } - if (!ser.write_parameter_id(id, member_size, must_understand)) { - return false; - } + case TK_INT64: { + CORBA::LongLong val; + rc = data->get_int64_value(val, member_id); + break; + } + case TK_UINT64: { + CORBA::ULongLong val; + rc = data->get_uint64_value(val, member_id); + break; + } + case TK_FLOAT32: { + CORBA::Float val; + rc = data->get_float32_value(val, member_id); + break; + } + case TK_FLOAT64: { + CORBA::Double val; + rc = data->get_float64_value(val, member_id); + break; + } + case TK_FLOAT128: { + CORBA::LongDouble val; + rc = data->get_float128_value(val, member_id); + break; + } + case TK_CHAR8: { + CORBA::Char val; + rc = data->get_char8_value(val, member_id); + break; + } +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: { + CORBA::WChar val; + rc = data->get_char16_value(val, member_id); + break; + } +#endif + case TK_BYTE: { + CORBA::Octet val; + rc = data->get_byte_value(val, member_id); + break; + } + case TK_BOOLEAN: { + CORBA::Boolean val = false; + rc = data->get_boolean_value(val, member_id); + break; } - if (is_basic(member_tk)) { - return serialize_basic_member_default_value(ser, member_tk); - } else if (member_tk == TK_ENUM) { - return serialize_enum_default_value(ser, member_type); - } else if (member_tk == TK_BITMASK) { - return serialize_bitmask_default_value(ser, member_type); } - return false; - } - - if (single_it != container_.single_map_.end()) { - return serialize_single_aggregated_member_xcdr2(ser, single_it, member_type, optional, - must_understand, extensibility); - } - return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional, - must_understand, extensibility, - DCPS::Sample::Full); -} - -void DynamicDataImpl::serialized_size_sequence_member_default_value( - const DCPS::Encoding& encoding, size_t& size, TypeKind elem_tk) const -{ - // Zero-length sequence - if (!is_primitive(elem_tk)) { - serialized_size_delimiter(encoding, size); - } - primitive_serialized_size_ulong(encoding, size); -} -bool DynamicDataImpl::serialize_sequence_member_default_value(DCPS::Serializer& ser, - TypeKind elem_tk) const -{ - // Zero-length sequence - const DCPS::Encoding& encoding = ser.encoding(); - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2 && !is_primitive(elem_tk)) { - if (!ser.write_delimiter(2 * DCPS::uint32_cdr_size)) { + if (!check_rc_from_get(rc, member_id, treat_member_as, "serialized_size_dynamic_member")) { return false; } + serialized_size_dynamic_member_header(encoding, size, mutable_running_total, + rc, extensibility, optional); + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + return serialized_size_primitive_value(encoding, size, treat_member_as); } - return ser << static_cast(0); -} -bool DynamicDataImpl::serialized_size_basic_sequence(const DCPS::Encoding& encoding, - size_t& size, const_sequence_iterator it) const -{ - switch (it->second.elem_kind_) { - case TK_INT32: { - const DDS::Int32Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_UINT32: { - const DDS::UInt32Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_INT8: { - const DDS::Int8Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_UINT8: { - const DDS::UInt8Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_INT16: { - const DDS::Int16Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_UINT16: { - const DDS::UInt16Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_INT64: { - const DDS::Int64Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_UINT64: { - const DDS::UInt64Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_FLOAT32: { - const DDS::Float32Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_FLOAT64: { - const DDS::Float64Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_FLOAT128: { - const DDS::Float128Seq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_CHAR8: { - const DDS::CharSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_BYTE: { - const DDS::ByteSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } - case TK_BOOLEAN: { - const DDS::BooleanSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } + switch (treat_member_as) { case TK_STRING8: { - const DDS::StringSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); + CORBA::String_var val; + rc = data->get_string_value(val, member_id); + if (!check_rc_from_get(rc, member_id, treat_member_as, "serialized_size_dynamic_member")) { + return false; + } + serialized_size_dynamic_member_header(encoding, size, mutable_running_total, + rc, extensibility, optional); + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + serialized_size_string_value(encoding, size, val.in()); return true; } #ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - const DDS::WcharSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); - return true; - } case TK_STRING16: { - const DDS::WstringSeq& seq = it->second.get(); - DCPS::serialized_size(encoding, size, seq); + CORBA::WString_var val; + rc = data->get_wstring_value(val, member_id); + if (!check_rc_from_get(rc, member_id, treat_member_as, "serialized_size_dynamic_member")) { + return false; + } + serialized_size_dynamic_member_header(encoding, size, mutable_running_total, + rc, extensibility, optional); + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + serialized_size_wstring_value(encoding, size, val.in()); return true; } #endif + case TK_STRUCTURE: + case TK_UNION: + case TK_ARRAY: + case TK_SEQUENCE: { + DDS::DynamicData_var member_data; + rc = data->get_complex_value(member_data, member_id); + if (!check_rc_from_get(rc, member_id, treat_member_as, "serialized_size_dynamic_member")) { + return false; + } + serialized_size_dynamic_member_header(encoding, size, mutable_running_total, + rc, extensibility, optional); + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + return serialized_size_i(encoding, size, member_data, ext); + } + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: serialized_size_dynamic_member:" + " Unsupported member type %C at ID %u\n", + XTypes::typekind_to_string(member_tk), member_id)); + } } return false; } -bool DynamicDataImpl::serialize_basic_sequence(DCPS::Serializer& ser, - const_sequence_iterator it) const +bool serialized_size_dynamic_struct(const Encoding& encoding, size_t& size, + DDS::DynamicData_ptr struct_data, Sample::Extent ext) { - switch (it->second.elem_kind_) { - case TK_INT32: { - const DDS::Int32Seq& seq = it->second.get(); - return ser << seq; - } - case TK_UINT32: { - const DDS::UInt32Seq& seq = it->second.get(); - return ser << seq; - } - case TK_INT8: { - const DDS::Int8Seq& seq = it->second.get(); - return ser << seq; - } - case TK_UINT8: { - const DDS::UInt8Seq& seq = it->second.get(); - return ser << seq; - } - case TK_INT16: { - const DDS::Int16Seq& seq = it->second.get(); - return ser << seq; - } - case TK_UINT16: { - const DDS::UInt16Seq& seq = it->second.get(); - return ser << seq; - } - case TK_INT64: { - const DDS::Int64Seq& seq = it->second.get(); - return ser << seq; - } - case TK_UINT64: { - const DDS::UInt64Seq& seq = it->second.get(); - return ser << seq; - } - case TK_FLOAT32: { - const DDS::Float32Seq& seq = it->second.get(); - return ser << seq; - } - case TK_FLOAT64: { - const DDS::Float64Seq& seq = it->second.get(); - return ser << seq; - } - case TK_FLOAT128: { - const DDS::Float128Seq& seq = it->second.get(); - return ser << seq; - } - case TK_CHAR8: { - const DDS::CharSeq& seq = it->second.get(); - return ser << seq; - } - case TK_BYTE: { - const DDS::ByteSeq& seq = it->second.get(); - return ser << seq; - } - case TK_BOOLEAN: { - const DDS::BooleanSeq& seq = it->second.get(); - return ser << seq; - } - case TK_STRING8: { - const DDS::StringSeq& seq = it->second.get(); - return ser << seq; + const DDS::DynamicType_var type = struct_data->type(); + const DDS::DynamicType_var base_type = XTypes::get_base_type(type); + const bool struct_has_explicit_keys = XTypes::has_explicit_keys(base_type); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { + return false; } -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - const DDS::WcharSeq& seq = it->second.get(); - return ser << seq; + + const DDS::ExtensibilityKind extensibility = td->extensibility_kind(); + if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { + serialized_size_delimiter(encoding, size); } - case TK_STRING16: { - const DDS::WstringSeq& seq = it->second.get(); - return ser << seq; + + size_t mutable_running_total = 0; + const CORBA::ULong member_count = base_type->get_member_count(); + for (CORBA::ULong i = 0; i < member_count; ++i) { + DDS::DynamicTypeMember_var dtm; + if (base_type->get_member_by_index(dtm, i) != DDS::RETCODE_OK) { + return false; + } + DDS::MemberDescriptor_var md; + if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { + return false; + } + + if (XTypes::exclude_member(ext, md->is_key(), struct_has_explicit_keys)) { + continue; + } + + if (!serialized_size_dynamic_member(struct_data, encoding, size, md, extensibility, + mutable_running_total, XTypes::nested(ext))) { + if (log_level >= LogLevel:: Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: serialized_size_dynamic_struct:" + " Failed to compute serialized size for member ID %u\n", md->id())); + } + return false; + } } -#endif + + if (extensibility == DDS::MUTABLE) { + serialized_size_list_end_parameter_id(encoding, size, mutable_running_total); } - return false; + return true; } -bool DynamicDataImpl::serialized_size_enum_sequence( - const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it) const +bool get_discriminator_value(CORBA::Long& disc_val, DDS::DynamicData_ptr union_data, + const DDS::DynamicType_var& disc_type) { - switch (it->second.elem_kind_) { - case TK_INT8: { - const DDS::Int8Seq& seq = it->second.get(); - serialized_size_enum_sequence(encoding, size, seq); + using namespace OpenDDS::XTypes; + const DDS::TypeKind disc_tk = disc_type->get_kind(); + DDS::TypeKind treat_as = disc_tk; + if (disc_tk == TK_ENUM && enum_bound(disc_type, treat_as) != DDS::RETCODE_OK) { + return false; + } + + const DDS::MemberId id = DISCRIMINATOR_ID; + switch (treat_as) { + case TK_BOOLEAN: { + CORBA::Boolean value = false; + const DDS::ReturnCode_t rc = union_data->get_boolean_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } - case TK_INT16: { - const DDS::Int16Seq& seq = it->second.get(); - serialized_size_enum_sequence(encoding, size, seq); + case TK_BYTE: { + CORBA::Octet value; + const DDS::ReturnCode_t rc = union_data->get_byte_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } - case TK_INT32: { - const DDS::Int32Seq& seq = it->second.get(); - serialized_size_enum_sequence(encoding, size, seq); + case TK_CHAR8: { + CORBA::Char value; + const DDS::ReturnCode_t rc = union_data->get_char8_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } + case TK_CHAR16: { + CORBA::WChar value; + const DDS::ReturnCode_t rc = union_data->get_char16_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); + return true; } - return false; -} - -bool DynamicDataImpl::serialize_enum_sequence( - DCPS::Serializer& ser, const_sequence_iterator it) const -{ - switch (it->second.elem_kind_) { case TK_INT8: { - const DDS::Int8Seq& seq = it->second.get(); - return serialize_enum_sequence_as_ints_i(ser, seq); - } - case TK_INT16: { - const DDS::Int16Seq& seq = it->second.get(); - return serialize_enum_sequence_as_ints_i(ser, seq); - } - case TK_INT32: { - const DDS::Int32Seq& seq = it->second.get(); - return serialize_enum_sequence_as_ints_i(ser, seq); - } + CORBA::Int8 value; + const DDS::ReturnCode_t rc = union_data->get_int8_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); + return true; } - return false; -} - -bool DynamicDataImpl::serialized_size_bitmask_sequence( - const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it) const -{ - switch (it->second.elem_kind_) { case TK_UINT8: { - const DDS::UInt8Seq& seq = it->second.get(); - serialized_size_bitmask_sequence(encoding, size, seq); + CORBA::UInt8 value; + const DDS::ReturnCode_t rc = union_data->get_uint8_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); + return true; + } + case TK_INT16: { + CORBA::Short value; + const DDS::ReturnCode_t rc = union_data->get_int16_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = value; return true; } case TK_UINT16: { - const DDS::UInt16Seq& seq = it->second.get(); - serialized_size_bitmask_sequence(encoding, size, seq); + CORBA::UShort value; + const DDS::ReturnCode_t rc = union_data->get_uint16_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } + case TK_INT32: { + const DDS::ReturnCode_t rc = union_data->get_int32_value(disc_val, id); + return check_rc_from_get(rc, id, disc_tk, "get_discriminator_value"); + } case TK_UINT32: { - const DDS::UInt32Seq& seq = it->second.get(); - serialized_size_bitmask_sequence(encoding, size, seq); + CORBA::ULong value; + const DDS::ReturnCode_t rc = union_data->get_uint32_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); + return true; + } + case TK_INT64: { + CORBA::LongLong value; + const DDS::ReturnCode_t rc = union_data->get_int64_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } case TK_UINT64: { - const DDS::UInt64Seq& seq = it->second.get(); - serialized_size_bitmask_sequence(encoding, size, seq); + CORBA::ULongLong value; + const DDS::ReturnCode_t rc = union_data->get_uint64_value(value, id); + if (!check_rc_from_get(rc, id, disc_tk, "get_discriminator_value")) { + return false; + } + disc_val = static_cast(value); return true; } } return false; } -bool DynamicDataImpl::serialize_bitmask_sequence(DCPS::Serializer& ser, - const_sequence_iterator it) const +bool serialized_size_enum(const Encoding& encoding, size_t& size, + const DDS::DynamicType_var& enum_type) { - switch (it->second.elem_kind_) { - case TK_UINT8: { - const DDS::UInt8Seq& seq = it->second.get(); - return serialize_bitmask_sequence_as_uints_i(ser, seq); - } - case TK_UINT16: { - const DDS::UInt16Seq& seq = it->second.get(); - return serialize_bitmask_sequence_as_uints_i(ser, seq); - } - case TK_UINT32: { - const DDS::UInt32Seq& seq = it->second.get(); - return serialize_bitmask_sequence_as_uints_i(ser, seq); - } - case TK_UINT64: { - const DDS::UInt64Seq& seq = it->second.get(); - return serialize_bitmask_sequence_as_uints_i(ser, seq); + using namespace OpenDDS::XTypes; + DDS::TypeKind equivalent_int_tk; + if (enum_bound(enum_type, equivalent_int_tk) != DDS::RETCODE_OK) { + return false; } + switch (equivalent_int_tk) { + case TK_INT8: + primitive_serialized_size_int8(encoding, size); + return true; + case TK_INT16: + return primitive_serialized_size(encoding, size, CORBA::Short()); + case TK_INT32: + return primitive_serialized_size(encoding, size, CORBA::Long()); } return false; } -// Serialize an aggregated member stored in the sequence map. -// The member type is sequence of basic or enum or bitmask type. -void DynamicDataImpl::serialized_size_sequence_aggregated_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, const_sequence_iterator it, TypeKind elem_tk, - bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const +bool serialized_size_dynamic_discriminator( + const Encoding& encoding, size_t& size, const DDS::DynamicType_var& disc_type, + DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) { - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - primitive_serialized_size_boolean(encoding, size); - } else if (extensibility == DDS::MUTABLE) { + if (extensibility == DDS::MUTABLE) { serialized_size_parameter_id(encoding, size, mutable_running_total); } - if (is_basic(elem_tk)) { - serialized_size_basic_sequence(encoding, size, it); - } else if (elem_tk == TK_ENUM) { - serialized_size_enum_sequence(encoding, size, it); - } else { // Bitmask - serialized_size_bitmask_sequence(encoding, size, it); - } -} - -bool DynamicDataImpl::serialize_sequence_aggregated_member_xcdr2(DCPS::Serializer& ser, - const_sequence_iterator it, TypeKind elem_tk, bool optional, - bool must_understand, DDS::ExtensibilityKind extensibility) const -{ - if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { - if (!(ser << ACE_OutputCDR::from_boolean(true))) { - return false; - } - } else if (extensibility == DDS::MUTABLE) { - const DCPS::Encoding& encoding = ser.encoding(); - size_t member_size = 0; - if (is_basic(elem_tk)) { - serialized_size_basic_sequence(encoding, member_size, it); - } else if (elem_tk == TK_ENUM) { - serialized_size_enum_sequence(encoding, member_size, it); - } else if (elem_tk == TK_BITMASK) { - serialized_size_bitmask_sequence(encoding, member_size, it); - } else { - return false; - } - if (!ser.write_parameter_id(it->first, member_size, must_understand)) { - return false; - } - } - if (is_basic(elem_tk)) { - return serialize_basic_sequence(ser, it); - } else if (elem_tk == TK_ENUM) { - return serialize_enum_sequence(ser, it); - } else if (elem_tk == TK_BITMASK) { - return serialize_bitmask_sequence(ser, it); + const DDS::TypeKind disc_tk = disc_type->get_kind(); + if (XTypes::is_primitive(disc_tk)) { + return serialized_size_primitive_value(encoding, size, disc_tk); } - return false; + return serialized_size_enum(encoding, size, disc_type); } -// Serialize a struct member whose type is sequence of basic type or enum or bitmask. -bool DynamicDataImpl::serialized_size_sequence_struct_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, DDS::MemberId id, TypeKind elem_tk, - bool optional, DDS::ExtensibilityKind extensibility, size_t& mutable_running_total, - DCPS::Sample::Extent) const +bool serialized_size_dynamic_union(const Encoding& encoding, size_t& size, + DDS::DynamicData_ptr union_data, Sample::Extent ext) { - const_sequence_iterator seq_it = container_.sequence_map_.find(id); - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (seq_it == container_.sequence_map_.end() && complex_it == container_.complex_map_.end()) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - primitive_serialized_size_boolean(encoding, size); - } - return true; - } - if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); - } - serialized_size_sequence_member_default_value(encoding, size, elem_tk); - return true; - } - if (seq_it != container_.sequence_map_.end()) { - serialized_size_sequence_aggregated_member_xcdr2(encoding, size, seq_it, elem_tk, optional, - extensibility, mutable_running_total); + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = union_data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) { + // nothing is serialized (not even a delimiter) for key-only serialization when there is no @key return true; } - return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional, - extensibility, mutable_running_total, - DCPS::Sample::Full); -} - -bool DynamicDataImpl::serialize_sequence_struct_member_xcdr2(DCPS::Serializer& ser, - DDS::MemberId id, TypeKind elem_tk, bool optional, - bool must_understand, DDS::ExtensibilityKind extensibility, - DCPS::Sample::Extent ext) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - const_sequence_iterator seq_it = container_.sequence_map_.find(id); - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (seq_it == container_.sequence_map_.end() && complex_it == container_.complex_map_.end()) { - if (optional) { - if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { - return ser << ACE_OutputCDR::from_boolean(false); - } - return true; - } - if (extensibility == DDS::MUTABLE) { - size_t member_size = 0; - serialized_size_sequence_member_default_value(encoding, member_size, elem_tk); - if (!ser.write_parameter_id(id, member_size, must_understand)) { - return false; - } - } - return serialize_sequence_member_default_value(ser, elem_tk); - } - if (seq_it != container_.sequence_map_.end()) { - return serialize_sequence_aggregated_member_xcdr2(ser, seq_it, elem_tk, optional, - must_understand, extensibility); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { + return false; } - return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional, - must_understand, extensibility, ext); -} - -bool DynamicDataImpl::serialized_size_structure_xcdr2( - const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const -{ - const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind(); - const bool struct_has_explicit_keys = has_explicit_keys(type_); - // Delimiter + // Dheader + const DDS::ExtensibilityKind extensibility = td->extensibility_kind(); if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { serialized_size_delimiter(encoding, size); } - // Members + // Discriminator size_t mutable_running_total = 0; - const CORBA::ULong member_count = type_->get_member_count(); - for (CORBA::ULong i = 0; i < member_count; ++i) { - DDS::DynamicTypeMember_var dtm; - if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var md; - if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { - return false; - } - - if (exclude_member(ext, md->is_key(), struct_has_explicit_keys)) { - continue; - } + DDS::DynamicType_var disc_type = get_base_type(td->discriminator_type()); + if (!serialized_size_dynamic_discriminator(encoding, size, disc_type, + extensibility, mutable_running_total)) { + return false; + } - const DDS::MemberId id = md->id(); - const CORBA::Boolean optional = md->is_optional(); - const DDS::DynamicType_var member_type = get_base_type(md->type()); - const TypeKind member_tk = member_type->get_kind(); + CORBA::Long disc_val; + if (!get_discriminator_value(disc_val, union_data, disc_type)) { + return false; + } - if (is_basic(member_tk) || member_tk == TK_ENUM || member_tk == TK_BITMASK) { - if (!serialized_size_basic_struct_member_xcdr2(encoding, size, id, member_type, optional, - extensibility, mutable_running_total)) { - return false; - } - continue; - } else if (member_tk == TK_SEQUENCE) { - DDS::TypeDescriptor_var member_td; - if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) { - return false; - } - const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) { - if (!serialized_size_sequence_struct_member_xcdr2(encoding, size, id, elem_tk, optional, - extensibility, mutable_running_total, nested(ext))) { - return false; - } - continue; - } + if (ext == Sample::Full) { + // Selected branch + bool has_branch = false; + DDS::MemberDescriptor_var selected_md; + if (get_selected_union_branch(base_type, disc_val, has_branch, selected_md) != DDS::RETCODE_OK) { + return false; } - const_complex_iterator it = container_.complex_map_.find(id); - if (it != container_.complex_map_.end()) { - if (!serialized_size_complex_aggregated_member_xcdr2(encoding, size, it, optional, - extensibility, mutable_running_total, - nested(ext))) { - return false; - } - } else if (!serialized_size_complex_aggregated_member_xcdr2_default(encoding, size, member_type, optional, - extensibility, mutable_running_total, - nested(ext))) { + if (has_branch && + !serialized_size_dynamic_member(union_data, encoding, size, selected_md, + extensibility, mutable_running_total, nested(ext))) { return false; } } @@ -7801,799 +5091,875 @@ bool DynamicDataImpl::serialized_size_structure_xcdr2( return true; } -bool DynamicDataImpl::serialize_structure_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const +bool serialized_size_dynamic_element(DDS::DynamicData_ptr col_data, const Encoding& encoding, + size_t& size, DDS::MemberId elem_id, DDS::TypeKind elem_tk, Sample::Extent ext) { - const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind(); - const bool struct_has_explicit_keys = has_explicit_keys(type_); - - // Delimiter - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { - if (!serialized_size_i(encoding, total_size, ext) || !ser.write_delimiter(total_size)) { + using namespace OpenDDS::XTypes; + DDS::ReturnCode_t rc = DDS::RETCODE_OK; + switch (elem_tk) { + case TK_STRING8: { + CORBA::String_var val; + rc = col_data->get_string_value(val, elem_id); + if (!check_rc_from_get(rc, elem_id, elem_tk, "serialized_size_dynamic_element")) { return false; } + serialized_size_string_value(encoding, size, val.in()); + return true; } - - // Members - const CORBA::ULong member_count = type_->get_member_count(); - for (CORBA::ULong i = 0; i < member_count; ++i) { - DDS::DynamicTypeMember_var dtm; - if (type_->get_member_by_index(dtm, i) != DDS::RETCODE_OK) { + case TK_STRING16: { + CORBA::WString_var val; + rc = col_data->get_wstring_value(val, elem_id); + if (!check_rc_from_get(rc, elem_id, elem_tk, "serialized_size_dynamic_element")) { return false; } - DDS::MemberDescriptor_var md; - if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { + serialized_size_wstring_value(encoding, size, val.in()); + return true; + } + case TK_STRUCTURE: + case TK_UNION: + case TK_ARRAY: + case TK_SEQUENCE: { + DDS::DynamicData_var elem_data; + rc = col_data->get_complex_value(elem_data, elem_id); + if (!check_rc_from_get(rc, elem_id, elem_tk, "serialized_size_dynamic_element")) { return false; } + return serialized_size_i(encoding, size, elem_data, ext); + } + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: serialized_size_dynamic_element:" + " Unsupported element type %C at ID %u\n", typekind_to_string(elem_tk), elem_id)); + } + } + return false; +} - if (exclude_member(ext, md->is_key(), struct_has_explicit_keys)) { - continue; +void serialized_size_primitive_elements(const Encoding& encoding, size_t& size, + DDS::TypeKind elem_tk, CORBA::ULong length) +{ + using namespace OpenDDS::XTypes; + switch (elem_tk) { + case TK_INT32: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::Long(), length); + } + return; + case TK_UINT32: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::ULong(), length); + } + return; + case TK_INT8: + if (length != 0) { + primitive_serialized_size_int8(encoding, size, length); + } + return; + case TK_UINT8: + if (length != 0) { + primitive_serialized_size_uint8(encoding, size, length); + } + return; + case TK_INT16: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::Short(), length); + } + return; + case TK_UINT16: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::UShort(), length); + } + return; + case TK_INT64: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::LongLong(), length); + } + return; + case TK_UINT64: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::ULongLong(), length); + } + return; + case TK_FLOAT32: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::Float(), length); + } + return; + case TK_FLOAT64: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::Double(), length); } + return; + case TK_FLOAT128: + if (length != 0) { + primitive_serialized_size(encoding, size, CORBA::LongDouble(), length); + } + return; + case TK_CHAR8: + if (length != 0) { + primitive_serialized_size_char(encoding, size, length); + } + return; +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: + if (length != 0) { + primitive_serialized_size_wchar(encoding, size, length); + } + return; +#endif + case TK_BYTE: + if (length != 0) { + primitive_serialized_size_octet(encoding, size, length); + } + return; + case TK_BOOLEAN: + if (length != 0) { + primitive_serialized_size_boolean(encoding, size, length); + } + return; + } +} + +bool serialized_size_dynamic_collection(const Encoding& encoding, size_t& size, + DDS::DynamicData_ptr col_data, Sample::Extent ext) +{ + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = col_data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { + return false; + } + DDS::DynamicType_var elem_type = get_base_type(td->element_type()); + const DDS::TypeKind elem_tk = elem_type->get_kind(); + DDS::TypeKind treat_elem_as = elem_tk; + + if (elem_tk == TK_ENUM && enum_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } + if (elem_tk == TK_BITMASK && bitmask_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } + + // Dheader + if (!is_primitive(elem_tk)) { + serialized_size_delimiter(encoding, size); + } - const DDS::MemberId id = md->id(); - const CORBA::Boolean optional = md->is_optional(); - const CORBA::Boolean must_understand = md->is_must_understand() || md->is_key(); - const DDS::DynamicType_var member_type = get_base_type(md->type()); - const TypeKind member_tk = member_type->get_kind(); + if (base_type->get_kind() == TK_SEQUENCE) { + // Sequence length. + primitive_serialized_size_ulong(encoding, size); + } - if (is_basic(member_tk) || member_tk == TK_ENUM || member_tk == TK_BITMASK) { - if (!serialize_basic_struct_member_xcdr2(ser, id, member_type, optional, - must_understand, extensibility)) { - return false; - } - continue; - } else if (member_tk == TK_SEQUENCE) { - DDS::TypeDescriptor_var member_td; - if (member_type->get_descriptor(member_td) != DDS::RETCODE_OK) { - return false; - } - const DDS::DynamicType_var elem_type = get_base_type(member_td->element_type()); - const TypeKind elem_tk = elem_type->get_kind(); - if (is_basic(elem_tk) || elem_tk == TK_ENUM || elem_tk == TK_BITMASK) { - if (!serialize_sequence_struct_member_xcdr2(ser, id, elem_tk, optional, - must_understand, extensibility, nested(ext))) { - return false; - } - continue; - } - } + const CORBA::ULong item_count = col_data->get_item_count(); + if (is_primitive(treat_elem_as)) { + serialized_size_primitive_elements(encoding, size, treat_elem_as, item_count); + return true; + } - const_complex_iterator it = container_.complex_map_.find(id); - if (it != container_.complex_map_.end()) { - if (!serialize_complex_aggregated_member_xcdr2(ser, it, optional, - must_understand, extensibility, nested(ext))) { - return false; - } - } else if (!serialize_complex_aggregated_member_xcdr2_default(ser, id, member_type, optional, - must_understand, extensibility, nested(ext))) { + // Non-primitive element types. + for (CORBA::ULong i = 0; i < item_count; ++i) { + const DDS::MemberId elem_id = col_data->get_member_id_at_index(i); + if (elem_id == MEMBER_ID_INVALID || + !serialized_size_dynamic_element(col_data, encoding, size, elem_id, + treat_elem_as, nested(ext))) { return false; } } return true; } -bool DynamicDataImpl::serialized_size_structure_xcdr1( - const DCPS::Encoding& /*encoding*/, size_t& /*size*/, DCPS::Sample::Extent /*ext*/) const +bool serialized_size_i(const Encoding& encoding, size_t& size, + DDS::DynamicData_ptr data, Sample::Extent ext) { - // TODO: Support Final & Mutable extensibility? + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + switch (base_type->get_kind()) { + case TK_STRUCTURE: + return serialized_size_dynamic_struct(encoding, size, data, ext); + case TK_UNION: + return serialized_size_dynamic_union(encoding, size, data, ext); + case TK_ARRAY: + case TK_SEQUENCE: + return serialized_size_dynamic_collection(encoding, size, data, ext); + } return false; } -bool DynamicDataImpl::serialize_structure_xcdr1(DCPS::Serializer& /*ser*/, DCPS::Sample::Extent) const +bool serialized_size(const Encoding& encoding, size_t& size, DDS::DynamicData_ptr data) { - // TODO: Support only Final & Mutable extensibility? - return false; + return serialized_size_i(encoding, size, data, Sample::Full); } -bool DynamicDataImpl::serialized_size_structure(const DCPS::Encoding& encoding, - size_t& size, DCPS::Sample::Extent ext) const +bool serialized_size(const Encoding& encoding, size_t& size, const KeyOnly& key) { - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - return serialized_size_structure_xcdr2(encoding, size, ext); - } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) { - return serialized_size_structure_xcdr1(encoding, size, ext); - } - return false; + return serialized_size_i(encoding, size, key.value, Sample::KeyOnly); } -bool DynamicDataImpl::serialize_structure(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const +// Serialize header for a basic member. +// The return code @rc must be either NO_DATA or OK. +bool serialize_dynamic_basic_member_header(Serializer& ser, void* value, DDS::ReturnCode_t rc, + DDS::MemberId id, DDS::TypeKind tk, DDS::ExtensibilityKind extensibility, + CORBA::Boolean optional, CORBA::Boolean must_understand) { - const DCPS::Encoding& encoding = ser.encoding(); - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - return serialize_structure_xcdr2(ser, ext); - } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) { - return serialize_structure_xcdr1(ser, ext); + using namespace OpenDDS::XTypes; + if (optional && rc == DDS::RETCODE_NO_DATA) { + if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { + return ser << ACE_OutputCDR::from_boolean(false); + } + return true; } - return false; + + if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { + return ser << ACE_OutputCDR::from_boolean(true); + } else if (extensibility == DDS::MUTABLE) { + const Encoding& encoding = ser.encoding(); + size_t member_size = 0; + if (is_primitive(tk)) { + if (!serialized_size_primitive_value(encoding, member_size, tk)) { + return false; + } + } else if (tk == TK_STRING8) { + const char* str = (const char*)value; + serialized_size_string_value(encoding, member_size, str); + } +#ifdef DDS_HAS_WCHAR + else if (tk == TK_STRING16) { + const CORBA::WChar* wstr = (const CORBA::WChar*)value; + serialized_size_wstring_value(encoding, member_size, wstr); + } +#endif + else { + return false; + } + return ser.write_parameter_id(id, member_size, must_understand); + } + return true; } -// Set discriminator to the default value of the corresponding type. -bool DynamicDataImpl::set_default_discriminator_value(CORBA::Long& value, - const DDS::DynamicType_var& disc_type) const +// Serialize header for a non-basic member. +// The return code @rc must be either NO_DATA or OK. +bool serialize_dynamic_complex_member_header(Serializer& ser, DDS::ReturnCode_t rc, + const DDS::DynamicData_ptr member_data, DDS::ExtensibilityKind extensibility, + CORBA::Boolean optional, DDS::MemberId id, CORBA::Boolean must_understand, Sample::Extent ext) { - const TypeKind disc_tk = disc_type->get_kind(); - switch (disc_tk) { - case TK_BOOLEAN: { - ACE_OutputCDR::from_boolean val(false); - set_default_basic_value(val); - value = static_cast(val.val_); + if (optional && rc == DDS::RETCODE_NO_DATA) { + if (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE) { + return ser << ACE_OutputCDR::from_boolean(false); + } return true; } - case TK_BYTE: { - ACE_OutputCDR::from_octet val(0x00); - set_default_basic_value(val); - value = static_cast(val.val_); - return true; + + if (optional && (extensibility == DDS::FINAL || extensibility == DDS::APPENDABLE)) { + return ser << ACE_OutputCDR::from_boolean(true); + } else if (extensibility == DDS::MUTABLE) { + const Encoding& encoding = ser.encoding(); + size_t member_size = 0; + return serialized_size_i(encoding, member_size, member_data, ext) + && ser.write_parameter_id(id, member_size, must_understand); } - case TK_CHAR8: { - ACE_OutputCDR::from_char val('\0'); - set_default_basic_value(val); - value = static_cast(val.val_); - return true; + return true; +} + +template +bool serialize_dynamic_primitive_member(Serializer& ser, const T& value, DDS::ReturnCode_t rc, + DDS::MemberId id, DDS::TypeKind type_kind, DDS::ExtensibilityKind extensibility, + CORBA::Boolean optional, CORBA::Boolean must_understand) +{ + if (!check_rc_from_get(rc, id, type_kind, "serialize_dynamic_primitive_member") || + !serialize_dynamic_basic_member_header(ser, 0, rc, id, type_kind, extensibility, + optional, must_understand)) { + return false; } -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: { - ACE_OutputCDR::from_wchar val(0); - set_default_basic_value(val); - value = static_cast(val.val_); + if (optional && rc == DDS::RETCODE_NO_DATA) { return true; } -#endif + return ser << value; +} + +bool serialize_dynamic_member(Serializer& ser, DDS::DynamicData_ptr data, + const DDS::MemberDescriptor_var md, DDS::ExtensibilityKind extensibility, Sample::Extent ext) +{ + using namespace OpenDDS::XTypes; + const DDS::MemberId id = md->id(); + const CORBA::Boolean optional = md->is_optional(); + const CORBA::Boolean must_understand = md->is_must_understand() || md->is_key(); + const DDS::DynamicType_var member_type = get_base_type(md->type()); + const DDS::TypeKind member_tk = member_type->get_kind(); + DDS::TypeKind treat_member_as = member_tk; + + if (member_tk == TK_ENUM && enum_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { + return false; + } + if (member_tk == TK_BITMASK && bitmask_bound(member_type, treat_member_as) != DDS::RETCODE_OK) { + return false; + } + + DDS::ReturnCode_t rc = DDS::RETCODE_OK; + switch (treat_member_as) { case TK_INT8: { - ACE_OutputCDR::from_int8 val(0); - set_default_basic_value(val); - value = static_cast(val.val_); - return true; + CORBA::Int8 val; + rc = data->get_int8_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_int8(val), rc, id, + treat_member_as, extensibility, optional, must_understand); } case TK_UINT8: { - ACE_OutputCDR::from_uint8 val(0); - set_default_basic_value(val); - value = static_cast(val.val_); - return true; + CORBA::UInt8 val; + rc = data->get_uint8_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_uint8(val), rc, id, + treat_member_as, extensibility, optional, must_understand); } case TK_INT16: { CORBA::Short val; - set_default_basic_value(val); - value = static_cast(val); - return true; + rc = data->get_int16_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } case TK_UINT16: { CORBA::UShort val; - set_default_basic_value(val); - value = static_cast(val); - return true; + rc = data->get_uint16_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } case TK_INT32: { - set_default_basic_value(value); - return true; + CORBA::Long val; + rc = data->get_int32_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } case TK_UINT32: { CORBA::ULong val; - set_default_basic_value(val); - value = static_cast(val); - return true; + rc = data->get_uint32_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } case TK_INT64: { CORBA::LongLong val; - set_default_basic_value(val); - value = static_cast(val); - return true; + rc = data->get_int64_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } case TK_UINT64: { CORBA::ULongLong val; - set_default_basic_value(val); - value = static_cast(val); - return true; + rc = data->get_uint64_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } - case TK_ENUM: { - return set_default_enum_value(disc_type, value); + case TK_FLOAT32: { + CORBA::Float val; + rc = data->get_float32_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } + case TK_FLOAT64: { + CORBA::Double val; + rc = data->get_float64_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } - return false; -} - -// Get discriminator value from the data container. The discriminator data must present -// in either single map or complex map. -bool DynamicDataImpl::get_discriminator_value( - CORBA::Long& value, const_single_iterator single_it, const_complex_iterator complex_it, - const DDS::DynamicType_var& disc_type) const -{ - if (single_it != container_.single_map_.end()) { - read_discriminator(value, disc_type, single_it); - } else { // Find in complex map - const DynamicDataImpl* dd_impl = dynamic_cast(complex_it->second.in()); - if (!dd_impl) { - return false; - } - const_single_iterator it = dd_impl->container_.single_map_.find(MEMBER_ID_INVALID); - if (it != dd_impl->container_.single_map_.end()) { - read_discriminator(value, disc_type, it); - } else { - return set_default_discriminator_value(value, disc_type); - } + case TK_FLOAT128: { + CORBA::LongDouble val; + rc = data->get_float128_value(val, id); + return serialize_dynamic_primitive_member(ser, val, rc, id, treat_member_as, + extensibility, optional, must_understand); } - return true; -} - -bool DynamicDataImpl::serialized_size_discriminator_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, const DDS::DynamicType_var& disc_type, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const -{ - if (extensibility == DDS::MUTABLE) { - serialized_size_parameter_id(encoding, size, mutable_running_total); + case TK_CHAR8: { + CORBA::Char val; + rc = data->get_char8_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_char(val), rc, id, + treat_member_as, extensibility, optional, must_understand); } - const TypeKind disc_tk = disc_type->get_kind(); - if (is_primitive(disc_tk)) { - return serialized_size_primitive_member(encoding, size, disc_tk); +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: { + CORBA::WChar val; + rc = data->get_char16_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_wchar(val), rc, id, + treat_member_as, extensibility, optional, must_understand); } - return serialized_size_enum(encoding, size, disc_type); -} - -bool DynamicDataImpl::serialize_discriminator_member_xcdr2( - DCPS::Serializer& ser, CORBA::Long value, const DDS::DynamicType_var& disc_type, - DDS::ExtensibilityKind extensibility) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - const TypeKind disc_tk = disc_type->get_kind(); - if (extensibility == DDS::MUTABLE) { - size_t disc_size = 0; - if (is_primitive(disc_tk)) { - serialized_size_primitive_member(encoding, disc_size, disc_tk); - } else { - serialized_size_enum(encoding, disc_size, disc_type); - } - // Use member Id 0 for discriminator? - if (!ser.write_parameter_id(0, disc_size, false)) { +#endif + case TK_BYTE: { + CORBA::Octet val; + rc = data->get_byte_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_octet(val), rc, id, + treat_member_as, extensibility, optional, must_understand); + } + case TK_BOOLEAN: { + CORBA::Boolean val = false; + rc = data->get_boolean_value(val, id); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_boolean(val), rc, id, + treat_member_as, extensibility, optional, must_understand); + } + case TK_STRING8: { + CORBA::String_var val; + rc = data->get_string_value(val, id); + if (!check_rc_from_get(rc, id, treat_member_as, "serialize_dynamic_member") || + !serialize_dynamic_basic_member_header(ser, (void*)val.in(), rc, id, TK_STRING8, + extensibility, optional, must_understand)) { return false; } + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + return ser << val.in(); } - - switch (disc_tk) { - case TK_BOOLEAN: - return ser << static_cast(value); - case TK_BYTE: - return ser << static_cast(value); - case TK_CHAR8: - return ser << static_cast(value); #ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return ser << static_cast(value); + case TK_STRING16: { + CORBA::WString_var val; + rc = data->get_wstring_value(val, id); + if (!check_rc_from_get(rc, id, treat_member_as, "serialize_dynamic_member") || + !serialize_dynamic_basic_member_header(ser, (void*)val.in(), rc, id, TK_STRING16, + extensibility, optional, must_understand)) { + return false; + } + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; + } + return ser << val.in(); + } #endif - case TK_INT8: - return ser << static_cast(value); - case TK_UINT8: - return ser << static_cast(value); - case TK_INT16: - return ser << static_cast(value); - case TK_UINT16: - return ser << static_cast(value); - case TK_INT32: - return ser << value; - case TK_UINT32: - return ser << static_cast(value); - case TK_INT64: - return ser << static_cast(value); - case TK_UINT64: - return ser << static_cast(value); - case TK_ENUM: { - DDS::TypeDescriptor_var td; - if (disc_type->get_descriptor(td) != DDS::RETCODE_OK) { + case TK_STRUCTURE: + case TK_UNION: + case TK_ARRAY: + case TK_SEQUENCE: { + DDS::DynamicData_var member_data; + rc = data->get_complex_value(member_data, id); + if (!check_rc_from_get(rc, id, treat_member_as, "serialize_dynamic_member") || + !serialize_dynamic_complex_member_header(ser, rc, member_data, extensibility, + optional, id, must_understand, ext)) { return false; } - const CORBA::ULong bitbound = td->bound()[0]; - if (bitbound >= 1 && bitbound <= 8) { - return ser << static_cast(value); - } else if (bitbound >= 9 && bitbound <= 16) { - return ser << static_cast(value); - } else if (bitbound >= 17 && bitbound <= 32) { - return ser << value; + if (optional && rc == DDS::RETCODE_NO_DATA) { + return true; } + return serialize(ser, member_data, ext); } + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: serialize_dynamic_member:" + " Unsupported member type %C at ID %u\n", typekind_to_string(member_tk), id)); + } } return false; } -bool DynamicDataImpl::serialized_size_selected_member_xcdr2( - const DCPS::Encoding& encoding, size_t& size, DDS::MemberId selected_id, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const +bool serialize_dynamic_struct(Serializer& ser, DDS::DynamicData_ptr data, Sample::Extent ext) { - DDS::DynamicTypeMember_var selected_dtm; - if (type_->get_member(selected_dtm, selected_id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var selected_md; - if (selected_dtm->get_descriptor(selected_md) != DDS::RETCODE_OK) { + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + const bool struct_has_explicit_keys = has_explicit_keys(base_type); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { return false; } - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - const bool optional = selected_md->is_optional(); - const_single_iterator single_it = container_.single_map_.find(selected_id); - if (single_it != container_.single_map_.end()) { - return serialized_size_single_aggregated_member_xcdr2(encoding, size, single_it, selected_type, optional, - extensibility, mutable_running_total); + const Encoding& encoding = ser.encoding(); + size_t total_size = 0; + const DDS::ExtensibilityKind extensibility = td->extensibility_kind(); + if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { + if (!serialized_size_dynamic_struct(encoding, total_size, data, ext) + || !ser.write_delimiter(total_size)) { + return false; + } } - const_sequence_iterator seq_it = container_.sequence_map_.find(selected_id); - if (seq_it != container_.sequence_map_.end()) { - DDS::TypeDescriptor_var selected_td; - if (selected_type->get_descriptor(selected_td) != DDS::RETCODE_OK) { + const CORBA::ULong member_count = base_type->get_member_count(); + for (CORBA::ULong i = 0; i < member_count; ++i) { + DDS::DynamicTypeMember_var dtm; + if (base_type->get_member_by_index(dtm, i) != DDS::RETCODE_OK) { + return false; + } + DDS::MemberDescriptor_var md; + if (dtm->get_descriptor(md) != DDS::RETCODE_OK) { return false; } - const TypeKind elem_tk = get_base_type(selected_td->element_type())->get_kind(); - serialized_size_sequence_aggregated_member_xcdr2(encoding, size, seq_it, elem_tk, optional, - extensibility, mutable_running_total); - return true; - } - const_complex_iterator complex_it = container_.complex_map_.find(selected_id); - if (complex_it != container_.complex_map_.end()) { - return serialized_size_complex_aggregated_member_xcdr2(encoding, size, complex_it, optional, - extensibility, mutable_running_total, - DCPS::Sample::Full); + if (exclude_member(ext, md->is_key(), struct_has_explicit_keys)) { + continue; + } + + // The serialization function for individual member must account for any header it has. + if (!serialize_dynamic_member(ser, data, md, extensibility, nested(ext))) { + return false; + } } - return false; + return true; } -bool DynamicDataImpl::serialize_selected_member_xcdr2(DCPS::Serializer& ser, - DDS::MemberId selected_id, DDS::ExtensibilityKind extensibility) const +bool serialize_dynamic_discriminator(Serializer& ser, DDS::DynamicData_ptr union_data, + const DDS::MemberDescriptor_var disc_md, DDS::ExtensibilityKind extensibility, CORBA::Long& disc_val) { - DDS::DynamicTypeMember_var selected_dtm; - if (type_->get_member(selected_dtm, selected_id) != DDS::RETCODE_OK) { - return false; - } - DDS::MemberDescriptor_var selected_md; - if (selected_dtm->get_descriptor(selected_md) != DDS::RETCODE_OK) { + using namespace OpenDDS::XTypes; + // What is the actual Id of the discriminator? Use 0 for serialization for now. + const DDS::MemberId disc_id = 0; + const CORBA::Boolean optional = disc_md->is_optional(); // Discriminator must be non-optional. + const CORBA::Boolean must_understand = disc_md->is_must_understand() || disc_md->is_key(); + const DDS::DynamicType_var disc_type = get_base_type(disc_md->type()); + const DDS::TypeKind disc_tk = disc_type->get_kind(); + DDS::TypeKind treat_disc_as = disc_tk; + + if (disc_tk == TK_ENUM && enum_bound(disc_type, treat_disc_as) != DDS::RETCODE_OK) { return false; } - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - const bool optional = selected_md->is_optional(); - const bool must_understand = selected_md->is_must_understand(); - const_single_iterator single_it = container_.single_map_.find(selected_id); - if (single_it != container_.single_map_.end()) { - return serialize_single_aggregated_member_xcdr2(ser, single_it, selected_type, optional, - must_understand, extensibility); + switch (treat_disc_as) { + case TK_BOOLEAN: { + CORBA::Boolean val = false; + const DDS::ReturnCode_t rc = union_data->get_boolean_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_boolean(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); } - - const_sequence_iterator seq_it = container_.sequence_map_.find(selected_id); - if (seq_it != container_.sequence_map_.end()) { - DDS::TypeDescriptor_var selected_td; - if (selected_type->get_descriptor(selected_td) != DDS::RETCODE_OK) { - return false; + case TK_BYTE: { + CORBA::Octet val; + const DDS::ReturnCode_t rc = union_data->get_byte_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_octet(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); + } + case TK_CHAR8: { + CORBA::Char val; + const DDS::ReturnCode_t rc = union_data->get_char8_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_char(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); + } +#ifdef DDS_HAS_WCHAR + case TK_CHAR16: { + CORBA::WChar val; + const DDS::ReturnCode_t rc = union_data->get_char16_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_wchar(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); + } +#endif + case TK_INT8: { + CORBA::Int8 val; + const DDS::ReturnCode_t rc = union_data->get_int8_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_int8(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); + } + case TK_UINT8: { + CORBA::UInt8 val; + const DDS::ReturnCode_t rc = union_data->get_uint8_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, ACE_OutputCDR::from_uint8(val), rc, disc_id, + treat_disc_as, extensibility, optional, must_understand); + } + case TK_INT16: { + CORBA::Short val; + const DDS::ReturnCode_t rc = union_data->get_int16_value(val, DISCRIMINATOR_ID); + disc_val = val; + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + case TK_UINT16: { + CORBA::UShort val; + const DDS::ReturnCode_t rc = union_data->get_uint16_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + case TK_INT32: { + CORBA::Long val; + const DDS::ReturnCode_t rc = union_data->get_int32_value(val, DISCRIMINATOR_ID); + disc_val = val; + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + case TK_UINT32: { + CORBA::ULong val; + const DDS::ReturnCode_t rc = union_data->get_uint32_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + case TK_INT64: { + CORBA::LongLong val; + const DDS::ReturnCode_t rc = union_data->get_int64_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + case TK_UINT64: { + CORBA::ULongLong val; + const DDS::ReturnCode_t rc = union_data->get_uint64_value(val, DISCRIMINATOR_ID); + disc_val = static_cast(val); + return serialize_dynamic_primitive_member(ser, val, rc, disc_id, treat_disc_as, + extensibility, optional, must_understand); + } + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: seialize_dynamic_discriminator:" + " Invalid discriminator type: %C\n", typekind_to_string(disc_tk))); } - const TypeKind elem_tk = get_base_type(selected_td->element_type())->get_kind(); - return serialize_sequence_aggregated_member_xcdr2(ser, seq_it, elem_tk, optional, - must_understand, extensibility); - } - - const_complex_iterator complex_it = container_.complex_map_.find(selected_id); - if (complex_it != container_.complex_map_.end()) { - return serialize_complex_aggregated_member_xcdr2(ser, complex_it, optional, - must_understand, extensibility, - DCPS::Sample::Full); } return false; } -bool DynamicDataImpl::serialized_size_union_xcdr2(const DCPS::Encoding& encoding, - size_t& size, DCPS::Sample::Extent ext) const +bool serialize_dynamic_union(Serializer& ser, DDS::DynamicData_ptr data, Sample::Extent ext) { - if (ext == DCPS::Sample::KeyOnly && !has_explicit_keys(type_)) { + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) { // nothing is serialized (not even a delimiter) for key-only serialization when there is no @key return true; } - const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind(); - if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { - serialized_size_delimiter(encoding, size); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { + return false; } - size_t mutable_running_total = 0; - DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); - if (ext != DCPS::Sample::Full) { - if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type, - extensibility, mutable_running_total)) { + // Dheader + const Encoding& encoding = ser.encoding(); + size_t total_size = 0; + const DDS::ExtensibilityKind extensibility = td->extensibility_kind(); + if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { + if (!serialized_size_dynamic_union(encoding, total_size, data, ext) + || !ser.write_delimiter(total_size)) { return false; } - serialized_size_list_end_parameter_id(encoding, size, mutable_running_total); - return true; } - const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID); - const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID); - const bool has_disc = single_it != container_.single_map_.end() || - complex_it != container_.complex_map_.end(); - const DDS::MemberId selected_id = find_selected_member(); - - CORBA::Long disc_value; - if (has_disc) { - if (!get_discriminator_value(disc_value, single_it, complex_it, disc_type)) { - return false; - } - } else if (!set_default_discriminator_value(disc_value, disc_type)) { + // Discriminator + DDS::DynamicTypeMember_var dtm; + if (base_type->get_member(dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) { + return false; + } + DDS::MemberDescriptor_var disc_md; + if (dtm->get_descriptor(disc_md) != DDS::RETCODE_OK) { + return false; + } + CORBA::Long disc_val; + if (!serialize_dynamic_discriminator(ser, data, disc_md, extensibility, disc_val)) { return false; } - if (selected_id == MEMBER_ID_INVALID) { - bool found_selected_member = false; - DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = - get_selected_union_branch(disc_value, found_selected_member, selected_md); - if (rc != DDS::RETCODE_OK) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialized_size_union_xcdr2:" - " get_selected_union_branch failed: %C\n", retcode_to_string(rc))); - } - return false; - } - if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type, - extensibility, mutable_running_total)) { - return false; - } - if (found_selected_member) { - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - const bool optional = selected_md->is_optional(); - if (!serialized_size_complex_aggregated_member_xcdr2_default(encoding, size, selected_type, optional, - extensibility, mutable_running_total, - DCPS::Sample::Full)) { - return false; - } - } - serialized_size_list_end_parameter_id(encoding, size, mutable_running_total); + if (ext != Sample::Full) { return true; } - if (!serialized_size_discriminator_member_xcdr2(encoding, size, disc_type, - extensibility, mutable_running_total)) { - return false; - } - if (ext != DCPS::Sample::KeyOnly) { - if (!serialized_size_selected_member_xcdr2( - encoding, size, selected_id, extensibility, mutable_running_total)) { + if (ext == Sample::Full) { + // Selected branch + bool has_branch = false; + DDS::MemberDescriptor_var selected_md; + if (get_selected_union_branch(base_type, disc_val, has_branch, selected_md) != DDS::RETCODE_OK) { return false; } + return !has_branch || serialize_dynamic_member(ser, data, selected_md, extensibility, nested(ext)); } - serialized_size_list_end_parameter_id(encoding, size, mutable_running_total); return true; } -bool DynamicDataImpl::serialize_union_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const +bool serialize_dynamic_element(Serializer& ser, DDS::DynamicData_ptr col_data, + DDS::MemberId elem_id, DDS::TypeKind elem_tk, Sample::Extent ext) { - if (ext == DCPS::Sample::KeyOnly && !has_explicit_keys(type_)) { - // nothing is serialized (not even a delimiter) for key-only serialization when there is no @key - return true; + using namespace OpenDDS::XTypes; + DDS::ReturnCode_t rc = DDS::RETCODE_OK; + switch (elem_tk) { + case TK_INT8: { + CORBA::Int8 val; + rc = col_data->get_int8_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_int8(val)); } - - const DDS::ExtensibilityKind extensibility = type_desc_->extensibility_kind(); - - // Delimiter - const DCPS::Encoding& encoding = ser.encoding(); - size_t total_size = 0; - if (extensibility == DDS::APPENDABLE || extensibility == DDS::MUTABLE) { - if (!serialized_size_i(encoding, total_size, ext) || !ser.write_delimiter(total_size)) { - return false; - } + case TK_UINT8: { + CORBA::UInt8 val; + rc = col_data->get_uint8_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_uint8(val)); } - - const_single_iterator single_it = container_.single_map_.find(DISCRIMINATOR_ID); - const_complex_iterator complex_it = container_.complex_map_.find(DISCRIMINATOR_ID); - const bool has_disc = single_it != container_.single_map_.end() || - complex_it != container_.complex_map_.end(); - const DDS::MemberId selected_id = find_selected_member(); - DDS::DynamicType_var disc_type = get_base_type(type_desc_->discriminator_type()); - const TypeKind disc_tk = disc_type->get_kind(); - - // Read the discriminator value if the user already set it. Otherwise, - // set it to the default value of the corresponding type. - CORBA::Long disc_value; - if (has_disc) { - if (!get_discriminator_value(disc_value, single_it, complex_it, disc_type)) { - return false; - } - } else if (!set_default_discriminator_value(disc_value, disc_type)) { - return false; + case TK_INT16: { + CORBA::Short val; + rc = col_data->get_int16_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); } - - if (selected_id == MEMBER_ID_INVALID) { - // If the defined discriminator value selects a member, serialize the member with - // its default value. Otherwise, serialize only the discriminator. - bool found_selected_member = false; - DDS::MemberDescriptor_var selected_md; - const DDS::ReturnCode_t rc = - get_selected_union_branch(disc_value, found_selected_member, selected_md); - if (rc != DDS::RETCODE_OK) { - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialize_union_xcdr2:" - " get_selected_union_branch failed: %C\n", retcode_to_string(rc))); - } - return false; - } - // Discriminator - if (!serialize_discriminator_member_xcdr2(ser, disc_value, disc_type, extensibility)) { - return false; - } - if (ext == DCPS::Sample::KeyOnly) { - return true; - } - // Selected member - if (found_selected_member) { - DDS::DynamicType_var selected_type = get_base_type(selected_md->type()); - const DDS::MemberId id = selected_md->id(); - const bool optional = selected_md->is_optional(); - const bool must_understand = selected_md->is_must_understand(); - return serialize_complex_aggregated_member_xcdr2_default(ser, id, selected_type, optional, - must_understand, extensibility, - DCPS::Sample::Full); - } - return true; + case TK_UINT16: { + CORBA::UShort val; + rc = col_data->get_uint16_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); } - - // Both discriminator and a selected member exist in the data container. - if (single_it != container_.single_map_.end()) { - if (extensibility == DDS::MUTABLE) { - size_t disc_size = 0; - if (is_primitive(disc_tk)) { - serialized_size_primitive_member(encoding, disc_size, disc_tk); - } else { // Enum is the only other type can be used for discriminator - serialized_size_enum(encoding, disc_size, disc_type); - } - // Discriminator always has Id 0? - if (!ser.write_parameter_id(0, disc_size, false)) { - return false; - } - } - if (!serialize_single_value(ser, single_it->second)) { - return false; - } - } else { - if (extensibility == DDS::MUTABLE) { - size_t disc_size = 0; - serialized_size_complex_member_i(encoding, disc_size, complex_it->first, DCPS::Sample::Full); - if (!ser.write_parameter_id(0, disc_size, false)) { - return false; - } - } - if (!serialize_complex_member_i(ser, complex_it->first, DCPS::Sample::Full)) { - return false; - } + case TK_INT32: { + CORBA::Long val; + rc = col_data->get_int32_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); } - return ext == DCPS::Sample::KeyOnly || - serialize_selected_member_xcdr2(ser, selected_id, extensibility); -} - -bool DynamicDataImpl::serialized_size_union_xcdr1(const DCPS::Encoding& /*encoding*/, - size_t& /*size*/, DCPS::Sample::Extent) const -{ - // TODO: - return false; -} - -bool DynamicDataImpl::serialize_union_xcdr1(DCPS::Serializer& /*ser*/, DCPS::Sample::Extent) const -{ - // TODO: - return false; -} - -bool DynamicDataImpl::serialized_size_union(const DCPS::Encoding& encoding, - size_t& size, DCPS::Sample::Extent ext) const -{ - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - return serialized_size_union_xcdr2(encoding, size, ext); - } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) { - return serialized_size_union_xcdr1(encoding, size, ext); + case TK_UINT32: { + CORBA::ULong val; + rc = col_data->get_uint32_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); } - return false; -} - -bool DynamicDataImpl::serialize_union(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const -{ - const DCPS::Encoding& encoding = ser.encoding(); - if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_2) { - return serialize_union_xcdr2(ser, ext); - } else if (encoding.xcdr_version() == DCPS::Encoding::XCDR_VERSION_1) { - return serialize_union_xcdr1(ser, ext); + case TK_INT64: { + CORBA::LongLong val; + rc = col_data->get_int64_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); + } + case TK_UINT64: { + CORBA::ULongLong val; + rc = col_data->get_uint64_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); + } + case TK_FLOAT32: { + CORBA::Float val; + rc = col_data->get_float32_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); + } + case TK_FLOAT64: { + CORBA::Double val; + rc = col_data->get_float64_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); + } + case TK_FLOAT128: { + CORBA::LongDouble val; + rc = col_data->get_float128_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val); + } + case TK_CHAR8: { + CORBA::Char val; + rc = col_data->get_char8_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_char(val)); } - return false; -} - -bool DynamicDataImpl::serialized_size_i(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const -{ - const TypeKind tk = type_->get_kind(); - switch (tk) { - case TK_INT32: - return primitive_serialized_size(encoding, size, CORBA::Long()); - case TK_UINT32: - return primitive_serialized_size(encoding, size, CORBA::ULong()); - case TK_INT8: - primitive_serialized_size_int8(encoding, size); - return true; - case TK_UINT8: - primitive_serialized_size_uint8(encoding, size); - return true; - case TK_INT16: - return primitive_serialized_size(encoding, size, CORBA::Short()); - case TK_UINT16: - return primitive_serialized_size(encoding, size, CORBA::UShort()); - case TK_INT64: - return primitive_serialized_size(encoding, size, CORBA::LongLong()); - case TK_UINT64: - return primitive_serialized_size(encoding, size, CORBA::ULongLong()); - case TK_FLOAT32: - return primitive_serialized_size(encoding, size, CORBA::Float()); - case TK_FLOAT64: - return primitive_serialized_size(encoding, size, CORBA::Double()); - case TK_FLOAT128: - return primitive_serialized_size(encoding, size, CORBA::LongDouble()); - case TK_CHAR8: - primitive_serialized_size_char(encoding, size); - return true; #ifdef DDS_HAS_WCHAR - case TK_CHAR16: - primitive_serialized_size_wchar(encoding, size); - return true; + case TK_CHAR16: { + CORBA::WChar val; + rc = col_data->get_char16_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_wchar(val)); + } #endif - case TK_BYTE: - primitive_serialized_size_octet(encoding, size); - return true; - case TK_BOOLEAN: - primitive_serialized_size_boolean(encoding, size); - return true; - case TK_ENUM: - return serialized_size_enum(encoding, size, type_); - case TK_BITMASK: - return serialized_size_bitmask(encoding, size, type_); - case TK_STRING8: - return serialized_size_string(encoding, size); + case TK_BYTE: { + CORBA::Octet val; + rc = col_data->get_byte_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_octet(val)); + } + case TK_BOOLEAN: { + CORBA::Boolean val = false; + rc = col_data->get_boolean_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << ACE_OutputCDR::from_boolean(val)); + } + case TK_STRING8: { + CORBA::String_var val; + rc = col_data->get_string_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val.in()); + } #ifdef DDS_HAS_WCHAR - case TK_STRING16: - return serialized_size_wstring(encoding, size); + case TK_STRING16: { + CORBA::WString_var val; + rc = col_data->get_wstring_value(val, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && (ser << val.in()); + } #endif case TK_STRUCTURE: - return serialized_size_structure(encoding, size, ext); case TK_UNION: - return serialized_size_union(encoding, size, ext); - case TK_SEQUENCE: - return serialized_size_sequence(encoding, size, ext); case TK_ARRAY: - return serialized_size_array(encoding, size, ext); - case TK_MAP: + case TK_SEQUENCE: { + DDS::DynamicData_var elem_data; + rc = col_data->get_complex_value(elem_data, elem_id); + return check_rc_from_get(rc, elem_id, elem_tk, "serialize_dynamic_element") + && serialize(ser, elem_data, ext); + } + default: if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialized_size_i: Serialization of map types is not supported\n")); + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: serialize_dynamic_element:" + " Unsupported element type %C at ID %u\n", typekind_to_string(elem_tk), elem_id)); } } return false; } -bool DynamicDataImpl::serialize_i(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const +bool serialize_dynamic_collection(Serializer& ser, DDS::DynamicData_ptr data, Sample::Extent ext) { - const TypeKind tk = type_->get_kind(); - switch (tk) { - case TK_INT32: - return serialize_primitive_value(ser, CORBA::Long()); - case TK_UINT32: - return serialize_primitive_value(ser, CORBA::ULong()); - case TK_INT8: - return serialize_primitive_value(ser, ACE_OutputCDR::from_int8(CORBA::Int8())); - case TK_UINT8: - return serialize_primitive_value(ser, ACE_OutputCDR::from_uint8(CORBA::UInt8())); - case TK_INT16: - return serialize_primitive_value(ser, CORBA::Short()); - case TK_UINT16: - return serialize_primitive_value(ser, CORBA::UShort()); - case TK_INT64: - return serialize_primitive_value(ser, CORBA::LongLong()); - case TK_UINT64: - return serialize_primitive_value(ser, CORBA::ULongLong()); - case TK_FLOAT32: - return serialize_primitive_value(ser, CORBA::Float()); - case TK_FLOAT64: - return serialize_primitive_value(ser, CORBA::Double()); - case TK_FLOAT128: - return serialize_primitive_value(ser, CORBA::LongDouble()); - case TK_CHAR8: - return serialize_primitive_value(ser, ACE_OutputCDR::from_char(CORBA::Char())); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return serialize_primitive_value(ser, ACE_OutputCDR::from_wchar(CORBA::WChar())); -#endif - case TK_BYTE: - return serialize_primitive_value(ser, ACE_OutputCDR::from_octet(CORBA::Octet())); - case TK_BOOLEAN: - return serialize_primitive_value(ser, ACE_OutputCDR::from_boolean(CORBA::Boolean())); - case TK_ENUM: - return serialize_enum_value(ser); - case TK_BITMASK: - return serialize_bitmask_value(ser); - case TK_STRING8: - return serialize_string_value(ser); -#ifdef DDS_HAS_WCHAR - case TK_STRING16: - return serialize_wstring_value(ser); -#endif - case TK_STRUCTURE: - return serialize_structure(ser, ext); - case TK_UNION: - return serialize_union(ser, ext); - case TK_SEQUENCE: - return serialize_sequence(ser, ext); - case TK_ARRAY: - return serialize_array(ser, ext); - case TK_MAP: - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::serialize_i: Serialization of map types is not supported\n")); - } + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + DDS::TypeDescriptor_var td; + if (!get_type_descriptor(base_type, td)) { + return false; } - return false; -} + DDS::DynamicType_var elem_type = get_base_type(td->element_type()); + const DDS::TypeKind elem_tk = elem_type->get_kind(); + DDS::TypeKind treat_elem_as = elem_tk; -bool DynamicDataImpl::serialize_single_value(DCPS::Serializer& ser, const SingleValue& sv) const -{ - switch (sv.kind_) { - case TK_INT32: - return ser << sv.get(); - case TK_UINT32: - return ser << sv.get(); - case TK_INT8: - return ser << sv.get(); - case TK_UINT8: - return ser << sv.get(); - case TK_INT16: - return ser << sv.get(); - case TK_UINT16: - return ser << sv.get(); - case TK_INT64: - return ser << sv.get(); - case TK_UINT64: - return ser << sv.get(); - case TK_FLOAT32: - return ser << sv.get(); - case TK_FLOAT64: - return ser << sv.get(); - case TK_FLOAT128: - return ser << sv.get(); - case TK_CHAR8: - return ser << sv.get(); - case TK_BYTE: - return ser << sv.get(); - case TK_BOOLEAN: - return ser << sv.get(); - case TK_STRING8: - return ser << sv.get(); -#ifdef DDS_HAS_WCHAR - case TK_CHAR16: - return ser << sv.get(); - case TK_STRING16: - return ser << sv.get(); -#endif - default: + if (elem_tk == TK_ENUM && enum_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { + return false; + } + if (elem_tk == TK_BITMASK && bitmask_bound(elem_type, treat_elem_as) != DDS::RETCODE_OK) { return false; } -} -} // namespace XTypes + // Dheader + const Encoding& encoding = ser.encoding(); + size_t total_size = 0; + if (!is_primitive(elem_tk)) { + if (!serialized_size_dynamic_collection(encoding, total_size, data, ext) || + !ser.write_delimiter(total_size)) { + return false; + } + } -namespace DCPS { + const DDS::TypeKind tk = base_type->get_kind(); + const CORBA::ULong item_count = data->get_item_count(); + if (tk == TK_SEQUENCE && !(ser << item_count)) { + // Sequence length + return false; + } -bool serialized_size(const Encoding& encoding, size_t& size, const XTypes::DynamicDataImpl& data) -{ - return data.serialized_size_i(encoding, size, Sample::Full); + // Use the get APIs for sequences when they are supported. + // Then we can serialize the whole sequence (for basic element types). + // For now, serialize elements one-by-one. + for (CORBA::ULong i = 0; i < item_count; ++i) { + const DDS::MemberId elem_id = data->get_member_id_at_index(i); + if (elem_id == MEMBER_ID_INVALID || + !serialize_dynamic_element(ser, data, elem_id, treat_elem_as, nested(ext))) { + return false; + } + } + return true; } -bool operator<<(Serializer& ser, const XTypes::DynamicDataImpl& data) +bool serialize(Serializer& ser, DDS::DynamicData_ptr data, Sample::Extent ext) { - return data.serialize_i(ser, Sample::Full); + using namespace OpenDDS::XTypes; + const DDS::DynamicType_var type = data->type(); + const DDS::DynamicType_var base_type = get_base_type(type); + switch (base_type->get_kind()) { + case TK_STRUCTURE: + return serialize_dynamic_struct(ser, data, ext); + case TK_UNION: + return serialize_dynamic_union(ser, data, ext); + case TK_ARRAY: + case TK_SEQUENCE: + return serialize_dynamic_collection(ser, data, ext); + } + return false; } -bool serialized_size(const Encoding& encoding, size_t& size, const KeyOnly& key) +bool operator<<(Serializer& ser, DDS::DynamicData_ptr data) { - return key.value.serialized_size_i(encoding, size, Sample::KeyOnly); + return serialize(ser, data, Sample::Full); } -bool operator<<(Serializer& ser, const KeyOnly& key) +bool operator<<(Serializer& ser, const KeyOnly& key) { - return key.value.serialize_i(ser, Sample::KeyOnly); + return serialize(ser, key.value, Sample::KeyOnly); } } // namespace DCPS diff --git a/dds/DCPS/XTypes/DynamicDataImpl.h b/dds/DCPS/XTypes/DynamicDataImpl.h index 5a83765ca3..f9d685ed30 100644 --- a/dds/DCPS/XTypes/DynamicDataImpl.h +++ b/dds/DCPS/XTypes/DynamicDataImpl.h @@ -20,22 +20,12 @@ namespace XTypes { class DynamicDataImpl; } -namespace DCPS { -OpenDDS_Dcps_Export -bool serialized_size(const Encoding& encoding, size_t& size, const XTypes::DynamicDataImpl& data); -OpenDDS_Dcps_Export -bool operator<<(Serializer& ser, const XTypes::DynamicDataImpl& data); -OpenDDS_Dcps_Export -bool serialized_size(const Encoding& encoding, size_t& size, const KeyOnly& data); -OpenDDS_Dcps_Export -bool operator<<(Serializer& ser, const KeyOnly& data); -} - namespace XTypes { class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { public: - explicit DynamicDataImpl(DDS::DynamicType_ptr type); + // An optional, read-only backing store can be passed as a last resort for reading data. + DynamicDataImpl(DDS::DynamicType_ptr type, DDS::DynamicData_ptr backing_store = 0); DynamicDataImpl(const DynamicDataImpl& other); DDS::ReturnCode_t set_descriptor(MemberId id, DDS::MemberDescriptor* value); @@ -239,7 +229,9 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { DDS::ReturnCode_t get_simple_value_enum(DCPS::Value& value, DDS::MemberId id) const; #endif - CORBA::ULong get_sequence_size() const; + CORBA::ULong get_string_item_count() const; + CORBA::ULong get_sequence_item_count() const; + bool has_member(DDS::MemberId id) const; void erase_member(DDS::MemberId id); /// Group of functions to read a basic value represented by this DynamicData instance @@ -270,6 +262,27 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { template void cast_to_enum_value(ValueType& dst, CORBA::Long src) const; + void set_backing_store(DDS::DynamicData_ptr backing_store); + + // Wrappers for reading different types from the backing store + bool get_value_from_backing_store(ACE_OutputCDR::from_int8& value, DDS::MemberId id); + bool get_value_from_backing_store(ACE_OutputCDR::from_uint8& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::Short& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::UShort& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::Long& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::ULong& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::LongLong& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::ULongLong& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::Float& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::Double& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::LongDouble& value, DDS::MemberId id); + bool get_value_from_backing_store(ACE_OutputCDR::from_octet& value, DDS::MemberId id); + bool get_value_from_backing_store(char*& value, DDS::MemberId id); + bool get_value_from_backing_store(CORBA::WChar*& value, DDS::MemberId id); + bool get_value_from_backing_store(ACE_OutputCDR::from_char& value, DDS::MemberId id); + bool get_value_from_backing_store(ACE_OutputCDR::from_wchar& value, DDS::MemberId id); + bool get_value_from_backing_store(ACE_OutputCDR::from_boolean& value, DDS::MemberId id); + /// Read a basic member from a containing type template bool read_basic_in_single_map(ValueType& value, DDS::MemberId id); @@ -281,31 +294,33 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { bool read_basic_member(ValueType& value, DDS::MemberId id); template - bool get_value_from_self(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_self(ValueType& value, DDS::MemberId id); template - bool get_value_from_enum(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_enum(ValueType& value, DDS::MemberId id); template - bool get_value_from_bitmask(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_bitmask(ValueType& value, DDS::MemberId id); template - bool get_value_from_struct(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_struct(ValueType& value, DDS::MemberId id); template - bool get_value_from_union(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_union(ValueType& value, DDS::MemberId id); + + bool check_out_of_bound_read(DDS::MemberId id); template - bool get_value_from_collection(ValueType& value, DDS::MemberId id); + DDS::ReturnCode_t get_value_from_collection(ValueType& value, DDS::MemberId id); template DDS::ReturnCode_t get_char_common(CharT& value, DDS::MemberId id); template - bool get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value); + DDS::ReturnCode_t get_boolean_from_bitmask(CORBA::ULong index, CORBA::Boolean& value); template - bool set_value_to_struct(DDS::MemberId id, const MemberType& value); + DDS::ReturnCode_t set_value_to_struct(DDS::MemberId id, const MemberType& value); bool cast_to_discriminator_value(CORBA::Long& disc_value, const ACE_OutputCDR::from_boolean& value) const; bool cast_to_discriminator_value(CORBA::Long& disc_value, const ACE_OutputCDR::from_octet& value) const; @@ -325,32 +340,46 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { template bool cast_to_discriminator_value(CORBA::Long& disc_value, const MemberType& value) const; + DDS::ReturnCode_t set_union_discriminator_helper(CORBA::Long disc_val, const char* func_name); + + bool get_union_member_type(DDS::MemberId id, DDS::DynamicType_var& member_type, + DDS::MemberDescriptor_var& md) const; + bool find_selected_union_branch(bool& has_existing_branch, DDS::MemberDescriptor_var& existing_md); + template - bool set_value_to_union(DDS::MemberId id, const MemberType& value, - TypeKind enum_or_bitmask = TK_NONE, LBound lower = 0, LBound upper = 0); + DDS::ReturnCode_t set_value_to_union(DDS::MemberId id, const MemberType& value); + + bool check_out_of_bound_write(DDS::MemberId id); template - bool set_value_to_collection(DDS::MemberId id, const ElementType& value, - TypeKind coll_tk, TypeKind enum_or_bitmask = TK_NONE, LBound lower = 0, LBound upper = 0); + DDS::ReturnCode_t set_value_to_collection(DDS::MemberId id, const ElementType& value); template - DDS::ReturnCode_t set_single_value(DDS::MemberId id, const ValueType& value, - TypeKind enum_or_bitmask = TK_NONE, LBound lower = 0, LBound upper = 0); + DDS::ReturnCode_t set_single_value(DDS::MemberId id, const ValueType& value); template DDS::ReturnCode_t set_char_common(DDS::MemberId id, const FromCharT& value); + // Conversion between index and ID for collection + CORBA::ULong index_to_id(CORBA::ULong index) const + { + return index; + } + + CORBA::ULong id_to_index(CORBA::ULong id) const + { + return id; + } + bool check_index_from_id(TypeKind tk, DDS::MemberId id, CORBA::ULong bound) const; static bool is_valid_discriminator_type(TypeKind tk); bool is_default_member_selected(CORBA::Long disc_val, DDS::MemberId default_id) const; - bool read_discriminator(CORBA::Long& disc_val) const; - DDS::MemberId find_selected_member() const; + bool read_discriminator(CORBA::Long& disc_val); bool validate_discriminator(CORBA::Long disc_val, const DDS::MemberDescriptor_var& md) const; - bool set_complex_to_struct(DDS::MemberId id, DDS::DynamicData_var value); - bool set_complex_to_union(DDS::MemberId id, DDS::DynamicData_var value); - bool set_complex_to_collection(DDS::MemberId id, DDS::DynamicData_var value, TypeKind tk); - bool validate_member_id_collection(DDS::MemberId id, TypeKind collection_tk) const; + DDS::ReturnCode_t set_complex_to_struct(DDS::MemberId id, DDS::DynamicData_var value); + DDS::ReturnCode_t set_complex_to_union(DDS::MemberId id, DDS::DynamicData_var value); + DDS::ReturnCode_t set_complex_to_collection(DDS::MemberId id, DDS::DynamicData_var value); DDS::ReturnCode_t clear_value_i(DDS::MemberId id, const DDS::DynamicType_var& member_type); @@ -371,32 +400,19 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { bool insert_sequence(DDS::MemberId id, const SequenceType& value); template - bool check_seqmem_in_struct_and_union(DDS::MemberId id, TypeKind enum_or_bitmask, - LBound lower, LBound upper) const; - template - bool check_seqmem_in_sequence_and_array(DDS::MemberId id, CORBA::ULong bound, - TypeKind enum_or_bitmask, LBound lower, LBound upper) const; - - template - bool set_values_to_struct(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper); + bool check_seqmem_in_struct_and_union(DDS::MemberId id, DDS::MemberDescriptor_var& md) const; template - bool set_values_to_union(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper); + bool set_values_to_struct(DDS::MemberId id, const SequenceType& value); template - bool set_values_to_sequence(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper); + bool set_values_to_union(DDS::MemberId id, const SequenceType& value); template - bool set_values_to_array(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask, LBound lower, LBound upper); + bool set_values_to_collection(DDS::MemberId id, const SequenceType& value); template - DDS::ReturnCode_t set_sequence_values(DDS::MemberId id, const SequenceType& value, - TypeKind enum_or_bitmask = TK_NONE, - LBound lower = 0, LBound upper = 0); + DDS::ReturnCode_t set_sequence_values(DDS::MemberId id, const SequenceType& value); template DDS::ReturnCode_t get_single_value(ValueType& value, DDS::MemberId id); @@ -459,6 +475,7 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { // Contain data for an instance of a basic type. struct SingleValue { + SingleValue(); SingleValue(CORBA::Long int32); SingleValue(CORBA::ULong uint32); SingleValue(ACE_OutputCDR::from_int8 from_int8); @@ -479,6 +496,8 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { SingleValue(const CORBA::WChar* wstr); #endif SingleValue(const SingleValue& other); + SingleValue& operator=(const SingleValue& other); + void copy(const SingleValue& other); ~SingleValue(); @@ -515,9 +534,6 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { const CORBA::WChar* wstr_; #endif }; - - private: - SingleValue& operator=(const SingleValue&); // = delete }; struct SequenceValue { @@ -637,393 +653,62 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { // Copy values of a basic sequence member from sequence map to a DynamicData object. bool move_sequence_to_complex(const const_sequence_iterator& it, DynamicDataImpl* data); + DDS::ReturnCode_t set_member_backing_store(DynamicDataImpl* member_ddi, DDS::MemberId id); + // Indicate whether the value of a member is found in the complex map or // one of the other two maps or not found from any map in the container. enum FoundStatus { FOUND_IN_COMPLEX_MAP, FOUND_IN_NON_COMPLEX_MAP, NOT_FOUND }; - bool get_complex_from_aggregated(DDS::DynamicData_var& value, DDS::MemberId id, - FoundStatus& found_status); - bool get_complex_from_struct(DDS::DynamicData_ptr& value, DDS::MemberId id); - bool write_discriminator_helper(CORBA::Long value, TypeKind treat_as); - bool write_discriminator(CORBA::Long value); - bool get_complex_from_union(DDS::DynamicData_ptr& value, DDS::MemberId id); - bool get_complex_from_collection(DDS::DynamicData_ptr& value, DDS::MemberId id); + bool get_complex_from_container(DDS::DynamicData_var& value, DDS::MemberId id, + FoundStatus& found_status); + DDS::ReturnCode_t get_complex_from_aggregated(DDS::DynamicData_var& dd_var, DDS::MemberId id); + DDS::ReturnCode_t get_complex_from_struct(DDS::DynamicData_ptr& value, DDS::MemberId id); + DDS::ReturnCode_t get_complex_from_union(DDS::DynamicData_ptr& value, DDS::MemberId id); + DDS::ReturnCode_t get_complex_from_collection(DDS::DynamicData_ptr& value, DDS::MemberId id); - bool read_discriminator(CORBA::Long& disc_val, const DDS::DynamicType_var& disc_type, - const_single_iterator it) const; + bool read_disc_from_single_map(CORBA::Long& disc_val, const DDS::DynamicType_var& disc_type, + const const_single_iterator& it) const; + bool read_disc_from_backing_store(CORBA::Long& disc_val, DDS::MemberId id, + const DDS::DynamicType_var& disc_type); // Add a single value for any valid discriminator value that selects the given member bool insert_valid_discriminator(DDS::MemberDescriptor* memberSelected); bool insert_discriminator(ACE_CDR::Long value); void clear_container(); + // Container for data set by the user. DataContainer container_; - // XCDR serialization functions - bool serialize_single_value(DCPS::Serializer& ser, const DynamicDataImpl::SingleValue& sv) const; + // Immutable backing store to retrieve data in case the container doesn't have it. + // The type associated with the backing store can be different (but assignable to) + // the type associated with this object. Reading from the backing store is considered + // best effort, that is failure to read from it doesn't cascade to the caller. + DDS::DynamicData_var backing_store_; - template - bool set_primitive_values(CollectionType& collection, CORBA::ULong bound, - const ElementType& elem_tag) const; - - template - bool serialize_primitive_value(DCPS::Serializer& ser, PrimitiveType default_value) const; - bool serialized_size_enum(const DCPS::Encoding& encoding, - size_t& size, const DDS::DynamicType_var& enum_type) const; - bool serialize_enum_default_value(DCPS::Serializer& ser, - const DDS::DynamicType_var& enum_type) const; - bool serialize_enum_value(DCPS::Serializer& ser) const; - bool serialized_size_bitmask(const DCPS::Encoding& encoding, - size_t& size, const DDS::DynamicType_var& bitmask_type) const; - bool serialize_bitmask_default_value(DCPS::Serializer& ser, - const DDS::DynamicType_var& bitmask_type) const; - bool serialize_bitmask_value(DCPS::Serializer& ser) const; bool reconstruct_string_value(CORBA::Char* str) const; - bool serialized_size_string(const DCPS::Encoding& encoding, size_t& size) const; - bool serialize_string_value(DCPS::Serializer& ser) const; bool reconstruct_wstring_value(CORBA::WChar* wstr) const; - bool serialized_size_wstring(const DCPS::Encoding& encoding, size_t& size) const; - bool serialize_wstring_value(DCPS::Serializer& ser) const; - void serialized_size_primitive_sequence(const DCPS::Encoding& encoding, size_t& size, - TypeKind elem_tk, CORBA::ULong length) const; - - template - bool reconstruct_primitive_collection(CollectionType& collection, - CORBA::ULong size, CORBA::ULong bound, const ElementType& elem_tag) const; - - bool serialize_primitive_sequence(DCPS::Serializer& ser, TypeKind elem_tk, - CORBA::ULong size, CORBA::ULong bound) const; - - void serialized_size_string_common(const DCPS::Encoding& encoding, size_t& size, - const char* str) const; -#ifdef DDS_HAS_WCHAR - void serialized_size_string_common(const DCPS::Encoding& encoding, size_t& size, - const CORBA::WChar* wstr) const; -#endif - void serialized_size_string_common(const DCPS::Encoding& encoding, size_t& size, - const SingleValue& sv) const; - - template - bool serialized_size_generic_string_collection(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - template - bool serialized_size_generic_string_sequence(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - template - bool serialize_generic_string_collection(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id) const; - template - bool serialize_generic_string_sequence(DCPS::Serializer& ser, CORBA::ULong length, - CORBA::ULong bound) const; - - template - bool reconstruct_enum_collection(CollectionType& collection, CORBA::ULong size, - CORBA::ULong bound, const DDS::DynamicType_var& enum_type, const WrapElementType& elem_tag) const; - - void serialized_size_enum_sequence_as_int8s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::Int8Seq& seq) const; - bool serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, const DDS::Int8Seq& enumseq) const; - bool serialize_enum_sequence_as_int8s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const; - void serialized_size_enum_sequence_as_int16s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::Int16Seq& seq) const; - bool serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, const DDS::Int16Seq& enumseq) const; - bool serialize_enum_sequence_as_int16s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const; - void serialized_size_enum_sequence_as_int32s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::Int32Seq& seq) const; - bool serialize_enum_sequence_as_ints_i(DCPS::Serializer& ser, const DDS::Int32Seq& enumseq) const; - bool serialize_enum_sequence_as_int32s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound, const DDS::DynamicType_var& enum_type) const; - - void serialized_size_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length, CORBA::ULong bitbound) const; - bool serialize_enum_sequence(DCPS::Serializer& ser, CORBA::ULong size, CORBA::ULong bitbound, - CORBA::ULong seqbound, const DDS::DynamicType_var& enum_type) const; - - template - bool reconstruct_bitmask_collection(CollectionType& collection, CORBA::ULong size, - CORBA::ULong bound, const WrapElementType& elem_tag) const; - void serialized_size_bitmask_sequence_as_uint8s(const DCPS::Encoding& encoding, - size_t& size, CORBA::ULong length) const; - void serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::UInt8Seq& seq) const; - bool serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt8Seq& bitmask_seq) const; - bool serialize_bitmask_sequence_as_uint8s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - void serialized_size_bitmask_sequence_as_uint16s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::UInt16Seq& seq) const; - bool serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt16Seq& bitmask_seq) const; - bool serialize_bitmask_sequence_as_uint16s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - void serialized_size_bitmask_sequence_as_uint32s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::UInt32Seq& seq) const; - bool serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt32Seq& bitmask_seq) const; - bool serialize_bitmask_sequence_as_uint32s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - void serialized_size_bitmask_sequence_as_uint64s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - void serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const DDS::UInt64Seq& seq) const; - bool serialize_bitmask_sequence_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt64Seq& bitmask_seq) const; - bool serialize_bitmask_sequence_as_uint64s(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - void serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length, CORBA::ULong bitbound) const; - bool serialize_bitmask_sequence(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bitbound, CORBA::ULong seqbound) const; - - bool serialized_size_sequence_value(const DCPS::Encoding& encoding, size_t& size, - const SequenceValue& sv) const; - bool serialize_sequence_value(DCPS::Serializer& ser, const SequenceValue& sv) const; - bool get_index_to_id_map(IndexToIdMap& index_to_id, CORBA::ULong bound) const; - bool serialized_size_complex_member_i(const DCPS::Encoding& encoding, size_t& size, - DDS::MemberId id, DCPS::Sample::Extent ext) const; - - template - bool serialized_size_nested_basic_sequences(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id, SequenceType protoseq) const; + bool has_discriminator_value(const_single_iterator& single_it, const_complex_iterator& complex_it) const; + bool get_discriminator_value(CORBA::Long& value, const const_single_iterator& single_it, + const const_complex_iterator& complex_it, const DDS::DynamicType_var& disc_type); +}; - template - bool serialized_size_nesting_basic_sequence(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id, SequenceType protoseq) const; +} // namespace XTypes - bool serialize_complex_member_i(DCPS::Serializer& ser, DDS::MemberId id, DCPS::Sample::Extent ext) const; +namespace DCPS { - template - bool serialize_nested_basic_sequences(DCPS::Serializer& ser, const IndexToIdMap& index_to_id, - SequenceType protoseq) const; +OpenDDS_Dcps_Export +bool serialized_size(const Encoding& encoding, size_t& size, DDS::DynamicData_ptr data); - template - bool serialize_nesting_basic_sequence_i(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound, SequenceType protoseq) const; - - bool serialized_size_nesting_basic_sequence(const DCPS::Encoding& encoding, size_t& size, - TypeKind nested_elem_tk, const IndexToIdMap& index_to_id) const; - bool serialize_nesting_basic_sequence(DCPS::Serializer& ser, TypeKind nested_elem_tk, - CORBA::ULong size, CORBA::ULong bound) const; - bool serialized_size_nested_enum_sequences(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialized_size_nesting_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialize_nested_enum_sequences(DCPS::Serializer& ser, const IndexToIdMap& index_to_id) const; - bool serialize_nesting_enum_sequence(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - bool serialized_size_nested_bitmask_sequences(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialized_size_nesting_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialize_nested_bitmask_sequences(DCPS::Serializer& ser, - const IndexToIdMap& index_to_id) const; - bool serialize_nesting_bitmask_sequence(DCPS::Serializer& ser, CORBA::ULong size, - CORBA::ULong bound) const; - bool serialized_size_complex_member(const DCPS::Encoding& encoding, size_t& size, - DDS::MemberId id, const DDS::DynamicType_var& elem_type, - DCPS::Sample::Extent ext) const; - bool serialized_size_complex_sequence(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const; - bool serialize_complex_sequence_i(DCPS::Serializer& ser, const IndexToIdMap& index_to_id, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const; - bool serialize_complex_sequence(DCPS::Serializer& ser, CORBA::ULong size, CORBA::ULong bound, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const; - bool get_index_to_id_from_complex(IndexToIdMap& index_to_id, CORBA::ULong bound) const; - bool serialized_size_sequence(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_sequence(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - - // Serialize array - void serialized_size_primitive_array(const DCPS::Encoding& encoding, size_t& size, - TypeKind elem_tk, CORBA::ULong length) const; - bool serialize_primitive_array(DCPS::Serializer& ser, TypeKind elem_tk, CORBA::ULong length) const; - - template - bool serialized_size_generic_string_array(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - template - bool serialize_generic_string_array(DCPS::Serializer& ser, CORBA::ULong length) const; - void serialized_size_enum_array_as_int8s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_enum_array_as_ints_i(DCPS::Serializer& ser, const DDS::Int8Seq& enumarr) const; - bool serialize_enum_array_as_int8s(DCPS::Serializer& ser, CORBA::ULong length, - const DDS::DynamicType_var& enum_type) const; - void serialized_size_enum_array_as_int16s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_enum_array_as_ints_i(DCPS::Serializer& ser, const DDS::Int16Seq& enumarr) const; - bool serialize_enum_array_as_int16s(DCPS::Serializer& ser, CORBA::ULong length, - const DDS::DynamicType_var& enum_type) const; - void serialized_size_enum_array_as_int32s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_enum_array_as_ints_i(DCPS::Serializer& ser, const DDS::Int32Seq& enumarr) const; - bool serialize_enum_array_as_int32s(DCPS::Serializer& ser, CORBA::ULong length, - const DDS::DynamicType_var& enum_type) const; - void serialized_size_enum_array(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length, CORBA::ULong bitbound) const; - bool serialize_enum_array(DCPS::Serializer& ser, CORBA::ULong bitbound, CORBA::ULong length, - const DDS::DynamicType_var& enum_type) const; - - void serialized_size_bitmask_array_as_uint8s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt8Seq& bitmask_arr) const; - bool serialize_bitmask_array_as_uint8s(DCPS::Serializer& ser, CORBA::ULong length) const; - void serialized_size_bitmask_array_as_uint16s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt16Seq& bitmask_arr) const; - bool serialize_bitmask_array_as_uint16s(DCPS::Serializer& ser, CORBA::ULong length) const; - void serialized_size_bitmask_array_as_uint32s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt32Seq& bitmask_arr) const; - bool serialize_bitmask_array_as_uint32s(DCPS::Serializer& ser, CORBA::ULong length) const; - void serialized_size_bitmask_array_as_uint64s(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length) const; - bool serialize_bitmask_array_as_uints_i(DCPS::Serializer& ser, - const DDS::UInt64Seq& bitmask_arr) const; - bool serialize_bitmask_array_as_uint64s(DCPS::Serializer& ser, CORBA::ULong length) const; - void serialized_size_bitmask_array(const DCPS::Encoding& encoding, size_t& size, - CORBA::ULong length, CORBA::ULong bitbound) const; - bool serialize_bitmask_array(DCPS::Serializer& ser, CORBA::ULong bitbound, - CORBA::ULong length) const; +OpenDDS_Dcps_Export +bool operator<<(Serializer& ser, DDS::DynamicData_ptr data); - template - bool serialized_size_nesting_basic_array(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id, SequenceType protoseq) const; +OpenDDS_Dcps_Export +bool serialized_size(const Encoding& encoding, size_t& size, const KeyOnly& key); - template - bool serialize_nesting_basic_array_i(DCPS::Serializer& ser, CORBA::ULong length, - SequenceType protoseq) const; - bool serialized_size_nesting_basic_array(const DCPS::Encoding& encoding, size_t& size, - TypeKind nested_elem_tk, const IndexToIdMap& index_to_id) const; - bool serialize_nesting_basic_array(DCPS::Serializer& ser, TypeKind nested_elem_tk, - CORBA::ULong length) const; - bool serialized_size_nesting_enum_array(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialize_nesting_enum_array(DCPS::Serializer& ser, CORBA::ULong length) const; - bool serialized_size_nesting_bitmask_array(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id) const; - bool serialize_nesting_bitmask_array(DCPS::Serializer& ser, CORBA::ULong length) const; - bool serialized_size_complex_array(const DCPS::Encoding& encoding, size_t& size, - const IndexToIdMap& index_to_id, const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const; - bool serialize_complex_array(DCPS::Serializer& ser, CORBA::ULong length, - const DDS::DynamicType_var& elem_type, DCPS::Sample::Extent ext) const; - bool serialized_size_array(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_array(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - - bool serialized_size_primitive_member(const DCPS::Encoding& encoding, size_t& size, - TypeKind member_tk) const; - - bool serialized_size_basic_member_default_value(const DCPS::Encoding& encoding, size_t& size, - TypeKind member_tk) const; - bool serialized_size_basic_member(const DCPS::Encoding& encoding, size_t& size, - TypeKind member_tk, const_single_iterator it) const; - bool serialize_basic_member_default_value(DCPS::Serializer& ser, TypeKind member_tk) const; - - bool serialized_size_single_aggregated_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - const_single_iterator it, const DDS::DynamicType_var& member_type, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const; - bool serialize_single_aggregated_member_xcdr2(DCPS::Serializer& ser, const_single_iterator it, - const DDS::DynamicType_var& member_type, bool optional, bool must_understand, - DDS::ExtensibilityKind extensibility) const; - bool serialized_size_complex_aggregated_member_xcdr2_default(const DCPS::Encoding& encoding, - size_t& size, const DDS::DynamicType_var& member_type, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total, DCPS::Sample::Extent ext) const; - bool serialize_complex_aggregated_member_xcdr2_default(DCPS::Serializer& ser, DDS::MemberId id, - const DDS::DynamicType_var& member_type, bool optional, bool must_understand, - DDS::ExtensibilityKind extensibility, DCPS::Sample::Extent ext) const; - bool serialized_size_complex_aggregated_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - const_complex_iterator it, bool optional, DDS::ExtensibilityKind extensibility, - size_t& mutable_running_total, DCPS::Sample::Extent ext) const; - bool serialize_complex_aggregated_member_xcdr2(DCPS::Serializer& ser, const_complex_iterator it, - bool optional, bool must_understand, DDS::ExtensibilityKind extensibility, DCPS::Sample::Extent ext) const; - bool serialized_size_basic_struct_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - DDS::MemberId id, const DDS::DynamicType_var& member_type, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const; - bool serialize_basic_struct_member_xcdr2(DCPS::Serializer& ser, DDS::MemberId id, - const DDS::DynamicType_var& member_type, bool optional, bool must_understand, - DDS::ExtensibilityKind extensibility) const; - - void serialized_size_sequence_member_default_value(const DCPS::Encoding& encoding, - size_t& size, TypeKind elem_tk) const; - bool serialize_sequence_member_default_value(DCPS::Serializer& ser, TypeKind elem_tk) const; - - bool serialized_size_basic_sequence(const DCPS::Encoding& encoding, size_t& size, - const_sequence_iterator it) const; - bool serialize_basic_sequence(DCPS::Serializer& ser, const_sequence_iterator it) const; - bool serialized_size_enum_sequence(const DCPS::Encoding& encoding, size_t& size, - const_sequence_iterator it) const; - bool serialize_enum_sequence(DCPS::Serializer& ser, const_sequence_iterator it) const; - bool serialized_size_bitmask_sequence(const DCPS::Encoding& encoding, size_t& size, - const_sequence_iterator it) const; - bool serialize_bitmask_sequence(DCPS::Serializer& ser, const_sequence_iterator it) const; - void serialized_size_sequence_aggregated_member_xcdr2(const DCPS::Encoding& encoding, - size_t& size, const_sequence_iterator it, TypeKind elem_tk, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total) const; - bool serialize_sequence_aggregated_member_xcdr2(DCPS::Serializer& ser, const_sequence_iterator it, - TypeKind elem_tk, bool optional, bool must_understand, DDS::ExtensibilityKind extensibility) const; - bool serialized_size_sequence_struct_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - DDS::MemberId id, TypeKind elem_tk, bool optional, - DDS::ExtensibilityKind extensibility, size_t& mutable_running_total, DCPS::Sample::Extent ext) const; - bool serialize_sequence_struct_member_xcdr2(DCPS::Serializer& ser, DDS::MemberId id, - TypeKind elem_tk, bool optional, bool must_understand, DDS::ExtensibilityKind extensibility, DCPS::Sample::Extent ext) const; - bool serialized_size_structure_xcdr2(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_structure_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - bool serialized_size_structure_xcdr1(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_structure_xcdr1(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - bool serialized_size_structure(const DCPS::Encoding& encoding, size_t& size, - DCPS::Sample::Extent ext) const; - bool serialize_structure(DCPS::Serializer& ser, DCPS::Sample::Extent) const; - - bool get_discriminator_value(CORBA::Long& value, const_single_iterator single_it, - const_complex_iterator complex_it, const DDS::DynamicType_var& disc_type) const; - bool serialized_size_discriminator_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - const DDS::DynamicType_var& disc_type, DDS::ExtensibilityKind extensibility, - size_t& mutable_running_total) const; - bool serialize_discriminator_member_xcdr2(DCPS::Serializer& ser, CORBA::Long value, - const DDS::DynamicType_var& disc_type, DDS::ExtensibilityKind extensibility) const; - bool serialized_size_selected_member_xcdr2(const DCPS::Encoding& encoding, size_t& size, - DDS::MemberId selected_id, DDS::ExtensibilityKind extensibility, - size_t& mutable_running_total) const; - bool serialize_selected_member_xcdr2(DCPS::Serializer& ser, DDS::MemberId selected_id, - DDS::ExtensibilityKind extensibility) const; - bool serialized_size_union_xcdr2(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_union_xcdr2(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - bool serialized_size_union_xcdr1(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_union_xcdr1(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - bool serialized_size_union(const DCPS::Encoding& encoding, size_t& size, - DCPS::Sample::Extent ext) const; - bool serialize_union(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - - bool serialized_size_i(const DCPS::Encoding& encoding, size_t& size, DCPS::Sample::Extent ext) const; - bool serialize_i(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; - - friend OpenDDS_Dcps_Export - bool DCPS::serialized_size(const DCPS::Encoding& encoding, size_t& size, const DynamicDataImpl& data); - - friend OpenDDS_Dcps_Export - bool DCPS::operator<<(DCPS::Serializer& ser, const DynamicDataImpl& data); - - friend OpenDDS_Dcps_Export - bool DCPS::serialized_size(const DCPS::Encoding& encoding, size_t& size, const DCPS::KeyOnly& data); - - friend OpenDDS_Dcps_Export - bool DCPS::operator<<(DCPS::Serializer& ser, const DCPS::KeyOnly& data); -}; +OpenDDS_Dcps_Export +bool operator<<(Serializer& ser, const KeyOnly& key); +} -} // namespace XTypes } // namespace OpenDDS OPENDDS_END_VERSIONED_NAMESPACE_DECL diff --git a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp index 3f9053e185..f28b42a940 100644 --- a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp +++ b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp @@ -3270,16 +3270,12 @@ bool print_dynamic_data(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS const DDS::DynamicType_var type = dd->type(); const DDS::DynamicType_var base_type = get_base_type(type); - bool result; switch (base_type->get_kind()) { case TK_STRUCTURE: case TK_UNION: - result = print_members(dd, type_string, indent, true); - break; - default: - result = false; + return print_members(dd, type_string, indent, true); } - return result; + return false; } #endif diff --git a/dds/DCPS/XTypes/Utils.cpp b/dds/DCPS/XTypes/Utils.cpp index 73cbf91081..83437aaa88 100644 --- a/dds/DCPS/XTypes/Utils.cpp +++ b/dds/DCPS/XTypes/Utils.cpp @@ -541,10 +541,10 @@ namespace { switch (tk) { case TK_BOOLEAN: { - DDS::Boolean a_value; + DDS::Boolean a_value = false; a_rc = a_data->get_boolean_value(a_value, a_id); if (a_rc == DDS::RETCODE_OK) { - DDS::Boolean b_value; + DDS::Boolean b_value = false; b_rc = b_data->get_boolean_value(b_value, b_id); if (b_rc == DDS::RETCODE_OK) { cmp(result, a_value, b_value); @@ -750,8 +750,7 @@ namespace { const DDS::UInt32 a_count = a_value->get_item_count(); const DDS::UInt32 b_count = b_value->get_item_count(); const DDS::UInt32 count = std::min(a_count, b_count); - for (DDS::UInt32 i = 0; - a_rc == DDS::RETCODE_OK && i < count && result == 0; ++i) { + for (DDS::UInt32 i = 0; a_rc == DDS::RETCODE_OK && i < count && result == 0; ++i) { a_rc = b_rc = member_compare(result, a_value, a_value->get_member_id_at_index(i), b_value, b_value->get_member_id_at_index(i)); @@ -1204,52 +1203,52 @@ DDS::ReturnCode_t copy_member( } const DDS::DynamicType_var dest_type = dest->type(); - DDS::DynamicType_var use_dest_type; + DDS::DynamicType_var dest_member_type; if (dest_id != MEMBER_ID_INVALID) { - rc = get_member_type(use_dest_type, dest_type, dest_id); + rc = get_member_type(dest_member_type, dest_type, dest_id); if (rc != DDS::RETCODE_OK) { return rc; } } else { - use_dest_type = get_base_type(dest_type); + dest_member_type = get_base_type(dest_type); } - const DDS::TypeKind dest_tk = use_dest_type->get_kind(); + const DDS::TypeKind dest_member_tk = dest_member_type->get_kind(); const DDS::DynamicType_var src_type = src->type(); - DDS::DynamicType_var use_src_type; + DDS::DynamicType_var src_member_type; if (src_id != MEMBER_ID_INVALID) { - rc = get_member_type(use_src_type, src_type, src_id); + rc = get_member_type(src_member_type, src_type, src_id); if (rc != DDS::RETCODE_OK) { return rc; } } else { - use_src_type = get_base_type(src_type); + src_member_type = get_base_type(src_type); } - const DDS::TypeKind src_tk = use_src_type->get_kind(); + const DDS::TypeKind src_member_tk = src_member_type->get_kind(); + const CORBA::String_var src_type_name = src_type->get_name(); + const CORBA::String_var dest_type_name = dest_type->get_name(); if (DCPS::DCPS_debug_level >= 8) { - const CORBA::String_var src_type_name = src_type->get_name(); - const CORBA::String_var dest_type_name = dest_type->get_name(); ACE_DEBUG((LM_DEBUG, "(%P|%t) copy_member(DynamicData): " "type %C from %C id %u to %C id %u\n", - typekind_to_string(src_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id)); + typekind_to_string(src_member_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id)); } - if (src_tk != dest_tk) { + if (src_member_tk != dest_member_tk) { if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: copy_member(DynamicData): " "Can not copy member type %C id %u to type %C id %u\n", - typekind_to_string(src_tk), src_id, typekind_to_string(dest_tk), dest_id)); + typekind_to_string(src_member_tk), src_id, typekind_to_string(dest_member_tk), dest_id)); } return DDS::RETCODE_OK; } DDS::ReturnCode_t get_rc = DDS::RETCODE_OK; DDS::ReturnCode_t set_rc = DDS::RETCODE_OK; - switch (src_tk) { + switch (src_member_tk) { case TK_BOOLEAN: { - DDS::Boolean value; + DDS::Boolean value = false; get_rc = src->get_boolean_value(value, src_id); if (get_rc == DDS::RETCODE_OK) { set_rc = dest->set_boolean_value(dest_id, value); @@ -1273,9 +1272,9 @@ DDS::ReturnCode_t copy_member( case TK_INT64: { DDS::Int64 value; - get_rc = get_int_value(value, src, src_id, src_tk); + get_rc = get_int_value(value, src, src_id, src_member_tk); if (get_rc == DDS::RETCODE_OK) { - set_rc = set_int_value(dest, dest_id, dest_tk, value); + set_rc = set_int_value(dest, dest_id, dest_member_tk, value); } } break; @@ -1286,9 +1285,9 @@ DDS::ReturnCode_t copy_member( case TK_UINT64: { DDS::UInt64 value; - get_rc = get_uint_value(value, src, src_id, src_tk); + get_rc = get_uint_value(value, src, src_id, src_member_tk); if (get_rc == DDS::RETCODE_OK) { - set_rc = set_uint_value(dest, dest_id, dest_tk, value); + set_rc = set_uint_value(dest, dest_id, dest_member_tk, value); } } break; @@ -1366,25 +1365,45 @@ DDS::ReturnCode_t copy_member( case TK_ENUM: { DDS::Int32 value; - get_rc = get_enum_value(value, use_src_type, src, src_id); + get_rc = get_enum_value(value, src_member_type, src, src_id); if (get_rc == DDS::RETCODE_OK) { - set_rc = set_enum_value(use_dest_type, dest, dest_id, value); + set_rc = set_enum_value(dest_member_type, dest, dest_id, value); } } break; - case TK_STRUCTURE: - case TK_UNION: case TK_SEQUENCE: case TK_ARRAY: + case TK_STRUCTURE: + case TK_UNION: { DDS::DynamicData_var subsrc; get_rc = src->get_complex_value(subsrc, src_id); if (get_rc == DDS::RETCODE_OK) { - DDS::DynamicType_var parent_dest_type = get_base_type(dest_type); - if (parent_dest_type->get_kind() == TK_UNION) { - DDS::DynamicData_var temp = new DynamicDataImpl(use_dest_type); - set_rc = dest->set_complex_value(dest_id, temp); + DDS::DynamicType_var base_dest_type = get_base_type(dest_type); + const DDS::TypeKind base_dest_tk = base_dest_type->get_kind(); + const DDS::UInt32 dest_count = dest->get_item_count(); + bool dest_member_optional = false; + if (base_dest_tk == TK_STRUCTURE || base_dest_tk == TK_UNION) { + DDS::DynamicTypeMember_var dest_dtm; + rc = dest_type->get_member(dest_dtm, dest_id); + if (rc != DDS::RETCODE_OK) { + return rc; + } + DDS::MemberDescriptor_var dest_md; + rc = dest_dtm->get_descriptor(dest_md); + if (rc != DDS::RETCODE_OK) { + return rc; + } + dest_member_optional = dest_md->is_optional(); + } + + // TODO: The sequence index check assumes that ID is mapped exactly to index. + // This is an internal detail and should be removed. + if ((base_dest_tk == TK_SEQUENCE && dest_id == dest_count) || + base_dest_tk == TK_UNION || dest_member_optional) { + DDS::DynamicData_var tmp = new DynamicDataImpl(dest_member_type); + set_rc = dest->set_complex_value(dest_id, tmp); } if (set_rc == DDS::RETCODE_OK) { DDS::DynamicData_var subdest; @@ -1404,18 +1423,16 @@ DDS::ReturnCode_t copy_member( default: if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: copy(DynamicData): " - "member has unexpected TypeKind %C\n", typekind_to_string(src_tk))); + "member has unexpected TypeKind %C\n", typekind_to_string(src_member_tk))); } get_rc = DDS::RETCODE_UNSUPPORTED; } if (get_rc == DDS::RETCODE_NO_DATA) { if (DCPS::DCPS_debug_level >= 8) { - const CORBA::String_var src_type_name = src_type->get_name(); - const CORBA::String_var dest_type_name = dest_type->get_name(); ACE_DEBUG((LM_DEBUG, "(%P|%t) copy(DynamicData): " "Did not copy member type %C from %C id %u to %C id %u: get returned %C\n", - typekind_to_string(src_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id, + typekind_to_string(src_member_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id, retcode_to_string(get_rc))); } return DDS::RETCODE_OK; @@ -1423,8 +1440,6 @@ DDS::ReturnCode_t copy_member( if (get_rc != DDS::RETCODE_OK || set_rc != DDS::RETCODE_OK) { if (log_level >= LogLevel::Warning) { - const CORBA::String_var src_type_name = src_type->get_name(); - const CORBA::String_var dest_type_name = dest_type->get_name(); const DDS::TypeKind tk = src_type->get_kind(); if (tk == TK_STRUCTURE || tk == TK_UNION) { CORBA::String_var src_member_name; @@ -1441,14 +1456,14 @@ DDS::ReturnCode_t copy_member( } ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: copy(DynamicData): " "Could not copy member type %C from %C.%C id %u to %C.%C id %u: get: %C set: %C\n", - typekind_to_string(src_tk), + typekind_to_string(src_member_tk), src_type_name.in(), src_member_name.in() ? src_member_name.in() : "?", src_id, dest_type_name.in(), dest_member_name.in() ? dest_member_name.in() : "?", dest_id, retcode_to_string(get_rc), retcode_to_string(set_rc))); } else { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: copy(DynamicData): " "Could not copy member type %C from %C id %u to %C id %u: get: %C set: %C\n", - typekind_to_string(src_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id, + typekind_to_string(src_member_tk), src_type_name.in(), src_id, dest_type_name.in(), dest_id, retcode_to_string(get_rc), retcode_to_string(set_rc))); } } @@ -1543,7 +1558,7 @@ DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src) dynamic_cast(dest_members_var.in()); for (DynamicTypeMembersByIdImpl::const_iterator src_it = src_members->begin(); - src_it != src_members->end(); ++src_it) { + src_it != src_members->end(); ++src_it) { const DDS::MemberId id = src_it->first; const DynamicTypeMembersByIdImpl::const_iterator dest_it = dest_members->find(id); if (dest_it == dest_members->end()) { @@ -1588,6 +1603,83 @@ DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src) return rc; } +DDS::ReturnCode_t get_selected_union_branch( + DDS::DynamicType_var union_type, DDS::Int32 disc, + bool& found_selected_member, DDS::MemberDescriptor_var& selected_md) +{ + found_selected_member = false; + bool has_default = false; + DDS::ReturnCode_t rc = DDS::RETCODE_OK; + DDS::MemberDescriptor_var default_md; + for (DDS::UInt32 i = 0; i < union_type->get_member_count(); ++i) { + DDS::DynamicTypeMember_var dtm; + rc = union_type->get_member_by_index(dtm, i); + if (rc != DDS::RETCODE_OK) { + return rc; + } + if (dtm->get_id() == DISCRIMINATOR_ID) { + continue; + } + DDS::MemberDescriptor_var md; + rc = dtm->get_descriptor(md); + if (rc != DDS::RETCODE_OK) { + return rc; + } + bool found_matched_label = false; + const DDS::UnionCaseLabelSeq labels = md->label(); + for (DDS::UInt32 j = 0; !found_matched_label && j < labels.length(); ++j) { + if (disc == labels[j]) { + found_matched_label = true; + } + } + if (found_matched_label) { + selected_md = md; + found_selected_member = true; + break; + } + if (md->is_default_label()) { + default_md = md; + has_default = true; + } + } + if (!found_selected_member && has_default) { + selected_md = default_md; + found_selected_member = true; + } + return rc; +} + +bool has_explicit_keys(DDS::DynamicType* dt) +{ + // see dds_generator.h struct_has_explicit_keys() in opendds_idl + DDS::TypeDescriptor_var type_descriptor; + DDS::ReturnCode_t ret = dt->get_descriptor(type_descriptor); + if (ret != DDS::RETCODE_OK) { + return false; + } + DDS::DynamicType* const base = type_descriptor->base_type(); + if (base && has_explicit_keys(base)) { + return true; + } + + for (ACE_CDR::ULong i = 0; i < dt->get_member_count(); ++i) { + DDS::DynamicTypeMember_var member; + ret = dt->get_member_by_index(member, i); + if (ret != DDS::RETCODE_OK) { + return false; + } + DDS::MemberDescriptor_var descriptor; + ret = member->get_descriptor(descriptor); + if (ret != DDS::RETCODE_OK) { + return false; + } + if (descriptor->is_key()) { + return true; + } + } + return false; +} + } // namespace XTypes } // namespace OpenDDS OPENDDS_END_VERSIONED_NAMESPACE_DECL diff --git a/dds/DCPS/XTypes/Utils.h b/dds/DCPS/XTypes/Utils.h index 98ff9c3f6d..fae51977bf 100644 --- a/dds/DCPS/XTypes/Utils.h +++ b/dds/DCPS/XTypes/Utils.h @@ -8,6 +8,7 @@ #ifndef OPENDDS_SAFETY_PROFILE # include +# include # include @@ -220,6 +221,23 @@ OpenDDS_Dcps_Export DDS::ReturnCode_t copy_member( DDS::DynamicData_ptr src, DDS::MemberId src_id); OpenDDS_Dcps_Export DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src); +DDS::ReturnCode_t get_selected_union_branch( + DDS::DynamicType_var union_type, DDS::Int32 disc, bool& found_selected_member, + DDS::MemberDescriptor_var& selected_md); +bool has_explicit_keys(DDS::DynamicType* dt); + +inline bool exclude_member(DCPS::Sample::Extent ext, bool is_key, bool has_explicit_keys) +{ + // see Fields::Iterator and explicit_keys_only() in opendds_idl's dds_generator.h + const bool explicit_keys_only = ext == DCPS::Sample::KeyOnly || (ext == DCPS::Sample::NestedKeyOnly && has_explicit_keys); + return explicit_keys_only && !is_key; +} + +inline DCPS::Sample::Extent nested(DCPS::Sample::Extent ext) +{ + return ext == DCPS::Sample::KeyOnly ? DCPS::Sample::NestedKeyOnly : ext; +} + } // namespace XTypes } // namespace OpenDDS OPENDDS_END_VERSIONED_NAMESPACE_DECL diff --git a/docs/devguide/xtypes.rst b/docs/devguide/xtypes.rst index 0bda592343..36244f1e89 100644 --- a/docs/devguide/xtypes.rst +++ b/docs/devguide/xtypes.rst @@ -273,7 +273,7 @@ Appendable Extensibility Sect<16.3.4> Mutable extensibility requires a certain amount of overhead both in terms of processing and network traffic. -A more efficient but less flexible form of extensibility is appendable +A more efficient but less flexible form of extensibility is appendable. Appendable is limited in that members can only be added to or removed from the end of the type. With appendable, the initial version of the weather station IDL would be: @@ -977,6 +977,7 @@ Suppose id is 1, meaning that the member at index 0 is ``l_field``, we now can g After the call, ``int32_value`` contains the value of the member ``l_field`` from the sample. The method returns ``DDS::RETCODE_OK`` if successful. +In case the type has an optional member and it is not present in the DynamicData instance, ``DDS::RETCODE_NO_DATA`` is returned. Similarly, suppose we have already found out the types and ids of the members ``us_field`` and ``f_field``, their values can be read as follows. @@ -987,6 +988,39 @@ Similarly, suppose we have already found out the types and ids of the members `` DDS::Float32 float32_value; ret = data.get_float32_value(float32_value, 3); // Get the value of f_field +Reading members from union is a little different as there is at most one active branch at any time. +In general, DynamicData in OpenDDS follows the IDL-to-C++ mappings for union. +Consider the following union as an example. + +.. code-block:: omg-idl + + @mutable + union MyUnion switch (short) { + case 1: + case 2: + @id(1) short s_field; + case 3: + @id(2) long l_field; + case 4: + @id(3) string str_field; + }; + +The discriminator can be read using the appropriate method for the discriminator type and id ``XTypes::DISCRIMINATOR_ID`` (see :ghfile:`dds/DCPS/XTypes/TypeObject.h`). + +.. code-block:: cpp + + DDS::Int32 disc_value; + ret = data.get_int16_value(disc_val, XTypes::DISCRIMINATOR_ID); + +Using the value of the discriminator, user can decide which branch is activated and read its value in a similar way as reading a struct member. +Reading a branch that is not activated returns ``DDS::RETCODE_PRECONDITION_NOT_MET``. + +At any time, a DynamicData instance of a union represents a valid state of that union. +A special case is an empty DynamicData instance. +In this case, the discriminator takes the default value of the discriminator type (the XTypes specification specifies the default value for each type). +If that discriminator value selects a branch, the selected branch also takes the default value corresponding to its type. +If it doesn't select a branch, the union contains only the discriminator. + .. _xtypes--reading-collections-of-basic-types: Reading Collections of Basic Types @@ -1118,17 +1152,38 @@ They are analogous to the "get_*" operations that are described in :ref:`xtypes- When populating the DynamicData of complex data types, use get_complex_value() (:ref:`xtypes--reading-members-of-more-complex-types`) to navigate from DynamicData representing containing types to DynamicData representing contained types. Setting the value of a member of a DynamicData union using a ``set_*`` method implicitly 1) activates the branch corresponding to the member and 2) sets the discriminator to a value corresponding to the active branch. -After a branch has been activated, the value of the discriminator can be changed using a ``set_*`` method. -However, the new value of the discriminator must correspond to the active branch. -To set the discriminator, use ``DISCRIMINATOR_ID`` as the member id for the call to ``set_*`` (see :ghfile:`dds/DCPS/XTypes/TypeObject.h`). - -Unions start in an "empty" state meaning that no branch is active. -At the point of serialization, the middleware will treat an empty union according to the following procedure. -The discriminator is assumed to have the default value for the discriminator type and all members are assumed to have the default value for their type. -There are three possibilities. -First, the discriminator selects a non-default branch in which case the serialized union will have the default discriminator value and the default value for the implicitly selected member; -Second, the discriminator selects a default branch in which case the serialized union will have the default discriminator value and the default value for the default branch member. -Third, the discriminator selects no branch (and a default branch is not defined) in which case the serialized union will have the default discriminator only. +For example, the ``l_field`` member of ``MyUnion`` above can be set as follows: + +.. code-block:: cpp + + DDS::Int32 l_field_value = 12; + data.set_int32_value(id, l_field_value); // id is 2 + +The discriminator can also be set directly in the following two cases. +First, the new discriminator value selects the same branch that is currently activated. +Second, the new discriminator value selects no branch. In all other cases, ``DDS::RETCODE_PRECONDITION_NOT_MET`` is returned. +As an example for the first case, suppose the union currently has the discriminator value of 1 and the member `s_field` is active. +We can set the discriminator value to 2 as it selects the same member. + +.. code-block:: cpp + + DDS::Int16 new_disc_value = 2; + data.set_int16_value(XTypes::DISCRIMINATOR_ID, new_disc_value); + +For the second case, setting the discriminator to any value that doesn't select a member will succeed. After that, the union contains only the discriminator. + +.. code-block:: cpp + + DDS::Int16 new_disc_value = 5; // does not select any branch + data.set_int16_value(XTypes::DISCRIMINATOR_ID, new_disc_value); + +Unions start in an "empty" state as described in :ref:`xtypes--interpreting-data-samples-with-dynamicdata`. +Consequently, at the point of serialization, empty and non-empty unions are not differentiated. + +Expandable collection types such as sequences or strings can be extended one element at a time. +To extend a sequence (or string), we first get the id of the new element at index equal to the current length of the sequence using the ``get_member_id_at_index`` operation. +The length of the sequence can be got using ``get_item_count``. +After we obtain the id, we can write the new element using the ``set_*`` operation as usual. .. _xtypes--dynamicdatawriters-and-dynamicdatareaders: @@ -1138,10 +1193,10 @@ DynamicDataWriters and DynamicDataReaders .. Sect<16.7.4> -DynamicDataWriters and DataReaders are designed to work like any other DataWriter and DataReader except that their APIs are defined in terms of the DynamicData type instead of a type generated from IDL. +DynamicDataWriters and DynamicDataReaders are designed to work like any other DataWriter and DataReader except that their APIs are defined in terms of the DynamicData type instead of a type generated from IDL. Each DataWriter and DataReader has an associated Topic and that Topic has a data type (represented by a TypeSupport object). -Behavior related to keys, QoS policies, discovery and built-in topics, DDS Security, and transport is not any different for a DynamicDataWriter or DataReader. -One exception is that in the current implementation, :ref:`content_subscription_profile` is not supported for DynamicDataWriters and DataReaders. +Behavior related to keys, QoS policies, discovery and built-in topics, DDS Security, and transport is not any different for a DynamicDataWriter or DynamicDataReader. +One exception is that in the current implementation, :ref:`content_subscription_profile` is not supported for DynamicDataWriters and DynamicDataReaders. .. _xtypes--obtaining-dynamictype-and-registering-typesupport: diff --git a/docs/news.d/dynamic-data-renovate.rst b/docs/news.d/dynamic-data-renovate.rst new file mode 100644 index 0000000000..0c879b40e8 --- /dev/null +++ b/docs/news.d/dynamic-data-renovate.rst @@ -0,0 +1,5 @@ +.. news-prs: 4278 + +.. news-start-section: Fixes +- Updated the :ref:`read ` and :ref:`write ` semantics of DynamicData for union, expandable collections (sequence and string), and optional member of an aggregated type. +.. news-end-section diff --git a/tests/DCPS/Compiler/xcdr/xcdr.cpp b/tests/DCPS/Compiler/xcdr/xcdr.cpp index 4ae43f7ac8..af129db037 100644 --- a/tests/DCPS/Compiler/xcdr/xcdr.cpp +++ b/tests/DCPS/Compiler/xcdr/xcdr.cpp @@ -228,14 +228,14 @@ void amalgam_serializer_test_base( DDS::DynamicData_var dd = DDS::DynamicDataFactory::get_instance()->create_data(type); ASSERT_RC_OK(copy(dd, dda)); - DynamicDataImpl& ddi = *dynamic_cast(dd.in()); + DDS::DynamicData_ptr dd_ptr = dd.in(); if (key_only) { - const KeyOnly key_only(ddi); + const KeyOnly key_only(dd_ptr); EXPECT_EQ(serialized_size(encoding, key_only), expected_cdr.size); ASSERT_TRUE(serializer << key_only); } else { - EXPECT_EQ(serialized_size(encoding, ddi), expected_cdr.size); - ASSERT_TRUE(serializer << ddi); + EXPECT_EQ(serialized_size(encoding, dd_ptr), expected_cdr.size); + ASSERT_TRUE(serializer << dd_ptr); } #else ASSERT_TRUE(false); @@ -333,7 +333,7 @@ template void baseline_checks_union(const Encoding& encoding, const DataView& expected_cdr, UnionDisc disc) { Type value; - value._d(disc); + set_values_union(value, disc); EXPECT_EQ(serialized_size(encoding, value), expected_cdr.size); serializer_test_union(encoding, expected_cdr, disc); } diff --git a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp index 0cc64c8423..73e9448fd0 100644 --- a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp +++ b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp @@ -8,6 +8,7 @@ #include #include #include +#include using namespace OpenDDS; using namespace DynamicDataImpl; @@ -167,10 +168,81 @@ void assert_serialized_data(size_t buff_size, XTypes::DynamicDataImpl& data, { ACE_Message_Block buffer(buff_size); DCPS::Serializer ser(&buffer, encoding); - ASSERT_TRUE(ser << data); + ASSERT_TRUE(ser << &data); EXPECT_PRED_FORMAT2(assert_DataView, expected_cdr, buffer); } +template +void verify_reading_single_value_struct(StructType input, XTypes::DynamicDataImpl& data) +{ + CORBA::Long enum_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(enum_val, 0)); + EXPECT_EQ(input.my_enum, enum_val); + CORBA::Long int32_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(int32_val, 1)); + EXPECT_EQ(input.int_32, int32_val); + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, data.get_int32_value(int32_val, 2)); + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 1)); + const DDS::MemberId invalid_id = 123; + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, nested_dd->get_int32_value(int32_val, invalid_id)); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, XTypes::MEMBER_ID_INVALID)); + EXPECT_EQ(input.int_32, int32_val); + CORBA::ULong uint32_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_uint32_value(uint32_val, 2)); + EXPECT_EQ(input.uint_32, uint32_val); + CORBA::Int8 int8_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int8_value(int8_val, 3)); + EXPECT_EQ(input.int_8, int8_val); + CORBA::UInt8 uint8_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_uint8_value(uint8_val, 4)); + EXPECT_EQ(input.uint_8, uint8_val); + CORBA::Short int16_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int16_value(int16_val, 5)); + EXPECT_EQ(input.int_16, int16_val); + CORBA::UShort uint16_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_uint16_value(uint16_val, 6)); + EXPECT_EQ(input.uint_16, uint16_val); + CORBA::LongLong int64_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int64_value(int64_val, 7)); + EXPECT_EQ(input.int_64, int64_val); + CORBA::ULongLong uint64_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_uint64_value(uint64_val, 8)); + EXPECT_EQ(input.uint_64, uint64_val); + CORBA::Float float32_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_float32_value(float32_val, 9)); + EXPECT_EQ(input.float_32, float32_val); + CORBA::Double float64_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_float64_value(float64_val, 10)); + EXPECT_EQ(input.float_64, float64_val); + CORBA::Char char8_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_char8_value(char8_val, 12)); + EXPECT_EQ(input.char_8, char8_val); +#ifdef DDS_HAS_WCHAR + CORBA::WChar char16_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_char16_value(char16_val, 13)); + EXPECT_EQ(input.char_16, char16_val); +#endif + CORBA::Octet byte_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_byte_value(byte_val, 14)); + EXPECT_EQ(input.byte, byte_val); + CORBA::Boolean bool_val = false; + EXPECT_EQ(DDS::RETCODE_OK, data.get_boolean_value(bool_val, 15)); + EXPECT_EQ(input._cxx_bool, bool_val); + EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 16)); + CORBA::Long nested_long_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(nested_long_val, 0)); + EXPECT_EQ(input.nested_struct.l, nested_long_val); + CORBA::String_var str; + EXPECT_EQ(DDS::RETCODE_OK, data.get_string_value(str, 17)); + EXPECT_STREQ(input.str.in(), str); +#ifdef DDS_HAS_WCHAR + CORBA::WString_var wstr; + EXPECT_EQ(DDS::RETCODE_OK, data.get_wstring_value(wstr, 18)); + EXPECT_STREQ(input.wstr.in(), wstr); +#endif +} + template void verify_single_value_struct(DDS::DynamicType_var type, const DataView& expected_cdr) { @@ -181,10 +253,10 @@ void verify_single_value_struct(DDS::DynamicType_var type, const DataView& expec EXPECT_EQ(ret, DDS::RETCODE_OK); // Set int_32 but use wrong Id ret = data.set_int32_value(2, input.int_32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_BAD_PARAMETER); // Set int_32 but use wrong interface ret = data.set_uint32_value(1, static_cast(input.int_32)); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_BAD_PARAMETER); ret = data.set_int32_value(1, input.int_32); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_uint32_value(2, input.uint_32); @@ -207,7 +279,7 @@ void verify_single_value_struct(DDS::DynamicType_var type, const DataView& expec EXPECT_EQ(ret, DDS::RETCODE_OK); // Member type at the given Id does not match interface ret = data.set_char8_value(14, input.char_8); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_BAD_PARAMETER); ret = data.set_char8_value(12, input.char_8); EXPECT_EQ(ret, DDS::RETCODE_OK); #ifdef DDS_HAS_WCHAR @@ -250,79 +322,123 @@ void verify_single_value_struct(DDS::DynamicType_var type, const DataView& expec EXPECT_EQ(ret, DDS::RETCODE_ERROR); // Use correct interface but wrong id (expect MEMBER_ID_INVALID) ret = int16_dd->set_int16_value(rewrite_id, input.int_16); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_BAD_PARAMETER); ret = int16_dd->set_int16_value(XTypes::MEMBER_ID_INVALID, input.int_16); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_complex_value(rewrite_id, int16_dd); EXPECT_EQ(ret, DDS::RETCODE_OK); assert_serialized_data(512, data, expected_cdr); - // Test getting out values + // Test getting out the values + verify_reading_single_value_struct(input, data); +} + +// Intended to test the DynamicDataImpl instance with backing store. +// The updated members overwrite the ones from the backing store. +void verify_modified_single_value_struct(XTypes::DynamicDataImpl& ddi) +{ + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int32_value(0, E_FLOAT32)); CORBA::Long enum_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(enum_val, 0)); - EXPECT_EQ(input.my_enum, enum_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(enum_val, 0)); + EXPECT_EQ(E_FLOAT32, enum_val); + + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, ddi.set_int64_value(0, E_FLOAT64)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int32_value(1, 123l)); CORBA::Long int32_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(int32_val, 1)); - EXPECT_EQ(input.int_32, int32_val); - EXPECT_EQ(DDS::RETCODE_ERROR, data.get_int32_value(int32_val, 2)); - DDS::DynamicData_var nested_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 1)); - const DDS::MemberId invalid_id = 123; - EXPECT_EQ(DDS::RETCODE_ERROR, nested_dd->get_int32_value(int32_val, invalid_id)); - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, XTypes::MEMBER_ID_INVALID)); - EXPECT_EQ(input.int_32, int32_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(int32_val, 1)); + EXPECT_EQ(123l, int32_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint32_value(2, 321ul)); CORBA::ULong uint32_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_uint32_value(uint32_val, 2)); - EXPECT_EQ(input.uint_32, uint32_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint32_value(uint32_val, 2)); + EXPECT_EQ(321ul, uint32_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int8_value(3, CORBA::Int8(128))); CORBA::Int8 int8_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int8_value(int8_val, 3)); - EXPECT_EQ(input.int_8, int8_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int8_value(int8_val, 3)); + EXPECT_EQ(CORBA::Int8(128), int8_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint8_value(4, CORBA::UInt8(100))); CORBA::UInt8 uint8_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_uint8_value(uint8_val, 4)); - EXPECT_EQ(input.uint_8, uint8_val); - CORBA::Short int16_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int16_value(int16_val, 5)); - EXPECT_EQ(input.int_16, int16_val); - CORBA::UShort uint16_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_uint16_value(uint16_val, 6)); - EXPECT_EQ(input.uint_16, uint16_val); - CORBA::LongLong int64_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int64_value(int64_val, 7)); - EXPECT_EQ(input.int_64, int64_val); - CORBA::ULongLong uint64_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_uint64_value(uint64_val, 8)); - EXPECT_EQ(input.uint_64, uint64_val); - CORBA::Float float32_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_float32_value(float32_val, 9)); - EXPECT_EQ(input.float_32, float32_val); - CORBA::Double float64_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_float64_value(float64_val, 10)); - EXPECT_EQ(input.float_64, float64_val); - CORBA::Char char8_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_char8_value(char8_val, 12)); - EXPECT_EQ(input.char_8, char8_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint8_value(uint8_val, 4)); + EXPECT_EQ(CORBA::UInt8(100), uint8_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int16_value(5, CORBA::Short(1000))); + CORBA::Short short_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int16_value(short_val, 5)); + EXPECT_EQ(CORBA::Short(1000), short_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint16_value(6, CORBA::UShort(1111))); + CORBA::UShort ushort_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint16_value(ushort_val, 6)); + EXPECT_EQ(CORBA::UShort(1111), ushort_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int64_value(7, 12345ll)); + CORBA::LongLong ll_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int64_value(ll_val, 7)); + EXPECT_EQ(12345ll, ll_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint64_value(8, 54321ull)); + CORBA::ULongLong ull_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint64_value(ull_val, 8)); + EXPECT_EQ(54321ull, ull_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_float32_value(9, 3.0f)); + CORBA::Float float_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_float32_value(float_val, 9)); + EXPECT_EQ(3.0f, float_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_float64_value(10, 4.0)); + CORBA::Double double_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_float64_value(double_val, 10)); + EXPECT_EQ(4.0, double_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_char8_value(12, 'd')); + CORBA::Char char_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_char8_value(char_val, 12)); + EXPECT_EQ('d', char_val); + #ifdef DDS_HAS_WCHAR - CORBA::WChar char16_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_char16_value(char16_val, 13)); - EXPECT_EQ(input.char_16, char16_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_char16_value(13, L'D')); + CORBA::WChar wchar_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_char16_value(wchar_val, 13)); + EXPECT_EQ(L'D', wchar_val); #endif + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_byte_value(14, CORBA::Octet(0x6789))); CORBA::Octet byte_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_byte_value(byte_val, 14)); - EXPECT_EQ(input.byte, byte_val); - CORBA::Boolean bool_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_boolean_value(bool_val, 15)); - EXPECT_EQ(input._cxx_bool, bool_val); - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 16)); - CORBA::Long nested_long_val; - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(nested_long_val, 0)); - EXPECT_EQ(input.nested_struct.l, nested_long_val); - CORBA::String_var str; - EXPECT_EQ(DDS::RETCODE_OK, data.get_string_value(str, 17)); - EXPECT_STREQ(input.str.in(), str); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_byte_value(byte_val, 14)); + EXPECT_EQ(CORBA::Octet(0x6789), byte_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_boolean_value(15, false)); + CORBA::Boolean bool_val = false; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_boolean_value(bool_val, 15)); + EXPECT_EQ(false, bool_val); + + DDS::DynamicType_var dt = ddi.type(); + DDS::DynamicTypeMember_var dtm; + EXPECT_EQ(DDS::RETCODE_OK, dt->get_member(dtm, 16)); + DDS::MemberDescriptor_var md; + EXPECT_EQ(DDS::RETCODE_OK, dtm->get_descriptor(md)); + DDS::DynamicData_var nested_dd = new XTypes::DynamicDataImpl(md->type()); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->set_int32_value(0, 2222l)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_complex_value(16, nested_dd)); + DDS::DynamicData_var out_nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(out_nested_dd, 16)); + CORBA::Long nested_val; + EXPECT_EQ(DDS::RETCODE_OK, out_nested_dd->get_int32_value(nested_val, 0)); + EXPECT_EQ(2222l, nested_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_string_value(17, "my string")); + CORBA::String_var str_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_string_value(str_val, 17)); + EXPECT_STREQ("my string", str_val.in()); + #ifdef DDS_HAS_WCHAR - CORBA::WString_var wstr; - EXPECT_EQ(DDS::RETCODE_OK, data.get_wstring_value(wstr, 18)); - EXPECT_STREQ(input.wstr.in(), wstr); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_wstring_value(18, L"my wstring")); + CORBA::WString_var wstr_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_wstring_value(wstr_val, 18)); + EXPECT_STREQ(L"my wstring", wstr_val.in()); #endif } @@ -376,7 +492,7 @@ void verify_default_single_value_struct(DDS::DynamicType_var type, const DataVie CORBA::Octet byte_val; EXPECT_EQ(DDS::RETCODE_OK, data.get_byte_value(byte_val, 14)); EXPECT_EQ(CORBA::Octet(0), byte_val); - CORBA::Boolean bool_val; + CORBA::Boolean bool_val = false; EXPECT_EQ(DDS::RETCODE_OK, data.get_boolean_value(bool_val, 15)); EXPECT_EQ(CORBA::Boolean(false), bool_val); DDS::DynamicData_var nested_dd; @@ -438,14 +554,14 @@ void verify_int32_union(DDS::DynamicType_var dt, const DataView& expected_cdr) { XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_int32_value(1, CORBA::Long(10)); EXPECT_EQ(ret, DDS::RETCODE_OK); assert_serialized_data(64, data, expected_cdr); // A new discriminator value doesn't select the existing member. ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); // Change the selected member, then change it back to the original member. ret = data.set_uint32_value(2, CORBA::ULong(100)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -465,25 +581,41 @@ void verify_int32_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(active_val, 1)); EXPECT_EQ(CORBA::Long(10), active_val); CORBA::ULong not_selected; - EXPECT_EQ(DDS::RETCODE_ERROR, data.get_uint32_value(not_selected, 2)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.get_uint32_value(not_selected, 2)); +} + +void verify_int32_union_backing_store(XTypes::DynamicDataImpl& ddi) +{ + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_INT32, disc_val); + CORBA::Long int32_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(int32_val, 1)); + EXPECT_EQ(10l, int32_val); + CORBA::ULong uint32_val; + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, ddi.get_uint32_value(uint32_val, 2)); + + // Write then read again. + // Rewrite the discriminator that selects the same branch. + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_INT32, disc_val); + // Update the value of the same selected branch. + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int32_value(1, 20l)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(int32_val, 1)); + EXPECT_EQ(20l, int32_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_INT32, disc_val); + // Select a different branch. + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint32_value(2, 30ul)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint32_value(uint32_val, 2)); + EXPECT_EQ(30ul, uint32_val); } void verify_default_int32_union_mutable(DDS::DynamicType_var dt) { { - // Only set the discriminator. - XTypes::DynamicDataImpl data(dt); - DDS::ReturnCode_t ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); - unsigned char expected_cdr[] = { - 0x00,0x00,0x00,0x10, // +4=4 dheader - 0x20,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, // +8=12 discriminator - 0x20,0x00,0x00,0x01, 0x00,0x00,0x00,0x00 // +8=20 int_32 - }; - assert_serialized_data(64, data, expected_cdr); - } - { - // Only set the Int32 member. + // Set the Int32 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_int32_value(1, CORBA::Long(11)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -497,21 +629,21 @@ void verify_default_int32_union_mutable(DDS::DynamicType_var dt) { // Doesn't set anything. Default discriminator value selects the Int32 member. XTypes::DynamicDataImpl data(dt); + CORBA::Long default_disc_val; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(default_disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_INT32, default_disc_val); + CORBA::Long default_int32; + EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(default_int32, 1)); + EXPECT_EQ(CORBA::Long(0), default_int32); + CORBA::Boolean tmp_bool = false; + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.get_boolean_value(tmp_bool, 15)); + unsigned char expected_cdr[] = { 0x00,0x00,0x00,0x10, // +4=4 dheader 0x20,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, // +8=12 discriminator 0x20,0x00,0x00,0x01, 0x00,0x00,0x00,0x00 // +8=20 int_32 }; assert_serialized_data(64, data, expected_cdr); - - CORBA::Long disc_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); - EXPECT_EQ(E_INT32, disc_val); - CORBA::Long selected_val; - EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(selected_val, 1)); - EXPECT_EQ(CORBA::Long(0), selected_val); - CORBA::Boolean not_selected; - EXPECT_EQ(DDS::RETCODE_ERROR, data.get_boolean_value(not_selected, 15)); } } @@ -523,7 +655,7 @@ void verify_uint32_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT8); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_int32_value(1, CORBA::Long(10)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_uint32_value(2, CORBA::ULong(11)); @@ -536,7 +668,26 @@ void verify_uint32_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.get_uint32_value(uint32_val, 2)); EXPECT_EQ(CORBA::ULong(11), uint32_val); CORBA::Short int16_val; - EXPECT_EQ(DDS::RETCODE_ERROR, data.get_int16_value(int16_val, 5)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.get_int16_value(int16_val, 5)); +} + +void verify_uint32_union_backing_store(XTypes::DynamicDataImpl& ddi) +{ + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_UINT32, disc_val); + CORBA::ULong uint32_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint32_value(uint32_val, 2)); + EXPECT_EQ(11ul, uint32_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint32_value(2, 22ul)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint32_value(uint32_val, 2)); + EXPECT_EQ(22ul, uint32_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_UINT32, disc_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_float32_value(9, 3.0f)); + CORBA::Float float32_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_float32_value(float32_val, 9)); + EXPECT_EQ(3.0f, float32_val); } void verify_default_uint32_union_mutable(DDS::DynamicType_var dt) @@ -598,7 +749,7 @@ void verify_uint8_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint32_value(2, CORBA::ULong(10)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_uint8_value(4, CORBA::UInt8(0xaa)); @@ -615,7 +766,6 @@ void verify_uint8_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_uint8_union_mutable(DDS::DynamicType_var dt) { { - // Only set the UInt8 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_uint8_value(4, CORBA::UInt8(3)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -636,7 +786,7 @@ void verify_int16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint32_value(2, CORBA::ULong(10)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_int16_value(5, CORBA::Short(100)); @@ -653,7 +803,6 @@ void verify_int16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_int16_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Int16 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_int16_value(5, CORBA::Short(123)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -674,7 +823,7 @@ void verify_uint16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT64); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint64_value(8, CORBA::ULongLong(222)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_uint16_value(6, CORBA::UShort(99)); @@ -691,7 +840,6 @@ void verify_uint16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_uint16_union_mutable(DDS::DynamicType_var dt) { { - // Only set the UInt16 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_uint16_value(6, CORBA::UShort(121)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -712,7 +860,7 @@ void verify_int64_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint8_value(4, CORBA::UInt8(7)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_int64_value(7, CORBA::LongLong(0xbb)); @@ -729,7 +877,6 @@ void verify_int64_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_int64_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Int64 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_int64_value(7, CORBA::LongLong(3456)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -750,7 +897,7 @@ void verify_uint64_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint8_value(4, CORBA::UInt8(7)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_uint64_value(8, CORBA::ULongLong(0xcd)); @@ -767,7 +914,6 @@ void verify_uint64_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_uint64_union_mutable(DDS::DynamicType_var dt) { { - // Only set the UInt64 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_uint64_value(8, CORBA::ULongLong(3456)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -788,7 +934,7 @@ void verify_float32_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT64); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint8_value(4, CORBA::UInt8(7)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_float32_value(9, CORBA::Float(2.0f)); @@ -810,7 +956,7 @@ void verify_float64_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_CHAR8); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_char8_value(12, CORBA::Char('a')); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_float64_value(10, CORBA::Double(2.0)); @@ -832,7 +978,7 @@ void verify_char8_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_int32_value(1, CORBA::Long(22)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_char8_value(12, CORBA::Char('b')); @@ -849,7 +995,6 @@ void verify_char8_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_char8_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Char8 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_char8_value(12, CORBA::Char('d')); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -871,7 +1016,7 @@ void verify_char16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_int16_value(5, CORBA::Short(34)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_char16_value(13, CORBA::WChar(0x0062)); @@ -888,7 +1033,6 @@ void verify_char16_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_char16_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Char16 member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_char16_value(13, CORBA::WChar(0x0063)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -910,7 +1054,7 @@ void verify_byte_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_int16_value(5, CORBA::Short(34)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_byte_value(14, CORBA::Octet(0xab)); @@ -927,7 +1071,6 @@ void verify_byte_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_byte_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Byte member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_byte_value(14, CORBA::Octet(0xaa)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -948,7 +1091,7 @@ void verify_bool_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint16_value(6, CORBA::UShort(56)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_boolean_value(15, CORBA::Boolean(false)); @@ -957,7 +1100,7 @@ void verify_bool_union(DDS::DynamicType_var dt, const DataView& expected_cdr) CORBA::Long disc_val; EXPECT_EQ(DDS::RETCODE_OK, data.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); EXPECT_EQ(E_BOOL, disc_val); - CORBA::Boolean bool_val; + CORBA::Boolean bool_val = false; EXPECT_EQ(DDS::RETCODE_OK, data.get_boolean_value(bool_val, 15)); EXPECT_FALSE(bool_val); } @@ -965,7 +1108,6 @@ void verify_bool_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_bool_union_mutable(DDS::DynamicType_var dt) { { - // Only set the Boolean member. XTypes::DynamicDataImpl data(dt); DDS::ReturnCode_t ret = data.set_boolean_value(15, CORBA::Boolean(true)); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -986,7 +1128,7 @@ void verify_string_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint16_value(6, CORBA::UShort(56)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_string_value(16, "def"); @@ -1000,6 +1142,28 @@ void verify_string_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_STREQ("def", str); } +void verify_string_union_backing_store(XTypes::DynamicDataImpl& ddi) +{ + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_STRING8, disc_val); + CORBA::String_var str_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_string_value(str_val, 16)); + EXPECT_STREQ("abc", str_val.in()); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int32_value(XTypes::DISCRIMINATOR_ID, E_STRING8)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_string_value(16, "my new string")); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_STRING8, disc_val); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_string_value(str_val, 16)); + EXPECT_STREQ("my new string", str_val.in()); + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_char8_value(12, 'c')); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_CHAR8, disc_val); + CORBA::Char c8_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_char8_value(c8_val, 12)); + EXPECT_EQ('c', c8_val); +} + #ifdef DDS_HAS_WCHAR void verify_wstring_union(DDS::DynamicType_var dt, const DataView& expected_cdr) { @@ -1009,7 +1173,7 @@ void verify_wstring_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT64); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint32_value(2, CORBA::UInt32(4321)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_wstring_value(17, L"def"); @@ -1032,7 +1196,7 @@ void verify_enum_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); ret = data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT64); - EXPECT_EQ(ret, DDS::RETCODE_ERROR); + EXPECT_EQ(ret, DDS::RETCODE_PRECONDITION_NOT_MET); ret = data.set_uint32_value(2, CORBA::UInt32(4321)); EXPECT_EQ(ret, DDS::RETCODE_OK); ret = data.set_int32_value(18, CORBA::Long(10)); @@ -1049,7 +1213,6 @@ void verify_enum_union(DDS::DynamicType_var dt, const DataView& expected_cdr) void verify_default_enum_union_mutable(DDS::DynamicType_var dt) { { - // Only set the SomeEnum member. XTypes::DynamicDataImpl data(dt); EXPECT_EQ(data.set_int32_value(18, CORBA::Long(6)), DDS::RETCODE_OK); unsigned char expected_cdr[] = { @@ -1069,7 +1232,7 @@ void verify_int32s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_int32_values(1, int32s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_UINT32)); DDS::UInt32Seq uint32s; EXPECT_EQ(DDS::RETCODE_OK, data.set_uint32_values(2, uint32s)); EXPECT_EQ(DDS::RETCODE_OK, data.set_int32_values(1, int32s)); @@ -1090,6 +1253,37 @@ void verify_int32s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(CORBA::Long(5), val); } +void verify_int32s_union_backing_store(XTypes::DynamicDataImpl& ddi) +{ + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_INT32, disc_val); + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 1)); + EXPECT_EQ(3ul, nested_dd->get_item_count()); + CORBA::Long l_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(3l, l_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(4l, l_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, nested_dd->get_member_id_at_index(2))); + EXPECT_EQ(5l, l_val); + + // Select a different branch + DDS::UInt32Seq ulseq; + ulseq.length(2); + ulseq[0] = 123; + ulseq[1] = 456; + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_uint32_values(2, ulseq)); + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 2)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::ULong ul_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(ul_val, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(123ul, ul_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(ul_val, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(456ul, ul_val); +} + void verify_uint32s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) { XTypes::DynamicDataImpl data(dt); @@ -1098,7 +1292,7 @@ void verify_uint32s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_uint32_values(2, uint32s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT8)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT8)); DDS::UInt8Seq uint8s; set_uint8_sequence(uint8s); EXPECT_EQ(DDS::RETCODE_OK, data.set_uint8_values(4, uint8s)); @@ -1126,7 +1320,7 @@ void verify_int8s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_int8_values(3, int8s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); DDS::UInt8Seq uint8s; set_uint8_sequence(uint8s); EXPECT_EQ(DDS::RETCODE_OK, data.set_uint8_values(4, uint8s)); @@ -1156,7 +1350,7 @@ void verify_uint8s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_uint8_values(4, uint8s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32)); DDS::Float32Seq float32s; set_float32_sequence(float32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_float32_values(9, float32s)); @@ -1172,7 +1366,7 @@ void verify_int16s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_int16_values(5, int16s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT32)); DDS::Float32Seq float32s; set_float32_sequence(float32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_float32_values(9, float32s)); @@ -1188,7 +1382,7 @@ void verify_uint16s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_uint16_values(6, uint16s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT64)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_FLOAT64)); DDS::ByteSeq bytes; set_byte_sequence(bytes); EXPECT_EQ(DDS::RETCODE_OK, data.set_byte_values(14, bytes)); @@ -1204,7 +1398,7 @@ void verify_int64s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_int64_values(7, int64s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); DDS::BooleanSeq bools; set_bool_sequence(bools); EXPECT_EQ(DDS::RETCODE_OK, data.set_boolean_values(15, bools)); @@ -1220,7 +1414,7 @@ void verify_uint64s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_uint64_values(8, uint64s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT32)); DDS::BooleanSeq bools; set_bool_sequence(bools); EXPECT_EQ(DDS::RETCODE_OK, data.set_boolean_values(15, bools)); @@ -1236,7 +1430,7 @@ void verify_float32s_union(DDS::DynamicType_var dt, const DataView& expected_cdr EXPECT_EQ(DDS::RETCODE_OK, data.set_float32_values(9, float32s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16)); DDS::Int16Seq int16s; EXPECT_EQ(DDS::RETCODE_OK, data.set_int16_values(5, int16s)); EXPECT_EQ(DDS::RETCODE_OK, data.set_float32_values(9, float32s)); @@ -1251,7 +1445,7 @@ void verify_float64s_union(DDS::DynamicType_var dt, const DataView& expected_cdr EXPECT_EQ(DDS::RETCODE_OK, data.set_float64_values(10, float64s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_INT16)); DDS::Int16Seq int16s; EXPECT_EQ(DDS::RETCODE_OK, data.set_int16_values(5, int16s)); EXPECT_EQ(DDS::RETCODE_OK, data.set_float64_values(10, float64s)); @@ -1266,7 +1460,7 @@ void verify_char8s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_char8_values(12, char8s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BOOL)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BOOL)); DDS::Int16Seq int16s; EXPECT_EQ(DDS::RETCODE_OK, data.set_int16_values(5, int16s)); EXPECT_EQ(DDS::RETCODE_OK, data.set_char8_values(12, char8s)); @@ -1282,7 +1476,7 @@ void verify_char16s_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_char16_values(13, char16s)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BOOL)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BOOL)); DDS::Int32Seq int32s; set_int32_sequence(int32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_int32_values(1, int32s)); @@ -1299,7 +1493,7 @@ void verify_bytes_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_byte_values(14, bytes)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_STRING8)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_STRING8)); DDS::Int32Seq int32s; set_int32_sequence(int32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_int32_values(1, int32s)); @@ -1315,7 +1509,7 @@ void verify_bools_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_boolean_values(15, bools)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_STRING8)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_STRING8)); DDS::Int32Seq int32s; set_int32_sequence(int32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_int32_values(1, int32s)); @@ -1331,7 +1525,7 @@ void verify_strings_union(DDS::DynamicType_var dt, const DataView& expected_cdr) EXPECT_EQ(DDS::RETCODE_OK, data.set_string_values(16, strings)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BYTE)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BYTE)); DDS::UInt32Seq uint32s; set_uint32_sequence(uint32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_uint32_values(2, uint32s)); @@ -1339,6 +1533,19 @@ void verify_strings_union(DDS::DynamicType_var dt, const DataView& expected_cdr) assert_serialized_data(64, data, expected_cdr); } +void verify_strings_union_backing_store(XTypes::DynamicDataImpl& ddi) +{ + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_STRING8, disc_val); + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 16)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::String_var str_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_string_value(str_val, nested_dd->get_member_id_at_index(0))); + EXPECT_STREQ("abc", str_val.in()); +} + #ifdef DDS_HAS_WCHAR void verify_wstrings_union(DDS::DynamicType_var dt, const DataView& expected_cdr) { @@ -1348,7 +1555,7 @@ void verify_wstrings_union(DDS::DynamicType_var dt, const DataView& expected_cdr EXPECT_EQ(DDS::RETCODE_OK, data.set_wstring_values(17, wstrings)); assert_serialized_data(64, data, expected_cdr); - EXPECT_EQ(DDS::RETCODE_ERROR, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BYTE)); + EXPECT_EQ(DDS::RETCODE_PRECONDITION_NOT_MET, data.set_int32_value(XTypes::DISCRIMINATOR_ID, E_BYTE)); DDS::UInt32Seq uint32s; set_uint32_sequence(uint32s); EXPECT_EQ(DDS::RETCODE_OK, data.set_uint32_values(2, uint32s)); @@ -1357,6 +1564,217 @@ void verify_wstrings_union(DDS::DynamicType_var dt, const DataView& expected_cdr } #endif +void verify_reading_sequence_value_struct(XTypes::DynamicDataImpl& ddi) +{ + DDS::DynamicData_var nested_dd; + + // my_enums + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 0)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + DDS::MemberId id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(0ul, id); + CORBA::Long enum_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(enum_val, id)); + EXPECT_EQ(1l, enum_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(1ul, id); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(enum_val, id)); + EXPECT_EQ(2l, enum_val); + + DDS::DynamicData_var tmp_dd; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_complex_value(tmp_dd, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_int32_value(enum_val, XTypes::MEMBER_ID_INVALID)); + EXPECT_EQ(E_UINT32, enum_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_complex_value(tmp_dd, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_int32_value(enum_val, XTypes::MEMBER_ID_INVALID)); + EXPECT_EQ(E_INT8, enum_val); + + // int_32s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 1)); + EXPECT_EQ(3ul, nested_dd->get_item_count()); + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(0ul, id); + CORBA::Long int32_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, id)); + EXPECT_EQ(3l, int32_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, id)); + EXPECT_EQ(4l, int32_val); + id = nested_dd->get_member_id_at_index(2); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, id)); + EXPECT_EQ(5l, int32_val); + + // uint_32s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 2)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + id = nested_dd->get_member_id_at_index(0); + CORBA::ULong uint32_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(uint32_val, id)); + EXPECT_EQ(10ul, uint32_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(uint32_val, id)); + EXPECT_EQ(11ul, uint32_val); + + // int_8s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 3)); + EXPECT_EQ(3ul, nested_dd->get_item_count()); + CORBA::Int8 int8_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int8_value(int8_val, id)); + EXPECT_EQ(CORBA::Int8(12), int8_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int8_value(int8_val, id)); + EXPECT_EQ(CORBA::Int8(13), int8_val); + id = nested_dd->get_member_id_at_index(2); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int8_value(int8_val, id)); + EXPECT_EQ(CORBA::Int8(14), int8_val); + + // uint_8s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 4)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::UInt8 uint8_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint8_value(uint8_val, id)); + EXPECT_EQ(CORBA::UInt8(15), uint8_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint8_value(uint8_val, id)); + EXPECT_EQ(CORBA::UInt8(16), uint8_val); + + // int_16s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 5)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Short short_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int16_value(short_val, id)); + EXPECT_EQ(CORBA::Short(1), short_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int16_value(short_val, id)); + EXPECT_EQ(CORBA::Short(2), short_val); + + // uint_16s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 6)); + EXPECT_EQ(3ul, nested_dd->get_item_count()); + CORBA::UShort ushort_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint16_value(ushort_val, id)); + EXPECT_EQ(CORBA::UShort(3), ushort_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint16_value(ushort_val, id)); + EXPECT_EQ(CORBA::UShort(4), ushort_val); + id = nested_dd->get_member_id_at_index(2); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint16_value(ushort_val, id)); + EXPECT_EQ(CORBA::UShort(5), ushort_val); + + // int_64s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 7)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::LongLong ll_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int64_value(ll_val, id)); + EXPECT_EQ(CORBA::LongLong(0x7ffffffffffffffe), ll_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int64_value(ll_val, id)); + EXPECT_EQ(CORBA::LongLong(0x7fffffffffffffff), ll_val); + + // uint_64s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 8)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::ULongLong ull_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint64_value(ull_val, id)); + EXPECT_EQ(CORBA::ULongLong(0xffffffffffffffff), ull_val); + + // float_32s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 9)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::Float fl_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_float32_value(fl_val, id)); + EXPECT_EQ(1.0f, fl_val); + + // float_64s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 10)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::Double dbl_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_float64_value(dbl_val, id)); + EXPECT_EQ(1.0, dbl_val); + + // char_8s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 12)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Char c_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char8_value(c_val, id)); + EXPECT_EQ('a', c_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char8_value(c_val, id)); + EXPECT_EQ('b', c_val); + +#ifdef DDS_HAS_WCHAR + // char_16s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 13)); + EXPECT_EQ(3ul, nested_dd->get_item_count()); + CORBA::WChar wc_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char16_value(wc_val, id)); + EXPECT_EQ(CORBA::WChar(0x0063), wc_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char16_value(wc_val, id)); + EXPECT_EQ(CORBA::WChar(0x0064), wc_val); + id = nested_dd->get_member_id_at_index(2); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char16_value(wc_val, id)); + EXPECT_EQ(CORBA::WChar(0x0065), wc_val); +#endif + + // byte_s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 14)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Octet byte_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_byte_value(byte_val, id)); + EXPECT_EQ(0xee, byte_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_byte_value(byte_val, id)); + EXPECT_EQ(0xff, byte_val); + + // bool_s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 15)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::Boolean bool_val = false; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_boolean_value(bool_val, id)); + EXPECT_EQ(true, bool_val); + + // str_s + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 16)); + EXPECT_EQ(1ul, nested_dd->get_item_count()); + CORBA::String_var str_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_string_value(str_val, id)); + EXPECT_STREQ("abc", str_val.in()); + + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_complex_value(tmp_dd, 0)); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_char8_value(c_val, tmp_dd->get_member_id_at_index(0))); + EXPECT_EQ('a', c_val); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_char8_value(c_val, tmp_dd->get_member_id_at_index(1))); + EXPECT_EQ('b', c_val); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_char8_value(c_val, tmp_dd->get_member_id_at_index(2))); + EXPECT_EQ('c', c_val); + +#ifdef DDS_HAS_WCHAR + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 17)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::WString_var wstr_val; + id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_wstring_value(wstr_val, id)); + EXPECT_STREQ(L"def", wstr_val.in()); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_wstring_value(wstr_val, id)); + EXPECT_STREQ(L"ghi", wstr_val.in()); +#endif +} + template void verify_sequence_value_struct(DDS::DynamicType_var type, const DataView& expected_cdr) { @@ -1382,7 +1800,7 @@ void verify_sequence_value_struct(DDS::DynamicType_var type, const DataView& exp DDS::UInt32Seq uint_32s; set_uint32_sequence(uint_32s); ret = data.set_uint32_values(4, uint_32s); - EXPECT_NE(ret, DDS::RETCODE_OK); + EXPECT_EQ(ret, DDS::RETCODE_ERROR); ret = data.set_uint32_values(2, uint_32s); EXPECT_EQ(ret, DDS::RETCODE_OK); @@ -1519,64 +1937,45 @@ void verify_sequence_value_struct(DDS::DynamicType_var type, const DataView& exp } assert_serialized_data(512, data, expected_cdr); - // Getting values from sequence - DDS::DynamicData_var enums_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(enums_dd, 0)); - EXPECT_EQ(CORBA::ULong(2), enums_dd->get_item_count()); - CORBA::Long enum_val; - EXPECT_EQ(DDS::RETCODE_OK, enums_dd->get_int32_value(enum_val, 0)); - EXPECT_EQ(CORBA::Long(E_UINT32), enum_val); - EXPECT_EQ(DDS::RETCODE_OK, enums_dd->get_int32_value(enum_val, 1)); - EXPECT_EQ(CORBA::Long(E_INT8), enum_val); - DDS::DynamicData_var nested_dd; - EXPECT_EQ(DDS::RETCODE_OK, enums_dd->get_complex_value(nested_dd, 0)); - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(enum_val, XTypes::MEMBER_ID_INVALID)); - EXPECT_EQ(CORBA::Long(E_UINT32), enum_val); - EXPECT_EQ(DDS::RETCODE_OK, enums_dd->get_complex_value(nested_dd, 1)); - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(enum_val, XTypes::MEMBER_ID_INVALID)); - EXPECT_EQ(CORBA::Long(E_INT8), enum_val); - - DDS::DynamicData_var int32s_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(int32s_dd, 1)); - EXPECT_EQ(CORBA::ULong(3), int32s_dd->get_item_count()); - CORBA::Long int32_val; - EXPECT_EQ(DDS::RETCODE_OK, int32s_dd->get_int32_value(int32_val, 0)); - EXPECT_EQ(CORBA::Long(3), int32_val); - EXPECT_EQ(DDS::RETCODE_OK, int32s_dd->get_int32_value(int32_val, 1)); - EXPECT_EQ(CORBA::Long(4), int32_val); - EXPECT_EQ(DDS::RETCODE_OK, int32s_dd->get_int32_value(int32_val, 2)); - EXPECT_EQ(CORBA::Long(5), int32_val); - - DDS::DynamicData_var uint32s_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(uint32s_dd, 2)); - EXPECT_EQ(CORBA::ULong(2), uint32s_dd->get_item_count()); - CORBA::ULong uint32_val; - EXPECT_EQ(DDS::RETCODE_OK, uint32s_dd->get_uint32_value(uint32_val, 0)); - EXPECT_EQ(CORBA::ULong(10), uint32_val); - EXPECT_EQ(DDS::RETCODE_OK, uint32s_dd->get_uint32_value(uint32_val, 1)); - EXPECT_EQ(CORBA::ULong(11), uint32_val); + verify_reading_sequence_value_struct(data); +} - DDS::DynamicData_var bools_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(bools_dd, 15)); - EXPECT_EQ(CORBA::ULong(1), bools_dd->get_item_count()); - CORBA::Boolean bool_val; - EXPECT_EQ(DDS::RETCODE_OK, bools_dd->get_boolean_value(bool_val, 0)); - EXPECT_EQ(true, bool_val); +// Intended to test updating members from an instance with backing store. +// The new values invalidate the ones from the backing store. +void verify_modified_sequence_value_struct(XTypes::DynamicDataImpl& ddi) +{ + DDS::StringSeq strseq; + strseq.length(2); + strseq[0] = "my string1"; + strseq[1] = "my string2"; + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_string_values(16, strseq)); + + DDS::Int16Seq short_seq; + short_seq.length(2); + short_seq[0] = 256; + short_seq[1] = 512; + EXPECT_EQ(DDS::RETCODE_OK, ddi.set_int16_values(5, short_seq)); - DDS::DynamicData_var strs_dd; - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(strs_dd, 16)); - EXPECT_EQ(CORBA::ULong(1), strs_dd->get_item_count()); - CORBA::String_var str; - EXPECT_EQ(DDS::RETCODE_OK, strs_dd->get_string_value(str, 0)); - EXPECT_STREQ("abc", str); - EXPECT_EQ(DDS::RETCODE_OK, strs_dd->get_complex_value(nested_dd, 0)); - CORBA::Char char_val; - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char8_value(char_val, 0)); - EXPECT_EQ('a', char_val); - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char8_value(char_val, 1)); - EXPECT_EQ('b', char_val); - EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_char8_value(char_val, 2)); - EXPECT_EQ('c', char_val); + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 16)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + DDS::MemberId id = nested_dd->get_member_id_at_index(0); + CORBA::String_var str_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_string_value(str_val, id)); + EXPECT_STREQ("my string1", str_val.in()); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_string_value(str_val, id)); + EXPECT_STREQ("my string2", str_val.in()); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 5)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + id = nested_dd->get_member_id_at_index(0); + CORBA::Short short_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int16_value(short_val, id)); + EXPECT_EQ(CORBA::Short(256), short_val); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int16_value(short_val, id)); + EXPECT_EQ(CORBA::Short(512), short_val); } template @@ -1589,10 +1988,6 @@ void verify_sequence_value_struct_default(DDS::DynamicType_var type, const DataV EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 0)); EXPECT_EQ(CORBA::ULong(0), nested_dd->get_item_count()); - // int_32s - EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 1)); - EXPECT_EQ(CORBA::ULong(0), nested_dd->get_item_count()); - // uint_32s EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 2)); EXPECT_EQ(CORBA::ULong(0), nested_dd->get_item_count()); @@ -1609,7 +2004,20 @@ void verify_sequence_value_struct_default(DDS::DynamicType_var type, const DataV EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 16)); EXPECT_EQ(CORBA::ULong(0), nested_dd->get_item_count()); + // int_32s + EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(nested_dd, 1)); + EXPECT_EQ(CORBA::ULong(0), nested_dd->get_item_count()); + assert_serialized_data(512, data, expected_cdr); + + DDS::MemberId id = nested_dd->get_member_id_at_index(0); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->set_int32_value(id, 1l)); + id = nested_dd->get_member_id_at_index(1); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->set_int32_value(id, 2l)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Long val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(val, id)); + EXPECT_EQ(2l, val); } void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr) @@ -1636,10 +2044,8 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(ret, DDS::RETCODE_OK); // uint_32a - dtm = 0; ret = type->get_member(dtm, 1); EXPECT_EQ(ret, DDS::RETCODE_OK); - md = 0; ret = dtm->get_descriptor(md); EXPECT_EQ(ret, DDS::RETCODE_OK); DDS::DynamicData_var ulongarr_dd = new XTypes::DynamicDataImpl(md->type()); @@ -1655,10 +2061,8 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(ret, DDS::RETCODE_OK); // int_8a - dtm = 0; ret = type->get_member(dtm, 2); EXPECT_EQ(ret, DDS::RETCODE_OK); - md = 0; ret = dtm->get_descriptor(md); EXPECT_EQ(ret, DDS::RETCODE_OK); DDS::DynamicData_var int8arr_dd = new XTypes::DynamicDataImpl(md->type()); @@ -1684,7 +2088,7 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(CORBA::Long(0x12), int32_val); EXPECT_EQ(DDS::RETCODE_OK, int32a_dd->get_int32_value(int32_val, 1)); EXPECT_EQ(CORBA::Long(0x34), int32_val); - EXPECT_EQ(DDS::RETCODE_ERROR, int32a_dd->get_int32_value(int32_val, 2)); + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, int32a_dd->get_int32_value(int32_val, 2)); DDS::DynamicData_var nested_dd; EXPECT_EQ(DDS::RETCODE_OK, int32a_dd->get_complex_value(nested_dd, 0)); EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, XTypes::MEMBER_ID_INVALID)); @@ -1692,7 +2096,7 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(DDS::RETCODE_OK, int32a_dd->get_complex_value(nested_dd, 1)); EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(int32_val, XTypes::MEMBER_ID_INVALID)); EXPECT_EQ(CORBA::Long(0x34), int32_val); - EXPECT_EQ(DDS::RETCODE_ERROR, int32a_dd->get_complex_value(nested_dd, 2)); + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, int32a_dd->get_complex_value(nested_dd, 2)); DDS::DynamicData_var uint32a_dd; EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(uint32a_dd, 1)); @@ -1702,7 +2106,7 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(CORBA::ULong(0xff), uint32_val); EXPECT_EQ(DDS::RETCODE_OK, uint32a_dd->get_uint32_value(uint32_val, 1)); EXPECT_EQ(CORBA::ULong(0xff), uint32_val); - EXPECT_EQ(DDS::RETCODE_ERROR, uint32a_dd->get_uint32_value(uint32_val, 2)); + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, uint32a_dd->get_uint32_value(uint32_val, 2)); DDS::DynamicData_var int8a_dd; EXPECT_EQ(DDS::RETCODE_OK, data.get_complex_value(int8a_dd, 2)); @@ -1712,7 +2116,7 @@ void verify_array_struct(DDS::DynamicType_var type, const DataView& expected_cdr EXPECT_EQ(CORBA::Int8(1), int8_val); EXPECT_EQ(DDS::RETCODE_OK, int8a_dd->get_int8_value(int8_val, 1)); EXPECT_EQ(CORBA::Int8(2), int8_val); - EXPECT_EQ(DDS::RETCODE_ERROR, int8a_dd->get_int8_value(int8_val, 2)); + EXPECT_EQ(DDS::RETCODE_BAD_PARAMETER, int8a_dd->get_int8_value(int8_val, 2)); } void verify_array_struct_default(DDS::DynamicType_var type, const DataView& expected_cdr) @@ -1786,6 +2190,76 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToStruct) 0x00,0x00,0x00,0x06, 0,0x61,0,0x62,0,0x63 // +4+4+10=198 swtr }; verify_single_value_struct(dt, single_value_struct); + + // Test reading from the backing store. + ACE_Message_Block bs_msg(256); + bs_msg.copy((const char*)single_value_struct, sizeof single_value_struct); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + MutableSingleValueStruct input; + set_single_value_struct(input); + verify_reading_single_value_struct(input, ddi); + + // Update some members and read again. + // The updated members are written to and read from the container. + verify_modified_single_value_struct(ddi); +} + +// The backing store is initialized with a buffer that doesn't have data for some members. +// For example, when the buffer corresponds to a remote type that is not exactly the same +// as the local type that we are using to read the data. +TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_ReadValueFromBackingStore) +{ + const XTypes::TypeIdentifier& ti = DCPS::getCompleteTypeIdentifier(); + const XTypes::TypeMap& type_map = DCPS::getCompleteTypeMap(); + const XTypes::TypeMap::const_iterator it = type_map.find(ti); + EXPECT_TRUE(it != type_map.end()); + + XTypes::TypeLookupService tls; + tls.add(type_map.begin(), type_map.end()); + DDS::DynamicType_var dt = tls.complete_to_dynamic(it->second.complete, DCPS::GUID_t()); + + // The backing store doesn't have data for some members. + const unsigned char buffer[] = { + 0x00,0x00,0x00,0x92, // +4=4 dheader + 0x20,0x00,0x00,0x00, 0x00,0x00,0x00,0x03, // +4+4=12 my_enum + 0x20,0x00,0x00,0x01, 0x00,0x00,0x00,0x0a, // +4+4=20 int_32 + 0x20,0x00,0x00,0x02, 0x00,0x00,0x00,0x0b, // +4+4=28 uint_32 + //0x00,0x00,0x00,0x03, 0x05, (0), (0), (0), // +4+1+(3)=36 int_8 + 0x00,0x00,0x00,0x04, 0x06, (0), (0), (0), // +4+1+(3)=44 uint_8 + 0x10,0x00,0x00,0x05, 0x11,0x11, (0), (0), // +4+2+(2)=52 int_16 + //0x10,0x00,0x00,0x06, 0x22,0x22, (0), (0), // +4+2+(2)=60 uint_16 + 0x30,0x00,0x00,0x07, 0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // +4+8=72 int_64 + 0x30,0x00,0x00,0x08, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // +4+8=84 uint_64 + 0x20,0x00,0x00,0x09, 0x3f,0x80,0x00,0x00, // +4+4=92 float_32 + 0x30,0x00,0x00,0x0a, 0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, // +4+8=104 float_64 + 0x00,0x00,0x00,0x0c, 'a', (0), (0), (0), // +4+1+(3)=136 char_8 + 0x10,0x00,0x00,0x0d, 0x00,0x61, (0), (0), // +4+2+(2)=144 char_16 + //0x00,0x00,0x00,0x0e, 0xff, (0), (0), (0), // +4+1+(3)=152 byte + 0x00,0x00,0x00,0x0f, 0x01, (0), (0), (0), // +4+1+(3)=160 bool + 0x20,0x00,0x00,0x10, 0x00,0x00,0x00,0x0c, // +4+4=168 nested_struct + 0x30,0x00,0x00,0x11, 0x00,0x00,0x00,0x04, 'a','b','c','\0', // +4+8=180 str + 0x40,0x00,0x00,0x12, 0x00,0x00,0x00,0x0a, + 0x00,0x00,0x00,0x06, 0,0x61,0,0x62,0,0x63 // +4+4+10=198 swtr + }; + + ACE_Message_Block bs_msg(256); + bs_msg.copy((const char*)buffer, sizeof buffer); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + CORBA::Int8 int8_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int8_value(int8_val, 3)); + EXPECT_EQ(DDS::Int8(0), int8_val); + CORBA::UShort ushort_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_uint16_value(ushort_val, 6)); + CORBA::Octet byte_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_byte_value(byte_val, 14)); + CORBA::Long l_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int32_value(l_val, 1)); + EXPECT_EQ(10l, l_val); + CORBA::String_var str_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_string_value(str_val, 17)); + EXPECT_STREQ("abc", str_val.in()); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToStructDefault) @@ -1836,6 +2310,8 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) tls.add(type_map.begin(), type_map.end()); DDS::DynamicType_var dt = tls.complete_to_dynamic(it->second.complete, DCPS::GUID_t()); + // Test that it works for different selected branch. + // Some cases include tests for starting off with a backing store. { unsigned char expected_cdr[] = { 0x00,0x00,0x00,0x10, // +4=4 dheader @@ -1843,6 +2319,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) 0x20,0x00,0x00,0x01, 0x00,0x00,0x00,0x0a // +8=20 int_32 }; verify_int32_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -1851,6 +2334,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) 0x20,0x00,0x00,0x02, 0x00,0x00,0x00,0x0b // +8=20 uint_32 }; verify_uint32_union(dt, expected_cdr); + + // Test an instance starting with a backing store. + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_uint32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -1957,6 +2447,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) 0x30,0x00,0x00,0x10, 0x00,0x00,0x00,0x04,'a','b','c','\0' // +12=24 str }; verify_string_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_string_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -2047,6 +2544,16 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToStruct) 0,0,0,6, 0,0x67,0,0x68,0,0x69 // +38=346 wstr_s }; verify_sequence_value_struct(dt, sequence_struct); + + // Test reading from the backing store + ACE_Message_Block bs_msg(512); + bs_msg.copy((const char*)sequence_struct, sizeof sequence_struct); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_reading_sequence_value_struct(ddi); + + // Update some members and read again. + verify_modified_sequence_value_struct(ddi); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToStructDefault) @@ -2102,6 +2609,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToUnion) 0x40,0,0,1, 0,0,0,16, 0,0,0,3, 0,0,0,3, 0,0,0,4, 0,0,0,5 // int_32s }; verify_int32s_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32s_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -2228,6 +2742,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToUnion) 0x00,0x00,0x00,0x04,'a','b','c','\0' // str_s }; verify_strings_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_strings_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -2261,6 +2782,37 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToArray) 0x90,0x00,0x00,0x02, 0x01, 0x02 // +6=34 int_8a }; verify_array_struct(dt, expected_cdr); + + // Test reading from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 0)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Long l_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(CORBA::Long(0x12), l_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(CORBA::Long(0x34), l_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 1)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::ULong ul_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(ul_val, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(CORBA::ULong(0xff), ul_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(ul_val, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(CORBA::ULong(0xff), ul_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 2)); + EXPECT_EQ(2ul, nested_dd->get_item_count()); + CORBA::Int8 int8_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int8_value(int8_val, nested_dd->get_member_id_at_index(0))); + EXPECT_EQ(CORBA::Int8(0x01), int8_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int8_value(int8_val, nested_dd->get_member_id_at_index(1))); + EXPECT_EQ(CORBA::Int8(0x02), int8_val); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToArrayDefault) @@ -2401,6 +2953,39 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteStructWithNestedMembers) CORBA::ULong ulong_val; EXPECT_EQ(DDS::RETCODE_OK, inner_dd2->get_uint32_value(ulong_val, 1)); EXPECT_EQ(CORBA::ULong(0xffffffff), ulong_val); + + // Read from the backing store + ACE_Message_Block bs_msg(128); + bs_msg.copy((const char*)mutable_struct, sizeof mutable_struct); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + + CORBA::Int8 i_val; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int8_value(i_val, 4)); + EXPECT_EQ(CORBA::Int8(0x11), i_val); + + DDS::DynamicData_var nested_dd; + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 3)); + CORBA::Long disc_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(disc_val, XTypes::DISCRIMINATOR_ID)); + EXPECT_EQ(E_UINT32, disc_val); + CORBA::ULong ul_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_uint32_value(ul_val, 1)); + EXPECT_EQ(0xffffffff, ul_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int16_value(short_val, 2)); + EXPECT_EQ(CORBA::Short(10), short_val); + + EXPECT_EQ(DDS::RETCODE_OK, ddi.get_complex_value(nested_dd, 1)); + CORBA::Long l_val; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int32_value(l_val, 0)); + EXPECT_EQ(CORBA::Long(0x12345678), l_val); + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_int16_value(short_val, 2)); + EXPECT_EQ(CORBA::Short(0x4321), short_val); + DDS::DynamicData_var tmp_dd; + EXPECT_EQ(DDS::RETCODE_OK, nested_dd->get_complex_value(tmp_dd, 1)); + EXPECT_EQ(DDS::RETCODE_OK, tmp_dd->get_int32_value(l_val, 0)); + EXPECT_EQ(CORBA::Long(0x7fffffff), l_val); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteRecursiveStruct) @@ -2502,6 +3087,18 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToStruct) 0x00,0x00,0x00,0x06, 0,0x61,0,0x62,0,0x63 // +10=82 wstr }; verify_single_value_struct(dt, single_value_struct); + + // Read-only from the backing store. + ACE_Message_Block bs_msg(128); + bs_msg.copy((const char*)single_value_struct, sizeof single_value_struct); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + AppendableSingleValueStruct input; + set_single_value_struct(input); + verify_reading_single_value_struct(input, ddi); + + // Update some members and read again. + verify_modified_single_value_struct(ddi); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) @@ -2522,6 +3119,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) 0x00,0x00,0x00,0x0a // int_32 }; verify_int32_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -2530,6 +3134,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) 0x00,0x00,0x00,0x0b // uint_32 }; verify_uint32_union(dt, expected_cdr); + + // Test an instance starting with a backing store. + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_uint32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -2636,6 +3247,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) 0x00,0x00,0x00,0x04,'a','b','c','\0' // str }; verify_string_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_string_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -2692,6 +3310,16 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToStruct) 0,0,0,6, 0,0x67,0,0x68,0,0x69 // wstr_s }; verify_sequence_value_struct(dt, expected_cdr); + + // Test reading from the backing store + ACE_Message_Block bs_msg(512); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_reading_sequence_value_struct(ddi); + + // Update some members and read again. + verify_modified_sequence_value_struct(ddi); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToUnion) @@ -2712,6 +3340,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToUnion) 0,0,0,3, 0,0,0,3, 0,0,0,4, 0,0,0,5 // int_32s }; verify_int32s_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32s_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -2828,6 +3463,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToUnion) 0x00,0x00,0x00,0x04,'a','b','c','\0' // str_s }; verify_strings_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_strings_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -2963,6 +3605,18 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToStruct) 0x00,0x00,0x00,0x06, 0,0x61,0,0x62,0,0x63 // +10=78 wstr }; verify_single_value_struct(dt, single_value_struct); + + // Read-only from the backing store. + ACE_Message_Block bs_msg(128); + bs_msg.copy((const char*)single_value_struct, sizeof single_value_struct); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + FinalSingleValueStruct input; + set_single_value_struct(input); + verify_reading_single_value_struct(input, ddi); + + // Update some members and read again. + verify_modified_single_value_struct(ddi); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) @@ -2982,6 +3636,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) 0x00,0x00,0x00,0x0a // int_32 }; verify_int32_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -2989,6 +3650,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) 0x00,0x00,0x00,0x0b // uint_32 }; verify_uint32_union(dt, expected_cdr); + + // Test an instance starting with a backing store. + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_uint32_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -3082,6 +3750,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) 0x00,0x00,0x00,0x04,'a','b','c','\0' // str }; verify_string_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(32); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_string_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -3135,6 +3810,16 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToStruct) 0,0,0,6, 0,0x67,0,0x68,0,0x69 // wstr_s }; verify_sequence_value_struct(dt, expected_cdr); + + // Test reading from the backing store + ACE_Message_Block bs_msg(512); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_reading_sequence_value_struct(ddi); + + // Update some members and read again. + verify_modified_sequence_value_struct(ddi); } TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToUnion) @@ -3154,6 +3839,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToUnion) 0,0,0,3, 0,0,0,3, 0,0,0,4, 0,0,0,5 // int_32s }; verify_int32s_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_int32s_union_backing_store(ddi); } { unsigned char expected_cdr[] = { @@ -3256,6 +3948,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToUnion) 0x00,0x00,0x00,0x04,'a','b','c','\0' // str_s }; verify_strings_union(dt, expected_cdr); + + // Read from the backing store + ACE_Message_Block bs_msg(64); + bs_msg.copy((const char*)expected_cdr, sizeof expected_cdr); + DDS::DynamicData_ptr backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); + XTypes::DynamicDataImpl ddi(dt, backstore); + verify_strings_union_backing_store(ddi); } #ifdef DDS_HAS_WCHAR { @@ -3374,11 +4073,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteKeyOnly) static const DCPS::Encoding xcdr2_noswap(DCPS::Encoding::KIND_XCDR2); static const size_t expected_size = 1u; - EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2_noswap, DCPS::KeyOnly(data))); + DDS::DynamicData_ptr dd_ptr = &data; + const DCPS::KeyOnly key_only(dd_ptr); + EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2_noswap, key_only)); ACE_Message_Block buffer(expected_size); DCPS::Serializer ser(&buffer, xcdr2_noswap); - EXPECT_TRUE(ser << DCPS::KeyOnly(data)); + EXPECT_TRUE(ser << key_only); static const unsigned char expected_buffer[] = {expected_value}; EXPECT_PRED_FORMAT2(assert_DataView, expected_buffer, buffer); } @@ -3400,11 +4101,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteKeyOnly) EXPECT_EQ(DDS::RETCODE_OK, data.set_int16_value(2, expected_value)); static const size_t expected_size = 6u; - EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, DCPS::KeyOnly(data))); + DDS::DynamicData_ptr dd_ptr = &data; + const DCPS::KeyOnly key_only(dd_ptr); + EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, key_only)); ACE_Message_Block buffer(expected_size); DCPS::Serializer ser(&buffer, xcdr2); - EXPECT_TRUE(ser << DCPS::KeyOnly(data)); + EXPECT_TRUE(ser << key_only); static const unsigned char expected_buffer[] = { 0, 0, 0, 2, // DHEADER (expected_value >> 8) & 0xff, expected_value & 0xff, @@ -3444,11 +4147,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteKeyOnly) 0, 0, 0, expected_value & 0xff }; static const size_t expected_size = sizeof expected_buffer; - EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, DCPS::KeyOnly(data))); + DDS::DynamicData_ptr dd_ptr = &data; + const DCPS::KeyOnly key_only(dd_ptr); + EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, key_only)); ACE_Message_Block buffer(expected_size); DCPS::Serializer ser(&buffer, xcdr2); - EXPECT_TRUE(ser << DCPS::KeyOnly(data)); + EXPECT_TRUE(ser << key_only); EXPECT_PRED_FORMAT2(assert_DataView, expected_buffer, buffer); } @@ -3487,11 +4192,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, MutableArray_WriteKeyOnly) static_cast(expected_values[0]), static_cast(expected_values[1]) }; static const size_t expected_size = sizeof expected_buffer; - EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, DCPS::KeyOnly(data))); + DDS::DynamicData_ptr dd_ptr = &data; + const DCPS::KeyOnly key_only(dd_ptr); + EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, key_only)); ACE_Message_Block buffer(expected_size); DCPS::Serializer ser(&buffer, xcdr2); - EXPECT_TRUE(ser << DCPS::KeyOnly(data)); + EXPECT_TRUE(ser << key_only); EXPECT_PRED_FORMAT2(assert_DataView, expected_buffer, buffer); } @@ -3526,11 +4233,13 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Nested_WriteKeyOnly) 0, 0, 0, expected_value & 0xff }; static const size_t expected_size = sizeof expected_buffer; - EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, DCPS::KeyOnly(data))); + DDS::DynamicData_ptr dd_ptr = &data; + const DCPS::KeyOnly key_only(dd_ptr); + EXPECT_EQ(expected_size, DCPS::serialized_size(xcdr2, key_only)); ACE_Message_Block buffer(expected_size); DCPS::Serializer ser(&buffer, xcdr2); - EXPECT_TRUE(ser << DCPS::KeyOnly(data)); + EXPECT_TRUE(ser << key_only); EXPECT_PRED_FORMAT2(assert_DataView, expected_buffer, buffer); } diff --git a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp index 7ba0bb613e..46b8c3b6b8 100644 --- a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp +++ b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp @@ -878,7 +878,7 @@ TEST(dds_DCPS_XTypes_DynamicDataXcdrReadImpl, Mutable_ReadValueFromStruct) 0x00,0x00,0x00,0x06, 0,0x61,0,0x62,0,0x63 // +4+4+10=198 wstr }; ACE_Message_Block msg(1024); - msg.copy((const char*)single_value_struct, sizeof(single_value_struct)); + msg.copy((const char*)single_value_struct, sizeof single_value_struct); XTypes::DynamicDataXcdrReadImpl data(&msg, xcdr2, dt); verify_single_value_struct(&data);