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, 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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:


Member Data Documentation

Definition at line 33 of file metaclass_generator.h.

Referenced by gen_struct().


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