OpenDDS  Snapshot(2023/04/28-20:55)
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, const std::string &qualifier="")
 
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 155 of file marshal_generator.cpp.

References Function::addArg(), OpenDDS::DCPS::align(), OpenDDS::DCPS::Encoding::align(), 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, RefWrapper::classic_array_copy(), RefWrapper::classic_array_copy_, AstTypeClassification::classify(), deepest_named_type(), RefWrapper::done(), OpenDDS::STUN::encoding(), Fields::end(), Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, generate_dheader_code(), RefWrapper::generate_tag(), getWrapper(), NestedForLoops::index_, RefWrapper::is_const_, Intro::join(), be_util::misc_error_and_abort(), name, needs_nested_key_only(), RefWrapper::nested_key_only_, RefWrapper::ref(), AstTypeClassification::resolveActualType(), scoped(), RefWrapper::seq_check_empty(), RefWrapper::seq_get_buffer(), RefWrapper::seq_get_length(), RefWrapper::seq_resize(), OpenDDS::DCPS::serialized_size(), OpenDDS::DCPS::set_default(), tryconstructfailaction_trim, tryconstructfailaction_use_default, FieldInfo::type_, RefWrapper::type_name_, type_to_default(), RefWrapper::typedef_node_, value, RefWrapper::value_access(), WD_INPUT, WD_OUTPUT, and RefWrapper::wrapped_type_name().

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

◆ gen_field_getValueFromSerialized()

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

Definition at line 2982 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(), deepest_named_type(), Fields::end(), Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, field_type_name(), FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, generate_dheader_code(), generateSwitchBody(), generateSwitchForUnion(), dds_generator::get_tag_name(), getWrapper(), name, 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().

