Skip to content

Commit

Permalink
Merge pull request OpenDDS#4771 from jrw972/java-union-topics
Browse files Browse the repository at this point in the history
Union topics are not supported in Java
  • Loading branch information
jrw972 authored Aug 22, 2024
2 parents 8a33db8 + 65ff26f commit 00d1d5c
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 9 deletions.
11 changes: 9 additions & 2 deletions dds/idl/dds_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,15 @@ std::string field_type_name(AST_Field* field, AST_Type* field_type)
field_type = field->field_type();
}
const Classification cls = classify(field_type);
const std::string name = (cls & CL_STRING) ?
string_type(cls) : scoped(deepest_named_type(field_type)->name());
std::string name;
if (cls & CL_STRING) {
name = string_type(cls);
} else if (cls & CL_PRIMITIVE) {
size_t size = 0;
name = to_cxx_type(deepest_named_type(field_type), size);
} else {
name = scoped(deepest_named_type(field_type)->name());
}
if (field) {
FieldInfo af(*field);
if (af.as_base_ && af.type_->anonymous()) {
Expand Down
3 changes: 3 additions & 0 deletions dds/idl/dds_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,9 @@ inline std::string to_cxx_type(AST_Type* type, std::size_t& size)
return "ACE_CDR::Double";
case AST_PredefinedType::PT_longdouble:
size = 16;
if (be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11) {
return "long double";
}
return "ACE_CDR::LongDouble";
case AST_PredefinedType::PT_char:
size = 1;
Expand Down
4 changes: 4 additions & 0 deletions dds/idl/dds_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ dds_visitor::visit_union(AST_Union* node)
node->repoID());
}

if (!node->imported() && be_global->java()) {
java_ts_generator::generate(node);
}

return 0;
}

Expand Down
30 changes: 26 additions & 4 deletions dds/idl/marshal_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ namespace {
AST_Type* type, const string& prefix, bool wrap_nested_key_only,
Intro& intro, const string& stru = "");

string initializeUnion(const std::string& indent, AST_Decl* node, const string& name,
AST_Type* type, const string& prefix, bool wrap_nested_key_only,
Intro& intro, const string& stru = "");

const std::string construct_bound_fail =
"strm.get_construction_status() == Serializer::BoundConstructionFailure";
const std::string construct_elem_fail =
Expand Down Expand Up @@ -1721,6 +1725,16 @@ namespace {
}
}

string initializeUnion(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& /*stru*/)
{
return
field_type_name(dynamic_cast<AST_Field*>(field), type) + " temp;\n" +
type_to_default(indent, type, "temp", type->anonymous(), false) +
"uni.value." + field->local_name()->get_string() + "(temp);\n";
}

std::string generate_field_stream(
const std::string& indent, AST_Field* field, const std::string& prefix, const std::string& field_name,
bool wrap_nested_key_only, Intro& intro)
Expand Down Expand Up @@ -3447,7 +3461,9 @@ namespace {
return true;
}

void gen_union_key_serializers(AST_Union* node, FieldFilter kind)
void gen_union_key_serializers(AST_Union* node,
FieldFilter kind,
const std::vector<AST_UnionBranch*>& branches)
{
const string cxx = scoped(node->name()); // name as a C++ class
AST_Type* const discriminator = node->disc_type();
Expand Down Expand Up @@ -3564,7 +3580,13 @@ namespace {

be_global->impl_
<< " " << scoped(discriminator->name()) << " disc;\n"
<< streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT))
<< streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT));

// Activate the branch with a default so the union is in a good state.
generateSwitchForUnion(node, "disc", initializeUnion, branches,
discriminator, "", ">> forceStreamExp", cxx.c_str());

be_global->impl_
<< " uni.value._d(disc);\n";
}

Expand Down Expand Up @@ -3826,9 +3848,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_NestedKeyOnly, branches);
if (be_global->is_topic_type(node)) {
gen_union_key_serializers(node, FieldFilter_KeyOnly);
gen_union_key_serializers(node, FieldFilter_KeyOnly, branches);
}

