// IDL is as follows: // struct Struct_B { // boolean b; // without this it works okay // sequence ls; // }; // // struct Struct_C { // boolean b; // Struct_B sb; // }; // comment out next line and seq shows both values as expected #define USE_B #include #include #include // function to build the typecode for Struct_C DDS::TypeCode* Struct_CTypeCode(); // function to print data contents void PrintComplexDynamicData(const char* data_name, DDS::DynamicData& data); int main(int argc, char** argv) { DDS::TypeCode *typecode = Struct_CTypeCode(); // make a sample DDS_DynamicDataProperty_t default_props; DDS::DynamicData sample(typecode, default_props); const DDS::Long first = 888; const DDS::Long second = 999; // set sample.b DDS::ReturnCode_t rc = sample.set_boolean("b", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, DDS::BOOLEAN_TRUE); if (rc != DDS::RETCODE_OK) { std::cerr << "error setting boolean b" << std::endl; exit(1); } // set sample.sb.b #ifdef USE_B { DDS::DynamicData sample_sb(NULL, default_props); rc = sample.bind_complex_member(sample_sb, "sb", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (rc != DDS::RETCODE_OK) { std::cerr << "error binding sb" << std::endl; exit(1); } rc = sample_sb.set_boolean("b", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, DDS::BOOLEAN_TRUE); if (rc != DDS::RETCODE_OK) { std::cerr << "error setting boolean sample b" << std::endl; exit(1); } sample.unbind_complex_member(sample_sb); } #endif // set sample.sb.ls[0] { DDS::DynamicData sample_sb(NULL, default_props); rc = sample.bind_complex_member(sample_sb, "sb", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (rc != DDS::RETCODE_OK) { std::cerr << "error binding sb" << std::endl; exit(1); } DDS::DynamicData sample_sb_ls(NULL, default_props); rc = sample_sb.bind_complex_member(sample_sb_ls, "ls", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (rc != DDS::RETCODE_OK) { std::cerr << "error binding ls" << std::endl; exit(1); } rc = sample_sb_ls.set_long(0, 1, first); // no name, id 1 is index 0 if (rc != DDS::RETCODE_OK) { std::cerr << "error setting ls[0]" << std::endl; exit(1); } sample_sb.unbind_complex_member(sample_sb_ls); sample.unbind_complex_member(sample_sb); } // set sample.sb.ls[1] { DDS::DynamicData sample_sb(NULL, default_props); rc = sample.bind_complex_member(sample_sb, "sb", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (rc != DDS::RETCODE_OK) { std::cerr << "error binding sb" << std::endl; exit(1); } DDS::DynamicData sample_sb_ls(NULL, default_props); rc = sample_sb.bind_complex_member(sample_sb_ls, "ls", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED); if (rc != DDS::RETCODE_OK) { std::cerr << "error binding ls" << std::endl; exit(1); } rc = sample_sb_ls.set_long(0, 2, second); // no name, id 2 is index 1 if (rc != DDS::RETCODE_OK) { std::cerr << "error setting ls[1]" << std::endl; exit(1); } sample_sb.unbind_complex_member(sample_sb_ls); sample.unbind_complex_member(sample_sb); } PrintComplexDynamicData("sample", sample); exit(0); } DDS::TypeCode* LongSeqTypeCode() { DDS::TypeCodeFactory *factory = DDS::TypeCodeFactory::get_instance(); DDS::ExceptionCode_t exc; DDS::TypeCode *tc = factory->create_sequence_tc(2, factory->get_primitive_tc(DDS::TK_LONG), exc); return tc; } DDS::TypeCode* Struct_BTypeCode() { DDS::TypeCodeFactory *factory = DDS::TypeCodeFactory::get_instance(); DDS::StructMemberSeq members; DDS::ExceptionCode_t exc; DDS::TypeCode *tc = factory->create_struct_tc("Struct_B", members, exc); #ifdef USE_B tc->add_member("b", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS::TK_BOOLEAN), DDS_TYPECODE_NONKEY_MEMBER, exc); #endif tc->add_member("ls", DDS_TYPECODE_MEMBER_ID_INVALID, LongSeqTypeCode(), DDS_TYPECODE_NONKEY_MEMBER, exc); return tc; } DDS::TypeCode* Struct_CTypeCode() { DDS::TypeCodeFactory *factory = DDS::TypeCodeFactory::get_instance(); DDS::StructMemberSeq members; DDS::ExceptionCode_t exc; DDS::TypeCode *tc = factory->create_struct_tc("Struct_C", members, exc); tc->add_member("b", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS::TK_BOOLEAN), DDS_TYPECODE_NONKEY_MEMBER, exc); tc->add_member("sb", DDS_TYPECODE_MEMBER_ID_INVALID, Struct_BTypeCode(), DDS_TYPECODE_NONKEY_MEMBER, exc); return tc; } void PrintComplexDynamicData(const char* data_name, DDS::DynamicData& data) { DDS::UnsignedLong num_members = data.get_member_count(); //std::cout << "MEMBER COUNT " << num_members << std::endl; for (DDS::UnsignedLong i = 0; i < num_members; ++i) { DDS_DynamicDataMemberInfo info; if (data.get_member_info_by_index(info, i) != DDS::RETCODE_OK) { std::cerr << "! failed to get member info" << std::endl; break; } //std::cout << "MEMBER " << i << std::endl; std::string pathname; if (data_name) pathname = std::string(data_name); if (info.member_name) pathname += std::string(".") + std::string(info.member_name); switch (info.member_kind) { case DDS_TK_NULL: std::cout << info.member_kind << pathname << std::endl; break; case DDS_TK_SHORT: { DDS::Short val = 0; data.get_short(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_LONG: { DDS::Long val = 0; data.get_long(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_USHORT: { DDS::UnsignedShort val = 0; data.get_ushort(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_ULONG: { DDS::UnsignedLong val = 0; data.get_ulong(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_FLOAT: { DDS::Float val = 0.0; data.get_float(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_DOUBLE: { DDS::Double val = 0.0; data.get_double(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_BOOLEAN: { DDS::Boolean val = 0; data.get_boolean(val, info.member_name, info.member_id); if (val == DDS::BOOLEAN_FALSE) std::cout << info.member_kind << " " << pathname << " false" << std::endl; else std::cout << info.member_kind << " " << pathname << " true" << std::endl; } break; case DDS_TK_CHAR: { DDS::Char val = '\0'; data.get_char(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_OCTET: { DDS::Octet val = 0; data.get_octet(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << static_cast (val) << std::endl; } break; case DDS_TK_ALIAS: case DDS_TK_STRUCT: case DDS_TK_UNION: case DDS_TK_SEQUENCE: case DDS_TK_ARRAY: { DDS::DynamicDataProperty_t default_props; DDS::DynamicData mdata(NULL, default_props); // binding technique - avoids copying data.bind_complex_member(mdata, info.member_name, info.member_id); if (mdata.is_valid()) { PrintComplexDynamicData(pathname.c_str(), mdata); } else std::cerr << "invalid complex member " << pathname << std::endl; data.unbind_complex_member(mdata); } break; case DDS_TK_ENUM: { // enums are just handled dynamically as longs DDS::Long val = 0; data.get_long(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_STRING: { char *val = 0; DDS::UnsignedLong str_len = 0; data.get_string(val, &str_len, info.member_name, info.member_id); if (val) std::cout << info.member_kind << " " << pathname << " " << val << " len " << str_len << std::endl; else std::cout << info.member_kind << " " << pathname << " (null) len " << str_len << std::endl; } break; case DDS_TK_LONGLONG: { DDS::LongLong val = 0; data.get_longlong(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_ULONGLONG: { DDS::UnsignedLongLong val = 0; data.get_ulonglong(val, info.member_name, info.member_id); std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_LONGDOUBLE: { DDS::LongDouble val; data.get_longdouble(val, info.member_name, info.member_id); //std::cout << info.member_kind << " " << pathname << " " << val << std::endl; } break; case DDS_TK_WSTRING: case DDS_TK_VALUE: case DDS_TK_SPARSE: case DDS_TK_RAW_BYTES: case DDS_TK_RAW_BYTES_KEYED: case DDS_TK_FINAL_EXTENSIBILITY: case DDS_TK_MUTABLE_EXTENSIBILITY: default: std::cout << info.member_kind << " " << pathname << " print not supported" << std::endl; break; } } }