2983 {
2984  //loop through meta struct
2985  //check the id for a match to our id
2986  //if we are not a match, skip to the next field
2987  //if we are a match, deserialize the field
2988  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
2989  std::string expr;
2990  const ExtensibilityKind exten = be_global->extensibility(node);
2991  const bool not_final = exten != extensibilitykind_final;
2992  const bool is_mutable = exten == extensibilitykind_mutable;
2993  const std::string actual_cpp_name = scoped(node->name());
2994  std::string cpp_name = actual_cpp_name;
2995  const Fields fields(node);
2996  const Fields::Iterator fields_end = fields.end();
2997  RtpsFieldCustomizer rtpsCustom(cpp_name);
2998 
2999  be_global->impl_ <<
3000  " Value getValue(Serializer& strm, const char* field, const TypeSupportImpl* = 0) const\n"
3001  " {\n"
3002  " const Encoding& encoding = strm.encoding();\n"
3003  " ACE_UNUSED_ARG(encoding);\n";
3005  " if (!strm.read_delimiter(total_size)) {\n"
3006  " throw std::runtime_error(\"Unable to reader delimiter in getValue\");\n"
3007  " }\n", not_final);
3008  be_global->impl_ <<
3009  " std::string base_field = field;\n"
3010  " const size_t index = base_field.find('.');\n"
3011  " std::string subfield;\n"
3012  " if (index != std::string::npos) {\n"
3013  " subfield = base_field.substr(index + 1);\n"
3014  " base_field = base_field.substr(0, index);\n"
3015  " }\n";
3016 
3017  if (is_mutable) {
3018  be_global->impl_ <<
3019  " if (encoding.xcdr_version() != Encoding::XCDR_VERSION_NONE) {\n"
3020  " unsigned field_id = map_name_to_id(base_field.c_str());\n"
3021  " ACE_UNUSED_ARG(field_id);\n"
3022  " unsigned member_id;\n"
3023  " size_t field_size;\n"
3024  " const size_t end_of_struct = strm.rpos() + total_size;\n"
3025  " while (true) {\n"
3026  " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_2 &&\n"
3027  " strm.rpos() >= end_of_struct) {\n"
3028  " break;\n"
3029  " }\n"
3030  " bool must_understand = false;\n"
3031  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3032  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" Deserialization "
3033  "Error for struct " << clazz << "\");\n"
3034  " }\n"
3035  " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_1 &&\n"
3036  " member_id == Serializer::pid_list_end) {\n"
3037  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" not "
3038  "valid for struct " << clazz << "\");\n"
3039  " }\n"
3040  " const size_t end_of_field = strm.rpos() + field_size;\n"
3041  " ACE_UNUSED_ARG(end_of_field);\n"
3042  "\n";
3043 
3044  std::ostringstream cases;
3045  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
3046  AST_Field* const field = *i;
3047  size_t size = 0;
3048  const OpenDDS::XTypes::MemberId id = be_global->get_id(field);
3049  std::string field_name = field->local_name()->get_string();
3050  AST_Type* const field_type = resolveActualType(field->field_type());
3051  Classification fld_cls = classify(field_type);
3052 
3053  cases << " case " << id << ": {\n";
3054  if (fld_cls & CL_SCALAR) {
3055  const std::string cxx_type = to_cxx_type(field_type, size);
3056  const std::string val = (fld_cls & CL_STRING) ? (use_cxx11 ? "val" : "val.out()")
3057  : getWrapper("val", field_type, WD_INPUT);
3058  std::string boundsCheck, transformPrefix, transformSuffix;
3059  if (fld_cls & CL_ENUM) {
3060  const std::string enumName = dds_generator::scoped_helper(field_type->name(), "_");
3061  boundsCheck = " if (val >= gen_" + enumName + "_names_size) {\n"
3062  " throw std::runtime_error(\"Enum value out of bounds\");\n"
3063  " }\n";
3064  transformPrefix = "gen_" + enumName + "_names[";
3065  transformSuffix = "]";
3066  }
3067  cases <<
3068  " if (field_id == member_id) {\n"
3069  " " << cxx_type << " val;\n" <<
3070  " if (!(strm >> " << val << ")) {\n"
3071  " throw std::runtime_error(\"Field '" << field_name << "' could not be deserialized\");\n" <<
3072  " }\n" <<
3073  boundsCheck <<
3074  " return " << transformPrefix << "val" << transformSuffix << ";\n"
3075  " } else {\n"
3076  " strm.skip(field_size);\n"
3077  " }\n"
3078  " break;\n"
3079  " }\n";
3080  } else if (fld_cls & CL_STRUCTURE) {
3081  cases <<
3082  " if (field_id == member_id) {\n"
3083  " return getMetaStruct<" << scoped(field_type->name()) << ">().getValue(strm, subfield.c_str());\n"
3084  " } else {\n"
3085  " strm.skip(field_size);\n"
3086  " }\n"
3087  " break;\n"
3088  " }\n";
3089  } else { // array, sequence, union:
3090  cases <<
3091  " strm.skip(field_size);\n"
3092  " break;\n"
3093  " }\n";
3094  }
3095  }
3096  const std::string switch_cases = cases.str();
3097  std::string sw_indent = " ";
3098  if (switch_cases.empty()) {
3099  sw_indent = " ";
3100  } else {
3101  be_global->impl_ <<
3102  " switch (member_id) {\n"
3103  << switch_cases <<
3104  " default:\n";
3105  }
3106  be_global->impl_ <<
3107  sw_indent << "if (must_understand) {\n" <<
3108  sw_indent << " if (DCPS_debug_level >= 8) {\n" <<
3109  sw_indent << " ACE_DEBUG((LM_DEBUG, ACE_TEXT(\"(%P|%t) unknown must_understand field(%u) in "
3110  << cpp_name << "\\n\"), member_id));\n" <<
3111  sw_indent << " }\n" <<
3112  sw_indent << " throw std::runtime_error(\"member id did not exist in getValue\");\n" <<
3113  sw_indent << "}\n" <<
3114  sw_indent << "strm.skip(field_size);\n";
3115  if (!switch_cases.empty()) {
3116  be_global->impl_ <<
3117  " break;\n"
3118  " }\n";
3119  }
3120  be_global->impl_ <<
3121  " }\n"
3122  " if (!field[0]) {\n" // if 'field' is the empty string...
3123  " return 0;\n" // the return value is ignored
3124  " }\n"
3125  " throw std::runtime_error(\"Did not find field in getValue\");\n"
3126  " }\n";
3127  }
3128  //The following is Appendable/Final
3129  //It is also used when Mutable but not in XCDR1 or XCDR2
3130  expr = "";
3131  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
3132  AST_Field* const field = *i;
3133  size_t size = 0;
3134  const std::string idl_name = canonical_name(field);
3135  AST_Type* const field_type = resolveActualType(field->field_type());
3136  Classification fld_cls = classify(field_type);
3137  if (fld_cls & CL_SCALAR) {
3138  const std::string cxx_type = to_cxx_type(field_type, size);
3139  const std::string val = (fld_cls & CL_STRING) ? (use_cxx11 ? "val" : "val.out()")
3140  : getWrapper("val", field_type, WD_INPUT);
3141  std::string boundsCheck, transformPrefix, transformSuffix;
3142  if (fld_cls & CL_ENUM) {
3143  const std::string enumName = dds_generator::scoped_helper(field_type->name(), "_");
3144  boundsCheck = " if (val >= gen_" + enumName + "_names_size) {\n"
3145  " throw std::runtime_error(\"Enum value out of bounds\");\n"
3146  " }\n";
3147  transformPrefix = "gen_" + enumName + "_names[";
3148  transformSuffix = "]";
3149  }
3150  expr +=
3151  " if (base_field == \"" + idl_name + "\") {\n"
3152  " " + cxx_type + " val;\n"
3153  " if (!(strm >> " + val + ")) {\n"
3154  " throw std::runtime_error(\"Field '" + idl_name + "' could "
3155  "not be deserialized\");\n"
3156  " }\n"
3157  + boundsCheck +
3158  " return " + transformPrefix + "val" + transformSuffix + ";\n"
3159  " } else {\n";
3160  if (fld_cls & CL_STRING) {
3161  expr +=
3162  " ACE_CDR::ULong len;\n"
3163  " if (!(strm >> len)) {\n"
3164  " throw std::runtime_error(\"String '" + idl_name +
3165  "' length could not be deserialized\");\n"
3166  " }\n"
3167  " if (!strm.skip(len)) {\n"
3168  " throw std::runtime_error(\"String '" + idl_name +
3169  "' contents could not be skipped\");\n"
3170  " }\n"
3171  " }\n";
3172  } else {
3173  expr +=
3174  " if (!strm.skip(1, " + OpenDDS::DCPS::to_dds_string(size) + " )) {\n"
3175  " throw std::runtime_error(\"Field '" + idl_name +
3176  "' could not be skipped\");\n"
3177  " }\n"
3178  " }\n";
3179  }
3180  } else if (fld_cls & CL_STRUCTURE) {
3181  expr +=
3182  " if (base_field == \"" + idl_name + "\") {\n"
3183  " return getMetaStruct<" + scoped(field_type->name()) + ">().getValue(strm, subfield.c_str());\n"
3184  " } else {\n"
3185  " if (!gen_skip_over(strm, static_cast<" + scoped(field_type->name()) + "*>(0))) {\n"
3186  " throw std::runtime_error(\"Field '" + idl_name + "' could not be skipped\");\n"
3187  " }\n"
3188  " }\n";
3189  } else { // array, sequence, union:
3190  std::string pre, post;
3191  if (!use_cxx11 && (fld_cls & CL_ARRAY)) {
3192  post = "_forany";
3193  } else if (use_cxx11 && (fld_cls & (CL_ARRAY | CL_SEQUENCE))) {
3194  pre = "IDL::DistinctType<";
3195  post = ", " + dds_generator::get_tag_name(scoped(deepest_named_type(field->field_type())->name())) + ">";
3196  }
3197  const std::string ptr = field->field_type()->anonymous() ?
3198  FieldInfo(*field).ptr_ : (pre + field_type_name(field) + post + '*');
3199  expr +=
3200  " if (!gen_skip_over(strm, static_cast<" + ptr + ">(0))) {\n"
3201  " throw std::runtime_error(\"Field \" + OPENDDS_STRING(field) + \" could not be skipped\");\n"
3202  " }\n";
3203  }
3204  }
3205  be_global->impl_ <<
3206  expr <<
3207  " if (!field[0]) {\n" // if 'field' is the empty string...
3208  " return 0;\n" // the return value is ignored
3209  " }\n"
3210  " throw std::runtime_error(\"Did not find field in getValue\");\n"
3211  " }\n\n";
3212 }
std::string to_cxx_type(AST_Type *type, std::size_t &size)
Classification classify(AST_Type *type)
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
ACE_CDR::ULong MemberId
Definition: TypeObject.h:910
const Classification CL_STRING
const Classification CL_SCALAR
std::string field_type_name(AST_Field *field, AST_Type *field_type)
String to_dds_string(unsigned short to_convert)
static std::string get_tag_name(const std::string &base_name, const std::string &qualifier="")
ExtensibilityKind
Definition: annotations.h:278
AST_Type * deepest_named_type(AST_Type *type)
const Classification CL_ARRAY
std::string ptr_
Definition: field_info.h:66
std::string canonical_name(UTL_ScopedName *sn)
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
AST_Type * resolveActualType(AST_Type *element)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
const char *const name
Definition: debug.cpp:60
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
const Classification CL_STRUCTURE
BE_GlobalData * be_global
Definition: be_global.cpp:44
const Classification CL_ENUM
const Classification CL_SEQUENCE