TopicKeys keys(node);
Expand Down
13 changes: 11 additions & 2 deletions dds/idl/ts_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ bool ts_generator::gen_union(AST_Union* node, UTL_ScopedName* name,

namespace java_ts_generator {

/// called directly by dds_visitor::visit_structure() if -Wb,java
void generate(AST_Structure* node) {
template <typename T>
void generate_common(T* node) {
UTL_ScopedName* name = node->name();

if (!(idl_global->is_dcps_type(name) || be_global->is_topic_type(node))) {
Expand Down Expand Up @@ -705,6 +705,15 @@ namespace java_ts_generator {
"}\n\n";
}

/// called by dds_visitor::visit_structure() if -Wb,java
void generate(AST_Structure* node) {
generate_common(node);
}

/// called by dds_visitor::visit_union() if -Wb,java
void generate(AST_Union* node) {
generate_common(node);
}
}

namespace face_ts_generator {
Expand Down
113 changes: 112 additions & 1 deletion java/tests/complex_idl/ComplexIDLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ComplexIDLTest extends QuoteSupport {
private static DomainParticipant participant;

private static Topic topic;
private static Topic union_topic;

private static Publisher publisher;
private static Subscriber subscriber;
Expand All @@ -50,11 +51,21 @@ protected static void setUp(String[] args) {
int result = typeSupport.register_type(participant, "Complex::Data");
assert (result != RETCODE_ERROR.value);

ElectionNews_tTypeSupportImpl electionNewsTypeSupport = new ElectionNews_tTypeSupportImpl();

result = electionNewsTypeSupport.register_type(participant, "Complex::ElectionNews_t");
assert (result != RETCODE_ERROR.value);

topic = participant.create_topic("Complex::Topic", "Complex::Data",
TOPIC_QOS_DEFAULT.get(), null,
DEFAULT_STATUS_MASK.value);
assert (topic != null);

union_topic = participant.create_topic("Complex::UnionTopic", "Complex::ElectionNews_t",
TOPIC_QOS_DEFAULT.get(), null,
DEFAULT_STATUS_MASK.value);
assert (union_topic != null);

publisher = participant.create_publisher(PUBLISHER_QOS_DEFAULT.get(), null, DEFAULT_STATUS_MASK.value);
assert (publisher != null);

Expand Down Expand Up @@ -212,11 +223,111 @@ public void on_data_available(DataReader dr) {
System.out.println("(Those responsible have been sacked.)");
}

protected static void testElectionNews() throws Exception {
final AtomicInteger count = new AtomicInteger();

final Lock lock = new ReentrantLock();
final Condition finished = lock.newCondition();

publisher.create_datawriter(union_topic, DATAWRITER_QOS_DEFAULT.get(),
new DDS._DataWriterListenerLocalBase() {
public void on_liveliness_lost(DataWriter dw, LivelinessLostStatus status) {}

public void on_offered_deadline_missed(DataWriter dw, OfferedDeadlineMissedStatus status) {}

public void on_offered_incompatible_qos(DataWriter dw, OfferedIncompatibleQosStatus status) {}

public void on_publication_matched(DataWriter dw, PublicationMatchedStatus status) {
try {
if (status.current_count == 0) return;
// Don't run the rest of this method if the callback is
// due to the datareader going away.

ElectionNews_tDataWriter writer = ElectionNews_tDataWriterHelper.narrow(dw);

count.set(1);

ElectionNews_t data = new ElectionNews_t();
data.status(ElectionNewsType_t.ELECTION_STATUS, new Candidate_t("A Name", 10));

int result = writer.write(data, HANDLE_NIL.value);
assert (result != RETCODE_ERROR.value);

} catch (Throwable t) {
t.printStackTrace();
}
};
}, DEFAULT_STATUS_MASK.value
);

lock.lock();
try {
subscriber.create_datareader(union_topic, DATAREADER_QOS_DEFAULT.get(),
new DDS._DataReaderListenerLocalBase() {
public void on_liveliness_changed(DataReader dr, LivelinessChangedStatus status) {}

public void on_requested_deadline_missed(DataReader dr, RequestedDeadlineMissedStatus status) {}

public void on_requested_incompatible_qos(DataReader dr, RequestedIncompatibleQosStatus status) {}

public void on_sample_lost(DataReader dr, SampleLostStatus status) {}

public void on_sample_rejected(DataReader dr, SampleRejectedStatus status) {}

public void on_subscription_matched(DataReader dr, SubscriptionMatchedStatus status) {}

public void on_data_available(DataReader dr) {
try {
ElectionNews_tDataReader reader = ElectionNews_tDataReaderHelper.narrow(dr);

ElectionNews_t en = new ElectionNews_t();
en.status(ElectionNewsType_t.ELECTION_STATUS, new Candidate_t(new String(""), 0));
ElectionNews_tHolder dh = new ElectionNews_tHolder(en);

SampleInfo si = new SampleInfo();
si.source_timestamp = new Time_t();

int result = reader.take_next_sample(dh, new SampleInfoHolder(si));
assert (result != RETCODE_ERROR.value);

ElectionNews_t data = dh.value;

if (si.valid_data) {
assert data.discriminator() == ElectionNewsType_t.ELECTION_STATUS;
assert data.status().name.equals("A Name");
assert data.status().votes == 10;
}

if (count.decrementAndGet() == 0) {
// Signal main thread
lock.lock();
try {
finished.signalAll();
} finally {
lock.unlock();
}
}

} catch (Throwable t) {
t.printStackTrace();
}
}
}, DEFAULT_STATUS_MASK.value
);

// Wait for DataReader
finished.await();

} finally {
lock.unlock();
}
}

public static void main(String[] args) throws Exception {
setUp(args);
try {
testQuotes();

testElectionNews();
} finally {
tearDown();
}
Expand Down
24 changes: 24 additions & 0 deletions java/tests/complex_idl/Complex_Idl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,28 @@ module Complex_Idl {
@key long time;
Position pos;
};

typedef unsigned long Vote_t;
struct Candidate_t {
string name;
Vote_t votes;
};

struct ElectionResult_t {
Candidate_t winner;
Vote_t total_votes;
};

enum ElectionNewsType_t {
ELECTION_STATUS,
ELECTION_RESULT
};

@topic
union ElectionNews_t switch (@key ElectionNewsType_t) {
case ELECTION_STATUS:
Candidate_t status;
case ELECTION_RESULT:
ElectionResult_t result;
};
};

0 comments on commit 00d1d5c

Please sign in to comment.