From 02b2ba3c0177d6171bfd8b8720dd9be56113ff61 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Tue, 5 Mar 2024 11:19:25 -0600 Subject: [PATCH 1/5] Update ValueReader interface --- dds/DCPS/JsonValueReader.h | 51 +++++++++++++++---- dds/DCPS/ValueCommon.cpp | 32 +++++++++--- dds/DCPS/ValueCommon.h | 9 ++-- dds/DCPS/ValueReader.h | 23 +++++++-- dds/idl/value_reader_generator.cpp | 3 +- tests/unit-tests/dds/DCPS/JsonValueReader.cpp | 39 ++++++++++++-- 6 files changed, 129 insertions(+), 28 deletions(-) diff --git a/dds/DCPS/JsonValueReader.h b/dds/DCPS/JsonValueReader.h index 8834ab574e3..b839a4c1a51 100644 --- a/dds/DCPS/JsonValueReader.h +++ b/dds/DCPS/JsonValueReader.h @@ -51,21 +51,22 @@ class JsonValueReader reader_.IterativeParseInit(); } - bool begin_struct(); + bool begin_struct(Extensibility extensibility); bool end_struct(); bool begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper); + bool members_remaining(); bool end_struct_member(); - bool begin_union(); + bool begin_union(Extensibility extensibility); bool end_union(); bool begin_discriminator(); bool end_discriminator(); bool begin_union_member(); bool end_union_member(); - bool begin_array(); + bool begin_array(XTypes::TypeKind elem_kind); bool end_array(); - bool begin_sequence(); + bool begin_sequence(XTypes::TypeKind elem_kind, ACE_CDR::ULong& length); bool elements_remaining(); bool end_sequence(); bool begin_element(); @@ -92,6 +93,7 @@ class JsonValueReader bool read_string(std::string& value); bool read_wstring(std::wstring& value); bool read_long_enum(ACE_CDR::Long& value, const EnumHelper& helper); + bool read_bitmask(ACE_CDR::ULongLong& value, const BitmaskHelper& helper); bool Null() { token_type_ = kNull; return true; } bool Bool(bool b) { token_type_ = kBool; bool_value_ = b; return true; } @@ -203,7 +205,7 @@ class JsonValueReader }; template -bool JsonValueReader::begin_struct() +bool JsonValueReader::begin_struct(Extensibility /*extensibility*/) { peek(); return consume(kStartObject); @@ -223,7 +225,7 @@ bool JsonValueReader::end_struct() template bool JsonValueReader::begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper) { - while (peek() == kKey) { + while (members_remaining()) { consume(kKey); if (helper.get_value(member_id, key_value_.c_str())) { return true; @@ -235,6 +237,12 @@ bool JsonValueReader::begin_struct_member(XTypes::MemberId& member_ return false; } +template +bool JsonValueReader::members_remaining() +{ + return peek() == kKey; +} + template bool JsonValueReader::end_struct_member() { @@ -242,7 +250,7 @@ bool JsonValueReader::end_struct_member() } template -bool JsonValueReader::begin_union() +bool JsonValueReader::begin_union(Extensibility /*extensibility*/) { peek(); return consume(kStartObject); @@ -286,7 +294,7 @@ bool JsonValueReader::end_union_member() } template -bool JsonValueReader::begin_array() +bool JsonValueReader::begin_array(XTypes::TypeKind /*elem_kind*/) { peek(); return consume(kStartArray); @@ -300,7 +308,7 @@ bool JsonValueReader::end_array() } template -bool JsonValueReader::begin_sequence() +bool JsonValueReader::begin_sequence(XTypes::TypeKind /*elem_kind*/, ACE_CDR::ULong& /*length*/) { peek(); return consume(kStartArray); @@ -631,7 +639,6 @@ bool JsonValueReader::read_long_enum(ACE_CDR::Long& value, const En return consume(kString); } return false; - break; case kInt: value = int_value_; return consume(kInt); @@ -643,6 +650,30 @@ bool JsonValueReader::read_long_enum(ACE_CDR::Long& value, const En } } +template +bool JsonValueReader::read_bitmask(ACE_CDR::ULongLong& value, const BitmaskHelper& helper) +{ + switch (peek()) { + case kString: + value = string_to_bitmask(string_value_, helper); + return consume(kString); + case kInt: + value = int_value_; + return consume(kInt); + case kUint: + value = uint_value_; + return consume(kUint); + case kInt64: + value = int64_value_; + return consume(kInt64); + case kUint64: + value = uint64_value_; + return consume(kUint64); + default: + return false; + } +} + template bool from_json(T& value, InputStream& stream) { diff --git a/dds/DCPS/ValueCommon.cpp b/dds/DCPS/ValueCommon.cpp index 2b5db32a5f0..d6fb8166e75 100644 --- a/dds/DCPS/ValueCommon.cpp +++ b/dds/DCPS/ValueCommon.cpp @@ -52,13 +52,17 @@ void MapBitmaskHelper::pairs(const OPENDDS_VECTOR(Pair)& pairs) } } -bool MapBitmaskHelper::get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(const char*)& names) const +bool MapBitmaskHelper::get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(String)& names) const { ACE_CDR::ULongLong rtn = 0; for (size_t i = 0; i < names.size(); ++i) { - const ntp_iterator it = name_to_pos_.find(names.at(i)); + const ntp_iterator it = name_to_pos_.find(names.at(i).c_str()); if (it == name_to_pos_.end()) { - return false; + if (log_level >= LogLevel::Warning) { + ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: MapBitmaskHelper::get_value:" + " Ignore unknown flag: %C\n", names.at(i).c_str())); + } + continue; } rtn |= 1ull << it->second; } @@ -66,10 +70,10 @@ bool MapBitmaskHelper::get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR return true; } -size_t MapBitmaskHelper::get_names(OPENDDS_VECTOR(const char*)& names, ACE_CDR::ULongLong value) const +size_t MapBitmaskHelper::get_names(OPENDDS_VECTOR(String)& names, ACE_CDR::ULongLong value) const { size_t rtn_size = 0; - OPENDDS_VECTOR(const char*) rtn; + OPENDDS_VECTOR(String) rtn; for (ACE_CDR::UShort i = 0; i < bit_bound_; ++i) { const ptn_iterator it = pos_to_name_.find(i); if ((it != pos_to_name_.end()) && (value & 1ull << i)) { @@ -84,7 +88,7 @@ size_t MapBitmaskHelper::get_names(OPENDDS_VECTOR(const char*)& names, ACE_CDR:: String bitmask_to_string(ACE_CDR::ULongLong value, const BitmaskHelper& helper) { String rtn; - OPENDDS_VECTOR(const char*) names; + OPENDDS_VECTOR(String) names; const size_t size = helper.get_names(names, value); rtn.reserve(size); @@ -97,6 +101,22 @@ String bitmask_to_string(ACE_CDR::ULongLong value, const BitmaskHelper& helper) return rtn; } +ACE_CDR::ULongLong string_to_bitmask(const String& flags, const BitmaskHelper& helper) +{ + // The flags string has format "FLAG_A|FLAG_B|FLAG_C" + OPENDDS_VECTOR(String) names; + size_t start = 0, end = 0; + while ((end = flags.find("|", start)) != String::npos) { + names.push_back(flags.substr(start, end - start)); + start = end + 1; + } + names.push_back(flags.substr(start)); + + ACE_CDR::ULongLong rtn = 0; + helper.get_value(rtn, names); + return rtn; +} + } // namespace DCPS } // namespace OpenDDS diff --git a/dds/DCPS/ValueCommon.h b/dds/DCPS/ValueCommon.h index 7ea06ffdb2c..33445d50821 100644 --- a/dds/DCPS/ValueCommon.h +++ b/dds/DCPS/ValueCommon.h @@ -63,11 +63,11 @@ class OpenDDS_Dcps_Export ListEnumHelper : public EnumHelper { class BitmaskHelper { public: virtual ~BitmaskHelper() {} - virtual bool get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(const char*)& names) const = 0; + virtual bool get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(String)& names) const = 0; // Return an estimated length of a string constructed by the returned flag names // with a delimiter character between two consecutive flags. - virtual size_t get_names(OPENDDS_VECTOR(const char*)& names, ACE_CDR::ULongLong value) const = 0; + virtual size_t get_names(OPENDDS_VECTOR(String)& names, ACE_CDR::ULongLong value) const = 0; virtual XTypes::TypeKind get_equivalent_uint() const = 0; }; @@ -101,8 +101,8 @@ class OpenDDS_Dcps_Export MapBitmaskHelper : public BitmaskHelper { bit_bound_ = bound; } - bool get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(const char*)& names) const; - size_t get_names(OPENDDS_VECTOR(const char*)& names, ACE_CDR::ULongLong value) const; + bool get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR(String)& names) const; + size_t get_names(OPENDDS_VECTOR(String)& names, ACE_CDR::ULongLong value) const; XTypes::TypeKind get_equivalent_uint() const { @@ -117,6 +117,7 @@ class OpenDDS_Dcps_Export MapBitmaskHelper : public BitmaskHelper { }; OpenDDS_Dcps_Export String bitmask_to_string(ACE_CDR::ULongLong value, const BitmaskHelper& helper); +OpenDDS_Dcps_Export ACE_CDR::ULongLong string_to_bitmask(const String& flags, const BitmaskHelper& helper); } // namespace DCPS } // namespace OpenDDS diff --git a/dds/DCPS/ValueReader.h b/dds/DCPS/ValueReader.h index a2bf096a8d8..14a3d128381 100644 --- a/dds/DCPS/ValueReader.h +++ b/dds/DCPS/ValueReader.h @@ -71,21 +71,22 @@ class OpenDDS_Dcps_Export ValueReader { ValueReader() {} virtual ~ValueReader() {} - virtual bool begin_struct() = 0; + virtual bool begin_struct(Extensibility extensibility) = 0; virtual bool end_struct() = 0; virtual bool begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper) = 0; + virtual bool members_remaining() = 0; virtual bool end_struct_member() = 0; - virtual bool begin_union() = 0; + virtual bool begin_union(Extensibility extensibility) = 0; virtual bool end_union() = 0; virtual bool begin_discriminator() = 0; virtual bool end_discriminator() = 0; virtual bool begin_union_member() = 0; virtual bool end_union_member() = 0; - virtual bool begin_array() = 0; + virtual bool begin_array(XTypes::TypeKind elem_kind) = 0; virtual bool end_array() = 0; - virtual bool begin_sequence() = 0; + virtual bool begin_sequence(XTypes::TypeKind elem_kind, ACE_CDR::ULong& length) = 0; virtual bool elements_remaining() = 0; virtual bool end_sequence() = 0; virtual bool begin_element() = 0; @@ -118,6 +119,7 @@ class OpenDDS_Dcps_Export ValueReader { virtual bool read_wstring(WString& value) = 0; virtual bool read_long_enum(ACE_CDR::Long& value, const EnumHelper& helper) = 0; + template bool read_enum(T& value, const EnumHelper& helper) { @@ -129,6 +131,19 @@ class OpenDDS_Dcps_Export ValueReader { return true; } + virtual bool read_bitmask(ACE_CDR::ULongLong& value, const BitmaskHelper& helper) = 0; + + template + bool read_bitmask(T& value, const BitmaskHelper& helper) + { + ACE_CDR::ULongLong ull_value; + if (!read_bitmask(ull_value, helper)) { + return false; + } + value = static_cast(ull_value); + return true; + } + /// Array read operations ///@{ virtual bool read_boolean_array(ACE_CDR::Boolean* value, size_t length); diff --git a/dds/idl/value_reader_generator.cpp b/dds/idl/value_reader_generator.cpp index 22604270034..8330d59dadb 100644 --- a/dds/idl/value_reader_generator.cpp +++ b/dds/idl/value_reader_generator.cpp @@ -304,7 +304,8 @@ bool value_reader_generator::gen_struct(AST_Structure*, be_global->impl_ << " if (!value_reader.begin_struct()) return false;\n" " XTypes::MemberId member_id;\n" - " while (value_reader.begin_struct_member(member_id, helper)) {\n" + " while (value_reader.members_remaining()) {\n" + " if (!value_reader.begin_struct_member(member_id, helper)) return false;\n" " switch (member_id) {\n"; for (std::vector::const_iterator pos = fields.begin(), limit = fields.end(); diff --git a/tests/unit-tests/dds/DCPS/JsonValueReader.cpp b/tests/unit-tests/dds/DCPS/JsonValueReader.cpp index 3f931b1d5ee..ee4c065cd33 100644 --- a/tests/unit-tests/dds/DCPS/JsonValueReader.cpp +++ b/tests/unit-tests/dds/DCPS/JsonValueReader.cpp @@ -32,6 +32,7 @@ static const MemberId CHAR16_MEMBER_ID = 15; static const MemberId STRING_MEMBER_ID = 16; //static const MemberId WSTRING_MEMBER_ID = 17; static const MemberId ENUM_MEMBER_ID = 18; +static const MemberId BITMASK_MEMBER_ID = 19; static const ListMemberHelper::Pair member_pairs[] = { {"bool", BOOL_MEMBER_ID}, @@ -51,6 +52,7 @@ static const ListMemberHelper::Pair member_pairs[] = { {"char16", CHAR16_MEMBER_ID}, {"string", STRING_MEMBER_ID}, {"enum", ENUM_MEMBER_ID}, + {"bitmask", BITMASK_MEMBER_ID}, {0, 0} }; @@ -69,6 +71,16 @@ static const ListEnumHelper::Pair enum_pairs[] = { static const ListEnumHelper enum_helper(enum_pairs); +static const MapBitmaskHelper::Pair bitmask_pairs[] = { + {"FLAG_0", 0}, + {"FLAG_1", 1}, + {"FLAG_2", 2}, + {"FLAG_3", 3}, + {0, 0} +}; + +static const MapBitmaskHelper bitmask_helper(bitmask_pairs); + TEST(dds_DCPS_JsonValueReader, struct_empty) { const char json[] = "{}"; @@ -147,7 +159,8 @@ TEST(dds_DCPS_JsonValueReader, struct_max) "\"char8\":\"a\"," "\"char16\":\"a\"," "\"string\":\"a string\"," - "\"enum\":\"kValue1\"" + "\"enum\":\"kValue1\"," + "\"bitmask\":\"FLAG_0|FLAG_2|FLAG_3\"" "}"; StringStream ss(json); JsonValueReader<> jvr(ss); @@ -171,6 +184,7 @@ TEST(dds_DCPS_JsonValueReader, struct_max) ACE_CDR::WChar char16_value; std::string string_value; MyEnum enum_value; + ACE_CDR::ULongLong bitmask_value; EXPECT_TRUE(jvr.begin_struct()); @@ -280,6 +294,12 @@ TEST(dds_DCPS_JsonValueReader, struct_max) EXPECT_EQ(enum_value, kValue1); EXPECT_TRUE(jvr.end_struct_member()); + EXPECT_TRUE(jvr.begin_struct_member(member_id, member_helper)); + EXPECT_EQ(member_id, BITMASK_MEMBER_ID); + EXPECT_TRUE(jvr.read_bitmask(bitmask_value, bitmask_helper)); + EXPECT_EQ(bitmask_value, 13ull); + EXPECT_TRUE(jvr.end_struct_member()); + EXPECT_TRUE(jvr.end_struct()); } @@ -309,7 +329,7 @@ TEST(dds_DCPS_JsonValueReader, array_min) #if OPENDDS_HAS_EXPLICIT_INTS "-128,0," #endif - "-32768,0,-2147483648,0,-9223372036854775808,0,-1.25,-1.25,-1.25,\"a\",\"a\",\"a string\",\"kValue2\"]"; + "-32768,0,-2147483648,0,-9223372036854775808,0,-1.25,-1.25,-1.25,\"a\",\"a\",\"a string\",\"kValue2\",\"FLAG_2|FLAG_3\"]"; StringStream ss(json); JsonValueReader<> jvr(ss); ACE_CDR::Boolean bool_value; @@ -331,6 +351,7 @@ TEST(dds_DCPS_JsonValueReader, array_min) ACE_CDR::WChar char16_value; std::string string_value; MyEnum enum_value; + ACE_CDR::ULongLong bitmask_value; EXPECT_TRUE(jvr.begin_array()); @@ -423,6 +444,11 @@ TEST(dds_DCPS_JsonValueReader, array_min) EXPECT_EQ(enum_value, kValue2); EXPECT_TRUE(jvr.end_element()); + EXPECT_TRUE(jvr.begin_element()); + EXPECT_TRUE(jvr.read_bitmask(bitmask_value, bitmask_helper)); + EXPECT_EQ(bitmask_value, 12ull); + EXPECT_TRUE(jvr.end_element()); + EXPECT_TRUE(jvr.end_array()); } @@ -432,7 +458,7 @@ TEST(dds_DCPS_JsonValueReader, sequence_zero) #if OPENDDS_HAS_EXPLICIT_INTS "0,0," #endif - "0,0,0,0,0,0,0,0,0,\"\\u0000\",\"\\u0000\",\"\",\"kValue1\"]"; + "0,0,0,0,0,0,0,0,0,\"\\u0000\",\"\\u0000\",\"\",\"kValue1\",\"FLAG_0|FLAG_2\"]"; StringStream ss(json); JsonValueReader<> jvr(ss); ACE_CDR::Boolean bool_value; @@ -454,6 +480,7 @@ TEST(dds_DCPS_JsonValueReader, sequence_zero) ACE_CDR::WChar char16_value; std::string string_value; MyEnum enum_value; + ACE_CDR::ULongLong bitmask_value; EXPECT_TRUE(jvr.begin_sequence()); @@ -563,6 +590,12 @@ TEST(dds_DCPS_JsonValueReader, sequence_zero) EXPECT_EQ(enum_value, kValue1); EXPECT_TRUE(jvr.end_element()); + EXPECT_TRUE(jvr.elements_remaining()); + EXPECT_TRUE(jvr.begin_element()); + EXPECT_TRUE(jvr.read_bitmask(bitmask_value, bitmask_helper)); + EXPECT_EQ(bitmask_value, 5ull); + EXPECT_TRUE(jvr.end_element()); + EXPECT_FALSE(jvr.elements_remaining()); EXPECT_TRUE(jvr.end_sequence()); From 7375fdd0522078a1deef2397e98482305b4962c8 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Tue, 5 Mar 2024 13:50:12 -0600 Subject: [PATCH 2/5] Update opendds_idl and tests --- dds/DCPS/JsonValueReader.h | 10 +-- dds/DCPS/ValueCommon.cpp | 4 +- dds/DCPS/ValueCommon.h | 4 +- dds/DCPS/ValueReader.h | 2 +- dds/idl/dds_generator.h | 74 +++++++++++++++++++ dds/idl/value_reader_generator.cpp | 16 ++-- dds/idl/value_writer_generator.cpp | 74 ------------------- tests/unit-tests/dds/DCPS/JsonValueReader.cpp | 4 +- tests/unit-tests/dds/DCPS/ValueCommon.cpp | 13 ++-- 9 files changed, 103 insertions(+), 98 deletions(-) diff --git a/dds/DCPS/JsonValueReader.h b/dds/DCPS/JsonValueReader.h index b839a4c1a51..28c82d82b7e 100644 --- a/dds/DCPS/JsonValueReader.h +++ b/dds/DCPS/JsonValueReader.h @@ -51,22 +51,22 @@ class JsonValueReader reader_.IterativeParseInit(); } - bool begin_struct(Extensibility extensibility); + bool begin_struct(Extensibility extensibility = FINAL); bool end_struct(); bool begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper); bool members_remaining(); bool end_struct_member(); - bool begin_union(Extensibility extensibility); + bool begin_union(Extensibility extensibility = FINAL); bool end_union(); bool begin_discriminator(); bool end_discriminator(); bool begin_union_member(); bool end_union_member(); - bool begin_array(XTypes::TypeKind elem_kind); + bool begin_array(XTypes::TypeKind elem_kind = XTypes::TK_NONE); bool end_array(); - bool begin_sequence(XTypes::TypeKind elem_kind, ACE_CDR::ULong& length); + bool begin_sequence(XTypes::TypeKind elem_kind = XTypes::TK_NONE); bool elements_remaining(); bool end_sequence(); bool begin_element(); @@ -308,7 +308,7 @@ bool JsonValueReader::end_array() } template -bool JsonValueReader::begin_sequence(XTypes::TypeKind /*elem_kind*/, ACE_CDR::ULong& /*length*/) +bool JsonValueReader::begin_sequence(XTypes::TypeKind /*elem_kind*/) { peek(); return consume(kStartArray); diff --git a/dds/DCPS/ValueCommon.cpp b/dds/DCPS/ValueCommon.cpp index d6fb8166e75..99fad6a8625 100644 --- a/dds/DCPS/ValueCommon.cpp +++ b/dds/DCPS/ValueCommon.cpp @@ -56,7 +56,7 @@ bool MapBitmaskHelper::get_value(ACE_CDR::ULongLong& value, const OPENDDS_VECTOR { ACE_CDR::ULongLong rtn = 0; for (size_t i = 0; i < names.size(); ++i) { - const ntp_iterator it = name_to_pos_.find(names.at(i).c_str()); + const ntp_iterator it = name_to_pos_.find(names.at(i)); if (it == name_to_pos_.end()) { if (log_level >= LogLevel::Warning) { ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: MapBitmaskHelper::get_value:" @@ -78,7 +78,7 @@ size_t MapBitmaskHelper::get_names(OPENDDS_VECTOR(String)& names, ACE_CDR::ULong const ptn_iterator it = pos_to_name_.find(i); if ((it != pos_to_name_.end()) && (value & 1ull << i)) { rtn.push_back(it->second); - rtn_size += std::strlen(it->second) + 1; // +1 for a delimiter like a pipe ('|') character + rtn_size += it->second.size() + 1; // +1 for a delimiter like a pipe ('|') character } } names = rtn; diff --git a/dds/DCPS/ValueCommon.h b/dds/DCPS/ValueCommon.h index 33445d50821..51bf7a3ce07 100644 --- a/dds/DCPS/ValueCommon.h +++ b/dds/DCPS/ValueCommon.h @@ -79,8 +79,8 @@ class OpenDDS_Dcps_Export MapBitmaskHelper : public BitmaskHelper { ACE_CDR::UShort position; }; - typedef OPENDDS_MAP(ACE_CDR::UShort, const char*) PosToNameMap; - typedef OPENDDS_MAP(const char*, ACE_CDR::UShort) NameToPosMap; + typedef OPENDDS_MAP(ACE_CDR::UShort, String) PosToNameMap; + typedef OPENDDS_MAP(String, ACE_CDR::UShort) NameToPosMap; typedef PosToNameMap::const_iterator ptn_iterator; typedef NameToPosMap::const_iterator ntp_iterator; diff --git a/dds/DCPS/ValueReader.h b/dds/DCPS/ValueReader.h index 14a3d128381..434ab616826 100644 --- a/dds/DCPS/ValueReader.h +++ b/dds/DCPS/ValueReader.h @@ -86,7 +86,7 @@ class OpenDDS_Dcps_Export ValueReader { virtual bool begin_array(XTypes::TypeKind elem_kind) = 0; virtual bool end_array() = 0; - virtual bool begin_sequence(XTypes::TypeKind elem_kind, ACE_CDR::ULong& length) = 0; + virtual bool begin_sequence(XTypes::TypeKind elem_kind) = 0; virtual bool elements_remaining() = 0; virtual bool end_sequence() = 0; virtual bool begin_element() = 0; diff --git a/dds/idl/dds_generator.h b/dds/idl/dds_generator.h index 19e5842ea1b..44b1f7c987e 100644 --- a/dds/idl/dds_generator.h +++ b/dds/idl/dds_generator.h @@ -1356,6 +1356,80 @@ inline const char* get_shift_op(const std::string& s) return ""; } +inline std::string extensibility_kind(ExtensibilityKind ek) +{ + switch (ek) { + case extensibilitykind_final: + return "OpenDDS::DCPS::FINAL"; + case extensibilitykind_appendable: + return "OpenDDS::DCPS::APPENDABLE"; + case extensibilitykind_mutable: + return "OpenDDS::DCPS::MUTABLE"; + default: + return "invalid"; + } +} + +inline std::string type_kind(AST_Type* type) +{ + type = AstTypeClassification::resolveActualType(type); + switch (type->node_type()) { + case AST_Decl::NT_pre_defined: { + AST_PredefinedType* pt_type = dynamic_cast(type); + switch (pt_type->pt()) { + case AST_PredefinedType::PT_long: + return "XTypes::TK_INT32"; + case AST_PredefinedType::PT_ulong: + return "XTypes::TK_UINT32"; + case AST_PredefinedType::PT_longlong: + return "XTypes::TK_INT64"; + case AST_PredefinedType::PT_ulonglong: + return "XTypes::TK_UINT64"; + case AST_PredefinedType::PT_short: + return "XTypes::TK_INT16"; + case AST_PredefinedType::PT_ushort: + return "XTypes::TK_UINT16"; + case AST_PredefinedType::PT_float: + return "XTypes::TK_FLOAT32"; + case AST_PredefinedType::PT_double: + return "XTypes::TK_FLOAT64"; + case AST_PredefinedType::PT_longdouble: + return "XTypes::TK_FLOAT128"; + case AST_PredefinedType::PT_char: + return "XTypes::TK_CHAR8"; + case AST_PredefinedType::PT_wchar: + return "XTypes::TK_CHAR16"; + case AST_PredefinedType::PT_boolean: + return "XTypes::TK_BOOLEAN"; + case AST_PredefinedType::PT_octet: + return "XTypes::TK_BYTE"; + case AST_PredefinedType::PT_int8: + return "XTypes::TK_INT8"; + case AST_PredefinedType::PT_uint8: + return "XTypes::TK_UINT8"; + default: + return "XTypes::TK_NONE"; + } + } + case AST_Decl::NT_string: + return "XTypes::TK_STRING8"; + case AST_Decl::NT_wstring: + return "XTypes::TK_STRING16"; + case AST_Decl::NT_array: + return "XTypes::TK_ARRAY"; + case AST_Decl::NT_sequence: + return "XTypes::TK_SEQUENCE"; + case AST_Decl::NT_union: + return "XTypes::TK_UNION"; + case AST_Decl::NT_struct: + return "XTypes::TK_STRUCTURE"; + case AST_Decl::NT_enum: + return "XTypes::TK_ENUM"; + default: + return "XTypes::TK_NONE"; + } +} + /// Handling wrapping and unwrapping references in the wrapper types: /// NestedKeyOnly, IDL::DistinctType, and *_forany. struct RefWrapper { diff --git a/dds/idl/value_reader_generator.cpp b/dds/idl/value_reader_generator.cpp index 8330d59dadb..c12e706ae6f 100644 --- a/dds/idl/value_reader_generator.cpp +++ b/dds/idl/value_reader_generator.cpp @@ -72,10 +72,11 @@ namespace { // When we have a primitive type the last dimension is read using the read_*_array // operation, when we have a not primitive type the last dimension is read element by element // in a loop in the generated code + const std::string elem_kind = type_kind(array->base_type()); if ((primitive && (dim_idx < array->n_dims() - 1)) || (!primitive && (dim_idx < array->n_dims()))) { const size_t dim = array->dims()[dim_idx]->ev()->u.ulval; be_global->impl_ << - indent << "if (!value_reader.begin_array()) return false;\n" << + indent << "if (!value_reader.begin_array(" << elem_kind << ")) return false;\n" << indent << "for (" << (use_cxx11 ? "size_t " : "unsigned int ") << idx << " = 0; " << idx << " != " << dim << "; ++" << idx << ") {\n" << indent << " if (!value_reader.begin_element()) return false;\n"; @@ -91,7 +92,7 @@ namespace { const AST_PredefinedType::PredefinedType pt = dynamic_cast(actual)->pt(); be_global->impl_ << - indent << "if (!value_reader.begin_array()) return false;\n"; + indent << "if (!value_reader.begin_array(" << elem_kind << ")) return false;\n"; be_global->impl_ << indent << "if (!value_reader.read_" << primitive_type(pt) << "_array (" << expression << (use_cxx11 ? ".data()" : "") << ", " << dim << ")) return false;\n"; be_global->impl_ << @@ -109,8 +110,9 @@ namespace { // TODO: Take advantage of the size. const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11; const std::string indent(level * 2, ' '); + const std::string elem_tk = type_kind(sequence->base_type()); be_global->impl_ << - indent << "if (!value_reader.begin_sequence()) return false;\n" << + indent << "if (!value_reader.begin_sequence(" << elem_tk << ")) return false;\n" << indent << "for (" << (use_cxx11 ? "size_t " : "unsigned int ") << idx << " = 0; " "value_reader.elements_remaining(); ++" << idx << ") {\n"; if (use_cxx11) { @@ -264,7 +266,7 @@ bool value_reader_generator::gen_typedef(AST_Typedef*, return true; } -bool value_reader_generator::gen_struct(AST_Structure*, +bool value_reader_generator::gen_struct(AST_Structure* node, UTL_ScopedName* name, const std::vector& fields, AST_Type::SIZE_TYPE, @@ -301,8 +303,9 @@ bool value_reader_generator::gen_struct(AST_Structure*, ",{0,0}};\n" " ListMemberHelper helper(pairs);\n"; + const ExtensibilityKind ek = be_global->extensibility(node); be_global->impl_ << - " if (!value_reader.begin_struct()) return false;\n" + " if (!value_reader.begin_struct(" << extensibility_kind(ek) << ")) return false;\n" " XTypes::MemberId member_id;\n" " while (value_reader.members_remaining()) {\n" " if (!value_reader.begin_struct_member(member_id, helper)) return false;\n" @@ -351,8 +354,9 @@ bool value_reader_generator::gen_union(AST_Union* u, read.addArg("value", type_name + "&"); read.endArgs(); + const ExtensibilityKind ek = be_global->extensibility(u); be_global->impl_ << - " if (!value_reader.begin_union()) return false;\n" + " if (!value_reader.begin_union(" << extensibility_kind(ek) << ")) return false;\n" " if (!value_reader.begin_discriminator()) return false;\n" " {\n" " " << scoped(discriminator->name()) << " d;\n"; diff --git a/dds/idl/value_writer_generator.cpp b/dds/idl/value_writer_generator.cpp index fe89cbd34ad..50eb0af77a7 100644 --- a/dds/idl/value_writer_generator.cpp +++ b/dds/idl/value_writer_generator.cpp @@ -60,66 +60,6 @@ namespace { } } - std::string type_kind(AST_Type* type) - { - type = resolveActualType(type); - switch (type->node_type()) { - case AST_Decl::NT_pre_defined: { - AST_PredefinedType* pt_type = dynamic_cast(type); - switch (pt_type->pt()) { - case AST_PredefinedType::PT_long: - return "XTypes::TK_INT32"; - case AST_PredefinedType::PT_ulong: - return "XTypes::TK_UINT32"; - case AST_PredefinedType::PT_longlong: - return "XTypes::TK_INT64"; - case AST_PredefinedType::PT_ulonglong: - return "XTypes::TK_UINT64"; - case AST_PredefinedType::PT_short: - return "XTypes::TK_INT16"; - case AST_PredefinedType::PT_ushort: - return "XTypes::TK_UINT16"; - case AST_PredefinedType::PT_float: - return "XTypes::TK_FLOAT32"; - case AST_PredefinedType::PT_double: - return "XTypes::TK_FLOAT64"; - case AST_PredefinedType::PT_longdouble: - return "XTypes::TK_FLOAT128"; - case AST_PredefinedType::PT_char: - return "XTypes::TK_CHAR8"; - case AST_PredefinedType::PT_wchar: - return "XTypes::TK_CHAR16"; - case AST_PredefinedType::PT_boolean: - return "XTypes::TK_BOOLEAN"; - case AST_PredefinedType::PT_octet: - return "XTypes::TK_BYTE"; - case AST_PredefinedType::PT_int8: - return "XTypes::TK_INT8"; - case AST_PredefinedType::PT_uint8: - return "XTypes::TK_UINT8"; - default: - return "XTypes::TK_NONE"; - } - } - case AST_Decl::NT_string: - return "XTypes::TK_STRING8"; - case AST_Decl::NT_wstring: - return "XTypes::TK_STRING16"; - case AST_Decl::NT_array: - return "XTypes::TK_ARRAY"; - case AST_Decl::NT_sequence: - return "XTypes::TK_SEQUENCE"; - case AST_Decl::NT_union: - return "XTypes::TK_UNION"; - case AST_Decl::NT_struct: - return "XTypes::TK_STRUCTURE"; - case AST_Decl::NT_enum: - return "XTypes::TK_ENUM"; - default: - return "XTypes::TK_NONE"; - } - } - void array_helper(const std::string& expression, AST_Array* array, size_t dim_idx, const std::string& idx, int level) { @@ -305,20 +245,6 @@ namespace { " }\n"; return ""; } - - std::string extensibility_kind(ExtensibilityKind ek) - { - switch (ek) { - case extensibilitykind_final: - return "OpenDDS::DCPS::FINAL"; - case extensibilitykind_appendable: - return "OpenDDS::DCPS::APPENDABLE"; - case extensibilitykind_mutable: - return "OpenDDS::DCPS::MUTABLE"; - default: - return "invalid"; - } - } } bool value_writer_generator::gen_enum(AST_Enum*, diff --git a/tests/unit-tests/dds/DCPS/JsonValueReader.cpp b/tests/unit-tests/dds/DCPS/JsonValueReader.cpp index ee4c065cd33..67c2cb3c64e 100644 --- a/tests/unit-tests/dds/DCPS/JsonValueReader.cpp +++ b/tests/unit-tests/dds/DCPS/JsonValueReader.cpp @@ -79,7 +79,7 @@ static const MapBitmaskHelper::Pair bitmask_pairs[] = { {0, 0} }; -static const MapBitmaskHelper bitmask_helper(bitmask_pairs); +static const MapBitmaskHelper bitmask_helper(bitmask_pairs, 64, OpenDDS::XTypes::TK_UINT64); TEST(dds_DCPS_JsonValueReader, struct_empty) { @@ -611,7 +611,7 @@ namespace DCPS { bool vread(ValueReader& reader, MyStruct& s) { - if (!reader.begin_struct()) return false; + if (!reader.begin_struct(APPENDABLE)) return false; MemberId member_id; if (!reader.begin_struct_member(member_id, member_helper)) return false; if (member_id != BOOL_MEMBER_ID) return false; diff --git a/tests/unit-tests/dds/DCPS/ValueCommon.cpp b/tests/unit-tests/dds/DCPS/ValueCommon.cpp index 673509a27c3..cc5651d11e7 100644 --- a/tests/unit-tests/dds/DCPS/ValueCommon.cpp +++ b/tests/unit-tests/dds/DCPS/ValueCommon.cpp @@ -53,7 +53,7 @@ TEST(dds_DCPS_ValueCommon, MapBitmaskHelper) }; MapBitmaskHelper helper(pairs, 32, OpenDDS::XTypes::TK_UINT32); - OPENDDS_VECTOR(const char*) names(3); + OPENDDS_VECTOR(String) names(3); names[0] = "FLAG1"; names[1] = "FLAG4"; names[2] = "FLAG5"; // 00110010 0x32 @@ -63,13 +63,14 @@ TEST(dds_DCPS_ValueCommon, MapBitmaskHelper) EXPECT_EQ(0x32ull, value); names.push_back("FLAG3"); - EXPECT_FALSE(helper.get_value(value, names)); + EXPECT_TRUE(helper.get_value(value, names)); + EXPECT_EQ(0x32ull, value); value = 0x65; EXPECT_GT(helper.get_names(names, value), (size_t)0); EXPECT_EQ(names.size(), (size_t)4); - EXPECT_STREQ("FLAG0", names[0]); - EXPECT_STREQ("FLAG2", names[1]); - EXPECT_STREQ("FLAG5", names[2]); - EXPECT_STREQ("FLAG6", names[3]); + EXPECT_STREQ("FLAG0", names[0].c_str()); + EXPECT_STREQ("FLAG2", names[1].c_str()); + EXPECT_STREQ("FLAG5", names[2].c_str()); + EXPECT_STREQ("FLAG6", names[3].c_str()); } From f752b955574cd9a10b6b1c961883b5148b883f77 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Tue, 5 Mar 2024 15:17:28 -0600 Subject: [PATCH 3/5] Add a header --- dds/DCPS/ValueCommon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dds/DCPS/ValueCommon.cpp b/dds/DCPS/ValueCommon.cpp index 99fad6a8625..1b8351b5b1e 100644 --- a/dds/DCPS/ValueCommon.cpp +++ b/dds/DCPS/ValueCommon.cpp @@ -7,6 +7,8 @@ #include "ValueCommon.h" +#include + OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL namespace OpenDDS { From 425637db2b4f6aa7c0f4eb776e1c5d8b07616995 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Wed, 6 Mar 2024 09:02:12 -0600 Subject: [PATCH 4/5] Fix lint --- dds/DCPS/ValueCommon.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dds/DCPS/ValueCommon.cpp b/dds/DCPS/ValueCommon.cpp index 1b8351b5b1e..1506a26b0db 100644 --- a/dds/DCPS/ValueCommon.cpp +++ b/dds/DCPS/ValueCommon.cpp @@ -6,8 +6,7 @@ #include "DCPS/DdsDcps_pch.h" #include "ValueCommon.h" - -#include +#include "debug.h" OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL From 6caf7d36a076fd60b4eae1f45438cd332e1fbfa2 Mon Sep 17 00:00:00 2001 From: Son Dinh Date: Thu, 7 Mar 2024 00:14:35 -0600 Subject: [PATCH 5/5] From review --- tests/unit-tests/dds/DCPS/ValueCommon.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit-tests/dds/DCPS/ValueCommon.cpp b/tests/unit-tests/dds/DCPS/ValueCommon.cpp index cc5651d11e7..936cc853a4e 100644 --- a/tests/unit-tests/dds/DCPS/ValueCommon.cpp +++ b/tests/unit-tests/dds/DCPS/ValueCommon.cpp @@ -69,8 +69,8 @@ TEST(dds_DCPS_ValueCommon, MapBitmaskHelper) value = 0x65; EXPECT_GT(helper.get_names(names, value), (size_t)0); EXPECT_EQ(names.size(), (size_t)4); - EXPECT_STREQ("FLAG0", names[0].c_str()); - EXPECT_STREQ("FLAG2", names[1].c_str()); - EXPECT_STREQ("FLAG5", names[2].c_str()); - EXPECT_STREQ("FLAG6", names[3].c_str()); + EXPECT_EQ("FLAG0", names[0]); + EXPECT_EQ("FLAG2", names[1]); + EXPECT_EQ("FLAG5", names[2]); + EXPECT_EQ("FLAG6", names[3]); }