#include <marshal_generator.h>
Public Member Functions | |
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 *base, const char *repoid) |
bool | gen_union (AST_Union *node, UTL_ScopedName *name, const std::vector< AST_UnionBranch * > &branches, AST_Type *discriminator, const char *repoid) |
Definition at line 13 of file marshal_generator.h.
bool marshal_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 125 of file marshal_generator.cpp.
References Function::addArg(), be_global, Function::endArgs(), and scoped().
00127 { 00128 NamespaceGuard ng; 00129 be_global->add_include("dds/DCPS/Serializer.h"); 00130 string cxx = scoped(name); // name as a C++ class 00131 { 00132 Function insertion("operator<<", "bool"); 00133 insertion.addArg("strm", "Serializer&"); 00134 insertion.addArg("enumval", "const " + cxx + "&"); 00135 insertion.endArgs(); 00136 be_global->impl_ << 00137 " return strm << static_cast<CORBA::ULong>(enumval);\n"; 00138 } 00139 { 00140 Function extraction("operator>>", "bool"); 00141 extraction.addArg("strm", "Serializer&"); 00142 extraction.addArg("enumval", cxx + "&"); 00143 extraction.endArgs(); 00144 be_global->impl_ << 00145 " CORBA::ULong temp = 0;\n" 00146 " if (strm >> temp) {\n" 00147 " enumval = static_cast<" << cxx << ">(temp);\n" 00148 " return true;\n" 00149 " }\n" 00150 " return false;\n"; 00151 } 00152 return true; 00153 }
bool marshal_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 1412 of file marshal_generator.cpp.
References ACE_TEXT_ALWAYS_CHAR, Function::addArg(), be_global, Function::endArgs(), LENGTH, AstTypeClassification::resolveActualType(), and scoped().
01417 { 01418 NamespaceGuard ng; 01419 be_global->add_include("dds/DCPS/Serializer.h"); 01420 string cxx = scoped(name); // name as a C++ class 01421 01422 for (size_t i = 0; i < LENGTH(special_structs); ++i) { 01423 if (special_structs[i].check(cxx)) { 01424 return special_structs[i].gen(cxx); 01425 } 01426 } 01427 01428 RtpsFieldCustomizer rtpsCustom(cxx); 01429 { 01430 Function find_size("gen_find_size", "void"); 01431 find_size.addArg("stru", "const " + cxx + "&"); 01432 find_size.addArg("size", "size_t&"); 01433 find_size.addArg("padding", "size_t&"); 01434 find_size.endArgs(); 01435 string expr, intro; 01436 for (size_t i = 0; i < fields.size(); ++i) { 01437 AST_Type* field_type = resolveActualType(fields[i]->field_type()); 01438 if (!field_type->in_main_file() 01439 && field_type->node_type() != AST_Decl::NT_pre_defined) { 01440 be_global->add_referenced(field_type->file_name().c_str()); 01441 } 01442 const string field_name = fields[i]->local_name()->get_string(), 01443 cond = rtpsCustom.getConditional(field_name); 01444 if (!cond.empty()) { 01445 expr += " if (" + cond + ") {\n "; 01446 } 01447 expr += findSizeCommon(field_name, field_type, "stru", intro); 01448 if (!cond.empty()) { 01449 expr += " }\n"; 01450 } 01451 } 01452 be_global->impl_ << intro << expr; 01453 } 01454 { 01455 Function insertion("operator<<", "bool"); 01456 insertion.addArg("strm", "Serializer&"); 01457 insertion.addArg("stru", "const " + cxx + "&"); 01458 insertion.endArgs(); 01459 string expr, intro = rtpsCustom.preamble_; 01460 for (size_t i = 0; i < fields.size(); ++i) { 01461 if (i) expr += "\n && "; 01462 const string field_name = fields[i]->local_name()->get_string(), 01463 cond = rtpsCustom.getConditional(field_name); 01464 if (!cond.empty()) { 01465 expr += "(!(" + cond + ") || "; 01466 } 01467 expr += streamCommon(field_name, fields[i]->field_type(), 01468 "<< stru", intro, cxx); 01469 if (!cond.empty()) { 01470 expr += ")"; 01471 } 01472 } 01473 be_global->impl_ << intro << " return " << expr << ";\n"; 01474 } 01475 { 01476 Function extraction("operator>>", "bool"); 01477 extraction.addArg("strm", "Serializer&"); 01478 extraction.addArg("stru", cxx + "&"); 01479 extraction.endArgs(); 01480 string expr, intro; 01481 for (size_t i = 0; i < fields.size(); ++i) { 01482 if (i) expr += "\n && "; 01483 const string field_name = fields[i]->local_name()->get_string(), 01484 cond = rtpsCustom.getConditional(field_name); 01485 if (!cond.empty()) { 01486 expr += rtpsCustom.preFieldRead(field_name); 01487 expr += "(!(" + cond + ") || "; 01488 } 01489 expr += streamCommon(field_name, fields[i]->field_type(), 01490 ">> stru", intro, cxx); 01491 if (!cond.empty()) { 01492 expr += ")"; 01493 } 01494 } 01495 be_global->impl_ << intro << " return " << expr << ";\n"; 01496 } 01497 01498 IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name); 01499 // Only generate these methods if this is a DCPS type 01500 if (info != 0) { 01501 bool is_bounded_struct = true; 01502 for (size_t i = 0; i < fields.size(); ++i) { 01503 if (!is_bounded_type(fields[i]->field_type())) { 01504 is_bounded_struct = false; 01505 break; 01506 } 01507 } 01508 { 01509 Function max_marsh("gen_max_marshaled_size", "size_t"); 01510 max_marsh.addArg("stru", "const " + cxx + "&"); 01511 max_marsh.addArg("align", "bool"); 01512 max_marsh.endArgs(); 01513 if (is_bounded_struct) { 01514 size_t size = 0, padding = 0; 01515 for (size_t i = 0; i < fields.size(); ++i) { 01516 max_marshaled_size(fields[i]->field_type(), size, padding); 01517 } 01518 if (padding) { 01519 be_global->impl_ 01520 << " return align ? " << size + padding << " : " << size << ";\n"; 01521 } else { 01522 be_global->impl_ 01523 << " return " << size << ";\n"; 01524 } 01525 } else { // unbounded 01526 be_global->impl_ 01527 << " return 0;\n"; 01528 } 01529 } 01530 01531 // Generate key-related marshaling code 01532 bool bounded_key = true; 01533 IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_); 01534 for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) { 01535 string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str()); 01536 AST_Type* field_type = 0; 01537 try { 01538 field_type = find_type(fields, key_name); 01539 } catch (const string& error) { 01540 std::cerr << "ERROR: Invalid key specification for " << cxx 01541 << " (" << key_name << "). " << error << std::endl; 01542 return false; 01543 } 01544 if (!is_bounded_type(field_type)) { 01545 bounded_key = false; 01546 break; 01547 } 01548 } 01549 01550 { 01551 Function max_marsh("gen_max_marshaled_size", "size_t"); 01552 max_marsh.addArg("stru", "KeyOnly<const " + cxx + ">"); 01553 max_marsh.addArg("align", "bool"); 01554 max_marsh.endArgs(); 01555 01556 if (bounded_key) { // Only generate a size if the key is bounded 01557 IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_); 01558 size_t size = 0, padding = 0; 01559 for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) { 01560 string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str()); 01561 AST_Type* field_type = 0; 01562 try { 01563 field_type = find_type(fields, key_name); 01564 } catch (const string& error) { 01565 std::cerr << "ERROR: Invalid key specification for " << cxx 01566 << " (" << key_name << "). " << error << std::endl; 01567 return false; 01568 } 01569 max_marshaled_size(field_type, size, padding); 01570 } 01571 if (padding) { 01572 be_global->impl_ 01573 << " return align ? " << size + padding << " : " << size << ";\n"; 01574 } else { 01575 be_global->impl_ 01576 << " return " << size << ";\n"; 01577 } 01578 } else { // unbounded 01579 be_global->impl_ 01580 << " return 0;\n"; 01581 } 01582 } 01583 01584 { 01585 Function find_size("gen_find_size", "void"); 01586 find_size.addArg("stru", "KeyOnly<const " + cxx + ">"); 01587 find_size.addArg("size", "size_t&"); 01588 find_size.addArg("padding", "size_t&"); 01589 find_size.endArgs(); 01590 string expr, intro; 01591 IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_); 01592 for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) { 01593 string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str()); 01594 AST_Type* field_type = 0; 01595 try { 01596 field_type = find_type(fields, key_name); 01597 } catch (const string& error) { 01598 std::cerr << "ERROR: Invalid key specification for " << cxx 01599 << " (" << key_name << "). " << error << std::endl; 01600 return false; 01601 } 01602 expr += findSizeCommon(key_name, field_type, "stru.t", intro); 01603 } 01604 be_global->impl_ << intro << expr; 01605 } 01606 01607 { 01608 Function insertion("operator<<", "bool"); 01609 insertion.addArg("strm", "Serializer&"); 01610 insertion.addArg("stru", "KeyOnly<const " + cxx + ">"); 01611 insertion.endArgs(); 01612 01613 bool first = true; 01614 string expr, intro; 01615 IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_); 01616 for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) { 01617 string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str()); 01618 AST_Type* field_type = 0; 01619 try { 01620 field_type = find_type(fields, key_name); 01621 } catch (const string& error) { 01622 std::cerr << "ERROR: Invalid key specification for " << cxx 01623 << " (" << key_name << "). " << error << std::endl; 01624 return false; 01625 } 01626 if (first) first = false; 01627 else expr += "\n && "; 01628 expr += streamCommon(key_name, field_type, "<< stru.t", intro); 01629 } 01630 if (first) be_global->impl_ << intro << " return true;\n"; 01631 else be_global->impl_ << intro << " return " << expr << ";\n"; 01632 } 01633 01634 { 01635 Function extraction("operator>>", "bool"); 01636 extraction.addArg("strm", "Serializer&"); 01637 extraction.addArg("stru", "KeyOnly<" + cxx + ">"); 01638 extraction.endArgs(); 01639 01640 bool first = true; 01641 string expr, intro; 01642 IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_); 01643 for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) { 01644 string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str()); 01645 AST_Type* field_type = 0; 01646 try { 01647 field_type = find_type(fields, key_name); 01648 } catch (const string& error) { 01649 std::cerr << "ERROR: Invalid key specification for " << cxx 01650 << " (" << key_name << "). " << error << std::endl; 01651 return false; 01652 } 01653 if (first) first = false; 01654 else expr += "\n && "; 01655 expr += streamCommon(key_name, field_type, ">> stru.t", intro); 01656 } 01657 if (first) be_global->impl_ << intro << " return true;\n"; 01658 else be_global->impl_ << intro << " return " << expr << ";\n"; 01659 } 01660 01661 be_global->header_ << 01662 "template <>\n" 01663 "struct MarshalTraits<" << cxx << "> {\n" 01664 " static bool gen_is_bounded_size() { return " << (is_bounded_struct ? "true" : "false") << "; }\n" 01665 " static bool gen_is_bounded_key_size() { return " << (bounded_key ? "true" : "false") << "; }\n" 01666 "};\n"; 01667 } 01668 01669 return true; 01670 }
bool marshal_generator::gen_typedef | ( | AST_Typedef * | node, | |
UTL_ScopedName * | name, | |||
AST_Type * | base, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 1010 of file marshal_generator.cpp.
01012 { 01013 switch (base->node_type()) { 01014 case AST_Decl::NT_sequence: 01015 gen_sequence(name, AST_Sequence::narrow_from_decl(base)); 01016 break; 01017 case AST_Decl::NT_array: 01018 gen_array(name, AST_Array::narrow_from_decl(base)); 01019 break; 01020 default: 01021 return true; 01022 } 01023 return true; 01024 }
bool marshal_generator::gen_union | ( | AST_Union * | node, | |
UTL_ScopedName * | name, | |||
const std::vector< AST_UnionBranch * > & | branches, | |||
AST_Type * | discriminator, | |||
const char * | repoid | |||
) | [virtual] |
Implements dds_generator.
Definition at line 1824 of file marshal_generator.cpp.
References Function::addArg(), be_global, Function::endArgs(), generateSwitchForUnion(), getWrapper(), LENGTH, scoped(), WD_INPUT, and WD_OUTPUT.
01827 { 01828 NamespaceGuard ng; 01829 be_global->add_include("dds/DCPS/Serializer.h"); 01830 string cxx = scoped(name); // name as a C++ class 01831 01832 for (size_t i = 0; i < LENGTH(special_unions); ++i) { 01833 if (special_unions[i].check(cxx)) { 01834 return special_unions[i].gen(cxx, discriminator, branches); 01835 } 01836 } 01837 01838 const string wrap_out = getWrapper("uni._d()", discriminator, WD_OUTPUT); 01839 { 01840 Function find_size("gen_find_size", "void"); 01841 find_size.addArg("uni", "const " + cxx + "&"); 01842 find_size.addArg("size", "size_t&"); 01843 find_size.addArg("padding", "size_t&"); 01844 find_size.endArgs(); 01845 const string align = getAlignment(discriminator); 01846 if (!align.empty()) { 01847 be_global->impl_ << 01848 " if ((size + padding) % " << align << ") {\n" 01849 " padding += " << align << " - ((size + padding) % " << align 01850 << ");\n" 01851 " }\n"; 01852 } 01853 be_global->impl_ << 01854 " size += gen_max_marshaled_size(" << wrap_out << ");\n"; 01855 generateSwitchForUnion("uni._d()", findSizeCommon, branches, discriminator, 01856 "", "", cxx.c_str()); 01857 } 01858 { 01859 Function insertion("operator<<", "bool"); 01860 insertion.addArg("strm", "Serializer&"); 01861 insertion.addArg("uni", "const " + cxx + "&"); 01862 insertion.endArgs(); 01863 be_global->impl_ << 01864 streamAndCheck("<< " + wrap_out); 01865 if (generateSwitchForUnion("uni._d()", streamCommon, branches, 01866 discriminator, "return", "<< ", cxx.c_str())) { 01867 be_global->impl_ << 01868 " return true;\n"; 01869 } 01870 } 01871 { 01872 Function extraction("operator>>", "bool"); 01873 extraction.addArg("strm", "Serializer&"); 01874 extraction.addArg("uni", cxx + "&"); 01875 extraction.endArgs(); 01876 be_global->impl_ << 01877 " " << scoped(discriminator->name()) << " disc;\n" << 01878 streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT)); 01879 if (generateSwitchForUnion("disc", streamCommon, branches, 01880 discriminator, "if", ">> ", cxx.c_str())) { 01881 be_global->impl_ << 01882 " return true;\n"; 01883 } 01884 } 01885 return true; 01886 }