OpenDDS  Snapshot(2023/04/07-19:43)
Public Member Functions | Static Public Member Functions | Private Member Functions | List of all members
marshal_generator Class Reference

#include <marshal_generator.h>

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

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)
 
- Public Member Functions inherited from dds_generator
virtual ~dds_generator ()=0
 
virtual bool do_included_files () const
 
virtual void gen_prologue ()
 
virtual void gen_epilogue ()
 
virtual bool gen_const (UTL_ScopedName *, bool, AST_Constant *)
 
virtual bool gen_struct_fwd (UTL_ScopedName *, AST_Type::SIZE_TYPE)
 
virtual bool gen_interf (AST_Interface *, UTL_ScopedName *, bool, const std::vector< AST_Interface *> &, const std::vector< AST_Interface *> &, const std::vector< AST_Attribute *> &, const std::vector< AST_Operation *> &, const char *)
 
virtual bool gen_interf_fwd (UTL_ScopedName *)
 
virtual bool gen_native (AST_Native *, UTL_ScopedName *, const char *)
 
virtual bool gen_union_fwd (AST_UnionFwd *, UTL_ScopedName *, AST_Type::SIZE_TYPE)
 

Static Public Member Functions

static void generate_dheader_code (const std::string &code, bool dheader_required, bool is_ser_func=true)
 
static void gen_field_getValueFromSerialized (AST_Structure *node, const std::string &clazz)
 
- Static Public Member Functions inherited from dds_generator
static std::string get_tag_name (const std::string &base_name, bool nested_key_only=false)
 
static std::string get_xtag_name (UTL_ScopedName *name)
 
static bool cxx_escaped (const std::string &s)
 
static std::string valid_var_name (const std::string &str)
 
static std::string to_string (Identifier *id, EscapeContext ec=EscapeContext_Normal)
 
