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 22 of file marshal_generator.cpp.

References BE_GlobalData::add_include(), Function::addArg(), be_global, Function::endArgs(), BE_GlobalData::impl_, and scoped().

00024 {
00025   NamespaceGuard ng;
00026   be_global->add_include("dds/DCPS/Serializer.h");
00027   string cxx = scoped(name); // name as a C++ class
00028   {
00029     Function insertion("operator<<", "bool");
00030     insertion.addArg("strm", "Serializer&");
00031     insertion.addArg("enumval", "const " + cxx + "&");
00032     insertion.endArgs();
00033     be_global->impl_ <<
00034       "  return strm << static_cast<CORBA::ULong>(enumval);\n";
00035   }
00036   {
00037     Function extraction("operator>>", "bool");
00038     extraction.addArg("strm", "Serializer&");
00039     extraction.addArg("enumval", cxx + "&");
00040     extraction.endArgs();
00041     be_global->impl_ <<
00042       "  CORBA::ULong temp = 0;\n"
00043       "  if (strm >> temp) {\n"
00044       "    enumval = static_cast<" << cxx << ">(temp);\n"
00045       "    return true;\n"
00046       "  }\n"
00047       "  return false;\n";
00048   }
00049   return true;
00050 }

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 1061 of file marshal_generator.cpp.

References BE_GlobalData::add_include(), BE_GlobalData::add_referenced(), Function::addArg(), be_global, Function::endArgs(), find_type(), findSizeCommon(), genRtpsSpecialStruct(), BE_GlobalData::impl_, is_bounded_type(), isRtpsSpecialStruct(), max_marshaled_size(), AstTypeClassification::resolveActualType(), scoped(), and streamCommon().

