diff --git a/dds/DCPS/XTypes/DynamicDataBase.cpp b/dds/DCPS/XTypes/DynamicDataBase.cpp index 4699ad18cc2..93d122c02ca 100644 --- a/dds/DCPS/XTypes/DynamicDataBase.cpp +++ b/dds/DCPS/XTypes/DynamicDataBase.cpp @@ -346,9 +346,94 @@ DDS::ReturnCode_t DynamicDataBase::unsupported_method(const char* method_name, b } #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE -DDS::ReturnCode_t DynamicDataBase::get_simple_value(DCPS::Value& /*value*/, DDS::MemberId /*id*/) +namespace { + template + DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DDS::DynamicData& dyn, + DDS::ReturnCode_t (DDS::DynamicData::* pmf)(T&, DDS::MemberId)) + { + T v; + const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); + if (ret == DDS::RETCODE_OK) { + value = v; + } + return ret; + } + + DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DDS::DynamicData& dyn, + DDS::ReturnCode_t (DDS::DynamicData::* pmf)(char*&, DDS::MemberId)) + { + CORBA::String_var v; + const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); + if (ret == DDS::RETCODE_OK) { + value = v.in(); + } + return ret; + } + + DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DDS::DynamicData& dyn, + DDS::ReturnCode_t (DDS::DynamicData::* pmf)(ACE_CDR::WChar*&, DDS::MemberId)) + { + CORBA::WString_var v; + const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); + if (ret == DDS::RETCODE_OK) { + value = v.in(); + } + return ret; + } +} + +DDS::ReturnCode_t DynamicDataBase::get_simple_value(DCPS::Value& value, DDS::MemberId id) { - return unsupported_method("DynamicDataBase::get_simple_value"); + DDS::DynamicType_var member_type; + DDS::ReturnCode_t rc = get_member_type(member_type, type_, id); + if (rc != DDS::RETCODE_OK) { + return rc; + } + const TypeKind member_kind = member_type->get_kind(); + switch (member_kind) { + case TK_BOOLEAN: + return get_some_value(value, id, *this, &DDS::DynamicData::get_boolean_value); + case TK_BYTE: + return get_some_value(value, id, *this, &DDS::DynamicData::get_byte_value); + case TK_INT8: + return get_some_value(value, id, *this, &DDS::DynamicData::get_int8_value); + case TK_INT16: + return get_some_value(value, id, *this, &DDS::DynamicData::get_int16_value); + case TK_INT32: + return get_some_value(value, id, *this, &DDS::DynamicData::get_int32_value); + case TK_INT64: + return get_some_value(value, id, *this, &DDS::DynamicData::get_int64_value); + case TK_UINT8: + return get_some_value(value, id, *this, &DDS::DynamicData::get_uint8_value); + case TK_UINT16: + return get_some_value(value, id, *this, &DDS::DynamicData::get_uint16_value); + case TK_UINT32: + return get_some_value(value, id, *this, &DDS::DynamicData::get_uint32_value); + case TK_UINT64: + return get_some_value(value, id, *this, &DDS::DynamicData::get_uint64_value); + case TK_FLOAT32: + return get_some_value(value, id, *this, &DDS::DynamicData::get_float32_value); + case TK_FLOAT64: + return get_some_value(value, id, *this, &DDS::DynamicData::get_float64_value); + case TK_FLOAT128: + return get_some_value(value, id, *this, &DDS::DynamicData::get_float128_value); + case TK_CHAR8: + return get_some_value(value, id, *this, &DDS::DynamicData::get_char8_value); + case TK_CHAR16: + return get_some_value(value, id, *this, &DDS::DynamicData::get_char16_value); + case TK_ENUM: + case TK_STRING8: + return get_some_value(value, id, *this, &DDS::DynamicData::get_string_value); + case TK_STRING16: + return get_some_value(value, id, *this, &DDS::DynamicData::get_wstring_value); + default: + if (log_level >= LogLevel::Notice) { + ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataBase::get_simple_value: " + "Member type %C is not supported by DCPS::Value\n", + typekind_to_string(member_kind))); + } + } + return DDS::RETCODE_ERROR; } #endif diff --git a/dds/DCPS/XTypes/DynamicDataImpl.cpp b/dds/DCPS/XTypes/DynamicDataImpl.cpp index a0f8487b833..931f37ae0ee 100644 --- a/dds/DCPS/XTypes/DynamicDataImpl.cpp +++ b/dds/DCPS/XTypes/DynamicDataImpl.cpp @@ -30,7 +30,7 @@ DynamicDataImpl::DynamicDataImpl(DDS::DynamicType_ptr type, DDS::DynamicData_ptr backing_store) : DynamicDataBase(type) , container_(type_, this) - , backing_store_(backing_store) + , backing_store_(DDS::DynamicData::_duplicate(backing_store)) { } @@ -2130,169 +2130,6 @@ DDS::ReturnCode_t DynamicDataImpl::set_wstring_value(DDS::MemberId id, const COR #endif } -#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE -DDS::ReturnCode_t DynamicDataImpl::get_simple_value_boolean(DCPS::Value& value, - DDS::MemberId id) const -{ - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - value = single_it->second.get().val_; - return DDS::RETCODE_OK; - } - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (complex_it != container_.complex_map_.end()) { - const DynamicDataImpl* inner_dd = dynamic_cast(complex_it->second.in()); - if (!inner_dd) { - return DDS::RETCODE_ERROR; - } - const_single_iterator inner_it = inner_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (inner_it != inner_dd->container_.single_map_.end()) { - value = inner_it->second.get().val_; - return DDS::RETCODE_OK; - } - } - return DDS::RETCODE_ERROR; -} - -DDS::ReturnCode_t DynamicDataImpl::get_simple_value_char(DCPS::Value& value, - DDS::MemberId id) const -{ - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - value = single_it->second.get().val_; - return DDS::RETCODE_OK; - } - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (complex_it != container_.complex_map_.end()) { - const DynamicDataImpl* inner_dd = dynamic_cast(complex_it->second.in()); - if (!inner_dd) { - return DDS::RETCODE_ERROR; - } - const_single_iterator inner_it = inner_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (inner_it != inner_dd->container_.single_map_.end()) { - value = inner_it->second.get().val_; - return DDS::RETCODE_OK; - } - } - return DDS::RETCODE_ERROR; -} - -template -DDS::ReturnCode_t DynamicDataImpl::get_simple_value_primitive(DCPS::Value& value, - DDS::MemberId id) const -{ - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - value = single_it->second.get(); - return DDS::RETCODE_OK; - } - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (complex_it != container_.complex_map_.end()) { - const DynamicDataImpl* inner_dd = dynamic_cast(complex_it->second.in()); - if (!inner_dd) { - return DDS::RETCODE_ERROR; - } - const_single_iterator inner_it = inner_dd->container_.single_map_.find(MEMBER_ID_INVALID); - if (inner_it != inner_dd->container_.single_map_.end()) { - value = inner_it->second.get(); - return DDS::RETCODE_OK; - } - } - return DDS::RETCODE_ERROR; -} - -DDS::ReturnCode_t DynamicDataImpl::get_simple_value_string(DCPS::Value& value, - DDS::MemberId id) const -{ - const_single_iterator single_it = container_.single_map_.find(id); - if (single_it != container_.single_map_.end()) { - value = single_it->second.get(); - return DDS::RETCODE_OK; - } - - const_complex_iterator complex_it = container_.complex_map_.find(id); - if (complex_it != container_.complex_map_.end()) { - // The string member has its own DynamicData object. - const DynamicDataImpl* str_dd = dynamic_cast(complex_it->second.in()); - char* str = 0; - if (!str_dd || !str_dd->read_basic_value(str)) { - return DDS::RETCODE_ERROR; - } - value = str; - return DDS::RETCODE_OK; - } - return DDS::RETCODE_ERROR; -} - -DDS::ReturnCode_t DynamicDataImpl::get_simple_value_enum(DCPS::Value& value, - DDS::MemberId id) const -{ - DDS::DynamicType_var mtype; - DDS::ReturnCode_t ret = get_member_type(mtype, type_, id); - if (ret != DDS::RETCODE_OK) { - return ret; - } - - DDS::Int32 enumAsInteger; - ret = get_enum_value(enumAsInteger, mtype, interface_from_this(), id); - if (ret != DDS::RETCODE_OK) { - return ret; - } - - DDS::String8_var str; - ret = get_enumerator_name(str, enumAsInteger, mtype); - if (ret != DDS::RETCODE_OK) { - return ret; - } - - value = str.in(); - return DDS::RETCODE_OK; -} - -DDS::ReturnCode_t DynamicDataImpl::get_simple_value(DCPS::Value& value, DDS::MemberId id) -{ - 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; - } - DDS::DynamicType_var member_type = get_base_type(md->type()); - const TypeKind member_kind = member_type->get_kind(); - switch (member_kind) { - case TK_BOOLEAN: - return get_simple_value_boolean(value, id); - case TK_INT32: - return get_simple_value_primitive(value, id); - case TK_UINT32: - return get_simple_value_primitive(value, id); - case TK_INT64: - return get_simple_value_primitive(value, id); - case TK_UINT64: - return get_simple_value_primitive(value, id); - case TK_CHAR8: - return get_simple_value_char(value, id); - case TK_FLOAT64: - return get_simple_value_primitive(value, id); - case TK_FLOAT128: - return get_simple_value_primitive(value, id); - case TK_STRING8: - return get_simple_value_string(value, id); - case TK_ENUM: - return get_simple_value_enum(value, id); - default: - if (log_level >= LogLevel::Notice) { - ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: DynamicDataImpl::get_simple_value:" - " Member type %C is not supported by DCPS::Value\n", - typekind_to_string(member_kind))); - } - } - return DDS::RETCODE_ERROR; -} -#endif - bool DynamicDataImpl::serialized_size(const DCPS::Encoding& enc, size_t& size, DCPS::Sample::Extent ext) const { DynamicDataImpl* non_const_this = const_cast(this); diff --git a/dds/DCPS/XTypes/DynamicDataImpl.h b/dds/DCPS/XTypes/DynamicDataImpl.h index c9fc3cd02b3..aa7f6625cfb 100644 --- a/dds/DCPS/XTypes/DynamicDataImpl.h +++ b/dds/DCPS/XTypes/DynamicDataImpl.h @@ -213,23 +213,10 @@ class OpenDDS_Dcps_Export DynamicDataImpl : public DynamicDataBase { DDS::ReturnCode_t set_wstring_values(DDS::MemberId id, const DDS::WstringSeq& value); -#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE - DDS::ReturnCode_t get_simple_value(DCPS::Value& value, DDS::MemberId id); -#endif - bool serialized_size(const DCPS::Encoding& enc, size_t& size, DCPS::Sample::Extent ext) const; bool serialize(DCPS::Serializer& ser, DCPS::Sample::Extent ext) const; private: -#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE - DDS::ReturnCode_t get_simple_value_boolean(DCPS::Value& value, DDS::MemberId id) const; - DDS::ReturnCode_t get_simple_value_char(DCPS::Value& value, DDS::MemberId id) const; - template - DDS::ReturnCode_t get_simple_value_primitive(DCPS::Value& value, DDS::MemberId id) const; - DDS::ReturnCode_t get_simple_value_string(DCPS::Value& value, DDS::MemberId id) const; - DDS::ReturnCode_t get_simple_value_enum(DCPS::Value& value, DDS::MemberId id) const; -#endif - CORBA::ULong get_string_item_count() const; CORBA::ULong get_sequence_item_count() const; bool has_member(DDS::MemberId id) const; diff --git a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp index 81e2cbad290..48433da6998 100644 --- a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp +++ b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.cpp @@ -2901,97 +2901,6 @@ bool DynamicDataXcdrReadImpl::check_xcdr1_mutable_i(DDS::DynamicType_ptr dt, Dyn return true; } -#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE -namespace { - template - DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn, - DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(T&, DDS::MemberId)) - { - T v; - const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); - if (ret == DDS::RETCODE_OK) { - value = v; - } - return ret; - } - - DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn, - DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(char*&, DDS::MemberId)) - { - CORBA::String_var v; - const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); - if (ret == DDS::RETCODE_OK) { - value = v.in(); - } - return ret; - } - - DDS::ReturnCode_t get_some_value(DCPS::Value& value, DDS::MemberId id, DynamicDataXcdrReadImpl& dyn, - DDS::ReturnCode_t (DynamicDataXcdrReadImpl::* pmf)(ACE_CDR::WChar*&, DDS::MemberId)) - { - CORBA::WString_var v; - const DDS::ReturnCode_t ret = (dyn.*pmf)(v, id); - if (ret == DDS::RETCODE_OK) { - value = v.in(); - } - return ret; - } -} - -DDS::ReturnCode_t DynamicDataXcdrReadImpl::get_simple_value(DCPS::Value& value, DDS::MemberId id) -{ - 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; - } - DDS::DynamicType_var member_type = get_base_type(md->type()); - const TypeKind member_kind = member_type->get_kind(); - switch (member_kind) { - case TK_BOOLEAN: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_boolean_value); - case TK_BYTE: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_byte_value); - case TK_INT8: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int8_value); - case TK_INT16: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int16_value); - case TK_INT32: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int32_value); - case TK_INT64: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_int64_value_impl); - case TK_UINT8: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint8_value); - case TK_UINT16: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint16_value); - case TK_UINT32: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint32_value); - case TK_UINT64: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_uint64_value_impl); - case TK_FLOAT32: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float32_value); - case TK_FLOAT64: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float64_value); - case TK_FLOAT128: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_float128_value); - case TK_CHAR8: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char8_value); - case TK_CHAR16: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_char16_value); - case TK_ENUM: - case TK_STRING8: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_string_value); - case TK_STRING16: - return get_some_value(value, id, *this, &DynamicDataXcdrReadImpl::get_wstring_value); - default: - return DDS::RETCODE_UNSUPPORTED; - } -} -#endif - #ifndef OPENDDS_SAFETY_PROFILE bool print_member(DDS::DynamicData_ptr dd, DCPS::String& type_string, DCPS::String& indent, MemberId member_id); diff --git a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.h b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.h index 339446ee6af..310c47cac35 100644 --- a/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.h +++ b/dds/DCPS/XTypes/DynamicDataXcdrReadImpl.h @@ -340,10 +340,6 @@ class OpenDDS_Dcps_Export DynamicDataXcdrReadImpl : public DynamicDataBase { CORBA::Boolean equals(DDS::DynamicData_ptr other); -#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE - DDS::ReturnCode_t get_simple_value(DCPS::Value& value, DDS::MemberId id); -#endif - bool serialized_size(const DCPS::Encoding&, size_t&, DCPS::Sample::Extent) const { // Not supported. diff --git a/dds/DCPS/XTypes/DynamicSample.cpp b/dds/DCPS/XTypes/DynamicSample.cpp index 1864abd5a5f..4390376d701 100644 --- a/dds/DCPS/XTypes/DynamicSample.cpp +++ b/dds/DCPS/XTypes/DynamicSample.cpp @@ -93,7 +93,8 @@ bool DynamicSample::deserialize(Serializer& ser) mb->wr_ptr(len); const DDS::DynamicType_var type = data_->type(); - data_ = new DynamicDataXcdrReadImpl(mb.get(), ser.encoding(), type, extent_); + DDS::DynamicData_var back = new DynamicDataXcdrReadImpl(mb.get(), ser.encoding(), type, extent_); + data_ = new DynamicDataImpl(type, back); return true; } diff --git a/docs/news.d/dynamic-read-write.rst b/docs/news.d/dynamic-read-write.rst new file mode 100644 index 00000000000..fb0ff9712e5 --- /dev/null +++ b/docs/news.d/dynamic-read-write.rst @@ -0,0 +1,5 @@ +.. news-prs: 04609 + +.. news-start-section: Additions +- Samples from DynamicDataReaders can be modified and passed to DynamicDataWriters. +.. news-end-section diff --git a/tests/DCPS/DynamicResponse/Common.h b/tests/DCPS/DynamicResponse/Common.h index e2a5d657ea6..1e40d2f81a8 100644 --- a/tests/DCPS/DynamicResponse/Common.h +++ b/tests/DCPS/DynamicResponse/Common.h @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -11,6 +12,15 @@ #include +const char ORIGIN[] = "origin"; +const char RESPONDER[] = "responder"; + +const char TOPICS_CREATED[] = "topics created"; +const char TOPICS_ANALYZED[] = "topics analyzed"; +const char ORIGIN_SAMPLES_AWAY[] = "origin samples away"; +const char RESPONDER_SAMPLES_AWAY[] = "responder samples away"; +const char DONE[] = "done"; + struct Test { const char* const name; int exit_status; @@ -114,6 +124,23 @@ struct Test { return dw2; } + template + typename DataReaderType::_var_type create_reader(DDS::Topic_var& topic) + { + DDS::DataReaderQos qos; + sub->get_default_datareader_qos(qos); + qos.history.kind = DDS::KEEP_ALL_HISTORY_QOS; + qos.reliability.kind = DDS::RELIABLE_RELIABILITY_QOS; + DDS::DataReader_var dr = + sub->create_datareader(topic, qos, 0, OpenDDS::DCPS::DEFAULT_STATUS_MASK); + typename DataReaderType::_var_type dr2 = DataReaderType::_narrow(dr); + if (!dr2) { + ACE_ERROR((LM_ERROR, "%C (%P|%t) ERROR: create_datareader failed!\n", name)); + exit_status = 1; + } + return dr2; + } + bool check_rc(DDS::ReturnCode_t rc, const std::string& what) { if (rc != DDS::RETCODE_OK) { @@ -127,14 +154,11 @@ struct Test { void wait_for(const std::string& actor, const std::string& what) { - ACE_DEBUG((LM_DEBUG, "%C is waiting for %C to post %C\n", name, actor.c_str(), what.c_str())); dcs->wait_for(name, actor, what); - ACE_DEBUG((LM_DEBUG, "%C is DONE waiting for %C to post %C\n", name, actor.c_str(), what.c_str())); } void post(const std::string& what) { - ACE_DEBUG((LM_DEBUG, "%C is posting %C\n", name, what.c_str())); dcs->post(name, what); } }; @@ -192,6 +216,21 @@ struct Topic { return true; } + bool write(const TopicType& msg) + { + return writer->write(msg, DDS::HANDLE_NIL) == DDS::RETCODE_OK; + } + + bool wait_dr_match(int count) const + { + DDS::DataReader_var dr = DDS::DataReader::_duplicate(reader); + if (Utils::wait_match(dr, count, Utils::EQ)) { + ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: main(): Error waiting for match for dr\n")); + return false; + } + return true; + } + bool read_multiple(SeqType& seq) { DDS::DataReader_var dr = DDS::DataReader::_duplicate(reader); diff --git a/tests/DCPS/DynamicResponse/Origin.cpp b/tests/DCPS/DynamicResponse/Origin.cpp index 0fa66d6e08f..2bd8d77bcc9 100644 --- a/tests/DCPS/DynamicResponse/Origin.cpp +++ b/tests/DCPS/DynamicResponse/Origin.cpp @@ -6,53 +6,81 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { - Test t("origin"); + Test t(ORIGIN); if (!t.init(argc, argv)) { - return 1; + return EXIT_FAILURE; } Topic ss_topic(t); if (!ss_topic.init()) { - return 1; + return EXIT_FAILURE; } Topic su_topic(t); if (!su_topic.init()) { - return 1; + return EXIT_FAILURE; } // This is just here to test that the responder can't get this type's // DynamicType because it's missing a complete TypeObject. Topic ssnc_topic(t); if (!ssnc_topic.init()) { - return 1; + return EXIT_FAILURE; } - t.post("ready"); + t.post(TOPICS_CREATED); - // TODO: Write samples to be changed by responder + t.wait_for(RESPONDER, TOPICS_ANALYZED); - t.wait_for("responder", "done"); + if (!ss_topic.wait_dr_match(2)) { + return EXIT_FAILURE; + } - SimpleStruct ss; - if (ss_topic.read_one(ss)) { - ACE_DEBUG((LM_DEBUG, "ss: string_value: %C\n", ss.string_value.in())); - if (std::strcmp(ss.string_value.in(), "Hello struct")) { - ACE_ERROR((LM_ERROR, "ERROR: Didn't get expected value from SimpleStruct\n")); - t.exit_status = 1; + if (!su_topic.wait_dr_match(2)) { + return EXIT_FAILURE; + } + + { + SimpleStruct ss; + ss.string_value = "initial"; + if (!ss_topic.write(ss)) { + return EXIT_FAILURE; } + + SimpleUnion su; + su.string_value("initial"); + if (!su_topic.write(su)) { + return EXIT_FAILURE; + } + } + + t.post(ORIGIN_SAMPLES_AWAY); + + t.wait_for(RESPONDER, RESPONDER_SAMPLES_AWAY); + + SimpleStruct ss; + if (!ss_topic.read_one(ss)) { + return EXIT_FAILURE; + } + + ACE_DEBUG((LM_DEBUG, "ss: string_value: %C\n", ss.string_value.in())); + if (std::strcmp(ss.string_value.in(), "Hello struct")) { + ACE_ERROR((LM_ERROR, "ERROR: Didn't get expected value from SimpleStruct\n")); + t.exit_status = 1; } SimpleUnion su; - if (su_topic.read_one(su)) { - ACE_DEBUG((LM_DEBUG, "su: string_value: %C\n", ss.string_value.in())); - if (std::strcmp(su.string_value(), "Hello union")) { - ACE_ERROR((LM_ERROR, "ERROR: Didn't get expected value from SimpleUnion\n")); - t.exit_status = 1; - } + if (!su_topic.read_one(su)) { + return EXIT_FAILURE; + } + + ACE_DEBUG((LM_DEBUG, "su: string_value: %C\n", su.string_value())); + if (std::strcmp(su.string_value(), "Hello union")) { + ACE_ERROR((LM_ERROR, "ERROR: Didn't get expected value from SimpleUnion\n")); + t.exit_status = 1; } - t.post("done"); + t.post(DONE); return t.exit_status; } diff --git a/tests/DCPS/DynamicResponse/README.rst b/tests/DCPS/DynamicResponse/README.rst new file mode 100644 index 00000000000..0466986cc79 --- /dev/null +++ b/tests/DCPS/DynamicResponse/README.rst @@ -0,0 +1,23 @@ +#################### +DynamicResponse Test +#################### + +This test creates two processes called the origin and the responder. + +The origin creates three topics +- a struct with CompleteTypeObject +- a union with CompleteTypeObject +- a struct without a CompleteTypeObject + +The availability of the CompleteTypeObject means a DynamicType is available in discovery. + +The basic flow is +1. The origin creates three topics. +2. The responder discovers the three topics and confirms if the DynamicType is available. +3. The origin writes samples. +4. The responder reads the (dynamic) samples, modifies them, and writes them. +5. The origin reads the samples. + +This test uses the file-based Distributed Condition Set. + +To run the test: `./run_test.pl` diff --git a/tests/DCPS/DynamicResponse/Responder.cpp b/tests/DCPS/DynamicResponse/Responder.cpp index 1bc978e9fc4..de197611466 100644 --- a/tests/DCPS/DynamicResponse/Responder.cpp +++ b/tests/DCPS/DynamicResponse/Responder.cpp @@ -21,6 +21,7 @@ struct DynamicTopic { DDS::DynamicType_var type; DDS::TypeSupport_var ts; DDS::Topic_var topic; + DDS::DynamicDataReader_var reader; DDS::DynamicDataWriter_var writer; }; @@ -28,7 +29,7 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { using OpenDDS::DCPS::retcode_to_string; - Test t("responder"); + Test t(RESPONDER); if (!t.init(argc, argv)) { return 1; } @@ -44,7 +45,7 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) topics["SimpleUnion"] = DynamicTopic(); topics["SimpleStructNotComplete"].get_dynamic_type_rc = DDS::RETCODE_NO_DATA; - t.wait_for("origin", "ready"); + t.wait_for(ORIGIN, TOPICS_CREATED); size_t found_count = 0; while (found_count < topics.size()) { @@ -85,10 +86,17 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) continue; } + topic.reader = t.create_reader(topic.topic); + DDS::DataReader_var dr = DDS::DataReader::_duplicate(topic.reader); + if (Utils::wait_match(dr, 1, Utils::EQ)) { + ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: main(): Error waiting for match for dr\n")); + continue; + } + topic.writer = t.create_writer(topic.topic); DDS::DataWriter_var dw = DDS::DataWriter::_duplicate(topic.writer); - if (Utils::wait_match(dw, 1, Utils::EQ)) { + if (Utils::wait_match(dw, 2, Utils::EQ)) { ACE_ERROR((LM_ERROR, "(%P|%t) ERROR: main(): Error waiting for match for dw\n")); continue; } @@ -97,12 +105,23 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) } ACE_DEBUG((LM_DEBUG, "Found all %B topics\n", topics.size())); + t.post(TOPICS_ANALYZED); + + t.wait_for(ORIGIN, ORIGIN_SAMPLES_AWAY); + for (DynamicTopicMap::iterator it = topics.begin(); it != topics.end(); ++it) { DynamicTopic& topic = it->second; if (topic.type) { - // TODO: Read First + DDS::DataReader_var dr = DDS::DataReader::_duplicate(topic.reader); + ACE_DEBUG((LM_DEBUG, "%C (%P|%t) waiting for sample on %C\n", RESPONDER, it->first.c_str())); + Utils::waitForSample(dr); + DDS::DynamicData_var dd; + DDS::SampleInfo info; + if (!t.check_rc(topic.reader->read_next_sample(dd, info), "read failed")) { + ACE_DEBUG((LM_ERROR, "ERROR: read_next_sample failed\n")); + t.exit_status = 1; + } - DDS::DynamicData_var dd = DDS::DynamicDataFactory::get_instance()->create_data(topic.type); const DDS::TypeKind tk = topic.type->get_kind(); if (!t.check_rc(dd->set_string_value(0, tk == OpenDDS::XTypes::TK_STRUCTURE ? "Hello struct" : "Hello union"), @@ -113,12 +132,17 @@ int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) if (!t.check_rc(topic.writer->write(dd, DDS::HANDLE_NIL), "write failed")) { t.exit_status = 1; } + const DDS::Duration_t duration = { 30, 0 }; + if (topic.writer->wait_for_acknowledgments(duration) != DDS::RETCODE_OK) { + ACE_DEBUG((LM_ERROR, "ERROR: wait_for_acknowledgments failed\n")); + t.exit_status = 1; + } } } - t.post("done"); + t.post(RESPONDER_SAMPLES_AWAY); - t.wait_for("origin", "done"); + t.wait_for(ORIGIN, DONE); return t.exit_status; } diff --git a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp index 905eb23ea40..27f505dac60 100644 --- a/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp +++ b/tests/unit-tests/dds/DCPS/XTypes/DynamicDataImpl.cpp @@ -2194,7 +2194,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); MutableSingleValueStruct input; set_single_value_struct(input); @@ -2245,7 +2245,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_ReadValueFromBackingStore) 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); CORBA::Int8 int8_val = 0; EXPECT_EQ(DDS::RETCODE_OK, ddi.get_int8_value(int8_val, 3)); @@ -2323,7 +2323,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32_union_backing_store(ddi); } @@ -2338,7 +2338,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_uint32_union_backing_store(ddi); } @@ -2451,7 +2451,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_string_union_backing_store(ddi); } @@ -2548,7 +2548,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_reading_sequence_value_struct(ddi); @@ -2613,7 +2613,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32s_union_backing_store(ddi); } @@ -2746,7 +2746,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_strings_union_backing_store(ddi); } @@ -2786,7 +2786,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteValueToArray) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); DDS::DynamicData_var nested_dd; @@ -2957,7 +2957,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Mutable_WriteStructWithNestedMembers) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); CORBA::Int8 i_val = 0; @@ -3091,7 +3091,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); AppendableSingleValueStruct input; set_single_value_struct(input); @@ -3123,7 +3123,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32_union_backing_store(ddi); } @@ -3138,7 +3138,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_uint32_union_backing_store(ddi); } @@ -3251,7 +3251,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_string_union_backing_store(ddi); } @@ -3314,7 +3314,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_reading_sequence_value_struct(ddi); @@ -3344,7 +3344,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32s_union_backing_store(ddi); } @@ -3467,7 +3467,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Appendable_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_strings_union_backing_store(ddi); } @@ -3609,7 +3609,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); FinalSingleValueStruct input; set_single_value_struct(input); @@ -3640,7 +3640,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32_union_backing_store(ddi); } @@ -3654,7 +3654,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_uint32_union_backing_store(ddi); } @@ -3754,7 +3754,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteValueToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_string_union_backing_store(ddi); } @@ -3814,7 +3814,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToStruct) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_reading_sequence_value_struct(ddi); @@ -3843,7 +3843,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_int32s_union_backing_store(ddi); } @@ -3952,7 +3952,7 @@ TEST(dds_DCPS_XTypes_DynamicDataImpl, Final_WriteSequenceToUnion) // 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); + DDS::DynamicData_var backstore = new XTypes::DynamicDataXcdrReadImpl(&bs_msg, xcdr2, dt); XTypes::DynamicDataImpl ddi(dt, backstore); verify_strings_union_backing_store(ddi); }