static std::string scoped_helper (UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
 
static std::string module_scope_helper (UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
 

Private Member Functions

void gen_union_default (AST_UnionBranch *branch, const std::string &varname)
 

Detailed Description

Definition at line 13 of file marshal_generator.h.

Member Function Documentation

◆ gen_enum()

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

References ACE_ASSERT, Function::addArg(), OpenDDS::DCPS::align(), OpenDDS::DCPS::Encoding::align(), OpenDDS::DCPS::array_count(), array_element_count(), be_global, Fields::begin(), bounded_arg(), canonical_name(), AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_BOUNDED, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_INTERFACE, AstTypeClassification::CL_PRIMITIVE, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::CL_UNION, AstTypeClassification::CL_UNKNOWN, AstTypeClassification::CL_WIDE, AstTypeClassification::classify(), OpenDDS::STUN::encoding(), Fields::end(), Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, generate_dheader_code(), dds_generator::get_tag_name(), getWrapper(), NestedForLoops::index_, Intro::join(), be_util::misc_error_and_abort(), name, OpenDDS::DCPS::ref(), AstTypeClassification::resolveActualType(), scoped(), OpenDDS::DCPS::serialized_size(), OpenDDS::DCPS::set_default(), struct_has_explicit_keys(), tryconstructfailaction_trim, tryconstructfailaction_use_default, FieldInfo::type_, type_to_default(), dds_generator::valid_var_name(), value, WD_INPUT, and WD_OUTPUT.

166 {
167  NamespaceGuard ng;
168  be_global->add_include("dds/DCPS/Serializer.h");
169  string cxx = scoped(name); // name as a C++ class
170  {
171  Function insertion("operator<<", "bool");
172  insertion.addArg("strm", "Serializer&");
173  insertion.addArg("enumval", "const " + cxx + "&");
174  insertion.endArgs();
175  const std::string idl_name = canonical_name(name);
176  be_global->impl_ <<
177  " if (CORBA::ULong(enumval) >= " << vals.size() << ") {\n"
178  " if (OpenDDS::DCPS::log_level >= OpenDDS::DCPS::LogLevel::Warning) {\n"
179  " ACE_ERROR((LM_WARNING, \"(%P|%t) WARNING: "
180  "%u is an invalid enumerated value for " << idl_name << "\\n\", enumval));\n"
181  " }\n"
182  " return false;\n"
183  " }\n";
184  be_global->impl_ <<
185  " return strm << static_cast<CORBA::ULong>(enumval);\n";
186  }
187  {
188  Function extraction("operator>>", "bool");
189  extraction.addArg("strm", "Serializer&");
190  extraction.addArg("enumval", cxx + "&");
191  extraction.endArgs();
192  be_global->impl_ <<
193  " CORBA::ULong temp = 0;\n"
194  " if (strm >> temp) {\n";
195  be_global->impl_ <<
196  " if (temp >= " << vals.size() << ") {\n"
197  " strm.set_construction_status(Serializer::ElementConstructionFailure);\n"
198  " return false;\n"
199  " }\n";
200  be_global->impl_ <<
201  " enumval = static_cast<" << cxx << ">(temp);\n"
202  " return true;\n"
203  " }\n"
204  " return false;\n";
205  }
206  return true;
207 }
std::string canonical_name(UTL_ScopedName *sn)
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
const char *const name
Definition: debug.cpp:60
BE_GlobalData * be_global
Definition: be_global.cpp:43

◆ gen_field_getValueFromSerialized()

void marshal_generator::gen_field_getValueFromSerialized ( AST_Structure *  node,
const std::string &  clazz 
)
static

Definition at line 3328 of file marshal_generator.cpp.

References Function::addArg(), be_global, Fields::begin(), canonical_name(), AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_SCALAR, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::classify(), Fields::end(), Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, generate_dheader_code(), generateSwitchBody(), generateSwitchForUnion(), dds_generator::get_tag_name(), getWrapper(), OPENDDS_IDL_STR, FieldInfo::ptr_, AstTypeClassification::resolveActualType(), scoped(), dds_generator::scoped_helper(), OpenDDS::DCPS::serialized_size(), to_cxx_type(), OpenDDS::DCPS::to_dds_string(), WD_INPUT, and WD_OUTPUT.

Referenced by metaclass_generator::gen_enum().

3329 {
3330  //loop through meta struct
3331  //check the id for a match to our id
3332  //if we are not a match, skip to the next field
3333  //if we are a match, deserialize the field
3334  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
3335  std::string expr;
3336  const ExtensibilityKind exten = be_global->extensibility(node);
3337  const bool not_final = exten != extensibilitykind_final;
3338  const bool is_mutable = exten == extensibilitykind_mutable;
3339  const std::string actual_cpp_name = scoped(node->name());
3340  std::string cpp_name = actual_cpp_name;
3341  const Fields fields(node);
3342  const Fields::Iterator fields_end = fields.end();
3343  RtpsFieldCustomizer rtpsCustom(cpp_name);
3344 
3345  be_global->impl_ <<
3346  " Value getValue(Serializer& strm, const char* field, const TypeSupportImpl* = 0) const\n"
3347  " {\n"
3348  " const Encoding& encoding = strm.encoding();\n"
3349  " ACE_UNUSED_ARG(encoding);\n";
3351  " if (!strm.read_delimiter(total_size)) {\n"
3352  " throw std::runtime_error(\"Unable to reader delimiter in getValue\");\n"
3353  " }\n", not_final);
3354  be_global->impl_ <<
3355  " std::string base_field = field;\n"
3356  " const size_t index = base_field.find('.');\n"
3357  " std::string subfield;\n"
3358  " if (index != std::string::npos) {\n"
3359  " subfield = base_field.substr(index + 1);\n"
3360  " base_field = base_field.substr(0, index);\n"
3361  " }\n";
3362 
3363  if (is_mutable) {
3364  be_global->impl_ <<
3365  " if (encoding.xcdr_version() != Encoding::XCDR_VERSION_NONE) {\n"
3366  " unsigned field_id = map_name_to_id(base_field.c_str());\n"
3367  " ACE_UNUSED_ARG(field_id);\n"
3368  " unsigned member_id;\n"
3369  " size_t field_size;\n"
3370  " const size_t end_of_struct = strm.rpos() + total_size;\n"
3371  " while (true) {\n"
3372  " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_2 &&\n"
3373  " strm.rpos() >= end_of_struct) {\n"
3374  " break;\n"
3375  " }\n"
3376  " bool must_understand = false;\n"
3377  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3378  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" Deserialization "
3379  "Error for struct " << clazz << "\");\n"
3380  " }\n"
3381  " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_1 &&\n"
3382  " member_id == Serializer::pid_list_end) {\n"
3383  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not "
3384  "valid for struct " << clazz << "\");\n"
3385  " }\n"
3386  " const size_t end_of_field = strm.rpos() + field_size;\n"
3387  " ACE_UNUSED_ARG(end_of_field);\n"
3388  "\n";
3389 
3390  std::ostringstream cases;
3391  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
3392  AST_Field* const field = *i;
3393  size_t size = 0;
3394  const OpenDDS::XTypes::MemberId id = be_global->get_id(field);
3395  std::string field_name = field->local_name()->get_string();
3396  AST_Type* const field_type = resolveActualType(field->field_type());
3397  Classification fld_cls = classify(field_type);
3398 
3399  cases << " case " << id << ": {\n";
3400  if (fld_cls & CL_SCALAR) {
3401  const std::string cxx_type = to_cxx_type(field_type, size);
3402  const std::string val = (fld_cls & CL_STRING) ? (use_cxx11 ? "val" : "val.out()")
3403  : getWrapper("val", field_type, WD_INPUT);
3404  std::string boundsCheck, transformPrefix, transformSuffix;
3405  if (fld_cls & CL_ENUM) {
3406  const std::string enumName = dds_generator::scoped_helper(field_type->name(), "_");
3407  boundsCheck = " if (val >= gen_" + enumName + "_names_size) {\n"
3408  " throw std::runtime_error(\"Enum value out of bounds\");\n"
3409  " }\n";
3410  transformPrefix = "gen_" + enumName + "_names[";
3411  transformSuffix = "]";
3412  }
3413  cases <<
3414  " if (field_id == member_id) {\n"
3415  " " << cxx_type << " val;\n" <<
3416  " if (!(strm >> " << val << ")) {\n"
3417  " throw std::runtime_error(\"Field '" << field_name << "' could not be deserialized\");\n" <<
3418  " }\n" <<
3419  boundsCheck <<
3420  " return " << transformPrefix << "val" << transformSuffix << ";\n"
3421  " } else {\n"
3422  " strm.skip(field_size);\n"
3423  " }\n"
3424  " break;\n"
3425  " }\n";
3426  } else if (fld_cls & CL_STRUCTURE) {
3427  cases <<
3428  " if (field_id == member_id) {\n"
3429  " return getMetaStruct<" << scoped(field_type->name()) << ">().getValue(strm, subfield.c_str());\n"
3430  " } else {\n"
3431  " strm.skip(field_size);\n"
3432  " }\n"
3433  " break;\n"
3434  " }\n";
3435  } else { // array, sequence, union:
3436  cases <<
3437  " strm.skip(field_size);\n"
3438  " break;\n"
3439  " }\n";
3440  }
3441  }
3442  const std::string switch_cases = cases.str();
3443  std::string sw_indent = " ";
3444  if (switch_cases.empty()) {
3445  sw_indent = " ";
3446  } else {
3447  be_global->impl_ <<
3448  " switch (member_id) {\n"
3449  << switch_cases <<
3450  " default:\n";
3451  }
3452  be_global->impl_ <<
3453  sw_indent << "if (must_understand) {\n" <<
3454  sw_indent << " if (DCPS_debug_level >= 8) {\n" <<
3455  sw_indent << " ACE_DEBUG((LM_DEBUG, ACE_TEXT(\"(%P|%t) unknown must_understand field(%u) in "
3456  << cpp_name << "\\n\"), member_id));\n" <<
3457  sw_indent << " }\n" <<
3458  sw_indent << " throw std::runtime_error(\"member id did not exist in getValue\");\n" <<
3459  sw_indent << "}\n" <<
3460  sw_indent << "strm.skip(field_size);\n";
3461  if (!switch_cases.empty()) {
3462  be_global->impl_ <<
3463  " break;\n"
3464  " }\n";
3465  }
3466  be_global->impl_ <<
3467  " }\n"
3468  " if (!field[0]) {\n" // if 'field' is the empty string...
3469  " return 0;\n" // the return value is ignored
3470  " }\n"
3471  " throw std::runtime_error(\"Did not find field in getValue\");\n"
3472  " }\n";
3473  }
3474  //The following is Appendable/Final
3475  //It is also used when Mutable but not in XCDR1 or XCDR2
3476  expr = "";
3477  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
3478  AST_Field* const field = *i;
3479  size_t size = 0;
3480  const std::string field_name = field->local_name()->get_string();
3481  const std::string idl_name = canonical_name(field);
3482  AST_Type* const field_type = resolveActualType(field->field_type());
3483  Classification fld_cls = classify(field_type);
3484  if (fld_cls & CL_SCALAR) {
3485  const std::string cxx_type = to_cxx_type(field_type, size);
3486  const std::string val = (fld_cls & CL_STRING) ? (use_cxx11 ? "val" : "val.out()")
3487  : getWrapper("val", field_type, WD_INPUT);
3488  std::string boundsCheck, transformPrefix, transformSuffix;
3489  if (fld_cls & CL_ENUM) {
3490  const std::string enumName = dds_generator::scoped_helper(field_type->name(), "_");
3491  boundsCheck = " if (val >= gen_" + enumName + "_names_size) {\n"
3492  " throw std::runtime_error(\"Enum value out of bounds\");\n"
3493  " }\n";
3494  transformPrefix = "gen_" + enumName + "_names[";
3495  transformSuffix = "]";
3496  }
3497  expr +=
3498  " if (base_field == \"" + idl_name + "\") {\n"
3499  " " + cxx_type + " val;\n"
3500  " if (!(strm >> " + val + ")) {\n"
3501  " throw std::runtime_error(\"Field '" + idl_name + "' could "
3502  "not be deserialized\");\n"
3503  " }\n"
3504  + boundsCheck +
3505  " return " + transformPrefix + "val" + transformSuffix + ";\n"
3506  " } else {\n";
3507  if (fld_cls & CL_STRING) {
3508  expr +=
3509  " ACE_CDR::ULong len;\n"
3510  " if (!(strm >> len)) {\n"
3511  " throw std::runtime_error(\"String '" + idl_name +
3512  "' length could not be deserialized\");\n"
3513  " }\n"
3514  " if (!strm.skip(len)) {\n"
3515  " throw std::runtime_error(\"String '" + idl_name +
3516  "' contents could not be skipped\");\n"
3517  " }\n"
3518  " }\n";
3519  } else {
3520  expr +=
3521  " if (!strm.skip(1, " + OpenDDS::DCPS::to_dds_string(size) + " )) {\n"
3522  " throw std::runtime_error(\"Field '" + idl_name +
3523  "' could not be skipped\");\n"
3524  " }\n"
3525  " }\n";
3526  }
3527  } else if (fld_cls & CL_STRUCTURE) {
3528  expr +=
3529  " if (base_field == \"" + idl_name + "\") {\n"
3530  " return getMetaStruct<" + scoped(field_type->name()) + ">().getValue(strm, subfield.c_str());\n"
3531  " } else {\n"
3532  " if (!gen_skip_over(strm, static_cast<" + scoped(field_type->name()) + "*>(0))) {\n"
3533  " throw std::runtime_error(\"Field '" + field_name + "' could not be skipped\");\n"
3534  " }\n"
3535  " }\n";
3536  } else { // array, sequence, union:
3537  std::string pre, post;
3538  if (!use_cxx11 && (fld_cls & CL_ARRAY)) {
3539  post = "_forany";
3540  } else if (use_cxx11 && (fld_cls & (CL_ARRAY | CL_SEQUENCE))) {
3541  pre = "IDL::DistinctType<";
3542  post = ", " + dds_generator::get_tag_name(scoped(field->field_type()->name())) + ">";
3543  }
3544  const std::string ptr = field->field_type()->anonymous() ?
3545  FieldInfo(*field).ptr_ : (pre + scoped(field->field_type()->name()) + post + '*');
3546  expr +=
3547  " if (!gen_skip_over(strm, static_cast<" + ptr + ">(0))) {\n"
3548  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" could not be skipped\");\n"
3549  " }\n";
3550  }
3551  }
3552  be_global->impl_ <<
3553  expr <<
3554  " if (!field[0]) {\n" // if 'field' is the empty string...
3555  " return 0;\n" // the return value is ignored
3556  " }\n"
3557  " throw std::runtime_error(\"Did not find field in getValue\");\n"
3558  " }\n\n";
3559 }
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
std::string ptr_
Definition: field_info.h:66
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
const Classification CL_ARRAY
static std::string get_tag_name(const std::string &base_name, bool nested_key_only=false)
const Classification CL_STRUCTURE
AST_Type * resolveActualType(AST_Type *element)
ExtensibilityKind
Definition: annotations.h:278
std::string canonical_name(UTL_ScopedName *sn)
Classification classify(AST_Type *type)
const Classification CL_STRING
const Classification CL_ENUM
const Classification CL_SEQUENCE
const Classification CL_SCALAR
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
std::string to_cxx_type(AST_Type *type, std::size_t &size)
BE_GlobalData * be_global
Definition: be_global.cpp:43
String to_dds_string(unsigned short to_convert)
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)

