13 #include <utl_identifier.h> 23 ContentSubscriptionGuard()
32 const std::vector<AST_EnumVal*>& contents,
const char*)
35 std::string array_decl =
"const char* gen_" + scoped_helper(name,
"_") +
"_names[]";
36 std::string size_decl =
"const size_t gen_" + scoped_helper(name,
"_") +
"_names_size";
37 std::string decl_prefix = ((
be_global->export_macro() ==
"") ? std::string(
"extern ") : (std::string(
be_global->export_macro().
c_str()) +
" extern "));
38 be_global->header_ << decl_prefix << array_decl <<
";\n";
39 be_global->header_ << decl_prefix << size_decl <<
";\n";
40 be_global->impl_ << array_decl <<
" = {\n";
41 for (
size_t i = 0; i < contents.size(); ++i) {
43 << ((i < contents.size() - 1) ?
"\",\n" :
"\"\n");
46 be_global->impl_ << size_decl <<
" = " << contents.size() <<
";\n";
53 delegateToNested(
const std::string& fieldName, AST_Field* field,
54 const std::string& firstArg)
56 const size_t n = fieldName.size() + 1 ;
57 const std::string fieldType =
scoped(field->field_type()->name());
59 " if (std::strncmp(field, \"" << fieldName <<
".\", " << n
61 " return getMetaStruct<" << fieldType <<
">().getValue(" 62 << firstArg <<
", field + " << n <<
");\n" 67 gen_field_getValue(AST_Field* field)
69 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
71 const std::string fieldName = field->local_name()->get_string();
74 std::string prefix, suffix;
81 prefix +=
"static_cast<int>(";
83 suffix = use_cxx11 ?
"())]" :
"]";
84 }
else if (use_cxx11) {
87 const std::string string_to_ptr = use_cxx11 ?
"" :
".in()";
89 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n" 90 " return " + prefix +
"typed." + fieldName
91 + (cls &
CL_STRING ? string_to_ptr :
"") + suffix +
";\n" 93 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
95 delegateToNested(idl_name, field,
96 "&typed." + std::string(use_cxx11 ?
"_" :
"") + fieldName);
97 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
102 gen_field_createQC(AST_Field* field)
104 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
106 const std::string fieldName = field->local_name()->get_string();
110 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n" 111 " return make_field_cmp(&T::" << (use_cxx11 ?
"_" :
"")
112 << fieldName <<
", next);\n" 114 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
116 const size_t n = idl_name.size() + 1 ;
117 std::string fieldType =
scoped(field->field_type()->name());
119 " if (std::strncmp(field, \"" << idl_name <<
".\", " << n <<
121 " return make_struct_cmp(&T::" << (use_cxx11 ?
"_" :
"")
123 ", getMetaStruct<" << fieldType <<
">().create_qc_comparator(" 124 "field + " << n <<
"), next);\n" 130 print_field_name(AST_Field* field)
136 get_raw_field(AST_Field* field)
138 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
139 const char* fieldName = field->local_name()->get_string();
142 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n" 143 " return &static_cast<const T*>(stru)->" << (use_cxx11 ?
"_" :
"")
144 << fieldName <<
";\n" 146 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
150 assign_field(AST_Field* field)
152 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
155 std::string fieldType = (cls &
CL_STRING) ?
158 if (af.as_base_ && af.type_->anonymous()) {
159 fieldType = af.scoped_type_;
163 || (use_cxx11 && (cls &
CL_ARRAY))) {
165 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n" 166 " static_cast<T*>(lhs)->" << (use_cxx11 ?
"_" :
"") << af.name_ <<
167 " = *static_cast<const " << fieldType <<
168 "*>(rhsMeta.getRawField(rhs, rhsFieldSpec));\n" 171 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
172 }
else if (cls & CL_ARRAY) {
174 AST_Array* arr =
dynamic_cast<AST_Array*
>(unTD);
176 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n" 177 " " << fieldType <<
"* lhsArr = &static_cast<T*>(lhs)->" << af.name_ <<
";\n" 178 " const " << fieldType <<
"* rhsArr = static_cast<const " <<
179 fieldType <<
"*>(rhsMeta.getRawField(rhs, rhsFieldSpec));\n";
180 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
181 AST_Type* elem = arr->base_type();
183 if (
classify(elemUnTD) & CL_ARRAY) {
186 " " << fieldType <<
"_forany rhsForany(const_cast<" <<
187 fieldType <<
"_slice*>(*rhsArr));\n" 189 " const Encoding encoding(Encoding::KIND_UNALIGNED_CDR);\n" 190 " ACE_Message_Block mb(serialized_size(encoding, rhsForany));\n" 191 " Serializer ser_out(&mb, encoding);\n" 192 " ser_out << rhsForany;\n" 193 " " << fieldType <<
"_forany lhsForany(*lhsArr);\n" 194 " Serializer ser_in(&mb, encoding);\n" 195 " ser_in >> lhsForany;\n";
197 std::string indent =
" ";
200 indent <<
"(*lhsArr)" << nfl.
index_ <<
" = (*rhsArr)" <<
210 compare_field(AST_Field* field)
212 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
215 const char* fieldName = field->local_name()->get_string();
218 " if (std::strcmp(field, \"" << idl_name <<
"\") == 0) {\n";
219 be_global->add_include(
"<cstring>", BE_GlobalData::STREAM_CPP);
222 " return 0 == ACE_OS::strcmp(static_cast<const T*>(lhs)->" 223 << fieldName <<
".in(), static_cast<const T*>(rhs)->" << fieldName
227 " return static_cast<const T*>(lhs)->" << (use_cxx11 ?
"_" :
"")
228 << fieldName <<
" == static_cast<const T*>(rhs)->" << (use_cxx11 ?
"_" :
"")
229 << fieldName <<
";\n";
235 generate_metaclass(AST_Decl* node, UTL_ScopedName*
name,
236 const std::vector<AST_Field*>& fields,
bool& first_struct_,
237 const std::string& clazz)
239 AST_Structure* struct_node = 0;
240 AST_Union* union_node = 0;
241 if (!node || !name) {
244 if (node->node_type() == AST_Decl::NT_struct) {
245 struct_node =
dynamic_cast<AST_Structure*
>(node);
246 }
else if (node->node_type() == AST_Decl::NT_union) {
247 union_node =
dynamic_cast<AST_Union*
>(node);
255 "class MetaStruct;\n\n" 256 "template<typename T>\n" 257 "const MetaStruct& getMetaStruct();\n\n";
258 first_struct_ =
false;
261 be_global->add_include(
"dds/DCPS/FilterEvaluator.h",
262 BE_GlobalData::STREAM_CPP);
264 std::string decl =
"const MetaStruct& getMetaStruct<" + clazz +
">()",
266 be_global->header_ <<
"template<>\n" << exp << (exp.length() ?
"\n" :
"")
270 IDL_GlobalData::DCPS_Data_Type_Info* info = 0;
271 const bool is_topic_type =
be_global->is_topic_type(node);
273 info = idl_global->is_dcps_type(name);
277 key_count = info->key_list_.size();
280 key_count =
be_global->union_discriminator_is_key(union_node) ? 1 : 0;
283 const std::string exception =
284 "throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 285 "found or its type is not supported (in struct" + clazz +
")\");\n";
289 "struct MetaStructImpl<" << clazz <<
"> : MetaStruct {\n" 290 " typedef " << clazz <<
" T;\n\n" 291 "#ifndef OPENDDS_NO_MULTI_TOPIC\n" 292 " void* allocate() const { return new T; }\n\n" 293 " void deallocate(void* stru) const { delete static_cast<T*>(stru); }\n\n" 294 " size_t numDcpsKeys() const { return " << key_count <<
"; }\n\n" 295 "#endif /* OPENDDS_NO_MULTI_TOPIC */\n\n";
298 " ACE_CDR::ULong map_name_to_id(const char* field) const\n" 300 " static const std::pair<std::string, ACE_CDR::ULong> name_to_id_pairs[] = {\n";
301 for (
size_t i = 0; i < fields.size(); ++i) {
307 " static const std::map<std::string, ACE_CDR::ULong> name_to_id_map(name_to_id_pairs," 308 " name_to_id_pairs + " << fields.size() <<
");\n" 309 " std::map<std::string, ACE_CDR::ULong>::const_iterator it = name_to_id_map.find(field);\n" 310 " if (it == name_to_id_map.end()) {\n" 313 " return it->second;\n" 318 " Value getValue(const void* stru, const char* field) const\n" 320 " const" << clazz <<
"& typed = *static_cast<const" << clazz <<
"*>(stru);\n" 321 " ACE_UNUSED_ARG(typed);\n";
322 std::for_each(fields.begin(), fields.end(), gen_field_getValue);
330 " Value getValue(Serializer& ser, const char* field, const TypeSupportImpl* = 0) const\n" 332 " ACE_UNUSED_ARG(ser);\n" 333 " if (!field[0]) {\n" 336 " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 337 "valid for union" << type_idl_name <<
"\");\n" 341 " ComparatorBase::Ptr create_qc_comparator(const char* field, " 342 "ComparatorBase::Ptr next) const\n" 344 " ACE_UNUSED_ARG(next);\n";
345 be_global->add_include(
"<stdexcept>", BE_GlobalData::STREAM_CPP);
347 std::for_each(fields.begin(), fields.end(), gen_field_createQC);
352 "#ifndef OPENDDS_NO_MULTI_TOPIC\n" 353 " const char** getFieldNames() const\n" 355 " static const char* names[] = {";
357 std::for_each(fields.begin(), fields.end(), print_field_name);
363 " const void* getRawField(const void* stru, const char* field) const\n" 365 if (struct_node && fields.size()) {
366 std::for_each(fields.begin(), fields.end(), get_raw_field);
368 be_global->impl_ <<
" ACE_UNUSED_ARG(stru);\n";
373 " void assign(void* lhs, const char* field, const void* rhs,\n" 374 " const char* rhsFieldSpec, const MetaStruct& rhsMeta) const\n" 376 " ACE_UNUSED_ARG(lhs);\n" 377 " ACE_UNUSED_ARG(field);\n" 378 " ACE_UNUSED_ARG(rhs);\n" 379 " ACE_UNUSED_ARG(rhsFieldSpec);\n" 380 " ACE_UNUSED_ARG(rhsMeta);\n";
382 std::for_each(fields.begin(), fields.end(), assign_field);
388 " bool compare(const void* lhs, const void* rhs, const char* field) " 391 " ACE_UNUSED_ARG(lhs);\n" 392 " ACE_UNUSED_ARG(field);\n" 393 " ACE_UNUSED_ARG(rhs);\n";
395 std::for_each(fields.begin(), fields.end(), compare_field);
400 "#endif /* OPENDDS_NO_MULTI_TOPIC */\n\n" 405 " static MetaStructImpl<" << clazz <<
"> msi;\n" 414 const Fields fields(node);
417 AST_Field*
const field = *i;
418 if (field->field_type()->anonymous()) {
421 Function f(
"gen_skip_over",
"bool");
422 f.
addArg(
"ser",
"Serializer&");
428 elem = af.
seq_->base_type();
430 elem = af.
arr_->base_type();
433 " const Encoding& encoding = ser.encoding();\n" 434 " ACE_UNUSED_ARG(encoding);\n";
438 " if (!ser.read_delimiter(total_size)) {\n" 440 " }\n", !primitive,
true);
444 std::ostringstream strstream;
446 len = strstream.str();
449 " ACE_CDR::ULong length;\n" 450 " if (!(ser >> length)) return false;\n";
453 const std::string cxx_elem =
scoped(elem->name());
454 AST_Type* elem_orig = elem;
458 if ((elem_cls & (CL_PRIMITIVE |
CL_ENUM))) {
463 " return ser.skip(" << af.
length_ <<
", " << sz <<
");\n";
466 " for (ACE_CDR::ULong i = 0; i < " << len <<
"; ++i) {\n";
469 " ACE_CDR::ULong strlength;\n" 470 " if (!(ser >> strlength && ser.skip(strlength))) return false;\n";
472 std::string pre, post;
473 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
474 if (!use_cxx11 && (elem_cls &
CL_ARRAY)) {
476 }
else if (use_cxx11 && (elem_cls & (CL_ARRAY |
CL_SEQUENCE))) {
477 pre =
"IDL::DistinctType<";
481 " if (!gen_skip_over(ser, static_cast<" << pre << cxx_elem << post
482 <<
"*>(0))) return false;\n";
496 const std::vector<AST_Field*>& fields, AST_Type::SIZE_TYPE,
const char*)
498 const std::string clazz =
scoped(name);
500 be_global->add_include(
"dds/DCPS/PoolAllocator.h",
501 BE_GlobalData::STREAM_CPP);
503 ContentSubscriptionGuard csg;
506 if (!generate_metaclass(node, name, fields, first_struct_, clazz)) {
513 Function f(
"gen_skip_over",
"bool");
514 f.
addArg(
"ser",
"Serializer&");
515 f.
addArg(
"", clazz +
"*");
518 " MetaStructImpl<" << clazz <<
">().getValue(ser, \"\");\n" 526 AST_Type* type,
const char*)
528 AST_Array* arr =
dynamic_cast<AST_Array*
>(type);
529 AST_Sequence* seq = 0;
530 if (!arr && !(seq = dynamic_cast<AST_Sequence*>(type))) {
533 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
534 const std::string clazz =
scoped(name);
536 ContentSubscriptionGuard csg;
538 Function f(
"gen_skip_over",
"bool");
539 f.
addArg(
"ser",
"Serializer&");
543 f.
addArg(
"", clazz + (arr ?
"_forany*" :
"*"));
549 elem = seq->base_type();
551 elem = arr->base_type();
554 " const Encoding& encoding = ser.encoding();\n" 555 " ACE_UNUSED_ARG(encoding);\n";
559 " if (!ser.read_delimiter(total_size)) {\n" 561 " }\n", !primitive,
true);
566 std::ostringstream strstream;
568 len = strstream.str();
571 " ACE_CDR::ULong length;\n" 572 " if (!(ser >> length)) return false;\n";
576 const std::string cxx_elem =
scoped(elem->name());
577 AST_Type* elem_orig = elem;
581 if ((elem_cls & (CL_PRIMITIVE |
CL_ENUM))) {
586 " return ser.skip(" << len <<
", " << sz <<
");\n";
589 " for (ACE_CDR::ULong i = 0; i < " << len <<
"; ++i) {\n";
592 " ACE_CDR::ULong strlength;\n" 593 " if (!(ser >> strlength && ser.skip(strlength))) return false;\n";
595 std::string pre, post;
596 if (!use_cxx11 && (elem_cls &
CL_ARRAY)) {
598 }
else if (use_cxx11 && (elem_cls & (CL_ARRAY |
CL_SEQUENCE))) {
599 pre =
"IDL::DistinctType<";
603 " if (!gen_skip_over(ser, static_cast<" << pre << cxx_elem << post
604 <<
"*>(0))) return false;\n";
616 AST_Type* br_type,
const std::string&,
bool,
Intro&,
const std::string&)
618 const bool use_cxx11 =
be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
619 std::stringstream ss;
622 " if (is_mutable && !ser.read_parameter_id(member_id, field_size, must_understand)) {\n" 627 " ACE_CDR::ULong len;\n" 628 " if (!(ser >> len && ser.skip(len))) return false;\n";
633 " if (!ser.skip(1, " << sz <<
")) return false;\n";
635 std::string pre, post;
636 if (!use_cxx11 && (br_cls &
CL_ARRAY)) {
638 }
else if (use_cxx11 && (br_cls & (CL_ARRAY |
CL_SEQUENCE))) {
639 pre =
"IDL::DistinctType<";
643 " if (!gen_skip_over(ser, static_cast<" << pre
644 <<
field_type_name(dynamic_cast<AST_Field*>(branch), br_type) << post <<
645 "*>(0))) return false;\n";
655 const std::vector<AST_UnionBranch*>& branches, AST_Type* discriminator,
658 const std::string clazz =
scoped(name);
660 ContentSubscriptionGuard csg;
663 std::vector<AST_Field*> dummy_field_list;
664 if (!generate_metaclass(node, name, dummy_field_list, first_struct_, clazz)) {
671 Function f(
"gen_skip_over",
"bool");
672 f.
addArg(
"ser",
"Serializer&");
673 f.
addArg(
"", clazz +
"*");
680 " const Encoding& encoding = ser.encoding();\n" 681 " ACE_UNUSED_ARG(encoding);\n" 682 " const bool is_mutable = " << is_mutable <<
";\n" 683 " unsigned member_id;\n" 684 " size_t field_size;\n" 685 " bool must_understand = false;\n";
687 " if (!ser.read_delimiter(total_size)) {\n" 692 " if (!ser.read_parameter_id(member_id, field_size, must_understand)) {\n" 697 " " <<
scoped(discriminator->name()) <<
" disc;\n" 702 false,
true,
false)) {
std::string to_cxx_type(AST_Type *type, std::size_t &size)
bool is_new(EleLenSet &el_set) const
Classification classify(AST_Type *type)
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 *> &branches, AST_Type *type, const char *repoid)
std::string string_type(AstTypeClassification::Classification cls)
const Classification CL_STRING
static void gen_field_getValueFromSerialized(AST_Structure *node, const std::string &clazz)
const Classification CL_SCALAR
std::string field_type_name(AST_Field *field, AST_Type *field_type)
const Classification CL_PRIMITIVE
bool gen_enum(AST_Enum *node, UTL_ScopedName *name, const std::vector< AST_EnumVal *> &contents, const char *repoid)
static std::string get_tag_name(const std::string &base_name, const std::string &qualifier="")
AST_Type * deepest_named_type(AST_Type *type)
const Classification CL_ARRAY
static std::string gen_union_branch(const std::string &, AST_Decl *branch, const std::string &, AST_Type *br_type, const std::string &, bool, Intro &, const std::string &)
bool generateSwitchForUnion(AST_Union *u, const char *switchExpr, CommonFn commonFn, const std::vector< AST_UnionBranch *> &branches, AST_Type *discriminator, const char *statementPrefix, const char *namePrefix="", const char *uni="", bool forceDisableDefault=false, bool parens=true, bool breaks=true, CommonFn commonFn2=0)
returns true if a default: branch was generated (no default: label in IDL)
std::string canonical_name(UTL_ScopedName *sn)
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
AST_Type * resolveActualType(AST_Type *element)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
bool gen_typedef(AST_Typedef *node, UTL_ScopedName *name, AST_Type *type, const char *repoid)
std::set< EleLen > EleLenSet
const Classification CL_STRUCTURE
void addArg(const char *name, const std::string &type)
BE_GlobalData * be_global
ACE_CDR::ULong array_element_count(AST_Array *arr)
bool gen_struct(AST_Structure *node, UTL_ScopedName *name, const std::vector< AST_Field *> &fields, AST_Type::SIZE_TYPE size, const char *repoid)
const Classification CL_ENUM
const Classification CL_SEQUENCE
DDS::ReturnCode_t key_count(DDS::DynamicType_ptr type, size_t &count)
void generate_anon_fields(AST_Structure *node)
const Classification CL_UNION