Skip to content

Commit

Permalink
Merge pull request OpenDDS#4500 from sonndinh/value-reader-writer-api
Browse files Browse the repository at this point in the history
Update ValueReader interface
  • Loading branch information
jrw972 authored Mar 11, 2024
2 parents 415170b + a291d38 commit 750e54a
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 120 deletions.
51 changes: 41 additions & 10 deletions dds/DCPS/JsonValueReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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; }
Expand Down Expand Up @@ -203,7 +205,7 @@ class JsonValueReader
};

template <typename InputStream>
bool JsonValueReader<InputStream>::begin_struct()
bool JsonValueReader<InputStream>::begin_struct(Extensibility /*extensibility*/)
{
peek();
return consume(kStartObject);
Expand All @@ -223,7 +225,7 @@ bool JsonValueReader<InputStream>::end_struct()
template <typename InputStream>
bool JsonValueReader<InputStream>::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;
Expand All @@ -235,14 +237,20 @@ bool JsonValueReader<InputStream>::begin_struct_member(XTypes::MemberId& member_
return false;
}

template <typename InputStream>
bool JsonValueReader<InputStream>::members_remaining()
{
return peek() == kKey;
}

template <typename InputStream>
bool JsonValueReader<InputStream>::end_struct_member()
{
return true;
}

template <typename InputStream>
bool JsonValueReader<InputStream>::begin_union()
bool JsonValueReader<InputStream>::begin_union(Extensibility /*extensibility*/)
{
peek();
return consume(kStartObject);
Expand Down Expand Up @@ -286,7 +294,7 @@ bool JsonValueReader<InputStream>::end_union_member()
}

template <typename InputStream>
bool JsonValueReader<InputStream>::begin_array()
bool JsonValueReader<InputStream>::begin_array(XTypes::TypeKind /*elem_kind*/)
{
peek();
return consume(kStartArray);
Expand All @@ -300,7 +308,7 @@ bool JsonValueReader<InputStream>::end_array()
}

template <typename InputStream>
bool JsonValueReader<InputStream>::begin_sequence()
bool JsonValueReader<InputStream>::begin_sequence(XTypes::TypeKind /*elem_kind*/)
{
peek();
return consume(kStartArray);
Expand Down Expand Up @@ -631,7 +639,6 @@ bool JsonValueReader<InputStream>::read_long_enum(ACE_CDR::Long& value, const En
return consume(kString);
}
return false;
break;
case kInt:
value = int_value_;
return consume(kInt);
Expand All @@ -643,6 +650,30 @@ bool JsonValueReader<InputStream>::read_long_enum(ACE_CDR::Long& value, const En
}
}

template <typename InputStream>
bool JsonValueReader<InputStream>::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<typename T, typename InputStream>
bool from_json(T& value, InputStream& stream)
{
Expand Down
33 changes: 27 additions & 6 deletions dds/DCPS/ValueCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "DCPS/DdsDcps_pch.h"

#include "ValueCommon.h"
#include "debug.h"

OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL

Expand Down Expand Up @@ -52,29 +53,33 @@ 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;
}
value = rtn;
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;
Expand All @@ -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);

Expand All @@ -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

Expand Down
13 changes: 7 additions & 6 deletions dds/DCPS/ValueCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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;

Expand All @@ -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
{
Expand All @@ -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
Expand Down
23 changes: 19 additions & 4 deletions dds/DCPS/ValueReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 <typename T>
bool read_enum(T& value, const EnumHelper& helper)
{
Expand All @@ -129,6 +131,19 @@ class OpenDDS_Dcps_Export ValueReader {
return true;
}

virtual bool read_bitmask(ACE_CDR::ULongLong& value, const BitmaskHelper& helper) = 0;

template <typename T>
bool read_bitmask(T& value, const BitmaskHelper& helper)
{
ACE_CDR::ULongLong ull_value;
if (!read_bitmask(ull_value, helper)) {
return false;
}
value = static_cast<T>(ull_value);
return true;
}

/// Array read operations
///@{
virtual bool read_boolean_array(ACE_CDR::Boolean* value, size_t length);
Expand Down
77 changes: 77 additions & 0 deletions dds/idl/dds_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<AST_PredefinedType*>(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 {
Expand Down
Loading

0 comments on commit 750e54a

Please sign in to comment.