Skip to content

Commit

Permalink
Merge pull request OpenDDS#4554 from sonndinh/key-only-vread-vwrite
Browse files Browse the repository at this point in the history
Generate `vread` and `vwrite` for key-only samples
  • Loading branch information
jrw972 authored Apr 12, 2024
2 parents 9a90b8a + 379fe7e commit 5c8dd05
Show file tree
Hide file tree
Showing 11 changed files with 681 additions and 243 deletions.
39 changes: 32 additions & 7 deletions dds/DCPS/ValueDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "TypeSupportImpl.h"
#include "ValueReader.h"
#include "ValueWriter.h"
#include "Sample.h"
#include "debug.h"

OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL

Expand All @@ -21,8 +23,8 @@ struct OpenDDS_Dcps_Export ValueDispatcher {
virtual void* new_value() const = 0;
virtual void delete_value(void* data) const = 0;

virtual bool read(ValueReader& value_reader, void* data) const = 0;
virtual bool write(ValueWriter& value_writer, const void* data) const = 0;
virtual bool read(ValueReader& value_reader, void* data, Sample::Extent ext = Sample::Full) const = 0;
virtual bool write(ValueWriter& value_writer, const void* data, Sample::Extent ext = Sample::Full) const = 0;

virtual DDS::InstanceHandle_t register_instance_helper(DDS::DataWriter* dw, const void* data) const = 0;
virtual DDS::ReturnCode_t write_helper(DDS::DataWriter* dw, const void* data, DDS::InstanceHandle_t inst) const = 0;
Expand All @@ -45,17 +47,40 @@ struct ValueDispatcher_T : public virtual ValueDispatcher {
delete tbd;
}

virtual bool read(ValueReader& value_reader, void* data) const
typedef typename OpenDDS::DCPS::DDSTraits<T> TraitsType;

virtual bool read(ValueReader& value_reader, void* data, Sample::Extent ext = Sample::Full) const
{
return vread(value_reader, *static_cast<T*>(data));
switch (ext) {
case Sample::Full:
return vread(value_reader, *static_cast<T*>(data));
case Sample::KeyOnly:
return vread(value_reader, *static_cast<const KeyOnly<T>*>(data));
default:
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: ValueDispatcher_T<%C>::read:"
" Called with Sample::Extent NestedKeyOnly\n", TraitsType::type_name()));
}
return false;
}
}

virtual bool write(ValueWriter& value_writer, const void* data) const
virtual bool write(ValueWriter& value_writer, const void* data, Sample::Extent ext = Sample::Full) const
{
return vwrite(value_writer, *static_cast<const T*>(data));
switch (ext) {
case Sample::Full:
return vwrite(value_writer, *static_cast<const T*>(data));
case Sample::KeyOnly:
return vwrite(value_writer, *static_cast<const KeyOnly<const T>*>(data));
default:
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: ValueDispatcher_T<%C>::write:"
" Called with Sample::Extent NestedKeyOnly\n", TraitsType::type_name()));
}
return false;
}
}

typedef typename OpenDDS::DCPS::DDSTraits<T> TraitsType;
typedef typename TraitsType::DataWriterType DataWriterType;

virtual DDS::InstanceHandle_t register_instance_helper(DDS::DataWriter* dw, const void* data) const
Expand Down
16 changes: 8 additions & 8 deletions dds/DCPS/XTypes/DynamicDataImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5042,10 +5042,6 @@ bool serialized_size_dynamic_union(const Encoding& encoding, size_t& size,
using namespace OpenDDS::XTypes;
const DDS::DynamicType_var type = union_data->type();
const DDS::DynamicType_var base_type = get_base_type(type);
if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) {
// nothing is serialized (not even a delimiter) for key-only serialization when there is no @key
return true;
}

DDS::TypeDescriptor_var td;
if (!get_type_descriptor(base_type, td)) {
Expand All @@ -5058,6 +5054,10 @@ bool serialized_size_dynamic_union(const Encoding& encoding, size_t& size,
serialized_size_delimiter(encoding, size);
}

if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) {
return true;
}

// Discriminator
size_t mutable_running_total = 0;
DDS::DynamicType_var disc_type = get_base_type(td->discriminator_type());
Expand Down Expand Up @@ -5704,10 +5704,6 @@ bool serialize_dynamic_union(Serializer& ser, DDS::DynamicData_ptr data, Sample:
using namespace OpenDDS::XTypes;
const DDS::DynamicType_var type = data->type();
const DDS::DynamicType_var base_type = get_base_type(type);
if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) {
// nothing is serialized (not even a delimiter) for key-only serialization when there is no @key
return true;
}