◆ 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 2822 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().

2827 {
2828  NamespaceGuard ng;
2829  be_global->add_include("dds/DCPS/Serializer.h");
2830  const string cxx = scoped(name); // name as a C++ class
2831  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
2832 
2833  {
2834  Function set_default("set_default", "void", "");
2835  set_default.addArg("stru", cxx + "&");
2836  set_default.endArgs();
2837  std::ostringstream contents;
2838  Intro intro;
2839  for (size_t i = 0; i < fields.size(); ++i) {
2840  AST_Field* const field = fields[i];
2841  AST_Type* const type = field->field_type();
2842  string field_name = string("stru.") + field->local_name()->get_string();
2843  if (use_cxx11) {
2844  field_name += "()";
2845  }
2846  contents << type_to_default(" ", type, field_name, type->anonymous());
2847  }
2848  intro.join(be_global->impl_, " ");
2849  be_global->impl_ << contents.str();
2850  }
2851 
2852  bool special_result;
2853  if (generate_special_struct(node, cxx, special_result)) {
2854  return special_result;
2855  }
2856 
2857  FieldInfo::EleLenSet anonymous_seq_generated;
2858  for (size_t i = 0; i < fields.size(); ++i) {
2859  if (fields[i]->field_type()->anonymous()) {
2860  FieldInfo af(*fields[i]);
2861  if (af.arr_) {
2862  gen_anonymous_array(af);
2863  } else if (af.seq_ && af.is_new(anonymous_seq_generated)) {
2864  gen_anonymous_sequence(af);
2865  }
2866  }
2867  }
2868 
2869  if (!generate_struct_serialization_functions(node, FieldFilter_All) ||
2870  !generate_struct_serialization_functions(node, FieldFilter_NestedKeyOnly)) {
2871  return false;
2872  }
2873 
2874  IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(name);
2875  const bool is_topic_type = be_global->is_topic_type(node);
2876  TopicKeys keys;
2877  if (is_topic_type) {
2878  keys = TopicKeys(node);
2879  info = 0; // Annotations Override DCPS_DATA_TYPE
2880 
2881  if (!generate_struct_serialization_functions(node, FieldFilter_KeyOnly)) {
2882  return false;
2883  }
2884  }
2885 
2886  if ((info || is_topic_type) &&
2887  !generate_marshal_traits(node, cxx, be_global->extensibility(node), keys, info)) {
2888  return false;
2889  }
2890 
2891  if (info && !is_topic_type) {
2892  {
2893  Function serialized_size("serialized_size", "void");
2894  serialized_size.addArg("encoding", "const Encoding&");
2895  serialized_size.addArg("size", "size_t&");
2896  serialized_size.addArg("stru", "const KeyOnly<const " + cxx + ">");
2897  serialized_size.endArgs();
2898 
2899  be_global->impl_ <<
2900  " switch (encoding.xcdr_version()) {\n";
2901  const char* indent = " ";
2902  for (unsigned e = 0; e <= Encoding::KIND_UNALIGNED_CDR; ++e) {
2903  string expr;
2904  Intro intro;
2905  const Encoding::Kind encoding = static_cast<Encoding::Kind>(e);
2906  if (!iterate_over_keys(indent, encoding, node, cxx, info, 0,
2907  serialized_size_iteration, 0, &expr, &intro)) {
2908  return false;
2909  }
2910  be_global->impl_ <<
2911  " case " << encoding_to_xcdr_version(encoding) << ":\n"
2912  " {\n";
2913  intro.join(be_global->impl_, indent);
2914  be_global->impl_
2915  << expr <<
2916  " break;\n"
2917  " }\n";
2918  }
2919  be_global->impl_ <<
2920  " }\n";
2921  }
2922 
2923  {
2924  Function insertion("operator<<", "bool");
2925  insertion.addArg("strm", "Serializer&");
2926  insertion.addArg("stru", "KeyOnly<const " + cxx + ">");
2927  insertion.endArgs();
2928 
2929  bool first = true;
2930  std::string expr;
2931  Intro intro;
2932  const char* indent = " ";
2933 
2934  IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
2935  for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
2936  const string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
2937  AST_Type* const field_type = find_type(node, key_name);
2938  if (first) {
2939  first = false;
2940  } else {
2941  expr += "\n && ";
2942  }
2943  expr += streamCommon(indent, 0, key_name, field_type, "<< stru.value", false, intro);
2944  }
2945 
2946  intro.join(be_global->impl_, indent);
2947  be_global->impl_ << " return " << (first ? "true" : expr) << ";\n";
2948  }
2949 
2950  {
2951  Function extraction("operator>>", "bool");
2952  extraction.addArg("strm", "Serializer&");
2953  extraction.addArg("stru", "KeyOnly<" + cxx + ">");
2954  extraction.endArgs();
2955 
2956  bool first = true;
2957  Intro intro;
2958  std::string expr;
2959  const std::string indent = " ";
2960 
2961  IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
2962  for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
2963  const string key_name = ACE_TEXT_ALWAYS_CHAR(kp->c_str());
2964  AST_Type* const field_type = find_type(node, key_name);
2965  if (first) {
2966  first = false;
2967  } else {
2968  expr += "\n && ";
2969  }
2970  expr += streamCommon(indent, 0, key_name, field_type, ">> stru.value", false, intro);
2971  }
2972 
2973  intro.join(be_global->impl_, indent);
2974  be_global->impl_ << " return " << (first ? "true" : expr) << ";\n";
2975  }
2976  }
2977 
2978  return true;
2979 }
void join(std::ostream &os, const std::string &indent)
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
void set_default(Type &)
Definition: Serializer.h:944
#define ACE_TEXT_ALWAYS_CHAR(STRING)
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
const char *const name
Definition: debug.cpp:60
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
std::set< EleLen > EleLenSet
Definition: field_info.h:31
BE_GlobalData * be_global
Definition: be_global.cpp:44
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)

