Skip to content

Commit e25a5ca

Browse files
authored
Merge pull request #4122 from mitza-oci/typesupport-data-conversions
IDL-accessible encoding conversions for topic types
2 parents 2f18b2c + 0233367 commit e25a5ca

20 files changed

+543
-23
lines changed

dds/DCPS/JsonValueReader.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
3232
namespace OpenDDS {
3333
namespace DCPS {
3434

35-
/// Convert values to JSON.
36-
/// Currently, this class does not produce value JSON nor does it adhere to the DDS JSON spec.
35+
/// Convert JSON to values.
3736
template <typename InputStream = rapidjson::StringStream>
3837
class JsonValueReader
3938
: public ValueReader,
@@ -162,6 +161,34 @@ class JsonValueReader
162161
return false;
163162
}
164163

164+
// consume tokens until peek() would return 'expected'
165+
// skips over objects and arrays atomically
166+
bool skip_to(TokenType expected)
167+
{
168+
int skip_level = 0;
169+
170+
while (peek() != kEnd) {
171+
if (skip_level == 0 && token_type_ == expected) {
172+
return true;
173+
}
174+
switch (token_type_) {
175+
case kStartArray:
176+
case kStartObject:
177+
++skip_level;
178+
break;
179+
case kEndArray:
180+
case kEndObject:
181+
--skip_level;
182+
break;
183+
default:
184+
break;
185+
}
186+
consume(token_type_);
187+
}
188+
189+
return false;
190+
}
191+
165192
TokenType token_type_;
166193
InputStream& input_stream_;
167194
rapidjson::Reader reader_;
@@ -185,15 +212,25 @@ bool JsonValueReader<InputStream>::begin_struct()
185212
template <typename InputStream>
186213
bool JsonValueReader<InputStream>::end_struct()
187214
{
188-
peek();
215+
if (peek() == kKey) { // skip any unknown members at the end
216+
if (!skip_to(kEndObject)) {
217+
return false;
218+
}
219+
}
189220
return consume(kEndObject);
190221
}
191222

192223
template <typename InputStream>
193224
bool JsonValueReader<InputStream>::begin_struct_member(XTypes::MemberId& member_id, const MemberHelper& helper)
194225
{
195-
if (peek() == kKey && helper.get_value(member_id, key_value_.c_str())) {
196-
return consume(kKey);
226+
while (peek() == kKey) {
227+
consume(kKey);
228+
if (helper.get_value(member_id, key_value_.c_str())) {
229+
return true;
230+
}
231+
if (!skip_to(kKey)) { // skip unknown members when expecting a known member
232+
return false;
233+
}
197234
}
198235
return false;
199236
}

dds/DCPS/TypeSupportImpl.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,29 @@ void TypeSupportImpl::get_type_from_type_lookup_service()
209209
}
210210
#endif
211211

212+
struct JsonRepresentationFormatImpl : JsonRepresentationFormat {
213+
};
214+
215+
struct CdrRepresentationFormatImpl : CdrRepresentationFormat {
216+
CdrRepresentationFormatImpl(DDS::DataRepresentationId_t)
217+
{}
218+
};
219+
220+
RepresentationFormat* TypeSupportImpl::make_format(DDS::DataRepresentationId_t representation)
221+
{
222+
switch (representation) {
223+
case JSON_DATA_REPRESENTATION:
224+
return new JsonRepresentationFormatImpl;
225+
case DDS::XCDR_DATA_REPRESENTATION:
226+
case DDS::XCDR2_DATA_REPRESENTATION:
227+
case UNALIGNED_CDR_DATA_REPRESENTATION:
228+
return new CdrRepresentationFormatImpl(representation);
229+
default:
230+
return 0;
231+
}
232+
}
233+
234+
212235
}
213236
}
214237

dds/DCPS/TypeSupportImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class OpenDDS_Dcps_Export TypeSupportImpl
140140

141141
void add_types(const XTypes::TypeLookupService_rch& tls) const;
142142

143+
RepresentationFormat* make_format(DDS::DataRepresentationId_t representation);
144+
143145
protected:
144146
#ifndef OPENDDS_SAFETY_PROFILE
145147
void get_type_from_type_lookup_service();