◆ gen_struct()

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

References ACE_TEXT_ALWAYS_CHAR, Function::addArg(), FieldInfo::arr_, be_global, OpenDDS::STUN::encoding(), Function::endArgs(), FieldFilter_All, FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, FieldInfo::is_new(), Intro::join(), scoped(), FieldInfo::seq_, OpenDDS::DCPS::serialized_size(), OpenDDS::DCPS::set_default(), and type_to_default().

3173 {
3174  NamespaceGuard ng;
3175  be_global->add_include("dds/DCPS/Serializer.h");
3176  const string cxx = scoped(name); // name as a C++ class
3177  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
3178 
3179  {
3180  Function set_default("set_default", "void", "");
3181  set_default.addArg("stru", cxx + "&");
3182  set_default.endArgs();
3183  std::ostringstream contents;
3184  Intro intro;
3185  for (size_t i = 0; i < fields.size(); ++i) {
3186  AST_Field* const field = fields[i];
3187  AST_Type* const type = field->field_type();
3188  string field_name = string("stru.") + field->local_name()->get_string();
3189  if (use_cxx11) {
3190  field_name += "()";
3191  }
3192  contents << type_to_default(" ", type, field_name, type->anonymous());
3193  }
3194  intro.join(be_global->impl_, " ");
3195  be_global->impl_ << contents.str();
3196  }
3197 
3198  const special_struct* special_struct_ptr = get_special_struct(cxx);
3199  if (special_struct_ptr) {
3200  return special_struct_ptr->gen(cxx);
3201  }
3202 
3203  FieldInfo::EleLenSet anonymous_seq_generated;
3204  for (size_t i = 0; i < fields.size(); ++i) {
3205  if (fields[i]->field_type()->anonymous()) {
3206  FieldInfo af(*fields[i]);
3207  if (af.arr_) {
3208  gen_anonymous_array(af);
3209  } else if (af.seq_ && af.is_new(anonymous_seq_generated)) {
3210  gen_anonymous_sequence(af);
3211  }
3212  }
3213  }
3214 
3215  if (!generate_struct_serialization_functions(node, FieldFilter_All) ||
3216  !generate_struct_serialization_functions(node, FieldFilter_NestedKeyOnly)) {
3217  return false;
3218  }
3219 
3220  IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name);
3221  const bool is_topic_type = be_global->is_topic_type(node);
3222  TopicKeys keys;
3223  if (is_topic_type) {
3224  keys = TopicKeys(node);
3225  info = 0; // Annotations Override DCPS_DATA_TYPE
3226 
3227  if (!generate_struct_serialization_functions(node, FieldFilter_KeyOnly)) {
3228  return false;
3229  }
3230  }
3231 
3232  if ((info || is_topic_type) &&
3233  !generate_marshal_traits(node, cxx, be_global->extensibility(node), keys, info)) {
3234  return false;
3235  }
3236 
3237  if (info && !is_topic_type) {
3238  {
3239  Function serialized_size("serialized_size", "void");
3240  serialized_size.addArg("encoding", "const Encoding&");
3241  serialized_size.addArg("size", "size_t&");
3242  serialized_size.addArg("stru", "const KeyOnly<const " + cxx + ">");
3243  serialized_size.endArgs();
3244 
3245  be_global->impl_ <<
3246  " switch (encoding.xcdr_version()) {\n";
3247  const char* indent = " ";
3248  for (unsigned e = 0; e <= Encoding::KIND_UNALIGNED_CDR; ++e) {
3249  string expr;
3250  Intro intro;
3251  const Encoding::Kind encoding = static_cast<Encoding::Kind>(e);
3252  if (!iterate_over_keys(indent, encoding, node, cxx, info, 0,
3253  serialized_size_iteration, 0, &expr, &intro)) {
3254  return false;
3255  }
3256  be_global->impl_ <<
3257  " case " << encoding_to_xcdr_version(encoding) << ":\n"
3258  " {\n";
3259  intro.join(be_global->impl_, indent);
3260  be_global->impl_
3261  << expr <<
3262  " break;\n"
3263  " }\n";
3264  }
3265  be_global->impl_ <<
3266  " }\n";
3267  }
3268 
3269  {
3270  Function insertion("operator<<", "bool");
3271  insertion.addArg("strm", "Serializer&");
3272  insertion.addArg("stru", "KeyOnly<const " + cxx + ">");
3273  insertion.endArgs();
3274 
3275  bool first = true;
3276  std::string expr;
3277  Intro intro;
3278  const char* indent = " ";
3279 
3280  IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
3281  for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
3282  const string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
3283  AST_Type* const field_type = find_type(node, key_name);
3284  if (first) {
3285  first = false;
3286  } else {
3287  expr += "\n && ";
3288  }
3289  expr += streamCommon(indent, 0, key_name, field_type, "<< stru.value", false, intro);
3290  }
3291 
3292  intro.join(be_global->impl_, indent);
3293  be_global->impl_ << " return " << (first ? "true" : expr) << ";\n";
3294  }
3295 
3296  {
3297  Function extraction("operator>>", "bool");
3298  extraction.addArg("strm", "Serializer&");
3299  extraction.addArg("stru", "KeyOnly<" + cxx + ">");
3300  extraction.endArgs();
3301 
3302  bool first = true;
3303  Intro intro;
3304  std::string expr;
3305  const std::string indent = " ";
3306 
3307  IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
3308  for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
3309  const string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
3310  AST_Type* const field_type = find_type(node, key_name);
3311  if (first) {
3312  first = false;
3313  } else {
3314  expr += "\n && ";
3315  }
3316  expr += streamCommon(indent, 0, key_name, field_type, ">> stru.value", false, intro);
3317  }
3318 
3319  intro.join(be_global->impl_, indent);
3320  be_global->impl_ << " return " << (first ? "true" : expr) << ";\n";
3321  }
3322  }
3323 
3324  return true;
3325 }
void set_default(Type &)
Definition: Serializer.h:934
#define ACE_TEXT_ALWAYS_CHAR(STRING)
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
std::set< EleLen > EleLenSet
Definition: field_info.h:31
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
const char *const name
Definition: debug.cpp:60
BE_GlobalData * be_global
Definition: be_global.cpp:43
void join(std::ostream &os, const std::string &indent)