01063 {
01064   NamespaceGuard ng;
01065   be_global->add_include("dds/DCPS/Serializer.h");
01066   string cxx = scoped(name); // name as a C++ class
01067   if (isRtpsSpecialStruct(cxx)) {
01068     return genRtpsSpecialStruct(cxx);
01069   }
01070   RtpsFieldCustomizer rtpsCustom(cxx);
01071   {
01072     Function find_size("gen_find_size", "void");
01073     find_size.addArg("stru", "const " + cxx + "&");
01074     find_size.addArg("size", "size_t&");
01075     find_size.addArg("padding", "size_t&");
01076     find_size.endArgs();
01077     string expr, intro;
01078     for (size_t i = 0; i < fields.size(); ++i) {
01079       AST_Type* field_type = resolveActualType(fields[i]->field_type());
01080       if (!field_type->in_main_file()
01081           && field_type->node_type() != AST_Decl::NT_pre_defined) {
01082         be_global->add_referenced(field_type->file_name().c_str());
01083       }
01084       const string field_name = fields[i]->local_name()->get_string(),
01085         cond = rtpsCustom.getConditional(field_name);
01086       if (!cond.empty()) {
01087         expr += "  if (" + cond + ") {\n  ";
01088       }
01089       expr += findSizeCommon(field_name, field_type, "stru", intro);
01090       if (!cond.empty()) {
01091         expr += "  }\n";
01092       }
01093     }
01094     be_global->impl_ << intro << expr;
01095   }
01096   {
01097     Function insertion("operator<<", "bool");
01098     insertion.addArg("strm", "Serializer&");
01099     insertion.addArg("stru", "const " + cxx + "&");
01100     insertion.endArgs();
01101     string expr, intro = rtpsCustom.preamble_;
01102     for (size_t i = 0; i < fields.size(); ++i) {
01103       if (i) expr += "\n    && ";
01104       const string field_name = fields[i]->local_name()->get_string(),
01105         cond = rtpsCustom.getConditional(field_name);
01106       if (!cond.empty()) {
01107         expr += "(!(" + cond + ") || ";
01108       }
01109       expr += streamCommon(field_name, fields[i]->field_type(),
01110                            "<< stru", intro, cxx);
01111       if (!cond.empty()) {
01112         expr += ")";
01113       }
01114     }
01115     be_global->impl_ << intro << "  return " << expr << ";\n";
01116   }
01117   {
01118     Function extraction("operator>>", "bool");
01119     extraction.addArg("strm", "Serializer&");
01120     extraction.addArg("stru", cxx + "&");
01121     extraction.endArgs();
01122     string expr, intro;
01123     for (size_t i = 0; i < fields.size(); ++i) {
01124       if (i) expr += "\n    && ";
01125       const string field_name = fields[i]->local_name()->get_string(),
01126         cond = rtpsCustom.getConditional(field_name);
01127       if (!cond.empty()) {
01128         expr += rtpsCustom.preFieldRead(field_name);
01129         expr += "(!(" + cond + ") || ";
01130       }
01131       expr += streamCommon(field_name, fields[i]->field_type(),
01132                            ">> stru", intro, cxx);
01133       if (!cond.empty()) {
01134         expr += ")";
01135       }
01136     }
01137     be_global->impl_ << intro << "  return " << expr << ";\n";
01138   }
01139 
01140   IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name);
01141   // Only generate these methods if this is a DCPS type
01142   if (info != 0) {
01143     bool is_bounded_struct = true;
01144     {
01145       Function is_bounded("gen_is_bounded_size", "bool");
01146       is_bounded.addArg("", "const " + cxx + "&");
01147       is_bounded.endArgs();
01148       for (size_t i = 0; i < fields.size(); ++i) {
01149         if (!is_bounded_type(fields[i]->field_type())) {
01150           is_bounded_struct = false;
01151           break;
01152         }
01153       }
01154       be_global->impl_ << "  return "
01155                        << (is_bounded_struct ? "true" : "false") << ";\n";
01156     }
01157     {
01158       Function max_marsh("gen_max_marshaled_size", "size_t");
01159       max_marsh.addArg("stru", "const " + cxx + "&");
01160       max_marsh.addArg("align", "bool");
01161       max_marsh.endArgs();
01162       if (is_bounded_struct) {
01163         size_t size = 0, padding = 0;
01164         for (size_t i = 0; i < fields.size(); ++i) {
01165           max_marshaled_size(fields[i]->field_type(), size, padding);
01166         }
01167         if (padding) {
01168           be_global->impl_
01169             << "  return align ? " << size + padding << " : " << size << ";\n";
01170         } else {
01171           be_global->impl_
01172             << "  return " << size << ";\n";
01173         }
01174       } else { // unbounded
01175         be_global->impl_
01176           << "  return 0;\n";
01177       }
01178     }
01179 
01180     // Generate key-related marshaling code
01181     bool bounded_key = true;
01182     {
01183       Function is_bounded("gen_is_bounded_size", "bool");
01184       is_bounded.addArg("", "KeyOnly<const " + cxx + ">");
01185       is_bounded.endArgs();
01186 
01187       IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
01188       for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
01189         string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
01190         AST_Type* field_type = 0;
01191         try {
01192           field_type = find_type(fields, key_name);
01193         } catch (const std::string& error) {
01194           std::cerr << "ERROR: Invalid key specification for " << cxx
01195                     << " (" << key_name << "). " << error << std::endl;
01196           return false;
01197         }
01198         if (!is_bounded_type(field_type)) {
01199           bounded_key = false;
01200           break;
01201         }
01202       }
01203 
01204       be_global->impl_ << "  return "
01205                        << (bounded_key ? "true" : "false") << ";\n";
01206     }
01207 
01208     {
01209       Function max_marsh("gen_max_marshaled_size", "size_t");
01210       max_marsh.addArg("stru", "KeyOnly<const " + cxx + ">");
01211       max_marsh.addArg("align", "bool");
01212       max_marsh.endArgs();
01213 
01214       if (bounded_key) {  // Only generate a size if the key is bounded
01215         IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
01216         size_t size = 0, padding = 0;
01217         for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
01218           string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
01219           AST_Type* field_type = 0;
01220           try {
01221             field_type = find_type(fields, key_name);
01222           } catch (const std::string& error) {
01223             std::cerr << "ERROR: Invalid key specification for " << cxx
01224                       << " (" << key_name << "). " << error << std::endl;
01225             return false;
01226           }
01227           max_marshaled_size(field_type, size, padding);
01228         }
01229         if (padding) {
01230           be_global->impl_
01231             << "  return align ? " << size + padding << " : " << size << ";\n";
01232         } else {
01233           be_global->impl_
01234             << "  return " << size << ";\n";
01235         }
01236       } else { // unbounded
01237         be_global->impl_
01238           << "  return 0;\n";
01239       }
01240     }
01241 
01242     {
01243       Function find_size("gen_find_size", "void");
01244       find_size.addArg("stru", "KeyOnly<const " + cxx + ">");
01245       find_size.addArg("size", "size_t&");
01246       find_size.addArg("padding", "size_t&");
01247       find_size.endArgs();
01248       string expr, intro;
01249       IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
01250       for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
01251         string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
01252         AST_Type* field_type = 0;
01253         try {
01254           field_type = find_type(fields, key_name);
01255         } catch (const std::string& error) {
01256           std::cerr << "ERROR: Invalid key specification for " << cxx
01257                     << " (" << key_name << "). " << error << std::endl;
01258           return false;
01259         }
01260         expr += findSizeCommon(key_name, field_type, "stru.t", intro);
01261       }
01262       be_global->impl_ << intro << expr;
01263     }
01264 
01265     {
01266       Function insertion("operator<<", "bool");
01267       insertion.addArg("strm", "Serializer&");
01268       insertion.addArg("stru", "KeyOnly<const " + cxx + ">");
01269       insertion.endArgs();
01270 
01271       bool first = true;
01272       string expr, intro;
01273       IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
01274       for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
01275         string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
01276         AST_Type* field_type = 0;
01277         try {
01278           field_type = find_type(fields, key_name);
01279         } catch (const std::string& error) {
01280           std::cerr << "ERROR: Invalid key specification for " << cxx
01281                     << " (" << key_name << "). " << error << std::endl;
01282           return false;
01283         }
01284         if (first) first = false;
01285         else       expr += "\n    && ";
01286         expr += streamCommon(key_name, field_type, "<< stru.t", intro);
01287       }
01288       if (first) be_global->impl_ << intro << "  return true;\n";
01289       else be_global->impl_ << intro << "  return " << expr << ";\n";
01290     }
01291 
01292     {
01293       Function extraction("operator>>", "bool");
01294       extraction.addArg("strm", "Serializer&");
01295       extraction.addArg("stru", "KeyOnly<" + cxx + ">");
01296       extraction.endArgs();
01297 
01298       bool first = true;
01299       string expr, intro;
01300       IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
01301       for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
01302         string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
01303         AST_Type* field_type = 0;
01304         try {
01305           field_type = find_type(fields, key_name);
01306         } catch (const std::string& error) {
01307           std::cerr << "ERROR: Invalid key specification for " << cxx
01308                     << " (" << key_name << "). " << error << std::endl;
01309           return false;
01310         }
01311         if (first) first = false;
01312         else       expr += "\n    && ";
01313         expr += streamCommon(key_name, field_type, ">> stru.t", intro);
01314       }
01315       if (first) be_global->impl_ << intro << "  return true;\n";
01316       else be_global->impl_ << intro << "  return " << expr << ";\n";
01317     }
01318   }
01319 
01320   return true;
01321 }