DDS::TypeDescriptor_var td;
if (!get_type_descriptor(base_type, td)) {
Expand All @@ -5725,6 +5721,10 @@ bool serialize_dynamic_union(Serializer& ser, DDS::DynamicData_ptr data, Sample:
}
}

if (ext == Sample::KeyOnly && !has_explicit_keys(base_type)) {
return true;
}

// Discriminator
DDS::DynamicTypeMember_var dtm;
if (base_type->get_member(dtm, DISCRIMINATOR_ID) != DDS::RETCODE_OK) {
Expand Down
46 changes: 41 additions & 5 deletions dds/idl/dds_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -1445,8 +1445,27 @@ inline std::string type_kind(AST_Type* type)
}
}

inline
FieldFilter nested(FieldFilter filter_kind)
{
return filter_kind == FieldFilter_KeyOnly ? FieldFilter_NestedKeyOnly : filter_kind;
}

inline
bool has_discriminator(AST_Union* u, FieldFilter filter_kind)
{
return be_global->union_discriminator_is_key(u)
|| filter_kind == FieldFilter_NestedKeyOnly
|| filter_kind == FieldFilter_All;
}

// TODO: Add more fine-grained control of "const" string for the wrapper type and wrapped type.
// Currently, there is a single bool to control both; that is, either both are "const" or
// none is "const". But sometimes, we want something like "const KeyOnly<SampleType>&", and
// not "const KeyOnly<const SampleType>&" or "KeyOnly<SampleType>&".