◆ 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 1557 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(), RefWrapper::done(), OpenDDS::STUN::encoding(), TopicKeys::end(), Fields::end(), Function::endArgs(), extensibilitykind_appendable, extensibilitykind_final, extensibilitykind_mutable, field_type_name(), FieldFilter_All, FieldFilter_KeyOnly, FieldFilter_NestedKeyOnly, generate_dheader_code(), get_struct_field(), getWrapper(), insert_cxx11_accessor_parens(), TopicKeys::InvalidType, Intro::join(), name, FieldInfo::name_, RefWrapper::nested_key_only_, TopicKeys::Iterator::path(), RefWrapper::ref(), AstTypeClassification::resolveActualType(), TopicKeys::root_type(), scoped(), FieldInfo::scoped_type_, OpenDDS::DCPS::serialized_size(), RefWrapper::stream(), 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.

1558 {
1559  switch (base->node_type()) {
1560  case AST_Decl::NT_sequence:
1561  gen_sequence(name, node, dynamic_cast<AST_Sequence*>(base));
1562  break;
1563  case AST_Decl::NT_array:
1564  gen_array(name, dynamic_cast<AST_Array*>(base));
1565  break;
1566  default:
1567  return true;
1568  }
1569  return true;
1570 }
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 3493 of file marshal_generator.cpp.

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