bool marshal_generator::gen_typedef ( AST_Typedef *  node,
UTL_ScopedName *  name,
AST_Type *  base,
const char *  repoid 
) [virtual]

Implements dds_generator.

Definition at line 834 of file marshal_generator.cpp.

References gen_array(), and gen_sequence().

00836 {
00837   switch (base->node_type()) {
00838   case AST_Decl::NT_sequence:
00839     gen_sequence(name, AST_Sequence::narrow_from_decl(base));
00840     break;
00841   case AST_Decl::NT_array:
00842     gen_array(name, AST_Array::narrow_from_decl(base));
00843     break;
00844   default:
00845     return true;
00846   }
00847   return true;
00848 }

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 1475 of file marshal_generator.cpp.

References BE_GlobalData::add_include(), Function::addArg(), align(), be_global, Function::endArgs(), findSizeCommon(), generateSwitchForUnion(), genRtpsSpecialUnion(), getAlignment(), getWrapper(), BE_GlobalData::impl_, isRtpsSpecialUnion(), scoped(), streamAndCheck(), streamCommon(), WD_INPUT, and WD_OUTPUT.

01478 {
01479   NamespaceGuard ng;
01480   be_global->add_include("dds/DCPS/Serializer.h");
01481   string cxx = scoped(name); // name as a C++ class
01482   if (isRtpsSpecialUnion(cxx)) {
01483     return genRtpsSpecialUnion(cxx, discriminator, branches);
01484   }
01485   const string wrap_out = getWrapper("uni._d()", discriminator, WD_OUTPUT);
01486   {
01487     Function find_size("gen_find_size", "void");
01488     find_size.addArg("uni", "const " + cxx + "&");
01489     find_size.addArg("size", "size_t&");
01490     find_size.addArg("padding", "size_t&");
01491     find_size.endArgs();
01492     const string align = getAlignment(discriminator);
01493     if (!align.empty()) {
01494       be_global->impl_ <<
01495         "  if ((size + padding) % " << align << ") {\n"
01496         "    padding += " << align << " - ((size + padding) % " << align
01497         << ");\n"
01498         "  }\n";
01499     }
01500     be_global->impl_ <<
01501       "  size += gen_max_marshaled_size(" << wrap_out << ");\n";
01502       generateSwitchForUnion("uni._d()", findSizeCommon, branches, discriminator,
01503                                "", "", cxx);
01504   }
01505   {
01506     Function insertion("operator<<", "bool");
01507     insertion.addArg("strm", "Serializer&");
01508     insertion.addArg("uni", "const " + cxx + "&");
01509     insertion.endArgs();
01510     be_global->impl_ <<
01511       streamAndCheck("<< " + wrap_out);
01512     generateSwitchForUnion("uni._d()", streamCommon, branches, discriminator,
01513                                "return", "<< ", cxx);
01514     be_global->impl_ <<
01515       "  return true;\n";
01516   }
01517   {
01518     Function extraction("operator>>", "bool");
01519     extraction.addArg("strm", "Serializer&");
01520     extraction.addArg("uni", cxx + "&");
01521     extraction.endArgs();
01522     be_global->impl_ <<
01523       "  " << scoped(discriminator->name()) << " disc;\n" <<
01524       streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT));
01525     generateSwitchForUnion("disc", streamCommon, branches, discriminator,
01526                            "if", ">> ", cxx);
01527     be_global->impl_ <<
01528       "  return true;\n";
01529   }
01530   return true;
01531 }


The documentation for this class was generated from the following files:
Generated on Fri Feb 12 20:05:57 2016 for OpenDDS by  doxygen 1.4.7