diff --git a/dds/DCPS/JsonValueReader.h b/dds/DCPS/JsonValueReader.h index 8834ab574e3..28c82d82b7e 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 = 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(); + 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(); + bool begin_array(XTypes::TypeKind elem_kind = XTypes::TK_NONE); bool end_array(); - bool begin_sequence(); + bool begin_sequence(XTypes::TypeKind elem_kind = XTypes::TK_NONE); 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*/) { 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..1506a26b0db 100644 --- a/dds/DCPS/ValueCommon.cpp +++ b/dds/DCPS/ValueCommon.cpp @@ -6,6 +6,7 @@ #include "DCPS/DdsDcps_pch.h" #include "ValueCommon.h" +#include "debug.h" OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL @@ -52,13 +53,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)); 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,15 +71,15 @@ 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)) { 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; @@ -84,7 +89,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 +102,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 a704fdbbc01..e716d232cd6 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; }; @@ -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; @@ -102,8 +102,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 { @@ -118,6 +118,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..434ab616826 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) = 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/dds_generator.h b/dds/idl/dds_generator.h index 19e5842ea1b..b0017586b02 100644 --- a/dds/idl/dds_generator.h +++ b/dds/idl/dds_generator.h @@ -1356,6 +1356,83 @@ 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); + if (!pt_type) { + return "XTypes::TK_NONE"; + } + 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 22604270034..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,10 +303,12 @@ 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.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(); @@ -350,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 7e3bd3657b5..50eb0af77a7 100644 --- a/dds/idl/value_writer_generator.cpp +++ b/dds/idl/value_writer_generator.cpp @@ -60,69 +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); - if (!pt_type) { - return "XTypes::TK_NONE"; - } - 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) { @@ -308,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 3f931b1d5ee..67c2cb3c64e 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, 64, OpenDDS::XTypes::TK_UINT64); + 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()); @@ -578,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..936cc853a4e 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_EQ("FLAG0", names[0]); + EXPECT_EQ("FLAG2", names[1]); + EXPECT_EQ("FLAG5", names[2]); + EXPECT_EQ("FLAG6", names[3]); }