3496 {
3497  NamespaceGuard ng;
3498  be_global->add_include("dds/DCPS/Serializer.h");
3499  string cxx = scoped(name); // name as a C++ class
3500  Classification disc_cls = classify(discriminator);
3501 
3502  FieldInfo::EleLenSet anonymous_seq_generated;
3503  for (size_t i = 0; i < branches.size(); ++i) {
3504  if (branches[i]->field_type()->anonymous()) {
3505  FieldInfo af(*branches[i]);
3506  if (af.arr_) {
3507  gen_anonymous_array(af);
3508  } else if (af.seq_ && af.is_new(anonymous_seq_generated)) {
3509  gen_anonymous_sequence(af);
3510  }
3511  }
3512  }
3513 
3514  const ExtensibilityKind exten = be_global->extensibility(node);
3515  const bool not_final = exten != extensibilitykind_final;
3516 
3517  {
3518  // Define the set_default function in the header and implementation file.
3519  const std::string varname("uni");
3520  Function set_default("set_default", "void", "");
3521  set_default.addArg(varname.c_str(), cxx + "&");
3522  set_default.endArgs();
3523 
3524  // Add a reference to the idl file, if the descriminator is user defined.
3525  AST_Type* disc_type = resolveActualType(discriminator);
3526  const Classification disc_cls = classify(disc_type);
3527  if (!disc_type->in_main_file() && disc_type->node_type() != AST_Decl::NT_pre_defined) {
3528  be_global->add_referenced(disc_type->file_name().c_str());
3529  }
3530 
3531  // Determine the default enum value
3532  ACE_CDR::ULong default_enum_val = 0;
3533  if (disc_cls & CL_ENUM) {
3534  AST_Enum* enu = dynamic_cast<AST_Enum*>(disc_type);
3535  UTL_ScopeActiveIterator i(enu, UTL_Scope::IK_decls);
3536  AST_EnumVal *item = dynamic_cast<AST_EnumVal*>(i.item());
3537  default_enum_val = item->constant_value()->ev()->u.eval;
3538  }
3539 
3540  // Search the union branches to find the default value according to
3541  // Table 9 of the XTypes spec v1.3
3542  bool found = false;
3543  for (std::vector<AST_UnionBranch*>::const_iterator itr = branches.begin(); itr < branches.end() && !found; ++itr) {
3544  AST_UnionBranch* branch = *itr;
3545  for (unsigned i = 0; i < branch->label_list_length(); ++i) {
3546  AST_UnionLabel* ul = branch->label(i);
3547  if (ul->label_kind() != AST_UnionLabel::UL_default) {
3548  AST_Expression::AST_ExprValue* ev = branch->label(i)->label_val()->ev();
3549  if ((ev->et == AST_Expression::EV_enum && ev->u.eval == default_enum_val) ||
3551  (ev->et == AST_Expression::EV_uint8 && ev->u.uint8val == 0) ||
3552  (ev->et == AST_Expression::EV_int8 && ev->u.int8val == 0) ||
3553 #endif
3554  (ev->et == AST_Expression::EV_short && ev->u.sval == 0) ||
3555  (ev->et == AST_Expression::EV_ushort && ev->u.usval == 0) ||
3556  (ev->et == AST_Expression::EV_long && ev->u.lval == 0) ||
3557  (ev->et == AST_Expression::EV_ulong && ev->u.ulval == 0) ||
3558  (ev->et == AST_Expression::EV_longlong && ev->u.llval == 0) ||
3559  (ev->et == AST_Expression::EV_ulonglong && ev->u.ullval == 0) ||
3560  (ev->et == AST_Expression::EV_float && ev->u.fval == 0) ||
3561  (ev->et == AST_Expression::EV_double && ev->u.dval == 0) ||
3562  (ev->et == AST_Expression::EV_longdouble && ev->u.sval == 0) ||
3563  (ev->et == AST_Expression::EV_char && ev->u.cval == 0) ||
3564  (ev->et == AST_Expression::EV_wchar && ev->u.wcval == 0) ||
3565  (ev->et == AST_Expression::EV_octet && ev->u.oval == 0) ||
3566  (ev->et == AST_Expression::EV_bool && ev->u.bval == 0))
3567  {
3568  gen_union_default(branch, varname);
3569  found = true;
3570  break;
3571  }
3572  }
3573  }
3574  }
3575 
3576  // If a default value was not found, just set the discriminator to the
3577  // default value.
3578  if (!found) {
3579  be_global->impl_ <<
3580  " " << scoped(discriminator->name()) << " temp;\n" <<
3581  type_to_default("", discriminator, " temp") <<
3582  " " << varname << "._d(temp);\n";
3583  }
3584  }
3585 
3586  bool special_result;
3587  if (generate_special_union(cxx, node, discriminator, branches, special_result)) {
3588  return special_result;
3589  }
3590 
3591  const string wrap_out = getWrapper("uni._d()", discriminator, WD_OUTPUT);
3592  {
3593  Function serialized_size("serialized_size", "void");
3594  serialized_size.addArg("encoding", "const Encoding&");
3595  serialized_size.addArg("size", "size_t&");
3596  serialized_size.addArg("uni", "const " + cxx + "&");
3597  serialized_size.endArgs();
3598 
3599  marshal_generator::generate_dheader_code(" serialized_size_delimiter(encoding, size);\n", not_final, false);
3600 
3601  if (exten == extensibilitykind_mutable) {
3602  be_global->impl_ <<
3603  " size_t mutable_running_total = 0;\n"
3604  " serialized_size_parameter_id(encoding, size, mutable_running_total);\n";
3605  }
3606 
3607  if (disc_cls & CL_ENUM) {
3608  be_global->impl_ <<
3609  " primitive_serialized_size_ulong(encoding, size);\n";
3610  } else {
3611  be_global->impl_ <<
3612  " primitive_serialized_size(encoding, size, " << wrap_out << ");\n";
3613  }
3614 
3615  generateSwitchForUnion(node, "uni._d()",
3616  exten == extensibilitykind_mutable ? findSizeMutableUnion : findSizeCommon,
3617  branches, discriminator, "", "", cxx.c_str());
3618 
3619  if (exten == extensibilitykind_mutable) {
3620  // TODO: XTypes B will need to edit this code to add the pid for the end of mutable unions.
3621  // Until this change is made, XCDR1 will NOT be functional
3622  be_global->impl_ <<
3623  " serialized_size_list_end_parameter_id(encoding, size, mutable_running_total);\n";
3624  }
3625  }
3626  {
3627  Function insertion("operator<<", "bool");
3628  insertion.addArg("strm", "Serializer&");
3629  insertion.addArg("uni", "const " + cxx + "&");
3630  insertion.endArgs();
3631 
3632  be_global->impl_ <<
3633  " const Encoding& encoding = strm.encoding();\n"
3634  " ACE_UNUSED_ARG(encoding);\n";
3636  " serialized_size(encoding, total_size, uni);\n"
3637  " if (!strm.write_delimiter(total_size)) {\n"
3638  " return false;\n"
3639  " }\n", not_final);
3640 
3641  // EMHEADER for discriminator
3642  if (exten == extensibilitykind_mutable) {
3643  be_global->impl_ <<
3644  " size_t size = 0;\n";
3645 
3646  if (disc_cls & CL_ENUM) {
3647  be_global->impl_ <<
3648  " primitive_serialized_size_ulong(encoding, size);\n";
3649  } else {
3650  be_global->impl_ <<
3651  " primitive_serialized_size(encoding, size, " << wrap_out << ");\n";
3652  }
3653 
3654  be_global->impl_ <<
3655  " if (!strm.write_parameter_id(0, size)) {\n"
3656  " return false;\n"
3657  " }\n"
3658  " size = 0;\n";
3659  }
3660 
3661  be_global->impl_ <<
3662  streamAndCheck("<< " + wrap_out);
3663  if (generateSwitchForUnion(node, "uni._d()", streamCommon, branches,
3664  discriminator, "return", "<< ", cxx.c_str(),
3665  false, true, true,
3666  exten == extensibilitykind_mutable ? findSizeCommon : 0)) {
3667  be_global->impl_ <<
3668  " return true;\n";
3669  }
3670  }
3671  {
3672  Function extraction("operator>>", "bool");
3673  extraction.addArg("strm", "Serializer&");
3674  extraction.addArg("uni", cxx + "&");
3675  extraction.endArgs();
3676 
3677  be_global->impl_ <<
3678  " const Encoding& encoding = strm.encoding();\n"
3679  " ACE_UNUSED_ARG(encoding);\n";
3681  " if (!strm.read_delimiter(total_size)) {\n"
3682  " return false;\n"
3683  " }\n", not_final);
3684 
3685  if (exten == extensibilitykind_mutable) {
3686  // EMHEADER for discriminator
3687  be_global->impl_ <<
3688  " unsigned member_id;\n"
3689  " size_t field_size;\n"
3690  " bool must_understand = false;\n"
3691  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3692  " return false;\n"
3693  " }\n";
3694  TryConstructFailAction try_construct = be_global->union_discriminator_try_construct(node);
3695  be_global->impl_ <<
3696  " " << scoped(discriminator->name()) << " disc;\n"
3697  " if (!(strm >> disc)) {\n";
3698  if (try_construct == tryconstructfailaction_use_default) {
3699  be_global->impl_ <<
3700  " set_default(uni);\n"
3701  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3702  " return false;\n"
3703  " }\n"
3704  " strm.skip(field_size);\n"
3705  " strm.set_construction_status(Serializer::ConstructionSuccessful);\n"
3706  " return true;\n";
3707  } else {
3708  be_global->impl_ <<
3709  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3710  " return false;\n"
3711  " }\n"
3712  " strm.skip(field_size);\n"
3713  " strm.set_construction_status(Serializer::ElementConstructionFailure);\n"
3714  " return false;\n";
3715  }
3716  be_global->impl_ << " }\n";
3717 
3718  be_global->impl_ <<
3719  " member_id = 0;\n"
3720  " field_size = 0;\n"
3721  " must_understand = false;\n";
3722 
3723  const char prefix[] =
3724  " if (!strm.read_parameter_id(member_id, field_size, must_understand)) {\n"
3725  " return false;\n"
3726  " }\n";
3727  if (generateSwitchForUnion(node, "disc", streamCommon, branches,
3728  discriminator, prefix, ">> ", cxx.c_str())) {
3729  be_global->impl_ <<
3730  " return true;\n";
3731  }
3732  } else {
3733  be_global->impl_ <<
3734  " " << scoped(discriminator->name()) << " disc;\n" <<
3735  streamAndCheck(">> " + getWrapper("disc", discriminator, WD_INPUT));
3736  if (generateSwitchForUnion(node, "disc", streamCommon, branches,
3737  discriminator, "", ">> ", cxx.c_str())) {
3738  be_global->impl_ <<
3739  " return true;\n";
3740  }
3741  }
3742  }
3743 
3744  gen_union_key_serializers(node, FieldFilter_NestedKeyOnly);
3745  gen_union_key_serializers(node, FieldFilter_KeyOnly);
3746 
3747  TopicKeys keys(node);
3748  return generate_marshal_traits(node, cxx, exten, keys);
3749 }
Classification classify(AST_Type *type)
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
void set_default(Type &)
Definition: Serializer.h:944
TryConstructFailAction
Definition: annotations.h:316
ExtensibilityKind
Definition: annotations.h:278
void serialized_size(const Encoding &encoding, size_t &size, const SequenceNumber &)
#define OPENDDS_HAS_EXPLICIT_INTS
Definition: Definitions.h:83
void gen_union_default(AST_UnionBranch *branch, const std::string &varname)
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)
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
AST_Type * resolveActualType(AST_Type *element)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
ACE_UINT32 ULong
const char *const name
Definition: debug.cpp:60
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
std::set< EleLen > EleLenSet
Definition: field_info.h:31
BE_GlobalData * be_global
Definition: be_global.cpp:44
const Classification CL_ENUM