◆ gen_typedef()

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

Implements dds_generator.

Definition at line 1876 of file marshal_generator.cpp.

References ACE_TEXT_ALWAYS_CHAR, Function::addArg(), FieldInfo::anonymous(), be_global, TopicKeys::begin(), Fields::begin(), bounded_arg(), ACE_String_Base< char >::c_str(), AstTypeClassification::CL_BOUNDED, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_PRIMITIVE, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_UNKNOWN, AstTypeClassification::CL_WIDE, AstTypeClassification::classify(), TopicKeys::count(), OpenDDS::STUN::encoding(), TopicKeys::end(), Fields::end(), Function::endArgs(), extensibilitykind_appendable, extensibilitykind_final, extensibilitykind_mutable, FieldFilter_All, FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, generate_dheader_code(), get_struct_field(), getWrapper(), insert_cxx11_accessor_parens(), TopicKeys::InvalidType, OpenDDS::XTypes::is_key(), Intro::join(), name, FieldInfo::name_, TopicKeys::Iterator::path(), AstTypeClassification::resolveActualType(), TopicKeys::root_type(), scoped(), FieldInfo::scoped_type_, OpenDDS::DCPS::serialized_size(), tryconstructfailaction_trim, tryconstructfailaction_use_default, FieldInfo::type_, type_to_default(), OpenDDS::DataRepresentation::unaligned, TopicKeys::UnionType, WD_INPUT, WD_OUTPUT, OpenDDS::DataRepresentation::xcdr1, OpenDDS::DataRepresentation::xcdr2, and OpenDDS::DataRepresentation::xml.

