metaclass_generator.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #include "metaclass_generator.h"
00009 #include "be_extern.h"
00010 
00011 #include "utl_identifier.h"
00012 
00013 using namespace AstTypeClassification;
00014 
00015 namespace {
00016   struct ContentSubscriptionGuard {
00017     explicit ContentSubscriptionGuard(bool activate = true)
00018       : activate_(activate)
00019     {
00020       if (activate) {
00021         be_global->header_ <<
00022           "#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE\n";
00023         be_global->impl_ <<
00024           "#ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE\n";
00025       }
00026     }
00027     ~ContentSubscriptionGuard()
00028     {
00029       if (activate_) {
00030         be_global->header_ << "#endif\n";
00031         be_global->impl_ << "#endif\n";
00032       }
00033     }
00034     bool activate_;
00035   };
00036 }
00037 
00038 bool metaclass_generator::gen_enum(AST_Enum*, UTL_ScopedName* name,
00039   const std::vector<AST_EnumVal*>& contents, const char*)
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 }
00053 
00054 namespace {
00055 
00056   void delegateToNested(const std::string& fieldName, AST_Field* field,
00057                         const std::string& firstArg, bool skip = false)
00058   {
00059     const size_t n = fieldName.size() + 1 /* 1 for the dot */;
00060     const std::string fieldType = scoped(field->field_type()->name());
00061     be_global->impl_ <<
00062       "    if (std::strncmp(field, \"" << fieldName << ".\", " << n
00063       << ") == 0) {\n"
00064       "      return getMetaStruct<" << fieldType << ">().getValue("
00065       << firstArg << ", field + " << n << ");\n"
00066       "    }" << (skip ? "" : "\n");
00067     if (skip) {
00068       be_global->impl_ << " else {\n"
00069         "      if (!gen_skip_over(" << firstArg << ", static_cast<" << fieldType
00070         << "*>(0))) {\n"
00071         "        throw std::runtime_error(\"Field '" << fieldName <<
00072         "' could not be skipped\");\n"
00073         "      }\n"
00074         "    }\n";
00075     }
00076   }
00077 
00078   void gen_field_getValue(AST_Field* field)
00079   {
00080     const Classification cls = classify(field->field_type());
00081     const std::string fieldName = field->local_name()->get_string();
00082     if (cls & CL_SCALAR) {
00083       std::string prefix, suffix;
00084       if (cls & CL_ENUM) {
00085         AST_Type* enum_type = resolveActualType(field->field_type());
00086         prefix = "gen_" +
00087           dds_generator::scoped_helper(enum_type->name(), "_")
00088           + "_names[";
00089         suffix = "]";
00090       }
00091       be_global->impl_ <<
00092         "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00093         "      return " + prefix + "typed." + fieldName
00094         + (cls & CL_STRING ? ".in()" : "") + suffix + ";\n"
00095         "    }\n";
00096       be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00097     } else if (cls & CL_STRUCTURE) {
00098       delegateToNested(fieldName, field, "&typed." + fieldName);
00099       be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00100     }
00101   }
00102 
00103   std::string to_cxx_type(AST_Type* type, int& size)
00104   {
00105     const Classification cls = classify(type);
00106     if (cls & CL_ENUM) {
00107       size = 4;
00108       return "ACE_CDR::ULong";
00109     }
00110     if (cls & CL_STRING) {
00111       size = 4; // encoding of str length is 4 bytes
00112       return ((cls & CL_WIDE) ? "TAO::W" : "TAO::")
00113         + std::string("String_Manager");
00114     }
00115     if (cls & CL_PRIMITIVE) {
00116       type = resolveActualType(type);
00117       AST_PredefinedType* p = AST_PredefinedType::narrow_from_decl(type);
00118       switch (p->pt()) {
00119       case AST_PredefinedType::PT_long:
00120         size = 4;
00121         return "ACE_CDR::Long";
00122       case AST_PredefinedType::PT_ulong:
00123         size = 4;
00124         return "ACE_CDR::ULong";
00125       case AST_PredefinedType::PT_longlong:
00126         size = 8;
00127         return "ACE_CDR::LongLong";
00128       case AST_PredefinedType::PT_ulonglong:
00129         size = 8;
00130         return "ACE_CDR::ULongLong";
00131       case AST_PredefinedType::PT_short:
00132         size = 2;
00133         return "ACE_CDR::Short";
00134       case AST_PredefinedType::PT_ushort:
00135         size = 2;
00136         return "ACE_CDR::UShort";
00137       case AST_PredefinedType::PT_float:
00138         size = 4;
00139         return "ACE_CDR::Float";
00140       case AST_PredefinedType::PT_double:
00141         size = 8;
00142         return "ACE_CDR::Double";
00143       case AST_PredefinedType::PT_longdouble:
00144         size = 16;
00145         return "ACE_CDR::LongDouble";
00146       case AST_PredefinedType::PT_char:
00147         size = 1;
00148         return "ACE_CDR::Char";
00149       case AST_PredefinedType::PT_wchar:
00150         size = 1; // encoding of wchar length is 1 byte
00151         return "ACE_CDR::WChar";
00152       case AST_PredefinedType::PT_boolean:
00153         size = 1;
00154         return "ACE_CDR::Boolean";
00155       case AST_PredefinedType::PT_octet:
00156         size = 1;
00157         return "ACE_CDR::Octet";
00158       default:
00159         break;
00160       }
00161     }
00162     return scoped(type->name());
00163   }
00164 
00165   void gen_field_getValueFromSerialized(AST_Field* field)
00166   {
00167     AST_Type* type = field->field_type();
00168     const Classification cls = classify(type);
00169     const std::string fieldName = field->local_name()->get_string();
00170     int size = 0;
00171     const std::string cxx_type = to_cxx_type(type, size);
00172     if (cls & CL_SCALAR) {
00173       type = resolveActualType(type);
00174       const std::string val =
00175         (cls & CL_STRING) ? "val.out()" : getWrapper("val", type, WD_INPUT);
00176       be_global->impl_ <<
00177         "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00178         "      " << cxx_type << " val;\n"
00179         "      if (!(ser >> " << val << ")) {\n"
00180         "        throw std::runtime_error(\"Field '" << fieldName << "' could "
00181         "not be deserialized\");\n"
00182         "      }\n"
00183         "      return val;\n"
00184         "    } else {\n";
00185       if (cls & CL_STRING) {
00186         be_global->impl_ <<
00187           "      ACE_CDR::ULong len;\n"
00188           "      if (!(ser >> len)) {\n"
00189           "        throw std::runtime_error(\"String '" << fieldName <<
00190           "' length could not be deserialized\");\n"
00191           "      }\n"
00192           "      if (!ser.skip(static_cast<ACE_UINT16>(len))) {\n"
00193           "        throw std::runtime_error(\"String '" << fieldName <<
00194           "' contents could not be skipped\");\n"
00195           "      }\n";
00196       } else if (cls & CL_WIDE) {
00197         be_global->impl_ <<
00198           "      ACE_CDR::Octet len;\n"
00199           "      if (!(ser >> ACE_InputCDR::to_octet(len))) {\n"
00200           "        throw std::runtime_error(\"WChar '" << fieldName <<
00201           "' length could not be deserialized\");\n"
00202           "      }\n"
00203           "      if (!ser.skip(static_cast<ACE_UINT16>(len))) {\n"
00204           "        throw std::runtime_error(\"WChar '" << fieldName <<
00205           "' contents could not be skipped\");\n"
00206           "      }\n";
00207       } else {
00208         be_global->impl_ <<
00209           "      if (!ser.skip(1, " << size << ")) {\n"
00210           "        throw std::runtime_error(\"Field '" << fieldName <<
00211           "' could not be skipped\");\n"
00212           "      }\n";
00213       }
00214       be_global->impl_ <<
00215         "    }\n";
00216     } else if (cls & CL_STRUCTURE) {
00217       delegateToNested(fieldName, field, "ser", true);
00218     } else { // array, sequence, union:
00219       be_global->impl_ <<
00220         "    if (!gen_skip_over(ser, static_cast<" << cxx_type
00221         << ((cls & CL_ARRAY) ? "_forany" : "") << "*>(0))) {\n"
00222         "      throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \""
00223         " could not be skipped\");\n"
00224         "    }\n";
00225     }
00226   }
00227 
00228   void gen_field_createQC(AST_Field* field)
00229   {
00230     Classification cls = classify(field->field_type());
00231     const std::string fieldName = field->local_name()->get_string();
00232     if (cls & CL_SCALAR) {
00233       be_global->impl_ <<
00234         "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00235         "      return make_field_cmp(&T::" << fieldName << ", next);\n"
00236         "    }\n";
00237       be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00238     } else if (cls & CL_STRUCTURE) {
00239       size_t n = fieldName.size() + 1 /* 1 for the dot */;
00240       std::string fieldType = scoped(field->field_type()->name());
00241       be_global->impl_ <<
00242         "    if (std::strncmp(field, \"" << fieldName << ".\", " << n <<
00243         ") == 0) {\n"
00244         "      return make_struct_cmp(&T::" << fieldName <<
00245         ", getMetaStruct<" << fieldType << ">().create_qc_comparator("
00246         "field + " << n << "), next);\n"
00247         "    }\n";
00248     }
00249   }
00250 
00251   void print_field_name(AST_Field* field)
00252   {
00253     be_global->impl_ << '"' << field->local_name()->get_string() << '"' << ", ";
00254   }
00255 
00256   void get_raw_field(AST_Field* field)
00257   {
00258     const char* fieldName = field->local_name()->get_string();
00259     be_global->impl_ <<
00260       "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00261       "      return &static_cast<const T*>(stru)->" << fieldName << ";\n"
00262       "    }\n";
00263     be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00264   }
00265 
00266   void assign_field(AST_Field* field)
00267   {
00268     Classification cls = classify(field->field_type());
00269     if (!cls) return; // skip CL_UNKNOWN types
00270     const char* fieldName = field->local_name()->get_string();
00271     const std::string fieldType = (cls & CL_STRING) ?
00272       ((cls & CL_WIDE) ? "TAO::WString_Manager" : "TAO::String_Manager")
00273       : scoped(field->field_type()->name());
00274     if (cls & (CL_SCALAR | CL_STRUCTURE | CL_SEQUENCE | CL_UNION)) {
00275       be_global->impl_ <<
00276         "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00277         "      static_cast<T*>(lhs)->" << fieldName <<
00278         " = *static_cast<const " << fieldType <<
00279         "*>(rhsMeta.getRawField(rhs, rhsFieldSpec));\n"
00280         "      return;\n"
00281         "    }\n";
00282       be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00283     } else if (cls & CL_ARRAY) {
00284       AST_Type* unTD = resolveActualType(field->field_type());
00285       AST_Array* arr = AST_Array::narrow_from_decl(unTD);
00286       be_global->impl_ <<
00287         "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n"
00288         "      " << fieldType << "* lhsArr = &static_cast<T*>(lhs)->" <<
00289         fieldName << ";\n"
00290         "      const " << fieldType << "* rhsArr = static_cast<const " <<
00291         fieldType << "*>(rhsMeta.getRawField(rhs, rhsFieldSpec));\n";
00292       be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00293       AST_Type* elem = arr->base_type();
00294       AST_Type* elemUnTD = resolveActualType(elem);
00295       if (classify(elemUnTD) & CL_ARRAY) {
00296         // array-of-array case, fall back on the Serializer
00297         be_global->impl_ <<
00298           "      " << fieldType << "_forany rhsForany(const_cast<" <<
00299           fieldType << "_slice*>(*rhsArr));\n"
00300           "      size_t size = 0, padding = 0;\n"
00301           "      gen_find_size(rhsForany, size, padding);\n"
00302           "      ACE_Message_Block mb(size);\n"
00303           "      Serializer ser_out(&mb);\n"
00304           "      ser_out << rhsForany;\n"
00305           "      " << fieldType << "_forany lhsForany(*lhsArr);\n"
00306           "      Serializer ser_in(&mb);\n"
00307           "      ser_in >> lhsForany;\n";
00308       } else {
00309         std::string indent = "      ";
00310         NestedForLoops nfl("CORBA::ULong", "i", arr, indent);
00311         be_global->impl_ <<
00312           indent << "(*lhsArr)" << nfl.index_ << " = (*rhsArr)" <<
00313           nfl.index_ << ";\n";
00314       }
00315       be_global->impl_ <<
00316         "      return;\n"
00317         "    }\n";
00318     }
00319   }
00320 
00321   void compare_field(AST_Field* field)
00322   {
00323     Classification cls = classify(field->field_type());
00324     if (!(cls & CL_SCALAR)) return;
00325     const char* fieldName = field->local_name()->get_string();
00326     be_global->impl_ <<
00327       "    if (std::strcmp(field, \"" << fieldName << "\") == 0) {\n";
00328     be_global->add_include("<cstring>", BE_GlobalData::STREAM_CPP);
00329     if (cls & CL_STRING) {
00330       be_global->impl_ << // ACE_OS::strcmp has overloads for narrow & wide
00331         "      return 0 == ACE_OS::strcmp(static_cast<const T*>(lhs)->"
00332         << fieldName << ".in(), static_cast<const T*>(rhs)->" << fieldName
00333         << ".in());\n";
00334     } else {
00335       be_global->impl_ <<
00336         "      return static_cast<const T*>(lhs)->" << fieldName <<
00337         " == static_cast<const T*>(rhs)->" << fieldName << ";\n";
00338     }
00339     be_global->impl_ << "    }\n";
00340   }
00341 }
00342 
00343 bool metaclass_generator::gen_struct(AST_Structure*, UTL_ScopedName* name,
00344   const std::vector<AST_Field*>& fields, AST_Type::SIZE_TYPE, const char*)
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 }
00468 
00469 bool
00470 metaclass_generator::gen_typedef(AST_Typedef*, UTL_ScopedName* name, AST_Type* type, const char*)
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 }
00543 
00544 static std::string func(const std::string&,
00545                         AST_Type* br_type,
00546                         const std::string&,
00547                         std::string&,
00548                         const std::string&)
00549 {
00550   std::stringstream ss;
00551   const Classification br_cls = classify(br_type);
00552   if (br_cls & CL_STRING) {
00553     ss <<
00554       "    ACE_CDR::ULong len;\n"
00555       "    if (!(ser >> len)) return false;\n"
00556       "    if (!ser.skip(static_cast<ACE_UINT16>(len))) return false;\n";
00557   } else if (br_cls & CL_WIDE) {
00558     ss <<
00559       "    ACE_CDR::Octet len;\n"
00560       "    if (!(ser >> ACE_InputCDR::to_octet(len))) return false;\n"
00561       "    if (!ser.skip(len)) return false;\n";
00562   } else if (br_cls & CL_SCALAR) {
00563     int sz = 1;
00564     to_cxx_type(br_type, sz);
00565     ss <<
00566       "    if (!ser.skip(1, " << sz << ")) return false;\n";
00567   } else {
00568     ss <<
00569       "    if (!gen_skip_over(ser, static_cast<" << scoped(br_type->name()) <<
00570       ((br_cls & CL_ARRAY) ? "_forany" : "") << "*>(0))) return false;\n";
00571   }
00572 
00573   ss <<
00574     "    return true;\n";
00575   return ss.str();
00576 }
00577 
00578 bool
00579 metaclass_generator::gen_union(AST_Union*, UTL_ScopedName* name,
00580   const std::vector<AST_UnionBranch*>& branches, AST_Type* discriminator,
00581   const char*)
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1