◆ gen_union_default()

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

Definition at line 3751 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.

3752 {
3753  AST_Type* br = resolveActualType(branch->field_type());
3754  const Classification br_cls = classify(br);
3755  const std::string tmpname = "tmp";
3756 
3757  if (br_cls & (CL_SEQUENCE | CL_ARRAY | CL_STRUCTURE | CL_UNION)) {
3758  be_global->impl_ << " " << scoped(branch->field_type()->name()) << " "
3759  << getWrapper(tmpname, branch->field_type(), WD_INPUT) << ";\n";
3760  }
3761 
3762  if (br_cls & (CL_STRUCTURE | CL_UNION)) {
3763  be_global->impl_ << type_to_default(" ", branch->field_type(), tmpname);
3764  be_global->impl_ << " " << varname << "." << branch->local_name()->get_string() << "(tmp);\n";
3765  } else {
3766  be_global->impl_ << type_to_default(" ", branch->field_type(),
3767  varname + "." + branch->local_name()->get_string(),
3768  false, true);
3769  }
3770 }
Classification classify(AST_Type *type)
string type_to_default(const std::string &indent, AST_Type *type, const string &name, bool is_anonymous, bool is_union)
const Classification CL_ARRAY
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
AST_Type * resolveActualType(AST_Type *element)
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
const Classification CL_STRUCTURE
BE_GlobalData * be_global
Definition: be_global.cpp:44
const Classification CL_SEQUENCE
const Classification CL_UNION

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

References be_global.

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

2809 {
2810  //DHeader appears on aggregated types that are mutable or appendable in XCDR2
2811  //DHeader also appears on ALL sequences and arrays of non-primitives
2812  if (dheader_required) {
2813  if (is_ser_func) {
2814  be_global->impl_ << " size_t total_size = 0;\n";
2815  }
2816  be_global->impl_ << " if (encoding.xcdr_version() == Encoding::XCDR_VERSION_2) {\n"
2817  << code <<
2818  " }\n";
2819  }
2820 }
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:44

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