marshal_generator Class Reference

#include <marshal_generator.h>

Inheritance diagram for marshal_generator:
Inheritance graph
[legend]
Collaboration diagram for marshal_generator:
Collaboration graph
[legend]

List of all members.

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)

Detailed Description

Definition at line 13 of file marshal_generator.h.


Member Function Documentation

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1