OpenDDS  Snapshot(2023/04/28-20:55)
ts_generator.cpp
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
8 #include "ts_generator.h"
9 
10 #include "be_extern.h"
11 #include "be_util.h"
12 #include "topic_keys.h"
13 #include "typeobject_generator.h"
14 
15 #include <utl_identifier.h>
16 
17 #include <ace/OS_NS_sys_stat.h>
18 
19 #include <cstring>
20 #include <fstream>
21 #include <sstream>
22 #include <map>
23 #include <iostream>
24 
25 namespace {
26  std::string read_template(const char* prefix)
27  {
28  std::string path = be_util::dds_root();
29  path.append("/dds/idl/");
30  path.append(prefix);
31  path.append("Template.txt");
32  std::ifstream ifs(path.c_str());
33  if (!ifs) {
34  ACE_ERROR((LM_ERROR, "Error - Couldn't open %C\n", path.c_str()));
35  return "";
36  }
37  std::ostringstream oss;
38  oss << ifs.rdbuf();
39  return oss.str();
40  }
41 
42  void replaceAll(std::string& s,
43  const std::map<std::string, std::string>& rep) {
44  typedef std::map<std::string, std::string>::const_iterator mapiter_t;
45  for (size_t i = s.find("<%"); i < s.length(); i = s.find("<%", i + 1)) {
46  size_t n = s.find("%>", i) - i + 2;
47  mapiter_t iter = rep.find(s.substr(i + 2, n - 4));
48  if (iter != rep.end()) {
49  s.replace(i, n, iter->second);
50  }
51  }
52  }
53 
54  template<size_t N>
55  void add_includes(const char* (&includes)[N],
56  BE_GlobalData::stream_enum_t whichStream) {
57  for (size_t i = 0; i < N; ++i) {
58  be_global->add_include(includes[i], whichStream);
59  }
60  }
61 }
62 
64  : idl_template_(read_template("IDL"))
65 {
66 }
67 
68 namespace {
69  void gen_isDcpsKey_i(const char* key)
70  {
71  be_global->impl_ <<
72  " if (!ACE_OS::strcmp(field, \"" << key << "\")) {\n"
73  " return true;\n"
74  " }\n";
75  }
76 
77  void gen_isDcpsKey(IDL_GlobalData::DCPS_Data_Type_Info* info)
78  {
79  IDL_GlobalData::DCPS_Key_List::CONST_ITERATOR i(info->key_list_);
80  for (ACE_TString* key = 0; i.next(key); i.advance()) {
81  gen_isDcpsKey_i(ACE_TEXT_ALWAYS_CHAR(key->c_str()));
82  }
83  }
84 
85  void gen_isDcpsKey(TopicKeys& keys)
86  {
87  TopicKeys::Iterator finished = keys.end();
88  for (TopicKeys::Iterator i = keys.begin(); i != finished; ++i) {
89  gen_isDcpsKey_i(i.canonical_path().c_str());
90  }
91  }
92 }
93 
94 bool ts_generator::generate_ts(AST_Decl* node, UTL_ScopedName* name)
95 {
96  if (idl_template_.empty()) {
97  // error reported in read_template
98  return false;
99  }
100  if (!node || !name) {
101  return false;
102  }
103 
104  AST_Structure* struct_node = 0;
105  AST_Union* union_node = 0;
106  AST_Type::SIZE_TYPE size_type;
107  if (node->node_type() == AST_Decl::NT_struct) {
108  struct_node = dynamic_cast<AST_Structure*>(node);
109  size_type = struct_node->size_type();
110  } else if (node->node_type() == AST_Decl::NT_union) {
111  union_node = dynamic_cast<AST_Union*>(node);
112  size_type = union_node->size_type();
113  } else {
114  idl_global->err()->misc_error(
115  "Could not cast AST Nodes to valid types", node);
116  return false;
117  }
118 
119  size_t key_count = 0;
120  IDL_GlobalData::DCPS_Data_Type_Info* info = 0;
121  TopicKeys keys;
122  if (struct_node) {
123  info = idl_global->is_dcps_type(name);
124  if (be_global->is_topic_type(struct_node)) {
125  keys = TopicKeys(struct_node);
126  key_count = keys.count();
127  } else if (info) {
128  key_count = info->key_list_.size();
129  } else {
130  return true;
131  }
132  } else if (be_global->is_topic_type(union_node)) {
133  key_count = be_global->union_discriminator_is_key(union_node) ? 1 : 0;
134  } else {
135  return true;
136  }
137 
138  const std::string cxx_name = scoped(name);
139  const std::string short_name = name->last_component()->get_string();
140  const std::string ts_name = scoped(name, EscapeContext_FromGenIdl);
141  const std::string ts_short_name = to_string(
142  name->last_component(), EscapeContext_FromGenIdl);
143  const std::string unescaped_name =
145  const std::string name_underscores = dds_generator::scoped_helper(name, "_");
146  static const std::string ns("OpenDDS::DCPS::");
147  const std::string xtag = ns + get_xtag_name(name);
148 
149  static const char* idl_includes[] = {
150  "dds/DdsDcpsInfrastructure.idl", "dds/DdsDcpsTopic.idl",
151  "dds/DdsDcpsPublication.idl", "dds/DdsDcpsSubscriptionExt.idl",
152  "dds/DdsDcpsTypeSupportExt.idl"
153  };
154  add_includes(idl_includes, BE_GlobalData::STREAM_IDL);
155 
156  std::string dc = be_global->header_name_.c_str();
157  dc.replace(dc.end() - 6, dc.end() - 2, "C"); // s/Impl.h$/C.h/
158  be_global->add_include(dc.c_str());
159 
160  static const char* h_includes[] = {
161  "dds/DCPS/TypeSupportImpl.h", "dds/DCPS/ValueDispatcher.h"
162  };
163  add_includes(h_includes, BE_GlobalData::STREAM_H);
164 
165  static const char* cpp_includes[] = {
166  "dds/DCPS/debug.h", "dds/DCPS/Registered_Data_Types.h",
167  "dds/DdsDcpsDomainC.h", "dds/DCPS/Service_Participant.h",
168  "dds/DCPS/Qos_Helper.h", "dds/DCPS/PublicationInstance.h",
169  "dds/DCPS/PublisherImpl.h", "dds/DCPS/SubscriberImpl.h",
170  "dds/DCPS/ReceivedDataElementList.h", "dds/DCPS/RakeResults_T.h",
171  "dds/DCPS/BuiltInTopicUtils.h", "dds/DCPS/Util.h",
172  "dds/DCPS/ContentFilteredTopicImpl.h", "dds/DCPS/RakeData.h",
173  "dds/DCPS/MultiTopicDataReader_T.h", "dds/DCPS/DataWriterImpl_T.h",
174  "dds/DCPS/DataReaderImpl_T.h", "dds/DCPS/XTypes/TypeObject.h"
175  };
176  add_includes(cpp_includes, BE_GlobalData::STREAM_CPP);
177 
178  std::map<std::string, std::string> replacements;
179  replacements["SCOPED"] = scoped(name, EscapeContext_ForGenIdl);
180  // SCOPED_NOT_GLOBAL is EscapeContext_FromGenIdl, because
181  // DCPS_DATA_SEQUENCE_TYPE is strange.
182  replacements["SCOPED_NOT_GLOBAL"] =
184  replacements["TYPE"] = to_string(name->last_component(), EscapeContext_ForGenIdl);
185  replacements["EXPORT"] = be_global->export_macro().c_str();
186  replacements["SEQ"] = be_global->sequence_suffix().c_str();
187 
188  ScopedNamespaceGuard idlGuard(name, be_global->idl_, "module");
189  std::string idl = idl_template_;
190  replaceAll(idl, replacements);
191  be_global->idl_ << idl;
192 
193  be_global->header_ << be_global->versioning_begin() << "\n";
194  {
195  ScopedNamespaceGuard hGuard(name, be_global->header_);
196 
197  be_global->header_ <<
198  "class " << ts_short_name << "TypeSupportImpl;\n";
199  }
200  be_global->header_ << be_global->versioning_end() << "\n";
201 
202  be_global->header_ <<
203  "OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL\n"
204  "namespace OpenDDS {\n"
205  "namespace DCPS {\n"
206  "template <>\n"
207  "struct DDSTraits<" << cxx_name << "> {\n"
208  " typedef " << cxx_name << " MessageType;\n"
209  " typedef " << ts_name << be_global->sequence_suffix() << " MessageSequenceType;\n"
210  " typedef " << ts_name << be_global->sequence_suffix() << "::PrivateMemberAccess MessageSequenceAdapterType;\n"
211  " typedef " << ts_name << "TypeSupport TypeSupportType;\n"
212  " typedef " << ts_name << "TypeSupportImpl TypeSupportImplType;\n"
213  " typedef " << ts_name << "DataWriter DataWriterType;\n"
214  " typedef " << ts_name << "DataReader DataReaderType;\n"
215  " typedef " << cxx_name << "_OpenDDS_KeyLessThan LessThanType;\n"
216  " typedef OpenDDS::DCPS::KeyOnly<const " << cxx_name << "> KeyOnlyType;\n"
217  " typedef " << xtag << " XtagType;\n"
218  "\n"
219  " static const char* type_name() { return \"" << unescaped_name << "\"; }\n"
220  " static size_t key_count() { return " << key_count << "; }\n"
221  " static bool is_key(const char*);\n"
222  "};\n"
223  "} // namespace DCPS\n"
224  "} // namespace OpenDDS\n"
225  "OPENDDS_END_VERSIONED_NAMESPACE_DECL\n\n";
226 
227  be_global->impl_ <<
228  "OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL\n"
229  "namespace OpenDDS {\n"
230  "namespace DCPS {\n"
231  "bool DDSTraits<" << cxx_name << ">::is_key(const char* field)\n"
232  "{\n"
233  " ACE_UNUSED_ARG(field);\n";
234  if (struct_node && key_count) {
235  if (info) {
236  gen_isDcpsKey(info);
237  } else {
238  gen_isDcpsKey(keys);
239  }
240  }
241  be_global->impl_ <<
242  " return false;\n"
243  "}\n"
244  "} // namespace DCPS\n"
245  "} // namespace OpenDDS\n"
246  "OPENDDS_END_VERSIONED_NAMESPACE_DECL\n\n";
247 
248  be_global->header_ << be_global->versioning_begin() << "\n";
249  {
250  ScopedNamespaceGuard hGuard(name, be_global->header_);
251 
252  be_global->header_ <<
253  "class " << be_global->export_macro() << " " << ts_short_name << "TypeSupportImpl\n"
254  " : public virtual OpenDDS::DCPS::LocalObject<" << ts_short_name << "TypeSupport>\n"
255  " , public virtual OpenDDS::DCPS::TypeSupportImpl_T<" << short_name << ">\n"
256  " , public virtual OpenDDS::DCPS::ValueDispatcher_T<" << short_name << ">\n"
257  "{\n"
258  "public:\n"
259  " typedef " << ts_short_name << "TypeSupport TypeSupportType;\n"
260  " typedef " << ts_short_name << "TypeSupport::_var_type _var_type;\n"
261  " typedef " << ts_short_name << "TypeSupport::_ptr_type _ptr_type;\n"
262  "\n"
263  " " << ts_short_name << "TypeSupportImpl() {}\n"
264  " virtual ~" << ts_short_name << "TypeSupportImpl() {}\n"
265  "\n"
266  " virtual " << be_global->versioning_name() << "::DDS::DataWriter_ptr create_datawriter();\n"
267  " virtual " << be_global->versioning_name() << "::DDS::DataReader_ptr create_datareader();\n"
268  "#ifndef OPENDDS_NO_MULTI_TOPIC\n"
269  " virtual " << be_global->versioning_name() << "::DDS::DataReader_ptr create_multitopic_datareader();\n"
270  "#endif /* !OPENDDS_NO_MULTI_TOPIC */\n"
271  "#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE\n"
272  " virtual const OpenDDS::DCPS::MetaStruct& getMetaStructForType() const;\n"
273  "#endif /* !OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE */\n"
274  "\n"
275  " virtual const OpenDDS::XTypes::TypeIdentifier& getMinimalTypeIdentifier() const;\n"
276  " virtual const OpenDDS::XTypes::TypeMap& getMinimalTypeMap() const;\n"
277  "\n"
278  " virtual const OpenDDS::XTypes::TypeIdentifier& getCompleteTypeIdentifier() const;\n"
279  " virtual const OpenDDS::XTypes::TypeMap& getCompleteTypeMap() const;\n"
280  "\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"
286  " static " << ts_short_name << "TypeSupport::_ptr_type _narrow(CORBA::Object_ptr obj);\n"
287  "};\n\n";
288  }
289  be_global->header_ << be_global->versioning_end() << "\n";
290 
291  be_global->impl_ << be_global->versioning_begin() << "\n";
292  {
293  ScopedNamespaceGuard cppGuard(name, be_global->impl_);
294  be_global->impl_ <<
295  "::DDS::DataWriter_ptr " << ts_short_name << "TypeSupportImpl::create_datawriter()\n"
296  "{\n"
297  " typedef OpenDDS::DCPS::DataWriterImpl_T<" << short_name << "> DataWriterImplType;\n"
298  " ::DDS::DataWriter_ptr writer_impl = ::DDS::DataWriter::_nil();\n"
299  " ACE_NEW_NORETURN(writer_impl,\n"
300  " DataWriterImplType());\n"
301  " return writer_impl;\n"
302  "}\n\n"
303  "::DDS::DataReader_ptr " << ts_short_name << "TypeSupportImpl::create_datareader()\n"
304  "{\n"
305  " typedef OpenDDS::DCPS::DataReaderImpl_T<" << short_name << "> DataReaderImplType;\n"
306  " ::DDS::DataReader_ptr reader_impl = ::DDS::DataReader::_nil();\n"
307  " ACE_NEW_NORETURN(reader_impl,\n"
308  " DataReaderImplType());\n"
309  " return reader_impl;\n"
310  "}\n\n"
311  "#ifndef OPENDDS_NO_MULTI_TOPIC\n"
312  "::DDS::DataReader_ptr " << ts_short_name << "TypeSupportImpl::create_multitopic_datareader()\n"
313  "{\n"
314  " typedef OpenDDS::DCPS::DataReaderImpl_T<" << short_name << "> DataReaderImplType;\n"
315  " typedef OpenDDS::DCPS::MultiTopicDataReader_T<" << short_name << ", DataReaderImplType> MultiTopicDataReaderImplType;\n"
316  " ::DDS::DataReader_ptr multitopic_reader_impl = ::DDS::DataReader::_nil();\n"
317  " ACE_NEW_NORETURN(multitopic_reader_impl,\n"
318  " MultiTopicDataReaderImplType());\n"
319  " return multitopic_reader_impl;\n"
320  "}\n"
321  "#endif /* !OPENDDS_NO_MULTI_TOPIC */\n\n"
322  "#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE\n"
323  "const OpenDDS::DCPS::MetaStruct& " << ts_short_name << "TypeSupportImpl::getMetaStructForType() const\n"
324  "{\n"
325  " return OpenDDS::DCPS::getMetaStruct<" << short_name << ">();\n"
326  "}\n"
327  "#endif /* !OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE */\n\n"
328  "namespace {\n"
329  " OpenDDS::DCPS::TypeSupportInitializer<" << ts_short_name << "TypeSupportImpl> ts_init_" << name_underscores << ";\n"
330  "}\n"
331  "\n"
332  "const OpenDDS::XTypes::TypeIdentifier& " << ts_short_name << "TypeSupportImpl::getMinimalTypeIdentifier() const\n"
333  "{\n";
334 
335  const bool java_ts_only = be_global->java_arg().length() > 0;
336  const bool generate_xtypes = !be_global->suppress_xtypes() && !java_ts_only;
337  if (generate_xtypes) {
338  be_global->impl_ <<
339  " return OpenDDS::DCPS::getMinimalTypeIdentifier<" << xtag << ">();\n";
340  } else {
341  be_global->impl_ <<
342  " static OpenDDS::XTypes::TypeIdentifier ti;\n"
343  " return ti;\n";
344  }
345  be_global->impl_ <<
346  "}\n\n"
347  "const OpenDDS::XTypes::TypeMap& " << ts_short_name << "TypeSupportImpl::getMinimalTypeMap() const\n"
348  "{\n";
349 
350  if (generate_xtypes) {
351  be_global->impl_ <<
352  " return OpenDDS::DCPS::getMinimalTypeMap<" << xtag << ">();\n";
353  } else {
354  be_global->impl_ <<
355  " static OpenDDS::XTypes::TypeMap tm;\n"
356  " return tm;\n";
357  }
358  be_global->impl_ <<
359  "}\n\n"
360  "const OpenDDS::XTypes::TypeIdentifier& " << ts_short_name << "TypeSupportImpl::getCompleteTypeIdentifier() const\n"
361  "{\n";
362 
363  const bool generate_xtypes_complete = generate_xtypes && be_global->xtypes_complete();
364  if (generate_xtypes_complete) {
365  be_global->impl_ <<
366  " return OpenDDS::DCPS::getCompleteTypeIdentifier<" << xtag << ">();\n";
367  } else {
368  be_global->impl_ <<
369  " static OpenDDS::XTypes::TypeIdentifier ti;\n"
370  " return ti;\n";
371  }
372  be_global->impl_ <<
373  "}\n\n"
374  "const OpenDDS::XTypes::TypeMap& " << ts_short_name << "TypeSupportImpl::getCompleteTypeMap() const\n"
375  "{\n";
376 
377  if (generate_xtypes_complete) {
378  be_global->impl_ <<
379  " return OpenDDS::DCPS::getCompleteTypeMap<" << xtag << ">();\n";
380  } else {
381  be_global->impl_ <<
382  " static OpenDDS::XTypes::TypeMap tm;\n"
383  " return tm;\n";
384  }
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;
388  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(format);\n"
405  "#endif\n"
406  " out = \"\";\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  "#if OPENDDS_HAS_JSON_VALUE_WRITER\n"
412  " OpenDDS::DCPS::JsonRepresentationFormat_var jrf = OpenDDS::DCPS::JsonRepresentationFormat::_narrow(format);\n"
413  " if (jrf) {\n"
414  " CORBA::String_var buffer;\n"
415  " const ::DDS::ReturnCode_t ret = encode_to_string(in, buffer, format);\n"
416  " if (ret == ::DDS::RETCODE_OK) {\n"
417  " const ::DDS::UInt32 len = static_cast< ::DDS::UInt32>(std::strlen(buffer));\n"
418  " out = new ::DDS::OctetSeq(len);\n"
419  " out->length(len);\n"
420  " std::memcpy(out->get_buffer(), buffer, len);\n"
421  " return ::DDS::RETCODE_OK;\n"
422  " } else {\n"
423  " out = new ::DDS::OctetSeq();\n"
424  " return ret;\n"
425  " }\n"
426  " }\n"
427  "#else\n"
428  " ACE_UNUSED_ARG(in);\n"
429  " ACE_UNUSED_ARG(format);\n"
430  "#endif\n"
431  " out = new ::DDS::OctetSeq();\n"
432  " return ::DDS::RETCODE_UNSUPPORTED;\n"
433  "}\n\n"
434  "::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::decode_from_string(const char* in, " << short_name << "_out " <<
435  (alloc_out ? "out" : "param") << ", OpenDDS::DCPS::RepresentationFormat* format)\n"
436  "{\n";
437 
438  if (alloc_out) {
439  be_global->impl_ << " out = new " << short_name << ";\n";
440  } else {
441  be_global->impl_ << " " << short_name << "* out = &param;\n";
442  }
443 
444  be_global->impl_ <<
445  " OpenDDS::DCPS::set_default(*out);\n"
446  "#if OPENDDS_HAS_JSON_VALUE_READER\n"
447  " OpenDDS::DCPS::JsonRepresentationFormat_var jrf = OpenDDS::DCPS::JsonRepresentationFormat::_narrow(format);\n"
448  " if (jrf) {\n"
449  " rapidjson::StringStream buffer(in);\n"
450  " OpenDDS::DCPS::JsonValueReader<> jvr(buffer);\n" <<
451  " return vread(jvr, *out) ? ::DDS::RETCODE_OK : ::DDS::RETCODE_ERROR;\n"
452  " }\n"
453  "#else\n"
454  " ACE_UNUSED_ARG(in);\n"
455  " ACE_UNUSED_ARG(format);\n"
456  "#endif\n"
457  " return ::DDS::RETCODE_UNSUPPORTED;\n"
458  "}\n\n"
459  "::DDS::ReturnCode_t " << ts_short_name << "TypeSupportImpl::decode_from_bytes(const ::DDS::OctetSeq& in, " << short_name << "_out out, OpenDDS::DCPS::RepresentationFormat* format)\n"
460  "{\n"
461  "#if OPENDDS_HAS_JSON_VALUE_READER\n"
462  " OpenDDS::DCPS::JsonRepresentationFormat_var jrf = OpenDDS::DCPS::JsonRepresentationFormat::_narrow(format);\n"
463  " if (jrf) {\n"
464  " return decode_from_string(reinterpret_cast<const char*>(in.get_buffer()), out, format);\n"
465  " }\n"
466  "#else\n"
467  " ACE_UNUSED_ARG(in);\n"
468  " ACE_UNUSED_ARG(format);\n"
469  "#endif\n"
470  " out = " << (alloc_out ? "new " : "") << short_name << "();\n"
471  " return ::DDS::RETCODE_UNSUPPORTED;\n"
472  "}\n\n"
473  << ts_short_name << "TypeSupport::_ptr_type " << ts_short_name << "TypeSupportImpl::_narrow(CORBA::Object_ptr obj)\n"
474  "{\n"
475  " return TypeSupportType::_narrow(obj);\n"
476  "}\n";
477  }
478  be_global->impl_ << be_global->versioning_end() << "\n";
479 
480  if (be_global->face_ts()) {
481  if (node->node_type() == AST_Decl::NT_struct) {
483  } else {
484  idl_global->err()->misc_error(
485  "Generating FACE type support for Union topic types is not supported", node);
486  return false;
487  }
488  }
489 
490  return true;
491 }
492 
493 bool ts_generator::gen_struct(AST_Structure* node, UTL_ScopedName* name,
494  const std::vector<AST_Field*>&, AST_Type::SIZE_TYPE, const char*)
495 {
496  return generate_ts(node, name);
497 }
498 
499 bool ts_generator::gen_union(AST_Union* node, UTL_ScopedName* name,
500  const std::vector<AST_UnionBranch*>&, AST_Type*, const char*)
501 {
502  return generate_ts(node, name);
503 }
504 
505 namespace java_ts_generator {
506 
507  /// called directly by dds_visitor::visit_structure() if -Wb,java
508  void generate(AST_Structure* node) {
509  UTL_ScopedName* name = node->name();
510 
511  if (!(idl_global->is_dcps_type(name) || be_global->is_topic_type(node))) {
512  return;
513  }
514 
515  ACE_CString output_file = be_global->java_arg();
516  if (output_file.length()) {
517  be_global->impl_name_ = output_file;
518  }
519  be_global->add_include("idl2jni_jni.h", BE_GlobalData::STREAM_CPP);
520 
521  std::string type = scoped(name);
522 
523  std::string file, jniclass, jpackage;
524  for (UTL_ScopedName* sn = name; sn;
525  sn = static_cast<UTL_ScopedName*>(sn->tail())) {
526  std::string tmp = sn->head()->get_string();
527  if (!tmp.empty() && sn->tail()) {
528  jpackage += tmp;
529  file += tmp;
530  if (ACE_OS::mkdir(file.c_str()) != 0 && errno != EEXIST) {
531  ACE_ERROR((LM_ERROR, ACE_TEXT("ERROR: java_ts_generator::generate - ")
532  ACE_TEXT("unable to create specified directory: %C"), file.c_str()));
533  }
534  }
535  for (size_t i = tmp.find('_'); i < tmp.length();
536  i = tmp.find('_', i + 1)) {
537  tmp.insert(++i, 1, '1');
538  }
539  jniclass += tmp;
540  if (!jniclass.empty() && sn->tail()) {
541  jniclass += '_';
542  jpackage += '.';
543  file += '/';
544  }
545  }
546 
547  if (jpackage.size() && jpackage[jpackage.size() - 1] == '.') {
548  jpackage.resize(jpackage.size() - 1);
549  }
550 
551  std::string clazz = name->last_component()->get_string();
552  file += clazz + "TypeSupportImpl.java";
553 
554  std::ofstream java(file.c_str());
555  java << (jpackage.size() ? "package " : "") << jpackage
556  << (jpackage.size() ? ";\n" :"") <<
557  "public class " << clazz << "TypeSupportImpl extends _" << clazz
558  << "TypeSupportTAOPeer {\n"
559  " public " << clazz << "TypeSupportImpl() {\n"
560  " super(_jni_init());\n"
561  " }\n"
562  " private static native long _jni_init();\n"
563  "}\n";
564  be_global->impl_ <<
565  "extern \"C\" JNIEXPORT jlong JNICALL\n"
566  "Java_" << jniclass << "TypeSupportImpl__1jni_1init(JNIEnv*, jclass) {\n"
567  " return reinterpret_cast<jlong>(static_cast<CORBA::Object_ptr>(new "
568  << type << "TypeSupportImpl));\n"
569  "}\n\n";
570  }
571 
572 }
573 
574 namespace face_ts_generator {
575 
576  void generate(UTL_ScopedName* name) {
577  const std::string cxx_name = scoped(name),
578  name_underscores = dds_generator::scoped_helper(name, "_"),
579  exportMacro = be_global->export_macro().c_str(),
580  exporter = exportMacro.empty() ? "" : (" " + exportMacro + '\n');
581  be_global->add_include("FACE/TS.hpp", BE_GlobalData::STREAM_FACETS_H);
582  be_global->facets_header_ <<
583  "namespace FACE\n"
584  "{\n"
585  " namespace Read_Callback\n"
586  " {\n"
587  " typedef void (*send_event_" << name_underscores << "_Ptr) (\n"
588  " /* in */ TRANSACTION_ID_TYPE transaction_id,\n"
589  " /* inout */ " << cxx_name << "& message,\n"
590  " /* in */ MESSAGE_TYPE_GUID message_type_id,\n"
591  " /* in */ MESSAGE_SIZE_TYPE message_size,\n"
592  " /* in */ const WAITSET_TYPE waitset,\n"
593  " /* out */ RETURN_CODE_TYPE& return_code);\n"
594  " }\n\n"
595  " namespace TS\n"
596  " {\n" << exporter <<
597  " void Receive_Message(\n"
598  " /* in */ CONNECTION_ID_TYPE connection_id,\n"
599  " /* in */ TIMEOUT_TYPE timeout,\n"
600  " /* inout */ TRANSACTION_ID_TYPE& transaction_id,\n"
601  " /* out */ " << cxx_name << "& message,\n"
602  " /* in */ MESSAGE_SIZE_TYPE message_size,\n"
603  " /* out */ RETURN_CODE_TYPE& return_code);\n\n" << exporter <<
604  " void Send_Message(\n"
605  " /* in */ CONNECTION_ID_TYPE connection_id,\n"
606  " /* in */ TIMEOUT_TYPE timeout,\n"
607  " /* inout */ TRANSACTION_ID_TYPE& transaction_id,\n"
608  " /* inout */ " << cxx_name << "& message,\n"
609  " /* inout */ MESSAGE_SIZE_TYPE& message_size,\n"
610  " /* out */ RETURN_CODE_TYPE& return_code);\n\n" << exporter <<
611  " void Register_Callback(\n"
612  " /* in */ CONNECTION_ID_TYPE connection_id,\n"
613  " /* in */ const WAITSET_TYPE waitset,\n"
614  " /* in */ Read_Callback::send_event_" << name_underscores
615  << "_Ptr data_callback,\n"
616  " /* in */ MESSAGE_SIZE_TYPE max_message_size,\n"
617  " /* out */ RETURN_CODE_TYPE& return_code);\n\n"
618  " }\n"
619  "}\n\n";
620  be_global->facets_impl_ <<
621  "void Receive_Message(CONNECTION_ID_TYPE connection_id,\n"
622  " TIMEOUT_TYPE timeout,\n"
623  " TRANSACTION_ID_TYPE& transaction_id,\n"
624  " " << cxx_name << "& message,\n"
625  " MESSAGE_SIZE_TYPE message_size,\n"
626  " RETURN_CODE_TYPE& return_code) {\n"
627  " OpenDDS::FaceTSS::receive_message(connection_id, timeout,\n"
628  " transaction_id, message,\n"
629  " message_size, return_code);\n"
630  "}\n\n"
631  "void Send_Message(CONNECTION_ID_TYPE connection_id,\n"
632  " TIMEOUT_TYPE timeout,\n"
633  " TRANSACTION_ID_TYPE& transaction_id,\n"
634  " " << cxx_name << "& message,\n"
635  " MESSAGE_SIZE_TYPE& message_size,\n"
636  " RETURN_CODE_TYPE& return_code) {\n"
637  " OpenDDS::FaceTSS::send_message(connection_id, timeout,\n"
638  " transaction_id, message,\n"
639  " message_size, return_code);\n"
640  "}\n\n"
641  "void Register_Callback(CONNECTION_ID_TYPE connection_id,\n"
642  " const WAITSET_TYPE waitset,\n"
643  " Read_Callback::send_event_" << name_underscores
644  << "_Ptr data_callback,\n"
645  " MESSAGE_SIZE_TYPE max_message_size,\n"
646  " RETURN_CODE_TYPE& return_code) {\n"
647  " OpenDDS::FaceTSS::register_callback(connection_id, waitset,\n"
648  " data_callback,\n"
649  " max_message_size, return_code);\n"
650  "}\n\n"
651  "namespace {\n"
652  " OpenDDS::DCPS::TypeSupportInitializer<" << cxx_name << "TypeSupportImpl> ts_init_" << name_underscores << ";\n"
653  "}\n\n";
654  }
655 }
Iterator end()
Definition: topic_keys.cpp:500
#define ACE_ERROR(X)
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
const char * c_str(void) const
bool gen_union(AST_Union *node, UTL_ScopedName *name, const std::vector< AST_UnionBranch *> &, AST_Type *, const char *)
sequence< octet > key
static std::string get_xtag_name(UTL_ScopedName *name)
#define ACE_TEXT_ALWAYS_CHAR(STRING)
void generate(UTL_ScopedName *name)
std::string idl_template_
Definition: ts_generator.h:40
Strip any escapes.
Definition: dds_generator.h:43
int mkdir(const char *path, mode_t mode=ACE_DEFAULT_DIR_PERMS)
size_t count()
Definition: topic_keys.cpp:515
static std::string to_string(Identifier *id, EscapeContext ec=EscapeContext_Normal)
const char * dds_root()
Get DDS_ROOT. It is a fatal error if it wasn&#39;t set.
This is for generated IDL. (Like *TypeSupport.idl)
Definition: dds_generator.h:39
This is for a name coming from generated IDL. (Like *TypeSupportC.h)
Definition: dds_generator.h:41
const char *const name
Definition: debug.cpp:60
ACE_TEXT("TCP_Factory")
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
Iterator begin()
Definition: topic_keys.cpp:495
BE_GlobalData * be_global
Definition: be_global.cpp:44
bool gen_struct(AST_Structure *node, UTL_ScopedName *name, const std::vector< AST_Field *> &fields, AST_Type::SIZE_TYPE size, const char *repoid)
size_type length(void) const
bool generate_ts(AST_Decl *node, UTL_ScopedName *name)
LM_ERROR
DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t &count)