#include <metaclass_generator.h>
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] |
Definition at line 15 of file metaclass_generator.h.
00016 : first_struct_(true) 00017 {}
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, and dds_generator::scoped_helper().
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 343 of file metaclass_generator.cpp.
References Function::addArg(), be_global, ACE_String_Base< ACE_CHAR_T >::c_str(), Function::endArgs(), first_struct_, and scoped().
00345 { 00346 ContentSubscriptionGuard csg; 00347 NamespaceGuard ng; 00348 be_global->add_include("dds/DCPS/PoolAllocator.h", 00349 BE_GlobalData::STREAM_CPP); 00350 be_global->add_include("dds/DCPS/FilterEvaluator.h", 00351 BE_GlobalData::STREAM_CPP); 00352 if (first_struct_) { 00353 be_global->header_ << 00354 "class MetaStruct;\n\n" 00355 "template<typename T>\n" 00356 "const MetaStruct& getMetaStruct();\n\n"; 00357 first_struct_ = false; 00358 } 00359 00360 size_t nKeys = 0; 00361 IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name); 00362 if (info) { 00363 nKeys = info->key_list_.size(); 00364 } 00365 00366 std::string clazz = scoped(name); 00367 std::string decl = "const MetaStruct& getMetaStruct<" + clazz + ">()", 00368 exp = be_global->export_macro().c_str(); 00369 be_global->header_ << "template<>\n" << exp << (exp.length() ? "\n" : "") 00370 << decl << ";\n"; 00371 00372 be_global->impl_ << 00373 "template<>\n" 00374 "struct MetaStructImpl<" << clazz << "> : MetaStruct {\n" 00375 " typedef " << clazz << " T;\n\n" 00376 "#ifndef OPENDDS_NO_MULTI_TOPIC\n" 00377 " void* allocate() const { return new T; }\n\n" 00378 " void deallocate(void* stru) const { delete static_cast<T*>(stru); }\n\n" 00379 " size_t numDcpsKeys() const { return " << nKeys << "; }\n" 00380 "#endif /* OPENDDS_NO_MULTI_TOPIC */\n\n" 00381 " Value getValue(const void* stru, const char* field) const\n" 00382 " {\n" 00383 " const " << clazz << "& typed = *static_cast<const " << clazz 00384 << "*>(stru);\n"; 00385 std::for_each(fields.begin(), fields.end(), gen_field_getValue); 00386 const std::string exception = 00387 " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 00388 "found or its type is not supported (in struct " + clazz + ")\");\n"; 00389 be_global->impl_ << 00390 " ACE_UNUSED_ARG(typed);\n" << 00391 exception << 00392 " }\n\n" 00393 " Value getValue(Serializer& ser, const char* field) const\n" 00394 " {\n"; 00395 std::for_each(fields.begin(), fields.end(), gen_field_getValueFromSerialized); 00396 be_global->impl_ << 00397 " if (!field[0]) {\n" // if 'field' is the empty string... 00398 " return 0;\n" // ...we've skipped the entire struct 00399 " }\n" // and the return value is ignored 00400 " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not " 00401 "valid for struct " << clazz << "\");\n" 00402 " }\n\n" 00403 " ComparatorBase::Ptr create_qc_comparator(const char* field, " 00404 "ComparatorBase::Ptr next) const\n" 00405 " {\n" 00406 " ACE_UNUSED_ARG(next);\n"; 00407 be_global->add_include("<stdexcept>", BE_GlobalData::STREAM_CPP); 00408 std::for_each(fields.begin(), fields.end(), gen_field_createQC); 00409 be_global->impl_ << 00410 exception << 00411 " }\n\n" 00412 "#ifndef OPENDDS_NO_MULTI_TOPIC\n" 00413 " const char** getFieldNames() const\n" 00414 " {\n" 00415 " static const char* names[] = {"; 00416 std::for_each(fields.begin(), fields.end(), print_field_name); 00417 be_global->impl_ << 00418 "0};\n" 00419 " return names;\n" 00420 " }\n\n" 00421 " const void* getRawField(const void* stru, const char* field) const\n" 00422 " {\n"; 00423 std::for_each(fields.begin(), fields.end(), get_raw_field); 00424 be_global->impl_ << 00425 exception << 00426 " }\n\n" 00427 " void assign(void* lhs, const char* field, const void* rhs,\n" 00428 " const char* rhsFieldSpec, const MetaStruct& rhsMeta) const\n" 00429 " {\n" 00430 " ACE_UNUSED_ARG(lhs);\n" 00431 " ACE_UNUSED_ARG(field);\n" 00432 " ACE_UNUSED_ARG(rhs);\n" 00433 " ACE_UNUSED_ARG(rhsFieldSpec);\n" 00434 " ACE_UNUSED_ARG(rhsMeta);\n"; 00435 std::for_each(fields.begin(), fields.end(), assign_field); 00436 be_global->impl_ << 00437 exception << 00438 " }\n" 00439 "#endif /* OPENDDS_NO_MULTI_TOPIC */\n\n" 00440 " bool compare(const void* lhs, const void* rhs, const char* field) " 00441 "const\n" 00442 " {\n" 00443 " ACE_UNUSED_ARG(lhs);\n" 00444 " ACE_UNUSED_ARG(field);\n" 00445 " ACE_UNUSED_ARG(rhs);\n"; 00446 std::for_each(fields.begin(), fields.end(), compare_field); 00447 be_global->impl_ << 00448 exception << 00449 " }\n" 00450 "};\n\n" 00451 "template<>\n" 00452 << decl << "\n" 00453 "{\n" 00454 " static MetaStructImpl<" << clazz << "> msi;\n" 00455 " return msi;\n" 00456 "}\n\n"; 00457 { 00458 Function f("gen_skip_over", "bool"); 00459 f.addArg("ser", "Serializer&"); 00460 f.addArg("", clazz + "*"); 00461 f.endArgs(); 00462 be_global->impl_ << 00463 " MetaStructImpl<" << clazz << ">().getValue(ser, \"\");\n" 00464 " return true;\n"; 00465 } 00466 return true; 00467 }
bool metaclass_generator::gen_typedef | ( | AST_Typedef * | node, | |
UTL_ScopedName * | name, | |||
AST_Type * | type, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 470 of file metaclass_generator.cpp.
References Function::addArg(), be_global, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::classify(), Function::endArgs(), len, AstTypeClassification::resolveActualType(), and scoped().
00471 { 00472 AST_Array* arr = AST_Array::narrow_from_decl(type); 00473 AST_Sequence* seq = 0; 00474 if (!arr && !(seq = AST_Sequence::narrow_from_decl(type))) { 00475 return true; 00476 } 00477 00478 const Classification cls = classify(type); 00479 const std::string clazz = scoped(name); 00480 ContentSubscriptionGuard csg; 00481 NamespaceGuard ng; 00482 Function f("gen_skip_over", "bool"); 00483 f.addArg("ser", "Serializer&"); 00484 f.addArg("", clazz + ((cls & CL_ARRAY) ? "_forany*" : "*")); 00485 f.endArgs(); 00486 00487 std::string len; 00488 AST_Type* elem; 00489 00490 if (arr) { 00491 elem = arr->base_type(); 00492 size_t n_elems = 1; 00493 for (size_t i = 0; i < arr->n_dims(); ++i) { 00494 n_elems *= arr->dims()[i]->ev()->u.ulval; 00495 } 00496 std::ostringstream strstream; 00497 strstream << n_elems; 00498 len = strstream.str(); 00499 } else { // Sequence 00500 elem = seq->base_type(); 00501 be_global->impl_ << 00502 " ACE_CDR::ULong length;\n" 00503 " if (!(ser >> length)) return false;\n"; 00504 len = "length"; 00505 } 00506 00507 const std::string cxx_elem = scoped(elem->name()); 00508 elem = resolveActualType(elem); 00509 const Classification elem_cls = classify(elem); 00510 00511 if ((elem_cls & (CL_PRIMITIVE | CL_ENUM)) && !(elem_cls & CL_WIDE)) { 00512 // fixed-length sequence/array element -> skip all elements at once 00513 int sz = 1; 00514 to_cxx_type(elem, sz); 00515 be_global->impl_ << 00516 " return ser.skip(static_cast<ACE_UINT16>(" << len << "), " << sz << ");\n"; 00517 } else { 00518 be_global->impl_ << 00519 " for (ACE_CDR::ULong i = 0; i < " << len << "; ++i) {\n"; 00520 if ((elem_cls & CL_PRIMITIVE) && (elem_cls & CL_WIDE)) { 00521 be_global->impl_ << 00522 " ACE_CDR::Octet o;\n" 00523 " if (!(ser >> ACE_InputCDR::to_octet(o))) return false;\n" 00524 " if (!ser.skip(o)) return false;\n"; 00525 } else if (elem_cls & CL_STRING) { 00526 be_global->impl_ << 00527 " ACE_CDR::ULong strlength;\n" 00528 " if (!(ser >> strlength)) return false;\n" 00529 " if (!ser.skip(static_cast<ACE_UINT16>(strlength))) return false;\n"; 00530 } else if (elem_cls & (CL_ARRAY | CL_SEQUENCE | CL_STRUCTURE)) { 00531 be_global->impl_ << 00532 " if (!gen_skip_over(ser, static_cast<" << cxx_elem << 00533 ((elem_cls & CL_ARRAY) ? "_forany" : "") << "*>(0))) return false;\n"; 00534 } 00535 be_global->impl_ << 00536 " }\n"; 00537 be_global->impl_ << 00538 " return true;\n"; 00539 } 00540 00541 return true; 00542 }
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 579 of file metaclass_generator.cpp.
References Function::addArg(), be_global, Function::endArgs(), func(), generateSwitchForUnion(), getWrapper(), scoped(), and WD_INPUT.
00582 { 00583 const std::string clazz = scoped(name); 00584 ContentSubscriptionGuard csg; 00585 NamespaceGuard ng; 00586 Function f("gen_skip_over", "bool"); 00587 f.addArg("ser", "Serializer&"); 00588 f.addArg("", clazz + "*"); 00589 f.endArgs(); 00590 be_global->impl_ << 00591 " " << scoped(discriminator->name()) << " disc;\n" 00592 " if (!(ser >> " << getWrapper("disc", discriminator, WD_INPUT) << ")) {\n" 00593 " return false;\n" 00594 " }\n"; 00595 if (generateSwitchForUnion("disc", func, branches, discriminator, "", "", "", 00596 false, true, false)) { 00597 be_global->impl_ << 00598 " return true;\n"; 00599 } 00600 return true; 00601 }
bool metaclass_generator::first_struct_ [private] |
Definition at line 33 of file metaclass_generator.h.
Referenced by gen_struct().