1877 {
1878  switch (base->node_type()) {
1879  case AST_Decl::NT_sequence:
1880  gen_sequence(name, dynamic_cast<AST_Sequence*>(base));
1881  break;
1882  case AST_Decl::NT_array:
1883  gen_array(name, dynamic_cast<AST_Array*>(base));
1884  break;
1885  default:
1886  return true;
1887  }
1888  return true;
1889 }
const char *const name
Definition: debug.cpp:60

◆ gen_union()

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

References Function::addArg(), OpenDDS::DCPS::array_count(), be_global, AstTypeClassification::CL_ENUM, AstTypeClassification::classify(), Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, generate_dheader_code(), generateSwitchForUnion(), getWrapper(), OPENDDS_HAS_EXPLICIT_INTS, AstTypeClassification::resolveActualType(), scoped(), OpenDDS::DCPS::serialized_size(), OpenDDS::DCPS::set_default(), tryconstructfailaction_use_default, type_to_default(), WD_INPUT, and WD_OUTPUT.

3862 {
3863  NamespaceGuard ng;
3864  be_global->add_include("dds/DCPS/Serializer.h");
3865  string cxx = scoped(name); // name as a C++ class
3866  Classification disc_cls = classify(discriminator);
3867 
3868  const ExtensibilityKind exten = be_global->extensibility(node);
3869  const bool not_final = exten != extensibilitykind_final;
3870 
3871  {
3872  // Define the set_default function in the header and implementation file.
3873  const std::string varname("uni");
3874  Function set_default("set_default", "void", "");
3875  set_default.addArg(varname.c_str(), cxx + "&");
3876  set_default.endArgs();
3877 
3878  // Add a reference to the idl file, if the descriminator is user defined.
3879  AST_Type* disc_type = resolveActualType(discriminator);
3880  const Classification disc_cls = classify(disc_type);
3881  if (!disc_type->in_main_file() && disc_type->node_type() != AST_Decl::NT_pre_defined) {
3882  be_global->add_referenced(disc_type->file_name().c_str());
3883  }
3884 
3885  // Determine the default enum value
3886  ACE_CDR::ULong default_enum_val = 0;
3887  if (disc_cls & CL_ENUM) {
3888  AST_Enum* enu = dynamic_cast<AST_Enum*>(disc_type);
3889  UTL_ScopeActiveIterator i(enu, UTL_Scope::IK_decls);
3890  AST_EnumVal *item = dynamic_cast<AST_EnumVal*>(i.item());
3891  default_enum_val = item->constant_value()->ev()->u.eval;
3892  }
3893 
3894  // Search the union branches to find the default value according to
3895  // Table 9 of the XTypes spec v1.3
3896  bool found = false;
3897  for (std::vector<AST_UnionBranch*>::const_iterator itr = branches.begin(); itr < branches.end() && !found; ++itr) {
3898  AST_UnionBranch* branch = *itr;
3899  for (unsigned i = 0; i < branch->label_list_length(); ++i) {
3900  AST_UnionLabel* ul = branch->label(i);
3901  if (ul->label_kind() != AST_UnionLabel::UL_default) {
3902  AST_Expression::AST_ExprValue* ev = branch->label(i)->label_val()->ev();
3903  if ((ev->et == AST_Expression::EV_enum && ev->u.eval == default_enum_val) ||
3905  (ev->et == AST_Expression::EV_uint8 && ev->u.uint8val == 0) ||
3906  (ev->et == AST_Expression::EV_int8 && ev->u.int8val == 0) ||
3907 #endif
3908  (ev->et == AST_Expression::EV_short && ev->u.sval == 0) ||
3909  (ev->et == AST_Expression::EV_ushort && ev->u.usval == 0) ||
3910  (ev->et == AST_Expression::EV_long && ev->u.lval == 0) ||
3911  (ev->et == AST_Expression::EV_ulong && ev->u.ulval == 0) ||
3912  (ev->et == AST_Expression::EV_longlong && ev->u.llval == 0) ||
3913  (ev->et == AST_Expression::EV_ulonglong && ev->u.ullval == 0) ||
3914  (ev->et == AST_Expression::EV_float && ev->u.fval == 0) ||
3915  (ev->et == AST_Expression::EV_double && ev->u.dval == 0) ||
3916  (ev->et == AST_Expression::EV_longdouble && ev->u.sval == 0) ||
3917  (ev->et == AST_Expression::EV_char && ev->u.cval == 0) ||
3918  (ev->et == AST_Expression::EV_wchar && ev->u.wcval == 0) ||
3919  (ev->et == AST_Expression::EV_octet && ev->u.oval == 0) ||
3920  (ev->et == AST_Expression::EV_bool && ev->u.bval == 0))
3921  {
3922  gen_union_default(branch, varname);
3923  found = true;
3924  break;
3925  }
3926  }
3927  }
3928  }
3929 
3930  // If a default value was not found, just set the discriminator to the
3931  // default value.
3932  if (!found) {
3933  be_global->impl_ << " " << scoped(discriminator->name()) << " temp;\n";
3934  be_global->impl_ << type_to_default("", discriminator, " temp");
3935  be_global->impl_ << " " << varname << "._d(temp);\n";
3936  }
3937  }
3938 
3939  for (size_t i = 0; i < array_count(special_unions); ++i) {
3940  if (special_unions[i].check(cxx)) {
3941  return special_unions[i].gen(cxx, node, discriminator, branches);
3942  }
3943  }
3944 
3945  const string wrap_out = getWrapper("uni._d()", discriminator, WD_OUTPUT);
3946  {
3947  Function serialized_size("serialized_size", "void");
3948  serialized_size.addArg("encoding", "const Encoding&");
3949  serialized_size.addArg("size", "size_t&");
3950  serialized_size.addArg("uni", "const " + cxx + "&");
3951  serialized_size.endArgs();
3952 
3953  marshal_generator::generate_dheader_code(" serialized_size_delimiter(encoding, size);\n", not_final, false);
3954 
3955  if (exten == extensibilitykind_mutable) {
3956  be_global->impl_ <<
3957  " size_t mutable_running_total = 0;\n"
3958  " serialized_size_parameter_id(encoding, size, mutable_running_total);\n";
3959  }
3960 
3961  if (disc_cls & CL_ENUM) {
3962  be_global->impl_ <<
3963  " primitive_serialized_size_ulong(encoding, size);\n";
3964  } else {
3965  be_global->impl_ <<
3966  " primitive_serialized_size(encoding, size, " << wrap_out << ");\n";
3967  }
3968 
3969  generateSwitchForUnion(node, "uni._d()",
3970  exten == extensibilitykind_mutable ? findSizeMutableUnion : findSizeCommon,
3971  branches, discriminator, "", "", cxx.c_str());
3972 
3973  if (exten == extensibilitykind_mutable) {
3974  // TODO: XTypes B will need to edit this code to add the pid for the end of mutable unions.
3975  // Until this change is made, XCDR1 will NOT be functional
3976  be_global->impl_ <<
3977  " serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);\n";
3978  }
3979  }
3980  {
3981  Function insertion("operator<<", "bool");
3982  insertion.addArg("strm", "Serializer&");
3983  insertion.addArg("uni", "const " + cxx + "&");
3984  insertion.endArgs();
3985 
3986  be_global->impl_ <<
3987  " const Encoding& encoding = strm.encoding();\n"
3988  " ACE_UNUSED_ARG(encoding);\n";
3990  " serialized_size(encoding, total_size, uni);\n"
3991  " if (!strm.write_delimiter(total_size)) {\n"
3992  " return false;\n"
3993  " }\n", not_final);
3994 
3995  // EMHEADER for discriminator
3996  if (exten == extensibilitykind_mutable) {
3997  be_global->impl_ <<
3998  " size_t size = 0;\n";
3999 
4000  if (disc_cls & CL_ENUM) {
4001  be_global->impl_ <<
4002  " primitive_serialized_size_ulong(encoding, size);\n";
4003  } else {
4004  be_global->impl_ <<
4005  " primitive_serialized_size(encoding, size, " << wrap_out << ");\n";
4006  }
4007 
4008  be_global->impl_ <<
4009  " if (!strm.write_parameter_id(0, size)) {\n"
4010  " return false;\n"
4011  " }\n"
4012  " size = 0;\n";
4013  }
4014 
4015  be_global->impl_ <<
4016  streamAndCheck("<< " + wrap_out);
4017  if (generateSwitchForUnion(node, "uni._d()", streamCommon, branches,
4018  discriminator, "return", "<< ", cxx.c_str(),
4019  false, true, true,
4020  exten == extensibilitykind_mutable ? findSizeCommon : 0)) {
4021  be_global->impl_ <<
4022  " return true;\n";
4023  }
4024  }
4025  {
4026  Function extraction("operator>>", "bool");
4027  extraction.addArg("strm", "Serializer&");
4028  extraction.addArg("uni", cxx + "&");
4029  extraction.endArgs();
4030 
4031  be_global->impl_ <<
4032  " const Encoding& encoding = strm.encoding();\n"
4033  " ACE_UNUSED_ARG(encoding);\n";
4035  " if (!strm.read_delimiter(total_size)) {\n"
4036  " return false;\n"
4037  " }\n", not_final);
4038 
4039  if (exten == extensibilitykind_mutable) {
4040  // EMHEADER for discriminator
4041  be_global->impl_ <<
4042  " unsigned member_id;\n"
4043  " size_t field_size;\n"
4044  " bool must_understand = false;\n"
4045  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
4046  " return false;\n"
4047  " }\n";
4048  TryConstructFailAction try_construct = be_global->union_discriminator_try_construct(node);
4049  be_global->impl_ <<
4050  " " << scoped(discriminator->name()) << " disc;\n"
4051  " if (!(strm >> disc)) {\n";
4052  if (try_construct == tryconstructfailaction_use_default) {
4053  be_global->impl_ <<
4054  " set_default(uni);\n"
4055  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
4056  " return false;\n"
4057  " }\n"
4058  " strm.skip(field_size);\n"
4059  " strm.set_construction_status(Serializer::ConstructionSuccessful);\n"
4060  " return true;\n";
4061  } else {
4062  be_global->impl_ <<
4063  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
4064  " return false;\n"
4065  " }\n"
4066  " strm.skip(field_size);\n"
4067  " strm.set_construction_status(Serializer::ElementConstructionFailure);\n"
4068  " return false;\n";
4069  }
4070  be_global->impl_ << " }\n";
4071 
4072  be_global->impl_ <<
4073  " member_id = 0;\n"
4074  " field_size = 0;\n"
4075  " must_understand = false;\n";
4076 
4077  const char prefix[] =
4078  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
4079  " return false;\n"
4080  " }\n";
4081  if (generateSwitchForUnion(node, "disc", streamCommon, branches,
4082  discriminator, prefix, ">> ", cxx.c_str())) {
4083  be_global->impl_ <<
4084  " return true;\n";
4085  }
4086  } else {
4087  be_global->impl_ <<
4088  " " << scoped(discriminator->name()) << " disc;\n" <<
4089  streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT));
4090  if (generateSwitchForUnion(node, "disc", streamCommon, branches,
4091  discriminator, "", ">> ", cxx.c_str())) {
4092  be_global->impl_ <<
4093  " return true;\n";
4094  }
4095  }
4096  }
4097 
4098  gen_union_key_serializers(node, FieldFilter_NestedKeyOnly);
4099  gen_union_key_serializers(node, FieldFilter_KeyOnly);
4100 
4101  TopicKeys keys(node);
4102  return generate_marshal_traits(node, cxx, exten, keys);
4103 }
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
void set_default(Type &)
Definition: Serializer.h:934
size_t array_count(Type(&)[count])
Definition: Util.h:221
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
AST_Type * resolveActualType(AST_Type *element)
ExtensibilityKind
Definition: annotations.h:278
Classification classify(AST_Type *type)
#define OPENDDS_HAS_EXPLICIT_INTS
Definition: Definitions.h:77
const Classification CL_ENUM
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
ACE_UINT32 ULong
void gen_union_default(AST_UnionBranch *branch, const std::string &varname)
const char *const name
Definition: debug.cpp:60
bool generateSwitchForUnion(AST_Union *u, const char *switchExpr, CommonFn commonFn, const std::vector< AST_UnionBranch *> &branches, AST_Type *discriminator, const char *statementPrefix, const char *namePrefix="", const char *uni="", bool forceDisableDefault=false, bool parens=true, bool breaks=true, CommonFn commonFn2=0)
returns true if a default: branch was generated (no default: label in IDL)
TryConstructFailAction
Definition: annotations.h:316
BE_GlobalData * be_global
Definition: be_global.cpp:43

