#include <metaclass_generator.h>
Inheritance diagram for metaclass_generator:
Public Member Functions | |
metaclass_generator () | |
bool | gen_enum (AST_Enum *node, UTL_ScopedName *name, const std::vector< AST_EnumVal * > &contents, const char *repoid) |
bool | gen_struct (AST_Structure *node, UTL_ScopedName *name, const std::vector< AST_Field * > &fields, AST_Type::SIZE_TYPE size, const char *repoid) |
bool | gen_typedef (AST_Typedef *node, UTL_ScopedName *name, AST_Type *type, const char *repoid) |
bool | gen_union (AST_Union *node, UTL_ScopedName *name, const std::vector< AST_UnionBranch * > &branches, AST_Type *type, const char *repoid) |
Private Attributes | |
bool | first_struct_ |
Definition at line 13 of file metaclass_generator.h.
metaclass_generator::metaclass_generator | ( | ) | [inline] |
bool metaclass_generator::gen_enum | ( | AST_Enum * | node, | |
UTL_ScopedName * | name, | |||
const std::vector< AST_EnumVal * > & | contents, | |||
const char * | repoid | |||
) | [virtual] |
Reimplemented from dds_generator.
Definition at line 38 of file metaclass_generator.cpp.
References be_global, BE_GlobalData::header_, BE_GlobalData::impl_, dds_generator::scoped_helper(), and BE_GlobalData::v8().
00040 { 00041 ContentSubscriptionGuard csg(!be_global->v8()); 00042 NamespaceGuard ng; 00043 std::string decl = "const char* gen_" + scoped_helper(name, "_") + "_names[]"; 00044 be_global->header_ << "extern " << decl << ";\n"; 00045 be_global->impl_ << decl << " = {\n"; 00046 for (size_t i = 0; i < contents.size(); ++i) { 00047 be_global->impl_ << " \"" << contents[i]->local_name()->get_string() 00048 << ((i < contents.size() - 1) ? "\",\n" : "\"\n"); 00049 } 00050 be_global->impl_ << "};\n"; 00051 return true; 00052 }
bool metaclass_generator::gen_struct | ( | AST_Structure * | node, | |
UTL_ScopedName * | name, | |||
const std::vector< AST_Field * > & | fields, | |||
AST_Type::SIZE_TYPE | size, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 328 of file metaclass_generator.cpp.
References BE_GlobalData::add_include(), Function::addArg(), assign_field(), be_global, compare_field(), Function::endArgs(), BE_GlobalData::export_macro(), first_struct_, gen_field_createQC(), gen_field_getValue(), gen_field_getValueFromSerialized(), get_raw_field(), BE_GlobalData::header_, BE_GlobalData::impl_, print_field_name(), scoped(), and BE_GlobalData::STREAM_CPP.
00330 { 00331 ContentSubscriptionGuard csg; 00332 NamespaceGuard ng; 00333 be_global->add_include("dds/DCPS/PoolAllocator.h", 00334 BE_GlobalData::STREAM_CPP); 00335 be_global->add_include("dds/DCPS/FilterEvaluator.h", 00336 BE_GlobalData::STREAM_CPP); 00337 if (first_struct_) { 00338 be_global->header_ << 00339 "class MetaStruct;\n\n" 00340 "template<typename T>\n" 00341 "const MetaStruct& getMetaStruct();\n\n"; 00342 first_struct_ = false; 00343 } 00344 00345 size_t nKeys = 0; 00346 IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name); 00347 if (info) { 00348 nKeys = info->key_list_.size(); 00349 } 00350 00351 std::string clazz = scoped(name); 00352 std::string decl = "const MetaStruct& getMetaStruct<" + clazz + ">()", 00353 exp = be_global->export_macro().c_str(); 00354 be_global->header_ << "template<>\n" << exp << (exp.length() ? "\n" : "") 00355 << decl << ";\n"; 00356 00357 be_global->impl_ << 00358 "template<>\n" 00359 "struct MetaStructImpl<" << clazz << "> : MetaStruct {\n" 00360 " typedef " << clazz << " T;\n\n" 00361 " void* allocate() const { return new T; }\n\n" 00362 " void deallocate(void* stru) const { delete static_cast<T*>(stru); }\n\n" 00363 " size_t numDcpsKeys() const { return " << nKeys << "; }\n\n" 00364 " Value getValue(const void* stru, const char* field) const\n" 00365 " {\n" 00366 " const " << clazz << "& typed = *static_cast<const " << clazz 00367 << "*>(stru);\n"; 00368 std::for_each(fields.begin(), fields.end(), gen_field_getValue); 00369 const std::string exception = 00370 " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 00371 "found or its type is not supported (in struct " + clazz + ")\");\n"; 00372 be_global->impl_ << 00373 " ACE_UNUSED_ARG(typed);\n" << 00374 exception << 00375 " }\n\n" 00376 " Value getValue(Serializer& ser, const char* field) const\n" 00377 " {\n"; 00378 std::for_each(fields.begin(), fields.end(), gen_field_getValueFromSerialized); 00379 be_global->impl_ << 00380 " if (!field[0]) {\n" // if 'field' is the empty string... 00381 " return 0;\n" // ...we've skipped the entire struct 00382 " }\n" // and the return value is ignored 00383 " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 00384 "valid for struct " << clazz << "\");\n" 00385 " }\n\n" 00386 " ComparatorBase::Ptr create_qc_comparator(const char* field, " 00387 "ComparatorBase::Ptr next) const\n" 00388 " {\n" 00389 " ACE_UNUSED_ARG(next);\n"; 00390 be_global->add_include("<stdexcept>", BE_GlobalData::STREAM_CPP); 00391 std::for_each(fields.begin(), fields.end(), gen_field_createQC); 00392 be_global->impl_ << 00393 exception << 00394 " }\n\n" 00395 " const char** getFieldNames() const\n" 00396 " {\n" 00397 " static const char* names[] = {"; 00398 std::for_each(fields.begin(), fields.end(), print_field_name); 00399 be_global->impl_ << 00400 "0};\n" 00401 " return names;\n" 00402 " }\n\n" 00403 " const void* getRawField(const void* stru, const char* field) const\n" 00404 " {\n"; 00405 std::for_each(fields.begin(), fields.end(), get_raw_field); 00406 be_global->impl_ << 00407 exception << 00408 " }\n\n" 00409 " void assign(void* lhs, const char* field, const void* rhs,\n" 00410 " const char* rhsFieldSpec, const MetaStruct& rhsMeta) const\n" 00411 " {\n" 00412 " ACE_UNUSED_ARG(lhs);\n" 00413 " ACE_UNUSED_ARG(field);\n" 00414 " ACE_UNUSED_ARG(rhs);\n" 00415 " ACE_UNUSED_ARG(rhsFieldSpec);\n" 00416 " ACE_UNUSED_ARG(rhsMeta);\n"; 00417 std::for_each(fields.begin(), fields.end(), assign_field); 00418 be_global->impl_ << 00419 exception << 00420 " }\n\n" 00421 " bool compare(const void* lhs, const void* rhs, const char* field) " 00422 "const\n" 00423 " {\n" 00424 " ACE_UNUSED_ARG(lhs);\n" 00425 " ACE_UNUSED_ARG(field);\n" 00426 " ACE_UNUSED_ARG(rhs);\n"; 00427 std::for_each(fields.begin(), fields.end(), compare_field); 00428 be_global->impl_ << 00429 exception << 00430 " }\n" 00431 "};\n\n" 00432 "template<>\n" 00433 << decl << "\n" 00434 "{\n" 00435 " static MetaStructImpl<" << clazz << "> msi;\n" 00436 " return msi;\n" 00437 "}\n\n"; 00438 { 00439 Function f("gen_skip_over", "void"); 00440 f.addArg("ser", "Serializer&"); 00441 f.addArg("", clazz + "*"); 00442 f.endArgs(); 00443 be_global->impl_ << 00444 " MetaStructImpl<" << clazz << ">().getValue(ser, \"\");\n"; 00445 } 00446 return true; 00447 }
bool metaclass_generator::gen_typedef | ( | AST_Typedef * | node, | |
UTL_ScopedName * | name, | |||
AST_Type * | type, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 450 of file metaclass_generator.cpp.
References Function::addArg(), be_global, AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_PRIMITIVE, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::CL_WIDE, AstTypeClassification::classify(), Function::endArgs(), BE_GlobalData::impl_, AstTypeClassification::resolveActualType(), scoped(), and to_cxx_type().
00451 { 00452 AST_Array* arr = AST_Array::narrow_from_decl(type); 00453 AST_Sequence* seq = 0; 00454 if (!arr && !(seq = AST_Sequence::narrow_from_decl(type))) { 00455 return true; 00456 } 00457 00458 const Classification cls = classify(type); 00459 const std::string clazz = scoped(name); 00460 ContentSubscriptionGuard csg; 00461 NamespaceGuard ng; 00462 Function f("gen_skip_over", "void"); 00463 f.addArg("ser", "Serializer&"); 00464 f.addArg("", clazz + ((cls & CL_ARRAY) ? "_forany*" : "*")); 00465 f.endArgs(); 00466 00467 std::string len; 00468 AST_Type* elem; 00469 00470 if (arr) { 00471 elem = arr->base_type(); 00472 size_t n_elems = 1; 00473 for (size_t i = 0; i < arr->n_dims(); ++i) { 00474 n_elems *= arr->dims()[i]->ev()->u.ulval; 00475 } 00476 std::ostringstream strstream; 00477 strstream << n_elems; 00478 len = strstream.str(); 00479 } else { // Sequence 00480 elem = seq->base_type(); 00481 be_global->impl_ << 00482 " ACE_CDR::ULong length;\n" 00483 " ser >> length;\n"; 00484 len = "length"; 00485 } 00486 00487 const std::string cxx_elem = scoped(elem->name()); 00488 elem = resolveActualType(elem); 00489 const Classification elem_cls = classify(elem); 00490 00491 if ((elem_cls & (CL_PRIMITIVE | CL_ENUM)) && !(elem_cls & CL_WIDE)) { 00492 // fixed-length sequence/array element -> skip all elements at once 00493 int sz = 1; 00494 to_cxx_type(elem, sz); 00495 be_global->impl_ << 00496 " ser.skip(" << len << ", " << sz << ");\n"; 00497 } else { 00498 be_global->impl_ << 00499 " for (ACE_CDR::ULong i = 0; i < " << len << "; ++i) {\n"; 00500 if ((elem_cls & CL_PRIMITIVE) && (elem_cls & CL_WIDE)) { 00501 be_global->impl_ << 00502 " ACE_CDR::Octet o;\n" 00503 " ser >> ACE_InputCDR::to_octet(o);\n" 00504 " ser.skip(o);\n"; 00505 } else if (elem_cls & CL_STRING) { 00506 be_global->impl_ << 00507 " ACE_CDR::ULong strlength;\n" 00508 " ser >> strlength;\n" 00509 " ser.skip(strlength);\n"; 00510 } else if (elem_cls & (CL_ARRAY | CL_SEQUENCE | CL_STRUCTURE)) { 00511 be_global->impl_ << 00512 " gen_skip_over(ser, static_cast<" << cxx_elem 00513 << ((elem_cls & CL_ARRAY) ? "_forany" : "") << "*>(0));\n"; 00514 } 00515 be_global->impl_ << 00516 " }\n"; 00517 } 00518 00519 return true; 00520 }
bool metaclass_generator::gen_union | ( | AST_Union * | node, | |
UTL_ScopedName * | name, | |||
const std::vector< AST_UnionBranch * > & | branches, | |||
AST_Type * | type, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 555 of file metaclass_generator.cpp.
References Function::addArg(), be_global, Function::endArgs(), func(), generateSwitchForUnion(), getWrapper(), BE_GlobalData::impl_, scoped(), and WD_INPUT.
00558 { 00559 const std::string clazz = scoped(name); 00560 ContentSubscriptionGuard csg; 00561 NamespaceGuard ng; 00562 Function f("gen_skip_over", "void"); 00563 f.addArg("ser", "Serializer&"); 00564 f.addArg("", clazz + "*"); 00565 f.endArgs(); 00566 be_global->impl_ << 00567 " " << scoped(discriminator->name()) << " disc;\n" 00568 " if (!(ser >> " << getWrapper("disc", discriminator, WD_INPUT) << ")) {\n" 00569 " return;\n" 00570 " }\n"; 00571 generateSwitchForUnion("disc", func, branches, discriminator, ""); 00572 return true; 00573 }
bool metaclass_generator::first_struct_ [private] |