/// Handling wrapping and unwrapping references in the wrapper types:
/// NestedKeyOnly, IDL::DistinctType, and *_forany.
/// NestedKeyOnly, KeyOnly, IDL::DistinctType, and *_forany.
struct RefWrapper {
const bool cpp11_;
AST_Type* const type_;
Expand All @@ -1456,6 +1475,7 @@ struct RefWrapper {
const std::string fieldref_;
const std::string local_;
bool is_const_;
FieldFilter field_filter_;
bool nested_key_only_;
bool classic_array_copy_;
bool dynamic_data_adapter_;
Expand All @@ -1470,6 +1490,7 @@ struct RefWrapper {
, to_wrap_(strip_shift_op(to_wrap))
, shift_op_(get_shift_op(to_wrap))
, is_const_(is_const)
, field_filter_(FieldFilter_All)
, nested_key_only_(false)
, classic_array_copy_(false)
, dynamic_data_adapter_(false)
Expand All @@ -1488,6 +1509,7 @@ struct RefWrapper {
, fieldref_(strip_shift_op(fieldref))
, local_(local)
, is_const_(is_const)
, field_filter_(FieldFilter_All)
, nested_key_only_(false)
, classic_array_copy_(false)
, dynamic_data_adapter_(false)
Expand All @@ -1508,8 +1530,9 @@ struct RefWrapper {
const bool forany = classic_array_copy_ || needs_forany(type_);
const bool distinct_type = needs_distinct_type(type_);
needs_dda_tag_ = dynamic_data_adapter_ && (forany || distinct_type);
nested_key_only_ = nested_key_only_ &&
needs_nested_key_only(typedef_node_ ? typedef_node_ : type_);
// If field_filter_ is set, this object is being used for vwrite or vread generator.
nested_key_only_ = field_filter_ == FieldFilter_NestedKeyOnly ||
(nested_key_only_ && needs_nested_key_only(typedef_node_ ? typedef_node_ : type_));
wrapped_type_name_ = type_name_;
bool by_ref = true;

Expand Down Expand Up @@ -1546,9 +1569,12 @@ struct RefWrapper {
ref_ = var_name;
}

if (field_filter_ == FieldFilter_KeyOnly) {
wrapped_type_name_ = std::string("KeyOnly<") + const_str + wrapped_type_name_ + ">";
}

if (nested_key_only_) {
wrapped_type_name_ =
std::string("NestedKeyOnly<") + const_str + wrapped_type_name_ + ">";
wrapped_type_name_ = std::string("NestedKeyOnly<") + const_str + wrapped_type_name_ + ">";
value_access_post_ = ".value" + value_access_post_;
const std::string nko_arg = "(" + ref_ + ")";
if (is_const_) {
Expand Down Expand Up @@ -1693,4 +1719,14 @@ struct RefWrapper {
}
};

inline
std::string key_only_type_name(AST_Type* type, const std::string& type_name,
FieldFilter field_filter, bool writing)
{
RefWrapper wrapper(type, type_name, "", writing ? true : false);
wrapper.field_filter_ = field_filter;
const bool has_wrapper = field_filter != FieldFilter_All;
return (has_wrapper && !writing ? "const " : "") + wrapper.done().wrapped_type_name();
}

#endif
46 changes: 24 additions & 22 deletions dds/idl/marshal_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1565,7 +1565,7 @@ bool marshal_generator::gen_typedef(AST_Typedef* node, UTL_ScopedName* name, AST

namespace {
// common to both fields (in structs) and branches (in unions)
string findSizeCommon(const std::string& indent, AST_Decl*field, const string& name,
string findSizeCommon(const std::string& indent, AST_Decl* field, const string& name,
AST_Type* type, const string& prefix, bool wrap_nested_key_only,
Intro& intro, const string& = "") // same sig as streamCommon
{
Expand Down Expand Up @@ -3379,9 +3379,9 @@ namespace {
serialized_size.addArg("uni", "const " + wrapper + "<const " + cxx + ">");
serialized_size.endArgs();

if (has_key) {
marshal_generator::generate_dheader_code(" serialized_size_delimiter(encoding, size);\n", not_final, false);
marshal_generator::generate_dheader_code(" serialized_size_delimiter(encoding, size);\n", not_final, false);

if (has_key) {
if (exten == extensibilitykind_mutable) {
be_global->impl_ <<
" size_t mutable_running_total = 0;\n"
Expand Down Expand Up @@ -3409,16 +3409,16 @@ namespace {
insertion.addArg("uni", wrapper + "<const " + cxx + ">");
insertion.endArgs();

if (has_key) {
be_global->impl_ <<
" const Encoding& encoding = strm.encoding();\n"
" ACE_UNUSED_ARG(encoding);\n";
marshal_generator::generate_dheader_code(
" serialized_size(encoding, total_size, uni);\n"
" if (!strm.write_delimiter(total_size)) {\n"
" return false;\n"
" }\n", not_final);
be_global->impl_ <<
" const Encoding& encoding = strm.encoding();\n"
" ACE_UNUSED_ARG(encoding);\n";
marshal_generator::generate_dheader_code(
" serialized_size(encoding, total_size, uni);\n"
" if (!strm.write_delimiter(total_size)) {\n"
" return false;\n"
" }\n", not_final);

if (has_key) {
// EMHEADER for discriminator
if (exten == extensibilitykind_mutable) {
be_global->impl_ <<
Expand Down Expand Up @@ -3452,16 +3452,16 @@ namespace {
extraction.addArg("uni", wrapper + "<" + cxx + ">");
extraction.endArgs();

if (has_key) {
// DHEADER
be_global->impl_ <<
" const Encoding& encoding = strm.encoding();\n"
" ACE_UNUSED_ARG(encoding);\n";
marshal_generator::generate_dheader_code(
" if (!strm.read_delimiter(total_size)) {\n"
" return false;\n"
" }\n", not_final);
// DHEADER
be_global->impl_ <<
" const Encoding& encoding = strm.encoding();\n"
" ACE_UNUSED_ARG(encoding);\n";
marshal_generator::generate_dheader_code(
" if (!strm.read_delimiter(total_size)) {\n"
" return false;\n"
" }\n", not_final);

if (has_key) {
if (exten == extensibilitykind_mutable) {
// EMHEADER for discriminator
be_global->impl_ <<
Expand Down Expand Up @@ -3739,7 +3739,9 @@ bool marshal_generator::gen_union(AST_Union* node, UTL_ScopedName* name,
}

gen_union_key_serializers(node, FieldFilter_NestedKeyOnly);
gen_union_key_serializers(node, FieldFilter_KeyOnly);
if (be_global->is_topic_type(node)) {
gen_union_key_serializers(node, FieldFilter_KeyOnly);
}

TopicKeys keys(node);
return generate_marshal_traits(node, cxx, exten, keys);
Expand Down
Loading

0 comments on commit 5c8dd05

Please sign in to comment.