◆ gen_union_default()

void marshal_generator::gen_union_default ( AST_UnionBranch *  branch,
const std::string &  varname 
)
private

Definition at line 4105 of file marshal_generator.cpp.

References be_global, AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::CL_UNION, AstTypeClassification::classify(), getWrapper(), AstTypeClassification::resolveActualType(), scoped(), type_to_default(), and WD_INPUT.

4106 {
4107  AST_Type* br = resolveActualType(branch->field_type());
4108  const Classification br_cls = classify(br);
4109  const std::string tmpname = "tmp";
4110 
4111  if (br_cls & (CL_SEQUENCE | CL_ARRAY | CL_STRUCTURE | CL_UNION)) {
4112  be_global->impl_ << " " << scoped(branch->field_type()->name()) << " "
4113  << getWrapper(tmpname, branch->field_type(), WD_INPUT) << ";\n";
4114  }
4115 
4116  if (br_cls & (CL_STRUCTURE | CL_UNION)) {
4117  be_global->impl_ << type_to_default(" ", branch->field_type(), tmpname);
4118  be_global->impl_ << " " << varname << "." << branch->local_name()->get_string() << "(tmp);\n";
4119  } else {
4120  be_global->impl_ << type_to_default(" ", branch->field_type(),
4121  varname + "." + branch->local_name()->get_string(),
4122  false, true);
4123  }
4124 }
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
const Classification CL_ARRAY
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
const Classification CL_UNION
const Classification CL_STRUCTURE
AST_Type * resolveActualType(AST_Type *element)
Classification classify(AST_Type *type)
const Classification CL_SEQUENCE
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
BE_GlobalData * be_global
Definition: be_global.cpp:43

