metaclass_generator Class Reference

#include <metaclass_generator.h>

Inheritance diagram for metaclass_generator:

Inheritance graph
[legend]
Collaboration diagram for metaclass_generator:

Collaboration graph
[legend]
List of all members.

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_

Detailed Description

Definition at line 13 of file metaclass_generator.h.


Constructor & Destructor Documentation

metaclass_generator::metaclass_generator (  )  [inline]

Definition at line 15 of file metaclass_generator.h.

00016     : first_struct_(true)
00017   {}


Member Function Documentation

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 }


Member Data Documentation

bool metaclass_generator::first_struct_ [private]

Definition at line 33 of file metaclass_generator.h.

Referenced by gen_struct().


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