dds/DdsDcpsCore.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ module DDS {
590590
module OpenDDS {
591591
module DCPS {
592592
const DDS::DataRepresentationId_t UNALIGNED_CDR_DATA_REPRESENTATION = -12140;
593+
const DDS::DataRepresentationId_t JSON_DATA_REPRESENTATION = -12141;
593594
};
594595
};
595596

dds/DdsDcpsTypeSupportExt.idl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,27 @@
1313
module OpenDDS {
1414
module DCPS {
1515

16+
/**
17+
* The generated type-specific FooTypeSupport interfaces include encode_to_* and
18+
* decode_from_* operations that take an argument of type RepresentationFormat.
19+
* Use one of the derived interfaces of RepresentationFormat to specify the external
20+
* format type (JSON, CDR, etc.) and any details of the type conversion.
21+
*/
22+
local interface RepresentationFormat {
23+
};
24+
25+
/**
26+
* Create an instance by passing *CDR_DATA_REPRESENTATION to TypeSupport::make_format().
27+
*/
28+
local interface CdrRepresentationFormat : RepresentationFormat {
29+
};
30+
31+
/**
32+
* Create an instance by passing JSON_DATA_REPRESENTATION to TypeSupport::make_format().
33+
*/
34+
local interface JsonRepresentationFormat : RepresentationFormat {
35+
};
36+
1637
local interface TypeSupport : ::DDS::TypeSupport {
1738

1839
/**
@@ -46,6 +67,8 @@ module OpenDDS {
4667
/// Get allowed representations defined by IDL annotations
4768
void representations_allowed_by_type(
4869
inout ::DDS::DataRepresentationIdSeq seq);
70+
71+
RepresentationFormat make_format(in ::DDS::DataRepresentationId_t representation);
4972
};
5073
};
5174
};

dds/idl/IDLTemplate.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ typedef sequence<<%SCOPED%>> <%TYPE%><%SEQ%>;
99
* this interface.
1010
*/
1111
local interface <%TYPE%>TypeSupport : OpenDDS::DCPS::TypeSupport {
12+
13+
::DDS::ReturnCode_t encode_to_string(in <%SCOPED%> sample, out string encoded, in OpenDDS::DCPS::RepresentationFormat format);
14+
::DDS::ReturnCode_t encode_to_bytes(in <%SCOPED%> sample, out ::DDS::OctetSeq encoded, in OpenDDS::DCPS::RepresentationFormat format);
15+
16+
::DDS::ReturnCode_t decode_from_string(in string encoded, out <%SCOPED%> sample, in OpenDDS::DCPS::RepresentationFormat format);
17+
::DDS::ReturnCode_t decode_from_bytes(in ::DDS::OctetSeq encoded, out <%SCOPED%> sample, in OpenDDS::DCPS::RepresentationFormat format);
1218
};
1319

1420
/** DataWriter interface for <%TYPE%> data type.

dds/idl/langmap_generator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,7 @@ struct Cxx11Generator : GeneratorBase
14881488
{
14891489
be_global->lang_header_ <<
14901490
"};\n\n"
1491+
"using " << nm << "_out = " << nm << "&; // for tao_idl compatibility\n\n"
14911492
<< exporter() << "void swap(" << nm << "& lhs, " << nm << "& rhs);\n\n";
14921493
}
14931494

dds/idl/ts_generator.cpp

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,20 @@ bool ts_generator::generate_ts(AST_Decl* node, UTL_ScopedName* name)
9797
// error reported in read_template
9898
return false;
9999
}
100-
101-
AST_Structure* struct_node = 0;
102-
AST_Union* union_node = 0;
103100
if (!node || !name) {
104101
return false;
105102
}
103+
104+
AST_Structure* struct_node = 0;
105+
AST_Union* union_node = 0;
106+
AST_Type::SIZE_TYPE size_type;
106107
if (node->node_type() == AST_Decl::NT_struct) {
107108
struct_node = dynamic_cast<AST_Structure*>(node);
109+
size_type = struct_node->size_type();
108110
} else if (node->node_type() == AST_Decl::NT_union) {
109111
union_node = dynamic_cast<AST_Union*>(node);
112+
size_type = union_node->size_type();
110113
} else {
111-
return false;
112-
}
113-
114-
if (!struct_node && !union_node) {
115114
idl_global->err()->misc_error(
116115
"Could not cast AST Nodes to valid types", node);
117116
return false;
@@ -279,6 +278,11 @@ bool ts_generator::generate_ts(AST_Decl* node, UTL_ScopedName* name)
279278
" virtual const OpenDDS::XTypes::TypeIdentifier& getCompleteTypeIdentifier() const;\n"
280279
" virtual const OpenDDS::XTypes::TypeMap& getCompleteTypeMap() const;\n"
281280
"\n"
281+
" ::DDS::ReturnCode_t encode_to_string(const " << short_name << "& in, CORBA::String_out out, OpenDDS::DCPS::RepresentationFormat* format);\n"
282+
" ::DDS::ReturnCode_t encode_to_bytes(const " << short_name << "& in, ::DDS::OctetSeq_out out, OpenDDS::DCPS::RepresentationFormat* format);\n"
283+
" ::DDS::ReturnCode_t decode_from_string(const char* in, " << short_name << "_out out, OpenDDS::DCPS::RepresentationFormat* format);\n"
284+
" ::DDS::ReturnCode_t decode_from_bytes(const ::DDS::OctetSeq& in, " << short_name << "_out out, OpenDDS::DCPS::RepresentationFormat* format);\n"
285+
"\n"
282286
" static " << ts_short_name << "TypeSupport::_ptr_type _narrow(CORBA::Object_ptr obj);\n"
283287
"};\n\n";
284288
}
@@ -378,7 +382,62 @@ bool ts_generator::generate_ts(AST_Decl* node, UTL_ScopedName* name)
378382
" static OpenDDS::XTypes::TypeMap tm;\n"
379383
" return tm;\n";
380384
}
385+
be_global->add_cpp_include("dds/DCPS/JsonValueReader.h");
386+
be_global->add_cpp_include("dds/DCPS/JsonValueWriter.h");
387+
const bool alloc_out = be_global->language_mapping() != BE_GlobalData::LANGMAP_CXX11 && size_type == AST_Type::VARIABLE;
381388
be_global->impl_ <<
389+
"}\n\n"
390+
"::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::encode_to_string(const " << short_name << "& in, CORBA::String_out out, OpenDDS::DCPS::RepresentationFormat* format)\n"
391+
"{\n"
392+
"#if OPENDDS_HAS_JSON_VALUE_WRITER\n"
393+
" OpenDDS::DCPS::JsonRepresentationFormat_var jrf = OpenDDS::DCPS::JsonRepresentationFormat::_narrow(format);\n"
394+
" if (jrf) {\n"
395+
" rapidjson::StringBuffer buffer;\n"
396+
" rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);\n"
397+
" OpenDDS::DCPS::JsonValueWriter<rapidjson::Writer<rapidjson::StringBuffer> > jvw(writer);\n"
398+
" vwrite(jvw, in);\n"
399+
" out = buffer.GetString();\n"
400+
" return ::DDS::RETCODE_OK;\n"
401+
" }\n"
402+
"#else\n"
403+
" ACE_UNUSED_ARG(in);\n"
404+
" ACE_UNUSED_ARG(out);\n"
405+
" ACE_UNUSED_ARG(format);\n"
406+
"#endif\n"
407+
" return ::DDS::RETCODE_UNSUPPORTED;\n"
408+
"}\n\n"
409+
"::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::encode_to_bytes(const " << short_name << "& in, ::DDS::OctetSeq_out out, OpenDDS::DCPS::RepresentationFormat* format)\n"
410+
"{\n"
411+
" ACE_UNUSED_ARG(in);\n"
412+
" ACE_UNUSED_ARG(out);\n"
413+
" ACE_UNUSED_ARG(format);\n"
414+
" return ::DDS::RETCODE_UNSUPPORTED;\n"
415+
"}\n\n"
416+
"::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::decode_from_string(const char* in, " << short_name << "_out " <<
417+
(alloc_out ? "out" : "param") << ", OpenDDS::DCPS::RepresentationFormat* format)\n"
418+
"{\n"
419+
"#if OPENDDS_HAS_JSON_VALUE_READER\n"
420+
" OpenDDS::DCPS::JsonRepresentationFormat_var jrf = OpenDDS::DCPS::JsonRepresentationFormat::_narrow(format);\n"
421+
" if (jrf) {\n"
422+
" rapidjson::StringStream buffer(in);\n"
423+
" OpenDDS::DCPS::JsonValueReader<> jvr(buffer);\n" <<
424+
(alloc_out ? " out = new " + short_name + ";\n" : " " + short_name + "* out = &param;\n") <<
425+
" OpenDDS::DCPS::set_default(*out);\n"
426+
" return vread(jvr, *out) ? ::DDS::RETCODE_OK : ::DDS::RETCODE_ERROR;\n"
427+
" }\n"
428+
"#else\n"
429+
" ACE_UNUSED_ARG(in);\n"
430+
" ACE_UNUSED_ARG(" << (alloc_out ? "out" : "param") << ");\n"
431+
" ACE_UNUSED_ARG(format);\n"
432+
"#endif\n"
433+
" return ::DDS::RETCODE_UNSUPPORTED;\n"
434+
"}\n\n"
435+
"::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::decode_from_bytes(const ::DDS::OctetSeq& in, " << short_name << "_out out, OpenDDS::DCPS::RepresentationFormat* format)\n"
436+
"{\n"
437+
" ACE_UNUSED_ARG(in);\n"
438+
" ACE_UNUSED_ARG(out);\n"
439+
" ACE_UNUSED_ARG(format);\n"
440+
" return ::DDS::RETCODE_UNSUPPORTED;\n"
382441
"}\n\n"
383442
<< ts_short_name << "TypeSupport::_ptr_type " << ts_short_name << "TypeSupportImpl::_narrow(CORBA::Object_ptr obj)\n"
384443
"{\n"

java/dds/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
/OpenDDS_DCPS__ParticipantLocationBuiltinTopicDataDataWriterTAOPeer.h
133133
/OpenDDS_DCPS__ParticipantLocationBuiltinTopicDataTypeSupportTAOPeer.h
134134
/OpenDDS_DCPS__TypeSupportTAOPeer.h
135+
/OpenDDS_DCPS_CdrRepresentationFormatHelper.h
135136
/OpenDDS_DCPS_ConnectionRecordDataReaderHelper.h
136137
/OpenDDS_DCPS_ConnectionRecordDataWriterHelper.h
137138
/OpenDDS_DCPS_ConnectionRecordTypeSupportHelper.h
@@ -143,11 +144,13 @@
143144
/OpenDDS_DCPS_InternalThreadBuiltinTopicDataDataWriterHelper.h
144145
/OpenDDS_DCPS_InternalThreadBuiltinTopicDataTypeSupportHelper.h
145146
/OpenDDS_DCPS_InternalThreadBuiltinTopicDataTypeSupportImpl.h
147+
/OpenDDS_DCPS_JsonRepresentationFormatHelper.h
146148
/OpenDDS_DCPS_NetworkConfigModifier.h
147149
/OpenDDS_DCPS_ParticipantLocationBuiltinTopicDataDataReaderHelper.h
148150
/OpenDDS_DCPS_ParticipantLocationBuiltinTopicDataDataWriterHelper.h
149151
/OpenDDS_DCPS_ParticipantLocationBuiltinTopicDataTypeSupportHelper.h
150152
/OpenDDS_DCPS_ParticipantLocationBuiltinTopicDataTypeSupportImpl.h
153+
/OpenDDS_DCPS_RepresentationFormatHelper.h
151154
/OpenDDS_DCPS_TheParticipantFactory.h
152155
/OpenDDS_DCPS_TheServiceParticipant.h
153156
/OpenDDS_DCPS_transport_MulticastInst.h

java/dds/OpenDDS/DCPS/.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1+
/_CdrRepresentationFormatLocalBase.java
2+
/_CdrRepresentationFormatTAOPeer.java
3+
/_JsonRepresentationFormatLocalBase.java
4+
/_JsonRepresentationFormatTAOPeer.java
5+
/_RepresentationFormatLocalBase.java
6+
/_RepresentationFormatTAOPeer.java
17
/ALL_STATUS_MASK.java
28
/BudgetExceededStatus.java
39
/BudgetExceededStatusHelper.java
410
/BudgetExceededStatusHolder.java
11+
/CdrRepresentationFormat.java
12+
/CdrRepresentationFormatHelper.java
13+
/CdrRepresentationFormatHolder.java
14+
/CdrRepresentationFormatOperations.java
515
/ConnectionData.java
616
/ConnectionDataDataReader.java
717
/ConnectionDataDataReaderHelper.java
@@ -116,6 +126,11 @@
116126
/InternalThreadBuiltinTopicDataTypeSupportHolder.java
117127
/InternalThreadBuiltinTopicDataTypeSupportImpl.java
118128
/InternalThreadBuiltinTopicDataTypeSupportOperations.java
129+
/JSON_DATA_REPRESENTATION.java
130+
/JsonRepresentationFormat.java
131+
/JsonRepresentationFormatHelper.java
132+
/JsonRepresentationFormatHolder.java
133+
/JsonRepresentationFormatOperations.java
119134
/LOCATION_ICE.java
120135
/LOCATION_ICE6.java
121136
/LOCATION_LOCAL.java
@@ -175,6 +190,10 @@
175190
/PublicationLostStatusHelper.java
176191
/PublicationLostStatusHolder.java
177192
/PublicationReconnectedStatusHelper.java
193+
/RepresentationFormat.java
194+
/RepresentationFormatHelper.java
195+
/RepresentationFormatHolder.java
196+
/RepresentationFormatOperations.java
178197
/RTPS_RELAY_STUN_PROTOCOL.java
179198
/SubscriberExt.java
180199
/SubscriberExtHelper.java

0 commit comments

Comments
 (0)