◆ generate_dheader_code()

void marshal_generator::generate_dheader_code ( const std::string &  code,
bool  dheader_required,
bool  is_ser_func = true 
)
static

Definition at line 3154 of file marshal_generator.cpp.

References be_global.

Referenced by gen_enum(), gen_field_getValueFromSerialized(), metaclass_generator::gen_struct(), gen_typedef(), metaclass_generator::gen_typedef(), gen_union(), and metaclass_generator::gen_union().

3155 {
3156  //DHeader appears on aggregated types that are mutable or appendable in XCDR2
3157  //DHeader also appears on ALL sequences and arrays of non-primitives
3158  if (dheader_required) {
3159  if (is_ser_func) {
3160  be_global->impl_ << " size_t total_size = 0;\n";
3161  }
3162  be_global->impl_ << " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_2) {\n"
3163  << code <<
3164  " }\n";
3165  }
3166 }
Christopher Diggins *renamed files *fixing compilation errors *adding Visual C project file *removed make Max Lybbert *removed references to missing and unused as reported by Andy Elvey and Dan Kosecki *resynced with Christopher Diggins s branch as it exists in tree building code is back Christopher Diggins *resynced codebase with Chris s branch *removed tree building code
Definition: CHANGELOG.txt:8
BE_GlobalData * be_global
Definition: be_global.cpp:43

The documentation for this class was generated from the following files: