// This C++ source file was generated by the TTCN-3 compiler
// of the TTCN-3 Test Executor version CRL 113 200/6 R6A
// for Lénárd Nagy (elnrnag@elx78355y6x) on Thu Oct 24 10:29:40 2019

// Copyright (c) 2000-2019 Ericsson Telecom AB

// Do not edit this file unless you know what you are doing.

/* Including header files */

#include "Bcm.hh"

namespace Bcm {

/* Prototypes of static functions */

static void pre_init_module();
static void post_init_module();

/* Literal string constants */

static const unsigned char module_checksum[] = { 0x42, 0xd3, 0x31, 0x8a, 0x5d, 0xa7, 0x3a, 0x27, 0x33, 0xab, 0xa8, 0x67, 0x69, 0x35, 0x6f, 0x9e };

/* Global variable definitions */

static INTEGER const_CAN__FRAME__MAX__NUMBER;
const INTEGER& CAN__FRAME__MAX__NUMBER = const_CAN__FRAME__MAX__NUMBER;
// No XER for BcmFlagsBitIndex__enum
const TTCN_Typedescriptor_t BcmFlagsBitIndex__enum_descr_ = { "@Bcm.BcmFlagsBitIndex_enum", NULL, NULL, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for BcmFlags__enum
const TTCN_Typedescriptor_t BcmFlags__enum_descr_ = { "@Bcm.BcmFlags_enum", NULL, NULL, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for BcmOpcode__enum
const TTCN_Typedescriptor_t BcmOpcode__enum_descr_ = { "@Bcm.BcmOpcode_enum", NULL, NULL, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       Bcm__long_xer_ = { {"Bcm_long>\n", "Bcm_long>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t Bcm__long_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t Bcm__long_descr_ = { "@Bcm.Bcm_long", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &Bcm__long_xer_, &INTEGER_json_, &Bcm__long_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       Bcm__timeval_tv__sec_xer_ = { {"tv_sec>\n", "tv_sec>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t Bcm__timeval_tv__sec_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t Bcm__timeval_tv__sec_descr_ = { "@Bcm.Bcm_timeval.tv_sec", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &Bcm__timeval_tv__sec_xer_, &INTEGER_json_, &Bcm__timeval_tv__sec_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       Bcm__timeval_tv__usec_xer_ = { {"tv_usec>\n", "tv_usec>\n"}, {9, 9}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t Bcm__timeval_tv__usec_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t Bcm__timeval_tv__usec_descr_ = { "@Bcm.Bcm_timeval.tv_usec", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &Bcm__timeval_tv__usec_xer_, &INTEGER_json_, &Bcm__timeval_tv__usec_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for Bcm__timeval
const TTCN_Typedescriptor_t Bcm__timeval_descr_ = { "@Bcm.Bcm_timeval", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bcm__frame_opcode_xer_ = { {"opcode>\n", "opcode>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__bcm__frame_opcode_oer_ext_arr_[0] = {};
const int SocketCAN__bcm__frame_opcode_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__bcm__frame_opcode_oer_ = { -1, TRUE, 4, FALSE, 0, 0, SocketCAN__bcm__frame_opcode_oer_ext_arr_, 0, SocketCAN__bcm__frame_opcode_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_opcode_descr_ = { "@Bcm.SocketCAN_bcm_frame.opcode", &OCTETSTRING_ber_, &General__Types::OCT4_raw_, &OCTETSTRING_text_, &SocketCAN__bcm__frame_opcode_xer_, &OCTETSTRING_json_, &SocketCAN__bcm__frame_opcode_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t SocketCAN__bcm__frame_flags_raw_ = {32,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       SocketCAN__bcm__frame_flags_xer_ = { {"flags>\n", "flags>\n"}, {7, 7}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__bcm__frame_flags_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_flags_descr_ = { "@Bcm.SocketCAN_bcm_frame.flags", &BITSTRING_ber_, &SocketCAN__bcm__frame_flags_raw_, NULL, &SocketCAN__bcm__frame_flags_xer_, &BITSTRING_json_, &SocketCAN__bcm__frame_flags_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bcm__frame_count_xer_ = { {"count>\n", "count>\n"}, {7, 7}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__bcm__frame_count_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_count_descr_ = { "@Bcm.SocketCAN_bcm_frame.count", &INTEGER_ber_, &General__Types::LIN4__BO__LAST_raw_, &INTEGER_text_, &SocketCAN__bcm__frame_count_xer_, &INTEGER_json_, &SocketCAN__bcm__frame_count_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bcm__frame_can__id_xer_ = { {"can_id>\n", "can_id>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__bcm__frame_can__id_oer_ext_arr_[0] = {};
const int SocketCAN__bcm__frame_can__id_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__bcm__frame_can__id_oer_ = { -1, TRUE, 4, FALSE, 0, 0, SocketCAN__bcm__frame_can__id_oer_ext_arr_, 0, SocketCAN__bcm__frame_can__id_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_can__id_descr_ = { "@Bcm.SocketCAN_bcm_frame.can_id", &OCTETSTRING_ber_, &Can::CAN__id_raw_, &OCTETSTRING_text_, &SocketCAN__bcm__frame_can__id_xer_, &OCTETSTRING_json_, &SocketCAN__bcm__frame_can__id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bcm__frame_frames
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_frames_descr_ = { "@Bcm.SocketCAN_bcm_frame.frames", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bcm__frame_frames_can__frame
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_frames_can__frame_descr_ = { "@Bcm.SocketCAN_bcm_frame.frames.can_frame", NULL, NULL, NULL, NULL, NULL, NULL, &Can::CAN__frame_descr_, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bcm__frame_frames_canfd__frame
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_frames_canfd__frame_descr_ = { "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame", NULL, NULL, NULL, NULL, NULL, NULL, &Can::CANFD__frame_descr_, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bcm__frame
const TTCN_Typedescriptor_t SocketCAN__bcm__frame_descr_ = { "@Bcm.SocketCAN_bcm_frame", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
TTCN_Module module_object("Bcm", __DATE__, __TIME__, module_checksum, pre_init_module, NULL, 0U, 4294967295U, 4294967295U, 4294967295U, NULL, 0LU, 0, post_init_module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

static const RuntimeVersionChecker ver_checker(  current_runtime_version.requires_major_version_6,
  current_runtime_version.requires_minor_version_6,
  current_runtime_version.requires_patch_level_0,  current_runtime_version.requires_runtime_1);

/* Member functions of C++ classes */

BcmFlagsBitIndex__enum::BcmFlagsBitIndex__enum()
{
enum_value = UNBOUND_VALUE;
}

BcmFlagsBitIndex__enum::BcmFlagsBitIndex__enum(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Initializing a variable of enumerated type @Bcm.BcmFlagsBitIndex_enum with invalid numeric value %d.", other_value);
enum_value = (enum_type)other_value;
}

BcmFlagsBitIndex__enum::BcmFlagsBitIndex__enum(enum_type other_value)
{
enum_value = other_value;
}

BcmFlagsBitIndex__enum::BcmFlagsBitIndex__enum(const BcmFlagsBitIndex__enum& other_value)
: Base_Type()
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Copying an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
enum_value = other_value.enum_value;
}

BcmFlagsBitIndex__enum& BcmFlagsBitIndex__enum::operator=(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Assigning unknown numeric value %d to a variable of enumerated type @Bcm.BcmFlagsBitIndex_enum.", other_value);
enum_value = (enum_type)other_value;
return *this;
}

BcmFlagsBitIndex__enum& BcmFlagsBitIndex__enum::operator=(enum_type other_value)
{
enum_value = other_value;
return *this;
}

BcmFlagsBitIndex__enum& BcmFlagsBitIndex__enum::operator=(const BcmFlagsBitIndex__enum& other_value)
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
enum_value = other_value.enum_value;
return *this;
}

boolean BcmFlagsBitIndex__enum::operator==(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value == other_value;
}

boolean BcmFlagsBitIndex__enum::operator==(const BcmFlagsBitIndex__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value == other_value.enum_value;
}

boolean BcmFlagsBitIndex__enum::operator<(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value < other_value;
}

boolean BcmFlagsBitIndex__enum::operator<(const BcmFlagsBitIndex__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value < other_value.enum_value;
}

boolean BcmFlagsBitIndex__enum::operator>(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value > other_value;
}

boolean BcmFlagsBitIndex__enum::operator>(const BcmFlagsBitIndex__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value > other_value.enum_value;
}

const char *BcmFlagsBitIndex__enum::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case e__CAN__BCM__SETTIMER__BITINDEX: return "e_CAN_BCM_SETTIMER_BITINDEX";
case e__CAN__BCM__STARTTIMER__BITINDEX: return "e_CAN_BCM_STARTTIMER_BITINDEX";
case e__CAN__BCM__TX__COUNTEVT__BITINDEX: return "e_CAN_BCM_TX_COUNTEVT_BITINDEX";
case e__CAN__BCM__TX__ANNOUNCE__BITINDEX: return "e_CAN_BCM_TX_ANNOUNCE_BITINDEX";
case e__CAN__BCM__TX__CP__CAN__ID__BITINDEX: return "e_CAN_BCM_TX_CP_CAN_ID_BITINDEX";
case e__CAN__BCM__RX__FILTER__ID__BITINDEX: return "e_CAN_BCM_RX_FILTER_ID_BITINDEX";
case e__CAN__BCM__RX__CHECK__DLC__BITINDEX: return "e_CAN_BCM_RX_CHECK_DLC_BITINDEX";
case e__CAN__BCM__RX__NO__AUTOTIMER__BITINDEX: return "e_CAN_BCM_RX_NO_AUTOTIMER_BITINDEX";
case e__CAN__BCM__RX__ANNOUNCE__RESUME__BITINDEX: return "e_CAN_BCM_RX_ANNOUNCE_RESUME_BITINDEX";
case e__CAN__BCM__TX__RESET__MULTI__IDX__BITINDEX: return "e_CAN_BCM_TX_RESET_MULTI_IDX_BITINDEX";
case e__CAN__BCM__RX__RTR__FRAME__BITINDEX: return "e_CAN_BCM_RX_RTR_FRAME_BITINDEX";
default: return "<unknown>";
}
}

BcmFlagsBitIndex__enum::enum_type BcmFlagsBitIndex__enum::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "e_CAN_BCM_SETTIMER_BITINDEX")) return e__CAN__BCM__SETTIMER__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_STARTTIMER_BITINDEX")) return e__CAN__BCM__STARTTIMER__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_TX_COUNTEVT_BITINDEX")) return e__CAN__BCM__TX__COUNTEVT__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_TX_ANNOUNCE_BITINDEX")) return e__CAN__BCM__TX__ANNOUNCE__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_TX_CP_CAN_ID_BITINDEX")) return e__CAN__BCM__TX__CP__CAN__ID__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_FILTER_ID_BITINDEX")) return e__CAN__BCM__RX__FILTER__ID__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_CHECK_DLC_BITINDEX")) return e__CAN__BCM__RX__CHECK__DLC__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_NO_AUTOTIMER_BITINDEX")) return e__CAN__BCM__RX__NO__AUTOTIMER__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_ANNOUNCE_RESUME_BITINDEX")) return e__CAN__BCM__RX__ANNOUNCE__RESUME__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_TX_RESET_MULTI_IDX_BITINDEX")) return e__CAN__BCM__TX__RESET__MULTI__IDX__BITINDEX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_RTR_FRAME_BITINDEX")) return e__CAN__BCM__RX__RTR__FRAME__BITINDEX;
else return UNKNOWN_VALUE;
}

boolean BcmFlagsBitIndex__enum::is_valid_enum(int int_par)
{
switch (int_par) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
return TRUE;
default:
return FALSE;
}
}

int BcmFlagsBitIndex__enum::enum2int(enum_type enum_par)
{
if (enum_par==UNBOUND_VALUE || enum_par==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmFlagsBitIndex_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int BcmFlagsBitIndex__enum::enum2int(const BcmFlagsBitIndex__enum& enum_par)
{
if (enum_par.enum_value==UNBOUND_VALUE || enum_par.enum_value==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmFlagsBitIndex_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

void BcmFlagsBitIndex__enum::int2enum(int int_val)
{
if (!is_valid_enum(int_val)) TTCN_error("Assigning invalid numeric value %d to a variable of enumerated type @Bcm.BcmFlagsBitIndex_enum.", int_val);
enum_value = (enum_type)int_val;
}

BcmFlagsBitIndex__enum::operator BcmFlagsBitIndex__enum::enum_type() const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Using the value of an unbound variable of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return enum_value;
}

void BcmFlagsBitIndex__enum::log() const
{
if (enum_value != UNBOUND_VALUE) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);
else TTCN_Logger::log_event_unbound();
}

void BcmFlagsBitIndex__enum::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "enumerated value");
  if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error("enumerated value", "@Bcm.BcmFlagsBitIndex_enum");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @Bcm.BcmFlagsBitIndex_enum.");
  }
}

void BcmFlagsBitIndex__enum::encode_text(Text_Buf& text_buf) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Text encoder: Encoding an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
text_buf.push_int(enum_value);
}

void BcmFlagsBitIndex__enum::decode_text(Text_Buf& text_buf)
{
enum_value = (enum_type)text_buf.pull_int().get_val();
if (!is_valid_enum(enum_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for enumerated type @Bcm.BcmFlagsBitIndex_enum.", enum_value);
}

void BcmFlagsBitIndex__enum_template::copy_template(const BcmFlagsBitIndex__enum_template& other_value)
{
set_selection(other_value);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = other_value.single_value;
break;
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new BcmFlagsBitIndex__enum_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
}
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template()
{
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(int other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (!BcmFlagsBitIndex__enum::is_valid_enum(other_value)) TTCN_error("Initializing a template of enumerated type @Bcm.BcmFlagsBitIndex_enum with unknown numeric value %d.", other_value);
single_value = (BcmFlagsBitIndex__enum::enum_type)other_value;
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(BcmFlagsBitIndex__enum::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(const BcmFlagsBitIndex__enum& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == BcmFlagsBitIndex__enum::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
single_value = other_value.enum_value;
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(const OPTIONAL<BcmFlagsBitIndex__enum>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlagsBitIndex__enum::enum_type)(const BcmFlagsBitIndex__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of enumerated type @Bcm.BcmFlagsBitIndex_enum from an unbound optional field.");
}
}

BcmFlagsBitIndex__enum_template::BcmFlagsBitIndex__enum_template(const BcmFlagsBitIndex__enum_template& other_value)
 : Base_Template()
{
copy_template(other_value);
}

BcmFlagsBitIndex__enum_template::~BcmFlagsBitIndex__enum_template()
{
clean_up();
}

boolean BcmFlagsBitIndex__enum_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
return TRUE;
}

boolean BcmFlagsBitIndex__enum_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value != BcmFlagsBitIndex__enum::UNBOUND_VALUE;
}

void BcmFlagsBitIndex__enum_template::clean_up()
{
if (template_selection == VALUE_LIST || template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
template_selection = UNINITIALIZED_TEMPLATE;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(int other_value)
{
if (!BcmFlagsBitIndex__enum::is_valid_enum(other_value)) TTCN_warning("Assigning unknown numeric value %d to a template of enumerated type @Bcm.BcmFlagsBitIndex_enum.", other_value);
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlagsBitIndex__enum::enum_type)other_value;
return *this;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(BcmFlagsBitIndex__enum::enum_type other_value)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value;
return *this;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(const BcmFlagsBitIndex__enum& other_value)
{
if (other_value.enum_value == BcmFlagsBitIndex__enum::UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmFlagsBitIndex_enum to a template.");
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value.enum_value;
return *this;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(const OPTIONAL<BcmFlagsBitIndex__enum>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlagsBitIndex__enum::enum_type)(const BcmFlagsBitIndex__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
}
return *this;
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::operator=(const BcmFlagsBitIndex__enum_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean BcmFlagsBitIndex__enum_template::match(BcmFlagsBitIndex__enum::enum_type other_value, boolean) const
{
switch (template_selection) {
case SPECIFIC_VALUE:
return single_value == other_value;
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
}
return FALSE;
}

boolean BcmFlagsBitIndex__enum_template::match(const BcmFlagsBitIndex__enum& other_value, boolean) const
{
if (other_value.enum_value == BcmFlagsBitIndex__enum::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @Bcm.BcmFlagsBitIndex_enum with an unbound value.");
return match(other_value.enum_value);
}

BcmFlagsBitIndex__enum::enum_type BcmFlagsBitIndex__enum_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return single_value;
}

void BcmFlagsBitIndex__enum_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error("Setting an invalid list type for a template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new BcmFlagsBitIndex__enum_template[list_length];
}

BcmFlagsBitIndex__enum_template& BcmFlagsBitIndex__enum_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list element in a non-list template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
return value_list.list_value[list_index];
}

void BcmFlagsBitIndex__enum_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(BcmFlagsBitIndex__enum::enum_to_str(single_value), single_value);
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[elem_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void BcmFlagsBitIndex__enum_template::log_match(const BcmFlagsBitIndex__enum& match_value, boolean) const
{
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}

void BcmFlagsBitIndex__enum_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
}
}

void BcmFlagsBitIndex__enum_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (BcmFlagsBitIndex__enum::enum_type)text_buf.pull_int().get_val();
if (!BcmFlagsBitIndex__enum::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @Bcm.BcmFlagsBitIndex_enum.", single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new BcmFlagsBitIndex__enum_template[value_list.n_values];
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of enumerated type @Bcm.BcmFlagsBitIndex_enum.");
}
}

boolean BcmFlagsBitIndex__enum_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean BcmFlagsBitIndex__enum_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void BcmFlagsBitIndex__enum_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "enumerated template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    BcmFlagsBitIndex__enum_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Enumerated: {
    BcmFlagsBitIndex__enum::enum_type enum_val = BcmFlagsBitIndex__enum::str_to_enum(m_p->get_enumerated());
    if (!BcmFlagsBitIndex__enum::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @Bcm.BcmFlagsBitIndex_enum.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@Bcm.BcmFlagsBitIndex_enum");
  }
  is_ifpresent = param.get_ifpresent();
}

void BcmFlagsBitIndex__enum_template::check_restriction(template_res t_res, const char* t_name,
boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_VALUE:
if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
break;
case TR_OMIT:
if (!is_ifpresent && (template_selection==OMIT_VALUE || template_selection==SPECIFIC_VALUE)) return;
break;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.BcmFlagsBitIndex_enum");
}

BcmFlags__enum::BcmFlags__enum()
{
enum_value = UNBOUND_VALUE;
}

BcmFlags__enum::BcmFlags__enum(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Initializing a variable of enumerated type @Bcm.BcmFlags_enum with invalid numeric value %d.", other_value);
enum_value = (enum_type)other_value;
}

BcmFlags__enum::BcmFlags__enum(enum_type other_value)
{
enum_value = other_value;
}

BcmFlags__enum::BcmFlags__enum(const BcmFlags__enum& other_value)
: Base_Type()
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Copying an unbound value of enumerated type @Bcm.BcmFlags_enum.");
enum_value = other_value.enum_value;
}

BcmFlags__enum& BcmFlags__enum::operator=(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Assigning unknown numeric value %d to a variable of enumerated type @Bcm.BcmFlags_enum.", other_value);
enum_value = (enum_type)other_value;
return *this;
}

BcmFlags__enum& BcmFlags__enum::operator=(enum_type other_value)
{
enum_value = other_value;
return *this;
}

BcmFlags__enum& BcmFlags__enum::operator=(const BcmFlags__enum& other_value)
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmFlags_enum.");
enum_value = other_value.enum_value;
return *this;
}

boolean BcmFlags__enum::operator==(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value == other_value;
}

boolean BcmFlags__enum::operator==(const BcmFlags__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value == other_value.enum_value;
}

boolean BcmFlags__enum::operator<(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value < other_value;
}

boolean BcmFlags__enum::operator<(const BcmFlags__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value < other_value.enum_value;
}

boolean BcmFlags__enum::operator>(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value > other_value;
}

boolean BcmFlags__enum::operator>(const BcmFlags__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmFlags_enum.");
return enum_value > other_value.enum_value;
}

const char *BcmFlags__enum::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case e__CAN__BCM__SETTIMER: return "e_CAN_BCM_SETTIMER";
case e__CAN__BCM__STARTTIMER: return "e_CAN_BCM_STARTTIMER";
case e__CAN__BCM__TX__COUNTEVT: return "e_CAN_BCM_TX_COUNTEVT";
case e__CAN__BCM__TX__ANNOUNCE: return "e_CAN_BCM_TX_ANNOUNCE";
case e__CAN__BCM__TX__CP__CAN__ID: return "e_CAN_BCM_TX_CP_CAN_ID";
case e__CAN__BCM__RX__FILTER__ID: return "e_CAN_BCM_RX_FILTER_ID";
case e__CAN__BCM__RX__CHECK__DLC: return "e_CAN_BCM_RX_CHECK_DLC";
case e__CAN__BCM__RX__NO__AUTOTIMER: return "e_CAN_BCM_RX_NO_AUTOTIMER";
case e__CAN__BCM__RX__ANNOUNCE__RESUME: return "e_CAN_BCM_RX_ANNOUNCE_RESUME";
case e__CAN__BCM__TX__RESET__MULTI__IDX: return "e_CAN_BCM_TX_RESET_MULTI_IDX";
case e__CAN__BCM__RX__RTR__FRAME: return "e_CAN_BCM_RX_RTR_FRAME";
default: return "<unknown>";
}
}

BcmFlags__enum::enum_type BcmFlags__enum::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "e_CAN_BCM_SETTIMER")) return e__CAN__BCM__SETTIMER;
else if (!strcmp(str_par, "e_CAN_BCM_STARTTIMER")) return e__CAN__BCM__STARTTIMER;
else if (!strcmp(str_par, "e_CAN_BCM_TX_COUNTEVT")) return e__CAN__BCM__TX__COUNTEVT;
else if (!strcmp(str_par, "e_CAN_BCM_TX_ANNOUNCE")) return e__CAN__BCM__TX__ANNOUNCE;
else if (!strcmp(str_par, "e_CAN_BCM_TX_CP_CAN_ID")) return e__CAN__BCM__TX__CP__CAN__ID;
else if (!strcmp(str_par, "e_CAN_BCM_RX_FILTER_ID")) return e__CAN__BCM__RX__FILTER__ID;
else if (!strcmp(str_par, "e_CAN_BCM_RX_CHECK_DLC")) return e__CAN__BCM__RX__CHECK__DLC;
else if (!strcmp(str_par, "e_CAN_BCM_RX_NO_AUTOTIMER")) return e__CAN__BCM__RX__NO__AUTOTIMER;
else if (!strcmp(str_par, "e_CAN_BCM_RX_ANNOUNCE_RESUME")) return e__CAN__BCM__RX__ANNOUNCE__RESUME;
else if (!strcmp(str_par, "e_CAN_BCM_TX_RESET_MULTI_IDX")) return e__CAN__BCM__TX__RESET__MULTI__IDX;
else if (!strcmp(str_par, "e_CAN_BCM_RX_RTR_FRAME")) return e__CAN__BCM__RX__RTR__FRAME;
else return UNKNOWN_VALUE;
}

boolean BcmFlags__enum::is_valid_enum(int int_par)
{
switch (int_par) {
case 1:
case 2:
case 4:
case 8:
case 16:
case 32:
case 64:
case 128:
case 256:
case 512:
case 1024:
return TRUE;
default:
return FALSE;
}
}

int BcmFlags__enum::enum2int(enum_type enum_par)
{
if (enum_par==UNBOUND_VALUE || enum_par==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmFlags_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int BcmFlags__enum::enum2int(const BcmFlags__enum& enum_par)
{
if (enum_par.enum_value==UNBOUND_VALUE || enum_par.enum_value==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmFlags_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

void BcmFlags__enum::int2enum(int int_val)
{
if (!is_valid_enum(int_val)) TTCN_error("Assigning invalid numeric value %d to a variable of enumerated type @Bcm.BcmFlags_enum.", int_val);
enum_value = (enum_type)int_val;
}

BcmFlags__enum::operator BcmFlags__enum::enum_type() const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Using the value of an unbound variable of enumerated type @Bcm.BcmFlags_enum.");
return enum_value;
}

void BcmFlags__enum::log() const
{
if (enum_value != UNBOUND_VALUE) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);
else TTCN_Logger::log_event_unbound();
}

void BcmFlags__enum::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "enumerated value");
  if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error("enumerated value", "@Bcm.BcmFlags_enum");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @Bcm.BcmFlags_enum.");
  }
}

void BcmFlags__enum::encode_text(Text_Buf& text_buf) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Text encoder: Encoding an unbound value of enumerated type @Bcm.BcmFlags_enum.");
text_buf.push_int(enum_value);
}

void BcmFlags__enum::decode_text(Text_Buf& text_buf)
{
enum_value = (enum_type)text_buf.pull_int().get_val();
if (!is_valid_enum(enum_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for enumerated type @Bcm.BcmFlags_enum.", enum_value);
}

void BcmFlags__enum_template::copy_template(const BcmFlags__enum_template& other_value)
{
set_selection(other_value);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = other_value.single_value;
break;
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new BcmFlags__enum_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of enumerated type @Bcm.BcmFlags_enum.");
}
}

BcmFlags__enum_template::BcmFlags__enum_template()
{
}

BcmFlags__enum_template::BcmFlags__enum_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

BcmFlags__enum_template::BcmFlags__enum_template(int other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (!BcmFlags__enum::is_valid_enum(other_value)) TTCN_error("Initializing a template of enumerated type @Bcm.BcmFlags_enum with unknown numeric value %d.", other_value);
single_value = (BcmFlags__enum::enum_type)other_value;
}

BcmFlags__enum_template::BcmFlags__enum_template(BcmFlags__enum::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

BcmFlags__enum_template::BcmFlags__enum_template(const BcmFlags__enum& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == BcmFlags__enum::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @Bcm.BcmFlags_enum.");
single_value = other_value.enum_value;
}

BcmFlags__enum_template::BcmFlags__enum_template(const OPTIONAL<BcmFlags__enum>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlags__enum::enum_type)(const BcmFlags__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of enumerated type @Bcm.BcmFlags_enum from an unbound optional field.");
}
}

BcmFlags__enum_template::BcmFlags__enum_template(const BcmFlags__enum_template& other_value)
 : Base_Template()
{
copy_template(other_value);
}

BcmFlags__enum_template::~BcmFlags__enum_template()
{
clean_up();
}

boolean BcmFlags__enum_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
return TRUE;
}

boolean BcmFlags__enum_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value != BcmFlags__enum::UNBOUND_VALUE;
}

void BcmFlags__enum_template::clean_up()
{
if (template_selection == VALUE_LIST || template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
template_selection = UNINITIALIZED_TEMPLATE;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(int other_value)
{
if (!BcmFlags__enum::is_valid_enum(other_value)) TTCN_warning("Assigning unknown numeric value %d to a template of enumerated type @Bcm.BcmFlags_enum.", other_value);
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlags__enum::enum_type)other_value;
return *this;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(BcmFlags__enum::enum_type other_value)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value;
return *this;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(const BcmFlags__enum& other_value)
{
if (other_value.enum_value == BcmFlags__enum::UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmFlags_enum to a template.");
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value.enum_value;
return *this;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(const OPTIONAL<BcmFlags__enum>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmFlags__enum::enum_type)(const BcmFlags__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of enumerated type @Bcm.BcmFlags_enum.");
}
return *this;
}

BcmFlags__enum_template& BcmFlags__enum_template::operator=(const BcmFlags__enum_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean BcmFlags__enum_template::match(BcmFlags__enum::enum_type other_value, boolean) const
{
switch (template_selection) {
case SPECIFIC_VALUE:
return single_value == other_value;
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of enumerated type @Bcm.BcmFlags_enum.");
}
return FALSE;
}

boolean BcmFlags__enum_template::match(const BcmFlags__enum& other_value, boolean) const
{
if (other_value.enum_value == BcmFlags__enum::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @Bcm.BcmFlags_enum with an unbound value.");
return match(other_value.enum_value);
}

BcmFlags__enum::enum_type BcmFlags__enum_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of enumerated type @Bcm.BcmFlags_enum.");
return single_value;
}

void BcmFlags__enum_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error("Setting an invalid list type for a template of enumerated type @Bcm.BcmFlags_enum.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new BcmFlags__enum_template[list_length];
}

BcmFlags__enum_template& BcmFlags__enum_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list element in a non-list template of enumerated type @Bcm.BcmFlags_enum.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @Bcm.BcmFlags_enum.");
return value_list.list_value[list_index];
}

void BcmFlags__enum_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(BcmFlags__enum::enum_to_str(single_value), single_value);
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[elem_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void BcmFlags__enum_template::log_match(const BcmFlags__enum& match_value, boolean) const
{
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}

void BcmFlags__enum_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of enumerated type @Bcm.BcmFlags_enum.");
}
}

void BcmFlags__enum_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (BcmFlags__enum::enum_type)text_buf.pull_int().get_val();
if (!BcmFlags__enum::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @Bcm.BcmFlags_enum.", single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new BcmFlags__enum_template[value_list.n_values];
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of enumerated type @Bcm.BcmFlags_enum.");
}
}

boolean BcmFlags__enum_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean BcmFlags__enum_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void BcmFlags__enum_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "enumerated template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    BcmFlags__enum_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Enumerated: {
    BcmFlags__enum::enum_type enum_val = BcmFlags__enum::str_to_enum(m_p->get_enumerated());
    if (!BcmFlags__enum::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @Bcm.BcmFlags_enum.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@Bcm.BcmFlags_enum");
  }
  is_ifpresent = param.get_ifpresent();
}

void BcmFlags__enum_template::check_restriction(template_res t_res, const char* t_name,
boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_VALUE:
if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
break;
case TR_OMIT:
if (!is_ifpresent && (template_selection==OMIT_VALUE || template_selection==SPECIFIC_VALUE)) return;
break;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.BcmFlags_enum");
}

BcmOpcode__enum::BcmOpcode__enum()
{
enum_value = UNBOUND_VALUE;
}

BcmOpcode__enum::BcmOpcode__enum(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Initializing a variable of enumerated type @Bcm.BcmOpcode_enum with invalid numeric value %d.", other_value);
enum_value = (enum_type)other_value;
}

BcmOpcode__enum::BcmOpcode__enum(enum_type other_value)
{
enum_value = other_value;
}

BcmOpcode__enum::BcmOpcode__enum(const BcmOpcode__enum& other_value)
: Base_Type()
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Copying an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
enum_value = other_value.enum_value;
}

BcmOpcode__enum& BcmOpcode__enum::operator=(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Assigning unknown numeric value %d to a variable of enumerated type @Bcm.BcmOpcode_enum.", other_value);
enum_value = (enum_type)other_value;
return *this;
}

BcmOpcode__enum& BcmOpcode__enum::operator=(enum_type other_value)
{
enum_value = other_value;
return *this;
}

BcmOpcode__enum& BcmOpcode__enum::operator=(const BcmOpcode__enum& other_value)
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
enum_value = other_value.enum_value;
return *this;
}

boolean BcmOpcode__enum::operator==(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value == other_value;
}

boolean BcmOpcode__enum::operator==(const BcmOpcode__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value == other_value.enum_value;
}

boolean BcmOpcode__enum::operator<(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value < other_value;
}

boolean BcmOpcode__enum::operator<(const BcmOpcode__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value < other_value.enum_value;
}

boolean BcmOpcode__enum::operator>(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value > other_value;
}

boolean BcmOpcode__enum::operator>(const BcmOpcode__enum& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value > other_value.enum_value;
}

const char *BcmOpcode__enum::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case e__CAN__BCM__TX__SETUP: return "e_CAN_BCM_TX_SETUP";
case e__CAN__BCM__TX__DELETE: return "e_CAN_BCM_TX_DELETE";
case e__CAN__BCM__TX__READ: return "e_CAN_BCM_TX_READ";
case e__CAN__BCM__TX__SEND: return "e_CAN_BCM_TX_SEND";
case e__CAN__BCM__RX__SETUP: return "e_CAN_BCM_RX_SETUP";
case e__CAN__BCM__RX__DELETE: return "e_CAN_BCM_RX_DELETE";
case e__CAN__BCM__RX__READ: return "e_CAN_BCM_RX_READ";
case e__CAN__BCM__TX__STATUS: return "e_CAN_BCM_TX_STATUS";
case e__CAN__BCM__TX__EXPIRED: return "e_CAN_BCM_TX_EXPIRED";
case e__CAN__BCM__RX__STATUS: return "e_CAN_BCM_RX_STATUS";
case e__CAN__BCM__RX__TIMEOUT: return "e_CAN_BCM_RX_TIMEOUT";
case e__CAN__BCM__RX__CHANGED: return "e_CAN_BCM_RX_CHANGED";
default: return "<unknown>";
}
}

BcmOpcode__enum::enum_type BcmOpcode__enum::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "e_CAN_BCM_TX_SETUP")) return e__CAN__BCM__TX__SETUP;
else if (!strcmp(str_par, "e_CAN_BCM_TX_DELETE")) return e__CAN__BCM__TX__DELETE;
else if (!strcmp(str_par, "e_CAN_BCM_TX_READ")) return e__CAN__BCM__TX__READ;
else if (!strcmp(str_par, "e_CAN_BCM_TX_SEND")) return e__CAN__BCM__TX__SEND;
else if (!strcmp(str_par, "e_CAN_BCM_RX_SETUP")) return e__CAN__BCM__RX__SETUP;
else if (!strcmp(str_par, "e_CAN_BCM_RX_DELETE")) return e__CAN__BCM__RX__DELETE;
else if (!strcmp(str_par, "e_CAN_BCM_RX_READ")) return e__CAN__BCM__RX__READ;
else if (!strcmp(str_par, "e_CAN_BCM_TX_STATUS")) return e__CAN__BCM__TX__STATUS;
else if (!strcmp(str_par, "e_CAN_BCM_TX_EXPIRED")) return e__CAN__BCM__TX__EXPIRED;
else if (!strcmp(str_par, "e_CAN_BCM_RX_STATUS")) return e__CAN__BCM__RX__STATUS;
else if (!strcmp(str_par, "e_CAN_BCM_RX_TIMEOUT")) return e__CAN__BCM__RX__TIMEOUT;
else if (!strcmp(str_par, "e_CAN_BCM_RX_CHANGED")) return e__CAN__BCM__RX__CHANGED;
else return UNKNOWN_VALUE;
}

boolean BcmOpcode__enum::is_valid_enum(int int_par)
{
switch (int_par) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
return TRUE;
default:
return FALSE;
}
}

int BcmOpcode__enum::enum2int(enum_type enum_par)
{
if (enum_par==UNBOUND_VALUE || enum_par==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmOpcode_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int BcmOpcode__enum::enum2int(const BcmOpcode__enum& enum_par)
{
if (enum_par.enum_value==UNBOUND_VALUE || enum_par.enum_value==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @Bcm.BcmOpcode_enum.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

void BcmOpcode__enum::int2enum(int int_val)
{
if (!is_valid_enum(int_val)) TTCN_error("Assigning invalid numeric value %d to a variable of enumerated type @Bcm.BcmOpcode_enum.", int_val);
enum_value = (enum_type)int_val;
}

BcmOpcode__enum::operator BcmOpcode__enum::enum_type() const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Using the value of an unbound variable of enumerated type @Bcm.BcmOpcode_enum.");
return enum_value;
}

void BcmOpcode__enum::log() const
{
if (enum_value != UNBOUND_VALUE) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);
else TTCN_Logger::log_event_unbound();
}

void BcmOpcode__enum::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "enumerated value");
  if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error("enumerated value", "@Bcm.BcmOpcode_enum");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @Bcm.BcmOpcode_enum.");
  }
}

void BcmOpcode__enum::encode_text(Text_Buf& text_buf) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Text encoder: Encoding an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
text_buf.push_int(enum_value);
}

void BcmOpcode__enum::decode_text(Text_Buf& text_buf)
{
enum_value = (enum_type)text_buf.pull_int().get_val();
if (!is_valid_enum(enum_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for enumerated type @Bcm.BcmOpcode_enum.", enum_value);
}

void BcmOpcode__enum_template::copy_template(const BcmOpcode__enum_template& other_value)
{
set_selection(other_value);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = other_value.single_value;
break;
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new BcmOpcode__enum_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of enumerated type @Bcm.BcmOpcode_enum.");
}
}

BcmOpcode__enum_template::BcmOpcode__enum_template()
{
}

BcmOpcode__enum_template::BcmOpcode__enum_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

BcmOpcode__enum_template::BcmOpcode__enum_template(int other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (!BcmOpcode__enum::is_valid_enum(other_value)) TTCN_error("Initializing a template of enumerated type @Bcm.BcmOpcode_enum with unknown numeric value %d.", other_value);
single_value = (BcmOpcode__enum::enum_type)other_value;
}

BcmOpcode__enum_template::BcmOpcode__enum_template(BcmOpcode__enum::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

BcmOpcode__enum_template::BcmOpcode__enum_template(const BcmOpcode__enum& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == BcmOpcode__enum::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @Bcm.BcmOpcode_enum.");
single_value = other_value.enum_value;
}

BcmOpcode__enum_template::BcmOpcode__enum_template(const OPTIONAL<BcmOpcode__enum>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmOpcode__enum::enum_type)(const BcmOpcode__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of enumerated type @Bcm.BcmOpcode_enum from an unbound optional field.");
}
}

BcmOpcode__enum_template::BcmOpcode__enum_template(const BcmOpcode__enum_template& other_value)
 : Base_Template()
{
copy_template(other_value);
}

BcmOpcode__enum_template::~BcmOpcode__enum_template()
{
clean_up();
}

boolean BcmOpcode__enum_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
return TRUE;
}

boolean BcmOpcode__enum_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value != BcmOpcode__enum::UNBOUND_VALUE;
}

void BcmOpcode__enum_template::clean_up()
{
if (template_selection == VALUE_LIST || template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
template_selection = UNINITIALIZED_TEMPLATE;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(int other_value)
{
if (!BcmOpcode__enum::is_valid_enum(other_value)) TTCN_warning("Assigning unknown numeric value %d to a template of enumerated type @Bcm.BcmOpcode_enum.", other_value);
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = (BcmOpcode__enum::enum_type)other_value;
return *this;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(BcmOpcode__enum::enum_type other_value)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value;
return *this;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(const BcmOpcode__enum& other_value)
{
if (other_value.enum_value == BcmOpcode__enum::UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @Bcm.BcmOpcode_enum to a template.");
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value.enum_value;
return *this;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(const OPTIONAL<BcmOpcode__enum>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (BcmOpcode__enum::enum_type)(const BcmOpcode__enum&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of enumerated type @Bcm.BcmOpcode_enum.");
}
return *this;
}

BcmOpcode__enum_template& BcmOpcode__enum_template::operator=(const BcmOpcode__enum_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean BcmOpcode__enum_template::match(BcmOpcode__enum::enum_type other_value, boolean) const
{
switch (template_selection) {
case SPECIFIC_VALUE:
return single_value == other_value;
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of enumerated type @Bcm.BcmOpcode_enum.");
}
return FALSE;
}

boolean BcmOpcode__enum_template::match(const BcmOpcode__enum& other_value, boolean) const
{
if (other_value.enum_value == BcmOpcode__enum::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @Bcm.BcmOpcode_enum with an unbound value.");
return match(other_value.enum_value);
}

BcmOpcode__enum::enum_type BcmOpcode__enum_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of enumerated type @Bcm.BcmOpcode_enum.");
return single_value;
}

void BcmOpcode__enum_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error("Setting an invalid list type for a template of enumerated type @Bcm.BcmOpcode_enum.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new BcmOpcode__enum_template[list_length];
}

BcmOpcode__enum_template& BcmOpcode__enum_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list element in a non-list template of enumerated type @Bcm.BcmOpcode_enum.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @Bcm.BcmOpcode_enum.");
return value_list.list_value[list_index];
}

void BcmOpcode__enum_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(BcmOpcode__enum::enum_to_str(single_value), single_value);
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[elem_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void BcmOpcode__enum_template::log_match(const BcmOpcode__enum& match_value, boolean) const
{
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}

void BcmOpcode__enum_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of enumerated type @Bcm.BcmOpcode_enum.");
}
}

void BcmOpcode__enum_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (BcmOpcode__enum::enum_type)text_buf.pull_int().get_val();
if (!BcmOpcode__enum::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @Bcm.BcmOpcode_enum.", single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new BcmOpcode__enum_template[value_list.n_values];
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of enumerated type @Bcm.BcmOpcode_enum.");
}
}

boolean BcmOpcode__enum_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean BcmOpcode__enum_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void BcmOpcode__enum_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "enumerated template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    BcmOpcode__enum_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Enumerated: {
    BcmOpcode__enum::enum_type enum_val = BcmOpcode__enum::str_to_enum(m_p->get_enumerated());
    if (!BcmOpcode__enum::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @Bcm.BcmOpcode_enum.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@Bcm.BcmOpcode_enum");
  }
  is_ifpresent = param.get_ifpresent();
}

void BcmOpcode__enum_template::check_restriction(template_res t_res, const char* t_name,
boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_VALUE:
if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
break;
case TR_OMIT:
if (!is_ifpresent && (template_selection==OMIT_VALUE || template_selection==SPECIFIC_VALUE)) return;
break;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.BcmOpcode_enum");
}

Bcm__timeval::Bcm__timeval()
{
}

Bcm__timeval::Bcm__timeval(const INTEGER& par_tv__sec,
    const INTEGER& par_tv__usec)
  :   field_tv__sec(par_tv__sec),
  field_tv__usec(par_tv__usec)
{
}

Bcm__timeval::Bcm__timeval(const Bcm__timeval& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Bcm.Bcm_timeval.");
if (other_value.tv__sec().is_bound()) field_tv__sec = other_value.tv__sec();
else field_tv__sec.clean_up();
if (other_value.tv__usec().is_bound()) field_tv__usec = other_value.tv__usec();
else field_tv__usec.clean_up();
}

void Bcm__timeval::clean_up()
{
field_tv__sec.clean_up();
field_tv__usec.clean_up();
}

const TTCN_Typedescriptor_t* Bcm__timeval::get_descriptor() const { return &Bcm__timeval_descr_; }
Bcm__timeval& Bcm__timeval::operator=(const Bcm__timeval& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Bcm.Bcm_timeval.");
  if (other_value.tv__sec().is_bound()) field_tv__sec = other_value.tv__sec();
  else field_tv__sec.clean_up();
  if (other_value.tv__usec().is_bound()) field_tv__usec = other_value.tv__usec();
  else field_tv__usec.clean_up();
}
return *this;
}

boolean Bcm__timeval::operator==(const Bcm__timeval& other_value) const
{
return field_tv__sec==other_value.field_tv__sec
  && field_tv__usec==other_value.field_tv__usec;
}

boolean Bcm__timeval::is_bound() const
{
return (field_tv__sec.is_bound())
  || (field_tv__usec.is_bound());
}
boolean Bcm__timeval::is_value() const
{
return field_tv__sec.is_value()
  && field_tv__usec.is_value();
}
void Bcm__timeval::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ tv_sec := ");
field_tv__sec.log();
TTCN_Logger::log_event_str(", tv_usec := ");
field_tv__usec.log();
TTCN_Logger::log_event_str(" }");
}

void Bcm__timeval::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record value of type @Bcm.Bcm_timeval has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) tv__sec().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) tv__usec().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "tv_sec")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tv__sec().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "tv_usec")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tv__usec().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @Bcm.Bcm_timeval: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Bcm.Bcm_timeval");
  }
}

void Bcm__timeval::set_implicit_omit()
{
if (tv__sec().is_bound()) tv__sec().set_implicit_omit();
if (tv__usec().is_bound()) tv__usec().set_implicit_omit();
}

void Bcm__timeval::encode_text(Text_Buf& text_buf) const
{
field_tv__sec.encode_text(text_buf);
field_tv__usec.encode_text(text_buf);
}

void Bcm__timeval::decode_text(Text_Buf& text_buf)
{
field_tv__sec.decode_text(text_buf);
field_tv__usec.decode_text(text_buf);
}

struct Bcm__timeval_template::single_value_struct {
INTEGER_template field_tv__sec;
INTEGER_template field_tv__usec;
};

void Bcm__timeval_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_tv__sec = ANY_VALUE;
single_value->field_tv__usec = ANY_VALUE;
}
}
}

void Bcm__timeval_template::copy_value(const Bcm__timeval& other_value)
{
single_value = new single_value_struct;
if (other_value.tv__sec().is_bound()) {
  single_value->field_tv__sec = other_value.tv__sec();
} else {
  single_value->field_tv__sec.clean_up();
}
if (other_value.tv__usec().is_bound()) {
  single_value->field_tv__usec = other_value.tv__usec();
} else {
  single_value->field_tv__usec.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void Bcm__timeval_template::copy_template(const Bcm__timeval_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.tv__sec().get_selection()) {
single_value->field_tv__sec = other_value.tv__sec();
} else {
single_value->field_tv__sec.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.tv__usec().get_selection()) {
single_value->field_tv__usec = other_value.tv__usec();
} else {
single_value->field_tv__usec.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new Bcm__timeval_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @Bcm.Bcm_timeval.");
break;
}
set_selection(other_value);
}

Bcm__timeval_template::Bcm__timeval_template()
{
}

Bcm__timeval_template::Bcm__timeval_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

Bcm__timeval_template::Bcm__timeval_template(const Bcm__timeval& other_value)
{
copy_value(other_value);
}

Bcm__timeval_template::Bcm__timeval_template(const OPTIONAL<Bcm__timeval>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const Bcm__timeval&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @Bcm.Bcm_timeval from an unbound optional field.");
}
}

Bcm__timeval_template::Bcm__timeval_template(const Bcm__timeval_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

Bcm__timeval_template::~Bcm__timeval_template()
{
clean_up();
}

Bcm__timeval_template& Bcm__timeval_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

Bcm__timeval_template& Bcm__timeval_template::operator=(const Bcm__timeval& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

Bcm__timeval_template& Bcm__timeval_template::operator=(const OPTIONAL<Bcm__timeval>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const Bcm__timeval&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @Bcm.Bcm_timeval.");
}
return *this;
}

Bcm__timeval_template& Bcm__timeval_template::operator=(const Bcm__timeval_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean Bcm__timeval_template::match(const Bcm__timeval& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.tv__sec().is_bound()) return FALSE;
if(!single_value->field_tv__sec.match(other_value.tv__sec(), legacy))return FALSE;
if(!other_value.tv__usec().is_bound()) return FALSE;
if(!single_value->field_tv__usec.match(other_value.tv__usec(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @Bcm.Bcm_timeval.");
}
return FALSE;
}

boolean Bcm__timeval_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_tv__sec.is_bound()

 ||single_value->field_tv__usec.is_bound()
;
}

boolean Bcm__timeval_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_tv__sec.is_value()
 &&single_value->field_tv__usec.is_value();
}

void Bcm__timeval_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

Bcm__timeval Bcm__timeval_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @Bcm.Bcm_timeval.");
Bcm__timeval ret_val;
if (single_value->field_tv__sec.is_bound()) {
ret_val.tv__sec() = single_value->field_tv__sec.valueof();
}
if (single_value->field_tv__usec.is_bound()) {
ret_val.tv__usec() = single_value->field_tv__usec.valueof();
}
return ret_val;
}

void Bcm__timeval_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @Bcm.Bcm_timeval.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new Bcm__timeval_template[list_length];
}

Bcm__timeval_template& Bcm__timeval_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @Bcm.Bcm_timeval.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @Bcm.Bcm_timeval.");
return value_list.list_value[list_index];
}

INTEGER_template& Bcm__timeval_template::tv__sec()
{
set_specific();
return single_value->field_tv__sec;
}

const INTEGER_template& Bcm__timeval_template::tv__sec() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field tv_sec of a non-specific template of type @Bcm.Bcm_timeval.");
return single_value->field_tv__sec;
}

INTEGER_template& Bcm__timeval_template::tv__usec()
{
set_specific();
return single_value->field_tv__usec;
}

const INTEGER_template& Bcm__timeval_template::tv__usec() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field tv_usec of a non-specific template of type @Bcm.Bcm_timeval.");
return single_value->field_tv__usec;
}

int Bcm__timeval_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @Bcm.Bcm_timeval which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 2;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @Bcm.Bcm_timeval containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @Bcm.Bcm_timeval containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.Bcm_timeval containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.Bcm_timeval containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.Bcm_timeval containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @Bcm.Bcm_timeval.");
  }
  return 0;
}

void Bcm__timeval_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ tv_sec := ");
single_value->field_tv__sec.log();
TTCN_Logger::log_event_str(", tv_usec := ");
single_value->field_tv__usec.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void Bcm__timeval_template::log_match(const Bcm__timeval& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_tv__sec.match(match_value.tv__sec(), legacy)){
TTCN_Logger::log_logmatch_info(".tv_sec");
single_value->field_tv__sec.log_match(match_value.tv__sec(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_tv__usec.match(match_value.tv__usec(), legacy)){
TTCN_Logger::log_logmatch_info(".tv_usec");
single_value->field_tv__usec.log_match(match_value.tv__usec(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ tv_sec := ");
single_value->field_tv__sec.log_match(match_value.tv__sec(), legacy);
TTCN_Logger::log_event_str(", tv_usec := ");
single_value->field_tv__usec.log_match(match_value.tv__usec(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void Bcm__timeval_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_tv__sec.encode_text(text_buf);
single_value->field_tv__usec.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @Bcm.Bcm_timeval.");
}
}

void Bcm__timeval_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_tv__sec.decode_text(text_buf);
single_value->field_tv__usec.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new Bcm__timeval_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @Bcm.Bcm_timeval.");
}
}

void Bcm__timeval_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    Bcm__timeval_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record template of type @Bcm.Bcm_timeval has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) tv__sec().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) tv__usec().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "tv_sec")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tv__sec().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "tv_usec")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tv__usec().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @Bcm.Bcm_timeval: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Bcm.Bcm_timeval");
  }
  is_ifpresent = param.get_ifpresent();
}

void Bcm__timeval_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_tv__sec.check_restriction(t_res, t_name ? t_name : "@Bcm.Bcm_timeval");
single_value->field_tv__usec.check_restriction(t_res, t_name ? t_name : "@Bcm.Bcm_timeval");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.Bcm_timeval");
}

boolean Bcm__timeval_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean Bcm__timeval_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void SocketCAN__bcm__frame_frames::copy_value(const SocketCAN__bcm__frame_frames& other_value)
{
switch (other_value.union_selection) {
case ALT_can__frame:
field_can__frame = new SocketCAN__bcm__frame_frames_can__frame(*other_value.field_can__frame);
break;
case ALT_canfd__frame:
field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame(*other_value.field_canfd__frame);
break;
default:
TTCN_error("Assignment of an unbound union value of type @Bcm.SocketCAN_bcm_frame.frames.");
}
union_selection = other_value.union_selection;
}

SocketCAN__bcm__frame_frames::SocketCAN__bcm__frame_frames()
{
union_selection = UNBOUND_VALUE;
}

SocketCAN__bcm__frame_frames::SocketCAN__bcm__frame_frames(const SocketCAN__bcm__frame_frames& other_value)
: Base_Type(){
copy_value(other_value);
}

SocketCAN__bcm__frame_frames::~SocketCAN__bcm__frame_frames()
{
clean_up();
}

SocketCAN__bcm__frame_frames& SocketCAN__bcm__frame_frames::operator=(const SocketCAN__bcm__frame_frames& other_value)
{
if (this != &other_value) {
clean_up();
copy_value(other_value);
}
return *this;
}

boolean SocketCAN__bcm__frame_frames::operator==(const SocketCAN__bcm__frame_frames& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @Bcm.SocketCAN_bcm_frame.frames.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @Bcm.SocketCAN_bcm_frame.frames.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_can__frame:
return *field_can__frame == *other_value.field_can__frame;
case ALT_canfd__frame:
return *field_canfd__frame == *other_value.field_canfd__frame;
default:
return FALSE;
}
}

SocketCAN__bcm__frame_frames_can__frame& SocketCAN__bcm__frame_frames::can__frame()
{
if (union_selection != ALT_can__frame) {
clean_up();
field_can__frame = new SocketCAN__bcm__frame_frames_can__frame;
union_selection = ALT_can__frame;
}
return *field_can__frame;
}

const SocketCAN__bcm__frame_frames_can__frame& SocketCAN__bcm__frame_frames::can__frame() const
{
if (union_selection != ALT_can__frame) TTCN_error("Using non-selected field can_frame in a value of union type @Bcm.SocketCAN_bcm_frame.frames.");
return *field_can__frame;
}

SocketCAN__bcm__frame_frames_canfd__frame& SocketCAN__bcm__frame_frames::canfd__frame()
{
if (union_selection != ALT_canfd__frame) {
clean_up();
field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame;
union_selection = ALT_canfd__frame;
}
return *field_canfd__frame;
}

const SocketCAN__bcm__frame_frames_canfd__frame& SocketCAN__bcm__frame_frames::canfd__frame() const
{
if (union_selection != ALT_canfd__frame) TTCN_error("Using non-selected field canfd_frame in a value of union type @Bcm.SocketCAN_bcm_frame.frames.");
return *field_canfd__frame;
}

boolean SocketCAN__bcm__frame_frames::ischosen(union_selection_type checked_selection) const
{
if (checked_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @Bcm.SocketCAN_bcm_frame.frames.");
return union_selection == checked_selection;
}

boolean SocketCAN__bcm__frame_frames::is_bound() const
{
  return union_selection != UNBOUND_VALUE;
}

boolean SocketCAN__bcm__frame_frames::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_can__frame: return field_can__frame->is_value();
case ALT_canfd__frame: return field_canfd__frame->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__bcm__frame_frames::clean_up()
{
switch (union_selection) {
case ALT_can__frame:
  delete field_can__frame;
  break;
case ALT_canfd__frame:
  delete field_canfd__frame;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__bcm__frame_frames::log() const
{
switch (union_selection) {
case ALT_can__frame:
TTCN_Logger::log_event_str("{ can_frame := ");
field_can__frame->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_canfd__frame:
TTCN_Logger::log_event_str("{ canfd_frame := ");
field_canfd__frame->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__bcm__frame_frames::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "union value");
  Module_Param_Ptr m_p = &param;
  if (m_p->get_type()==Module_Param::MP_Value_List && m_p->get_size()==0) return;
  if (m_p->get_type()!=Module_Param::MP_Assignment_List) {
    param.error("union value with field name was expected");
  }
  Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
  char* last_name = mp_last->get_id()->get_name();
  if (!strcmp(last_name, "can_frame")) {
    can__frame().set_param(*mp_last);
    if (!can__frame().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "canfd_frame")) {
    canfd__frame().set_param(*mp_last);
    if (!canfd__frame().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @Bcm.SocketCAN_bcm_frame.frames.", last_name);
}

void SocketCAN__bcm__frame_frames::set_implicit_omit()
{
switch (union_selection) {
case ALT_can__frame:
field_can__frame->set_implicit_omit(); break;
case ALT_canfd__frame:
field_canfd__frame->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__bcm__frame_frames::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_can__frame:
field_can__frame->encode_text(text_buf);
break;
case ALT_canfd__frame:
field_canfd__frame->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
}

void SocketCAN__bcm__frame_frames::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_can__frame:
can__frame().decode_text(text_buf);
break;
case ALT_canfd__frame:
canfd__frame().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @Bcm.SocketCAN_bcm_frame.frames.");
}
}

void SocketCAN__bcm__frame_frames_template::copy_value(const SocketCAN__bcm__frame_frames& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
single_value.field_can__frame = new SocketCAN__bcm__frame_frames_can__frame_template(other_value.can__frame());
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
single_value.field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame_template(other_value.canfd__frame());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bcm__frame_frames_template::copy_template(const SocketCAN__bcm__frame_frames_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value.union_selection = other_value.single_value.union_selection;
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
single_value.field_can__frame = new SocketCAN__bcm__frame_frames_can__frame_template(*other_value.single_value.field_can__frame);
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
single_value.field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame_template(*other_value.single_value.field_canfd__frame);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @Bcm.SocketCAN_bcm_frame.frames.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new SocketCAN__bcm__frame_frames_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
set_selection(other_value);
}

SocketCAN__bcm__frame_frames_template::SocketCAN__bcm__frame_frames_template()
{
}

SocketCAN__bcm__frame_frames_template::SocketCAN__bcm__frame_frames_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

SocketCAN__bcm__frame_frames_template::SocketCAN__bcm__frame_frames_template(const SocketCAN__bcm__frame_frames& other_value)
{
copy_value(other_value);
}

SocketCAN__bcm__frame_frames_template::SocketCAN__bcm__frame_frames_template(const OPTIONAL<SocketCAN__bcm__frame_frames>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of union type @Bcm.SocketCAN_bcm_frame.frames from an unbound optional field.");
}
}

SocketCAN__bcm__frame_frames_template::SocketCAN__bcm__frame_frames_template(const SocketCAN__bcm__frame_frames_template& other_value)
: Base_Template(){
copy_template(other_value);
}

SocketCAN__bcm__frame_frames_template::~SocketCAN__bcm__frame_frames_template()
{
clean_up();
}

void SocketCAN__bcm__frame_frames_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
delete single_value.field_can__frame;
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
delete single_value.field_canfd__frame;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_frames_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_frames_template::operator=(const SocketCAN__bcm__frame_frames& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_frames_template::operator=(const OPTIONAL<SocketCAN__bcm__frame_frames>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
return *this;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_frames_template::operator=(const SocketCAN__bcm__frame_frames_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean SocketCAN__bcm__frame_frames_template::match(const SocketCAN__bcm__frame_frames& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
{
SocketCAN__bcm__frame_frames::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__bcm__frame_frames::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
return single_value.field_can__frame->match(other_value.can__frame(), legacy);
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
return single_value.field_canfd__frame->match(other_value.canfd__frame(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
}
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error ("Matching an uninitialized template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
return FALSE;
}

boolean SocketCAN__bcm__frame_frames_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
return single_value.field_can__frame->is_value();
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
return single_value.field_canfd__frame->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
}

SocketCAN__bcm__frame_frames SocketCAN__bcm__frame_frames_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of union type @Bcm.SocketCAN_bcm_frame.frames.");
SocketCAN__bcm__frame_frames ret_val;
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
ret_val.can__frame() = single_value.field_can__frame->valueof();
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
ret_val.canfd__frame() = single_value.field_canfd__frame->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
return ret_val;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_frames_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Internal error: Accessing a list element of a non-list template of union type @Bcm.SocketCAN_bcm_frame.frames.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @Bcm.SocketCAN_bcm_frame.frames.");
return value_list.list_value[list_index];
}
void SocketCAN__bcm__frame_frames_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error ("Internal error: Setting an invalid list for a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bcm__frame_frames_template[list_length];
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_template::can__frame()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__bcm__frame_frames::ALT_can__frame) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_can__frame = new SocketCAN__bcm__frame_frames_can__frame_template(ANY_VALUE);
else single_value.field_can__frame = new SocketCAN__bcm__frame_frames_can__frame_template;
single_value.union_selection = SocketCAN__bcm__frame_frames::ALT_can__frame;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_can__frame;
}

const SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_template::can__frame() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field can_frame in a non-specific template of union type @Bcm.SocketCAN_bcm_frame.frames.");
if (single_value.union_selection != SocketCAN__bcm__frame_frames::ALT_can__frame) TTCN_error("Accessing non-selected field can_frame in a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
return *single_value.field_can__frame;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_template::canfd__frame()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__bcm__frame_frames::ALT_canfd__frame) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame_template(ANY_VALUE);
else single_value.field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame_template;
single_value.union_selection = SocketCAN__bcm__frame_frames::ALT_canfd__frame;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_canfd__frame;
}

const SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_template::canfd__frame() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field canfd_frame in a non-specific template of union type @Bcm.SocketCAN_bcm_frame.frames.");
if (single_value.union_selection != SocketCAN__bcm__frame_frames::ALT_canfd__frame) TTCN_error("Accessing non-selected field canfd_frame in a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
return *single_value.field_canfd__frame;
}

boolean SocketCAN__bcm__frame_frames_template::ischosen(SocketCAN__bcm__frame_frames::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__bcm__frame_frames::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @Bcm.SocketCAN_bcm_frame.frames.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__bcm__frame_frames::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
return single_value.union_selection == checked_selection;
case VALUE_LIST:
{
if (value_list.n_values < 1)
TTCN_error("Internal error: Performing ischosen() operation on a template of union type @Bcm.SocketCAN_bcm_frame.frames containing an empty list.");
boolean ret_val = value_list.list_value[0].ischosen(checked_selection);
for (unsigned int list_count = 1; ret_val == TRUE && list_count < value_list.n_values; list_count++) {
ret_val = value_list.list_value[list_count].ischosen(checked_selection);
}
return ret_val;
}
default:
return FALSE;
}
return FALSE;
}

void SocketCAN__bcm__frame_frames_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
TTCN_Logger::log_event_str("{ can_frame := ");
single_value.field_can__frame->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
TTCN_Logger::log_event_str("{ canfd_frame := ");
single_value.field_canfd__frame->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_str("<invalid selector>");
}
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void SocketCAN__bcm__frame_frames_template::log_match(const SocketCAN__bcm__frame_frames& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() && match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
return;
}
if (template_selection == SPECIFIC_VALUE && single_value.union_selection == match_value.get_selection()) {
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".can_frame");
single_value.field_can__frame->log_match(match_value.can__frame(), legacy);
} else {
TTCN_Logger::log_event_str("{ can_frame := ");
single_value.field_can__frame->log_match(match_value.can__frame(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".canfd_frame");
single_value.field_canfd__frame->log_match(match_value.canfd__frame(), legacy);
} else {
TTCN_Logger::log_event_str("{ canfd_frame := ");
single_value.field_canfd__frame->log_match(match_value.canfd__frame(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
default:
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str("<invalid selector>");
}
} else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void SocketCAN__bcm__frame_frames_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value.union_selection);
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
single_value.field_can__frame->encode_text(text_buf);
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
single_value.field_canfd__frame->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized template of type @Bcm.SocketCAN_bcm_frame.frames.");
}
}

void SocketCAN__bcm__frame_frames_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
{
single_value.union_selection = SocketCAN__bcm__frame_frames::UNBOUND_VALUE;
SocketCAN__bcm__frame_frames::union_selection_type new_selection = (SocketCAN__bcm__frame_frames::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
single_value.field_can__frame = new SocketCAN__bcm__frame_frames_can__frame_template;
single_value.field_can__frame->decode_text(text_buf);
break;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
single_value.field_canfd__frame = new SocketCAN__bcm__frame_frames_canfd__frame_template;
single_value.field_canfd__frame->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @Bcm.SocketCAN_bcm_frame.frames.");
}
single_value.union_selection = new_selection;
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new SocketCAN__bcm__frame_frames_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized selector was received in a template of type @Bcm.SocketCAN_bcm_frame.frames.");
}
}

boolean SocketCAN__bcm__frame_frames_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean SocketCAN__bcm__frame_frames_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)
if (value_list.list_value[v_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void SocketCAN__bcm__frame_frames_template::set_param(Module_Param& param)
{
  if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
      param.get_id()->next_name()) {
    char* param_field = param.get_id()->get_current_name();
    if (param_field[0] >= '0' && param_field[0] <= '9') {
      param.error("Unexpected array index in module parameter, expected a valid field"
        " name for union template type `@Bcm.SocketCAN_bcm_frame.frames'");
    }
    if (strcmp("can_frame", param_field) == 0) {
      can__frame().set_param(param);
      return;
    } else if (strcmp("canfd_frame", param_field) == 0) {
      canfd__frame().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@Bcm.SocketCAN_bcm_frame.frames'", param_field);
  }
  param.basic_check(Module_Param::BC_TEMPLATE, "union template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    SocketCAN__bcm__frame_frames_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (m_p->get_size()==0) break;
    param.type_error("union template", "@Bcm.SocketCAN_bcm_frame.frames");
    break;
  case Module_Param::MP_Assignment_List: {
    Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
    char* last_name = mp_last->get_id()->get_name();
    if (!strcmp(last_name, "can_frame")) {
      can__frame().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "canfd_frame")) {
      canfd__frame().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @Bcm.SocketCAN_bcm_frame.frames.", last_name);
  } break;
  default:
    param.type_error("union template", "@Bcm.SocketCAN_bcm_frame.frames");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bcm__frame_frames_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
switch (single_value.union_selection) {
case SocketCAN__bcm__frame_frames::ALT_can__frame:
single_value.field_can__frame->check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames");
return;
case SocketCAN__bcm__frame_frames::ALT_canfd__frame:
single_value.field_canfd__frame->check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @Bcm.SocketCAN_bcm_frame.frames.");
}
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames");
}


const Can::CAN__frame SocketCAN__bcm__frame_frames_can__frame::UNBOUND_ELEM;
SocketCAN__bcm__frame_frames_can__frame::SocketCAN__bcm__frame_frames_can__frame()
{
val_ptr = NULL;
}

SocketCAN__bcm__frame_frames_can__frame::SocketCAN__bcm__frame_frames_can__frame(null_type)
{
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
}

SocketCAN__bcm__frame_frames_can__frame::SocketCAN__bcm__frame_frames_can__frame(const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
if (!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}

SocketCAN__bcm__frame_frames_can__frame::~SocketCAN__bcm__frame_frames_can__frame()
{
clean_up();
if (val_ptr != NULL) val_ptr = NULL;
}

void SocketCAN__bcm__frame_frames_can__frame::clean_up()
{
if (val_ptr != NULL) {
if (val_ptr->ref_count > 1) {
val_ptr->ref_count--;
val_ptr = NULL;
}
else if (val_ptr->ref_count == 1) {
for (int elem_count = 0; elem_count < val_ptr->n_elements;
elem_count++)
if (val_ptr->value_elements[elem_count] != NULL)
delete val_ptr->value_elements[elem_count];
free_pointers((void**)val_ptr->value_elements);
delete val_ptr;
val_ptr = NULL;
}
else
TTCN_error("Internal error: Invalid reference counter in a record of/set of value.");
}
}

SocketCAN__bcm__frame_frames_can__frame& SocketCAN__bcm__frame_frames_can__frame::operator=(null_type)
{
clean_up();
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
return *this;
}

SocketCAN__bcm__frame_frames_can__frame& SocketCAN__bcm__frame_frames_can__frame::operator=(const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
if (other_value.val_ptr == NULL) TTCN_error("Assigning an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (this != &other_value) {
clean_up();
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}
return *this;
}

boolean SocketCAN__bcm__frame_frames_can__frame::operator==(null_type) const
{
if (val_ptr == NULL)
TTCN_error("The left operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return val_ptr->n_elements == 0 ;
}

boolean SocketCAN__bcm__frame_frames_can__frame::operator==(const SocketCAN__bcm__frame_frames_can__frame& other_value) const
{
if (val_ptr == NULL) TTCN_error("The left operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (other_value.val_ptr == NULL) TTCN_error("The right operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (val_ptr == other_value.val_ptr) return TRUE;
if (val_ptr->n_elements != (other_value.val_ptr)->n_elements)
return FALSE;
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++){
if (val_ptr->value_elements[elem_count] != NULL){
if ((other_value.val_ptr)->value_elements[elem_count] != NULL){
  if (*val_ptr->value_elements[elem_count] != *(other_value.val_ptr)->value_elements[elem_count]) return FALSE;
} else return FALSE;
} else {
if ((other_value.val_ptr)->value_elements[elem_count] != NULL) return FALSE;
}
}
return TRUE;
}

Can::CAN__frame& SocketCAN__bcm__frame_frames_can__frame::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of type @Bcm.SocketCAN_bcm_frame.frames.can_frame using a negative index: %d.", index_value);
if (val_ptr == NULL) {
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
} else if (val_ptr->ref_count > 1) {
struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
new_val_ptr->ref_count = 1;
new_val_ptr->n_elements = (index_value >= val_ptr->n_elements) ? index_value + 1 : val_ptr->n_elements;
new_val_ptr->value_elements = (Can::CAN__frame**)allocate_pointers(new_val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++){
if (val_ptr->value_elements[elem_count] != NULL){
new_val_ptr->value_elements[elem_count] = new Can::CAN__frame(*(val_ptr->value_elements[elem_count]));
}
}
clean_up();
val_ptr = new_val_ptr;
}
if (index_value >= val_ptr->n_elements) set_size(index_value + 1);
if (val_ptr->value_elements[index_value] == NULL) {
val_ptr->value_elements[index_value] = new Can::CAN__frame;
}
return *val_ptr->value_elements[index_value];
}

Can::CAN__frame& SocketCAN__bcm__frame_frames_can__frame::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return (*this)[(int)index_value];
}

const Can::CAN__frame& SocketCAN__bcm__frame_frames_can__frame::operator[](int index_value) const
{
if (val_ptr == NULL)
TTCN_error("Accessing an element in an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (index_value < 0) TTCN_error("Accessing an element of type @Bcm.SocketCAN_bcm_frame.frames.can_frame using a negative index: %d.", index_value);
if (index_value >= val_ptr->n_elements) TTCN_error("Index overflow in a value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame: The index is %d, but the value has only %d elements.", index_value, val_ptr->n_elements);
return (val_ptr->value_elements[index_value] == NULL) ?
UNBOUND_ELEM : *val_ptr->value_elements[index_value];
}

const Can::CAN__frame& SocketCAN__bcm__frame_frames_can__frame::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return (*this)[(int)index_value];
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::operator<<=(int rotate_count) const
{
return *this >>= (-rotate_count);
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::operator<<=(const INTEGER& rotate_count) const
{
rotate_count.must_bound("Unbound integer operand of rotate left operator.");
return *this >>= (int)(-rotate_count);
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::operator>>=(const INTEGER& rotate_count) const
{
rotate_count.must_bound("Unbound integer operand of rotate right operator.");
return *this >>= (int)rotate_count;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::operator>>=(int rotate_count) const
{
if (val_ptr == NULL) TTCN_error("Performing rotation operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (val_ptr->n_elements == 0) return *this;
int rc;
if (rotate_count>=0) rc = rotate_count % val_ptr->n_elements;
else rc = val_ptr->n_elements - ((-rotate_count) % val_ptr->n_elements);
if (rc == 0) return *this;
SocketCAN__bcm__frame_frames_can__frame ret_val;
ret_val.set_size(val_ptr->n_elements);
for (int i=0; i<val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[(i+rc)%val_ptr->n_elements] =new Can::CAN__frame(*val_ptr->value_elements[i]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::operator+(const SocketCAN__bcm__frame_frames_can__frame& other_value) const
{
if (val_ptr == NULL || other_value.val_ptr == NULL) TTCN_error("Unbound operand of @Bcm.SocketCAN_bcm_frame.frames.can_frame concatenation.");
if (val_ptr->n_elements == 0) return other_value;
if (other_value.val_ptr->n_elements == 0) return *this;
SocketCAN__bcm__frame_frames_can__frame ret_val;
ret_val.set_size(val_ptr->n_elements+other_value.val_ptr->n_elements);
for (int i=0; i<val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CAN__frame(*val_ptr->value_elements[i]);
}
}
for (int i=0; i<other_value.val_ptr->n_elements; i++) {
if (other_value.val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i+val_ptr->n_elements] = new Can::CAN__frame(*other_value.val_ptr->value_elements[i]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::substr(int index, int returncount) const
{
if (val_ptr == NULL) TTCN_error("The first argument of substr() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
check_substr_arguments(val_ptr->n_elements, index, returncount, "@Bcm.SocketCAN_bcm_frame.frames.can_frame","element");
SocketCAN__bcm__frame_frames_can__frame ret_val;
ret_val.set_size(returncount);
for (int i=0; i<returncount; i++) {
if (val_ptr->value_elements[i+index] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CAN__frame(*val_ptr->value_elements[i+index]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::replace(int index, int len, const SocketCAN__bcm__frame_frames_can__frame& repl) const
{
if (val_ptr == NULL) TTCN_error("The first argument of replace() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (repl.val_ptr == NULL) TTCN_error("The fourth argument of replace() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
check_replace_arguments(val_ptr->n_elements, index, len, "@Bcm.SocketCAN_bcm_frame.frames.can_frame","element");
SocketCAN__bcm__frame_frames_can__frame ret_val;
ret_val.set_size(val_ptr->n_elements + repl.val_ptr->n_elements - len);
for (int i = 0; i < index; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CAN__frame(*val_ptr->value_elements[i]);
}
}
for (int i = 0; i < repl.val_ptr->n_elements; i++) {
if (repl.val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i+index] = new Can::CAN__frame(*repl.val_ptr->value_elements[i]);
}
}
for (int i = 0; i < val_ptr->n_elements - index - len; i++) {
if (val_ptr->value_elements[index+i+len] != NULL) {
ret_val.val_ptr->value_elements[index+i+repl.val_ptr->n_elements] = new Can::CAN__frame(*val_ptr->value_elements[index+i+len]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame::replace(int index, int len, const SocketCAN__bcm__frame_frames_can__frame_template& repl) const
{
if (!repl.is_value()) TTCN_error("The fourth argument of function replace() is a template with non-specific value.");
return replace(index, len, repl.valueof());
}

void SocketCAN__bcm__frame_frames_can__frame::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (val_ptr == NULL) {
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
} else if (val_ptr->ref_count > 1) {
struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
new_val_ptr->ref_count = 1;
new_val_ptr->n_elements = (new_size < val_ptr->n_elements) ? new_size : val_ptr->n_elements;
new_val_ptr->value_elements = (Can::CAN__frame**)allocate_pointers(new_val_ptr->n_elements);
for (int elem_count = 0; elem_count < new_val_ptr->n_elements; elem_count++) {
if (val_ptr->value_elements[elem_count] != NULL){
new_val_ptr->value_elements[elem_count] = new Can::CAN__frame(*(val_ptr->value_elements[elem_count]));
}
}
clean_up();
val_ptr = new_val_ptr;
}
if (new_size > val_ptr->n_elements) {
val_ptr->value_elements = (Can::CAN__frame**)reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
#ifdef TITAN_MEMORY_DEBUG_SET_RECORD_OF
if((val_ptr->n_elements/1000)!=(new_size/1000)) TTCN_warning("New size of type @Bcm.SocketCAN_bcm_frame.frames.can_frame: %d",new_size);
#endif
val_ptr->n_elements = new_size;
} else if (new_size < val_ptr->n_elements) {
for (int elem_count = new_size; elem_count < val_ptr->n_elements; elem_count++)
if (val_ptr->value_elements[elem_count] != NULL)delete val_ptr->value_elements[elem_count];
val_ptr->value_elements = (Can::CAN__frame**)reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
val_ptr->n_elements = new_size;
}
}

boolean SocketCAN__bcm__frame_frames_can__frame::is_value() const
{
if (val_ptr == NULL) return FALSE;
for(int i = 0; i < val_ptr->n_elements; ++i) {
if (val_ptr->value_elements[i] == NULL || !val_ptr->value_elements[i]->is_value()) return FALSE;
}
return TRUE;
}

int SocketCAN__bcm__frame_frames_can__frame::size_of() const
{
if (val_ptr == NULL) TTCN_error("Performing sizeof operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return val_ptr->n_elements;
}

int SocketCAN__bcm__frame_frames_can__frame::lengthof() const
{
if (val_ptr == NULL) TTCN_error("Performing lengthof operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
for (int my_length=val_ptr->n_elements; my_length>0; my_length--) if (val_ptr->value_elements[my_length-1] != NULL) return my_length;
return 0;
}

void SocketCAN__bcm__frame_frames_can__frame::log() const
{
if (val_ptr == NULL) {;
TTCN_Logger::log_event_unbound();
return;
}
switch (val_ptr->n_elements) {
case 0:
TTCN_Logger::log_event_str("{ }");
break;
default:
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
(*this)[elem_count].log();
}
TTCN_Logger::log_event_str(" }");
}
}

void SocketCAN__bcm__frame_frames_can__frame::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "record of value");
  switch (param.get_operation_type()) {
  case Module_Param::OT_ASSIGN:
    if (param.get_type()==Module_Param::MP_Value_List && param.get_size()==0) {
      *this = NULL_VALUE;
      return;
    }
    switch (param.get_type()) {
    case Module_Param::MP_Value_List:
      set_size(param.get_size());
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        if (curr->get_type()!=Module_Param::MP_NotUsed) {
          (*this)[i].set_param(*curr);
          if (!(*this)[i].is_bound()) {
            delete val_ptr->value_elements[i];
            val_ptr->value_elements[i] = NULL;
          }
        }
      }
      break;
    case Module_Param::MP_Indexed_List:
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        (*this)[curr->get_id()->get_index()].set_param(*curr);
        if (!(*this)[curr->get_id()->get_index()].is_bound()) {
          delete val_ptr->value_elements[curr->get_id()->get_index()];
          val_ptr->value_elements[curr->get_id()->get_index()] = NULL;
        }
      }
      break;
    default:
      param.type_error("record of value", "@Bcm.SocketCAN_bcm_frame.frames.can_frame");
    }
    break;
  case Module_Param::OT_CONCAT:
    switch (param.get_type()) {
    case Module_Param::MP_Value_List: {
      if (!is_bound()) *this = NULL_VALUE;
      int start_idx = lengthof();
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        if ((curr->get_type()!=Module_Param::MP_NotUsed)) {
          (*this)[start_idx+(int)i].set_param(*curr);
        }
      }
    } break;
    case Module_Param::MP_Indexed_List:
      param.error("Cannot concatenate an indexed value list");
      break;
    default:
      param.type_error("record of value", "@Bcm.SocketCAN_bcm_frame.frames.can_frame");
    }
    break;
  default:
    TTCN_error("Internal error: Unknown operation type.");
  }
}

void SocketCAN__bcm__frame_frames_can__frame::set_implicit_omit()
{
if (val_ptr == NULL) return;
for (int i = 0; i < val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) val_ptr->value_elements[i]->set_implicit_omit();
}
}

void SocketCAN__bcm__frame_frames_can__frame::encode_text(Text_Buf& text_buf) const
{
if (val_ptr == NULL) TTCN_error("Text encoder: Encoding an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
text_buf.push_int(val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++)
(*this)[elem_count].encode_text(text_buf);
}

void SocketCAN__bcm__frame_frames_can__frame::decode_text(Text_Buf& text_buf)
{
clean_up();
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = text_buf.pull_int().get_val();
if (val_ptr->n_elements < 0) TTCN_error("Text decoder: Negative size was received for a value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
val_ptr->value_elements = (Can::CAN__frame**)allocate_pointers(val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
val_ptr->value_elements[elem_count] = new Can::CAN__frame;
val_ptr->value_elements[elem_count]->decode_text(text_buf);
}
}

void SocketCAN__bcm__frame_frames_can__frame_template::copy_value(const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
if (!other_value.is_bound()) TTCN_error("Initialization of a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame with an unbound value.");
single_value.n_elements = other_value.size_of();
single_value.value_elements = (Can::CAN__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (other_value[elem_count].is_bound()) {
single_value.value_elements[elem_count] = new Can::CAN__frame_template(other_value[elem_count]);
} else {
single_value.value_elements[elem_count] = new Can::CAN__frame_template;
}
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bcm__frame_frames_can__frame_template::copy_template(const SocketCAN__bcm__frame_frames_can__frame_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value.n_elements = other_value.single_value.n_elements;
single_value.value_elements = (Can::CAN__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (UNINITIALIZED_TEMPLATE != other_value.single_value.value_elements[elem_count]->get_selection()) {
single_value.value_elements[elem_count] = new Can::CAN__frame_template(*other_value.single_value.value_elements[elem_count]);
} else {
single_value.value_elements[elem_count] = new Can::CAN__frame_template;
}
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new SocketCAN__bcm__frame_frames_can__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
break;
}
set_selection(other_value);
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::match_function_specific(const Base_Type *value_ptr, int value_index, const Restricted_Length_Template *template_ptr, int template_index, boolean legacy)
{
if (value_index >= 0) return ((const SocketCAN__bcm__frame_frames_can__frame_template*)template_ptr)->single_value.value_elements[template_index]->match((*(const SocketCAN__bcm__frame_frames_can__frame*)value_ptr)[value_index], legacy);
else return ((const SocketCAN__bcm__frame_frames_can__frame_template*)template_ptr)->single_value.value_elements[template_index]->is_any_or_omit();
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template()
{
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template(template_sel other_value)
 : Record_Of_Template(other_value)
{
check_single_selection(other_value);
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template(null_type)
 : Record_Of_Template(SPECIFIC_VALUE)
{
single_value.n_elements = 0;
single_value.value_elements = NULL;
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template(const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
copy_value(other_value);
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template(const OPTIONAL<SocketCAN__bcm__frame_frames_can__frame>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames_can__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame from an unbound optional field.");
}
}

SocketCAN__bcm__frame_frames_can__frame_template::SocketCAN__bcm__frame_frames_can__frame_template(const SocketCAN__bcm__frame_frames_can__frame_template& other_value)
 : Record_Of_Template()
{
copy_template(other_value);
}

SocketCAN__bcm__frame_frames_can__frame_template::~SocketCAN__bcm__frame_frames_can__frame_template()
{
clean_up();
}

void SocketCAN__bcm__frame_frames_can__frame_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
delete single_value.value_elements[elem_count];
free_pointers((void**)single_value.value_elements);
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator=(null_type)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value.n_elements = 0;
single_value.value_elements = NULL;
return *this;
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator=(const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator=(const OPTIONAL<SocketCAN__bcm__frame_frames_can__frame>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames_can__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
}
return *this;
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator=(const SocketCAN__bcm__frame_frames_can__frame_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

Can::CAN__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @Bcm.SocketCAN_bcm_frame.frames.can_frame using a negative index: %d.", index_value);
switch (template_selection)
{
  case SPECIFIC_VALUE:
    if(index_value < single_value.n_elements) break;
    // no break
  case OMIT_VALUE:
  case ANY_VALUE:
  case ANY_OR_OMIT:
  case UNINITIALIZED_TEMPLATE:
    set_size(index_value + 1);
    break;
  default:
    TTCN_error("Accessing an element of a non-specific template for type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
    break;
}
return *single_value.value_elements[index_value];
}

Can::CAN__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return (*this)[(int)index_value];
}

const Can::CAN__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator[](int index_value) const
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @Bcm.SocketCAN_bcm_frame.frames.can_frame using a negative index: %d.", index_value);
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing an element of a non-specific template for type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (index_value >= single_value.n_elements) TTCN_error("Index overflow in a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame: The index is %d, but the template has only %d elements.", index_value, single_value.n_elements);
return *single_value.value_elements[index_value];
}

const Can::CAN__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return (*this)[(int)index_value];
}

void SocketCAN__bcm__frame_frames_can__frame_template::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
template_sel old_selection = template_selection;
if (old_selection != SPECIFIC_VALUE) {
clean_up();
set_selection(SPECIFIC_VALUE);
single_value.n_elements = 0;
single_value.value_elements = NULL;
}
if (new_size > single_value.n_elements) {
single_value.value_elements = (Can::CAN__frame_template**)reallocate_pointers((void**)single_value.value_elements, single_value.n_elements, new_size);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
for (int elem_count = single_value.n_elements; elem_count < new_size; elem_count++)
single_value.value_elements[elem_count] = new Can::CAN__frame_template(ANY_VALUE);
} else {
for (int elem_count = single_value.n_elements; elem_count < new_size; elem_count++)
single_value.value_elements[elem_count] = new Can::CAN__frame_template;
}
single_value.n_elements = new_size;
} else if (new_size < single_value.n_elements) {
for (int elem_count = new_size; elem_count < single_value.n_elements; elem_count++)
delete single_value.value_elements[elem_count];
single_value.value_elements = (Can::CAN__frame_template**)reallocate_pointers((void**)single_value.value_elements, single_value.n_elements, new_size);
single_value.n_elements = new_size;
}
}

int SocketCAN__bcm__frame_frames_can__frame_template::n_elem() const
{
  switch (template_selection) {
  case SPECIFIC_VALUE:
    return single_value.n_elements;
    break;
  case VALUE_LIST:
    return value_list.n_values;
    break;
  default:
    TTCN_error("Performing n_elem");
  }
}

int SocketCAN__bcm__frame_frames_can__frame_template::size_of(boolean is_size) const
{
const char* op_name = is_size ? "size" : "length";
int min_size;
boolean has_any_or_none;
if (is_ifpresent) TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame which has an ifpresent attribute.", op_name);
switch (template_selection)
{
case SPECIFIC_VALUE: {
  min_size = 0;
  has_any_or_none = FALSE;
  int elem_count = single_value.n_elements;
  if (!is_size) { while (elem_count>0 && !single_value.value_elements[elem_count-1]->is_bound()) elem_count--; }
  for (int i=0; i<elem_count; i++) {
    switch (single_value.value_elements[i]->get_selection()) {
    case OMIT_VALUE:
      TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame containing omit element.", op_name);
    case ANY_OR_OMIT:
      has_any_or_none = TRUE;
      break;
    default:
      min_size++;
      break;
    }
  }
} break;
case OMIT_VALUE:
  TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame containing omit value.", op_name);
case ANY_VALUE:
case ANY_OR_OMIT:
  min_size = 0;
  has_any_or_none = TRUE;
  break;
case VALUE_LIST:
{
  if (value_list.n_values<1)
    TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame containing an empty list.", op_name);
  int item_size = value_list.list_value[0].size_of(is_size);
  for (unsigned int i = 1; i < value_list.n_values; i++) {
    if (value_list.list_value[i].size_of(is_size)!=item_size)
      TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame containing a value list with different sizes.", op_name);
  }
  min_size = item_size;
  has_any_or_none = FALSE;
  break;
}
case COMPLEMENTED_LIST:
  TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame containing complemented list.", op_name);
default:
  TTCN_error("Performing %sof() operation on an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.", op_name);
}
return check_section_is_single(min_size, has_any_or_none, op_name, "a", "template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame");
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::match(const SocketCAN__bcm__frame_frames_can__frame& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
int value_length = other_value.size_of();
if (!match_length(value_length)) return FALSE;
switch (template_selection) {
case SPECIFIC_VALUE:
return match_record_of(&other_value, value_length, this, single_value.n_elements, match_function_specific, legacy);
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching with an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
}
return FALSE;
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
if (!single_value.value_elements[elem_count]->is_value()) return FALSE;
return TRUE;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
SocketCAN__bcm__frame_frames_can__frame ret_val;
ret_val.set_size(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
if (single_value.value_elements[elem_count]->is_bound()) {
ret_val[elem_count] = single_value.value_elements[elem_count]->valueof();
}
return ret_val;
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame_template::substr(int index, int returncount) const
{
if (!is_value()) TTCN_error("The first argument of function substr() is a template with non-specific value.");
return valueof().substr(index, returncount);
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame_template::replace(int index, int len, const SocketCAN__bcm__frame_frames_can__frame_template& repl) const
{
if (!is_value()) TTCN_error("The first argument of function replace() is a template with non-specific value.");
if (!repl.is_value()) TTCN_error("The fourth argument of function replace() is a template with non-specific value.");
return valueof().replace(index, len, repl.valueof());
}

SocketCAN__bcm__frame_frames_can__frame SocketCAN__bcm__frame_frames_can__frame_template::replace(int index, int len, const SocketCAN__bcm__frame_frames_can__frame& repl) const
{
if (!is_value()) TTCN_error("The first argument of function replace() is a template with non-specific value.");
return valueof().replace(index, len, repl);
}

void SocketCAN__bcm__frame_frames_can__frame_template::set_type(template_sel template_type, unsigned int list_length)
{
clean_up();
switch (template_type) {
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bcm__frame_frames_can__frame_template[list_length];
break;
default:
TTCN_error("Internal error: Setting an invalid type for a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
}
set_selection(template_type);
}

SocketCAN__bcm__frame_frames_can__frame_template& SocketCAN__bcm__frame_frames_can__frame_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Internal error: Accessing a list element of a non-list template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return value_list.list_value[list_index];
}

void SocketCAN__bcm__frame_frames_can__frame_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.n_elements > 0) {
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
if (permutation_starts_at(elem_count)) TTCN_Logger::log_event_str("permutation(");
single_value.value_elements[elem_count]->log();
if (permutation_ends_at(elem_count)) TTCN_Logger::log_char(')');
}
TTCN_Logger::log_event_str(" }");
} else TTCN_Logger::log_event_str("{ }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_restricted();
log_ifpresent();
}

void SocketCAN__bcm__frame_frames_can__frame_template::log_match(const SocketCAN__bcm__frame_frames_can__frame& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
}else{
if (template_selection == SPECIFIC_VALUE && single_value.n_elements > 0 && get_number_of_permutations() == 0 && single_value.n_elements == match_value.size_of()) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if(!single_value.value_elements[elem_count]->match(match_value[elem_count], legacy)){
TTCN_Logger::log_logmatch_info("[%d]", elem_count);
single_value.value_elements[elem_count]->log_match(match_value[elem_count], legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}
log_match_length(single_value.n_elements);
} else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE && single_value.n_elements > 0 && get_number_of_permutations() == 0 && single_value.n_elements == match_value.size_of()) {
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
single_value.value_elements[elem_count]->log_match(match_value[elem_count], legacy);
}
TTCN_Logger::log_event_str(" }");
log_match_length(single_value.n_elements);
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void SocketCAN__bcm__frame_frames_can__frame_template::encode_text(Text_Buf& text_buf) const
{
encode_text_permutation(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
single_value.value_elements[elem_count]->encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
}
}

void SocketCAN__bcm__frame_frames_can__frame_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_permutation(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value.n_elements = text_buf.pull_int().get_val();
if (single_value.n_elements < 0) TTCN_error("Text decoder: Negative size was received for a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
single_value.value_elements = (Can::CAN__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
single_value.value_elements[elem_count] = new Can::CAN__frame_template;
single_value.value_elements[elem_count]->decode_text(text_buf);
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new SocketCAN__bcm__frame_frames_can__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
}
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void SocketCAN__bcm__frame_frames_can__frame_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE|Module_Param::BC_LIST, "record of template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    SocketCAN__bcm__frame_frames_can__frame_template temp;
    temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = temp;
    break; }
  case Module_Param::MP_Indexed_List:
    if (template_selection!=SPECIFIC_VALUE) set_size(0);
    for (size_t p_i=0; p_i<param.get_size(); ++p_i) {
      (*this)[(int)(param.get_elem(p_i)->get_id()->get_index())].set_param(*param.get_elem(p_i));
    }
    break;
  case Module_Param::MP_Value_List: {
    set_size(param.get_size());
    int curr_idx = 0;
    for (size_t p_i=0; p_i<param.get_size(); ++p_i) {
      switch (param.get_elem(p_i)->get_type()) {
      case Module_Param::MP_NotUsed:
        curr_idx++;
        break;
      case Module_Param::MP_Permutation_Template: {
        int perm_start_idx = curr_idx;
        Module_Param* param_i = param.get_elem(p_i);
        for (size_t perm_i=0; perm_i<param_i->get_size(); perm_i++) {
          (*this)[curr_idx].set_param(*(param_i->get_elem(perm_i)));
          curr_idx++;
        }
        int perm_end_idx = curr_idx - 1;
        add_permutation(perm_start_idx, perm_end_idx);
      } break;
      default:
        (*this)[curr_idx].set_param(*param.get_elem(p_i));
        curr_idx++;
      }
    }
  } break;
  default:
    param.type_error("record of template", "@Bcm.SocketCAN_bcm_frame.frames.can_frame");
  }
  is_ifpresent = param.get_ifpresent();
  set_length_range(param);
}

void SocketCAN__bcm__frame_frames_can__frame_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
for (int i=0; i<single_value.n_elements; i++) single_value.value_elements[i]->check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames.can_frame");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames.can_frame");
}

boolean SocketCAN__bcm__frame_frames_can__frame_template::get_istemplate_kind(const char* type) const {
if (!strcmp(type, "AnyElement")) {
  if (template_selection != SPECIFIC_VALUE) {
    return FALSE;
  }
  for (int i = 0; i < single_value.n_elements; i++) {
    if (single_value.value_elements[i]->get_selection() == ANY_VALUE) {
      return TRUE;
    }
  }
  return FALSE;
} else if (!strcmp(type, "AnyElementsOrNone")) {
  if (template_selection != SPECIFIC_VALUE) {
    return FALSE;
  }
  for (int i = 0; i < single_value.n_elements; i++) {
    if (single_value.value_elements[i]->get_selection() == ANY_OR_OMIT) {
      return TRUE;
    }
  }
  return FALSE;
} else if (!strcmp(type, "permutation")) {
  return number_of_permutations;
} else if (!strcmp(type, "length")) {
  return length_restriction_type != NO_LENGTH_RESTRICTION;
} else {
  return Base_Template::get_istemplate_kind(type);
}
}

const Can::CANFD__frame SocketCAN__bcm__frame_frames_canfd__frame::UNBOUND_ELEM;
SocketCAN__bcm__frame_frames_canfd__frame::SocketCAN__bcm__frame_frames_canfd__frame()
{
val_ptr = NULL;
}

SocketCAN__bcm__frame_frames_canfd__frame::SocketCAN__bcm__frame_frames_canfd__frame(null_type)
{
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
}

SocketCAN__bcm__frame_frames_canfd__frame::SocketCAN__bcm__frame_frames_canfd__frame(const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
if (!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}

SocketCAN__bcm__frame_frames_canfd__frame::~SocketCAN__bcm__frame_frames_canfd__frame()
{
clean_up();
if (val_ptr != NULL) val_ptr = NULL;
}

void SocketCAN__bcm__frame_frames_canfd__frame::clean_up()
{
if (val_ptr != NULL) {
if (val_ptr->ref_count > 1) {
val_ptr->ref_count--;
val_ptr = NULL;
}
else if (val_ptr->ref_count == 1) {
for (int elem_count = 0; elem_count < val_ptr->n_elements;
elem_count++)
if (val_ptr->value_elements[elem_count] != NULL)
delete val_ptr->value_elements[elem_count];
free_pointers((void**)val_ptr->value_elements);
delete val_ptr;
val_ptr = NULL;
}
else
TTCN_error("Internal error: Invalid reference counter in a record of/set of value.");
}
}

SocketCAN__bcm__frame_frames_canfd__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator=(null_type)
{
clean_up();
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
return *this;
}

SocketCAN__bcm__frame_frames_canfd__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator=(const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
if (other_value.val_ptr == NULL) TTCN_error("Assigning an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (this != &other_value) {
clean_up();
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}
return *this;
}

boolean SocketCAN__bcm__frame_frames_canfd__frame::operator==(null_type) const
{
if (val_ptr == NULL)
TTCN_error("The left operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return val_ptr->n_elements == 0 ;
}

boolean SocketCAN__bcm__frame_frames_canfd__frame::operator==(const SocketCAN__bcm__frame_frames_canfd__frame& other_value) const
{
if (val_ptr == NULL) TTCN_error("The left operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (other_value.val_ptr == NULL) TTCN_error("The right operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (val_ptr == other_value.val_ptr) return TRUE;
if (val_ptr->n_elements != (other_value.val_ptr)->n_elements)
return FALSE;
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++){
if (val_ptr->value_elements[elem_count] != NULL){
if ((other_value.val_ptr)->value_elements[elem_count] != NULL){
  if (*val_ptr->value_elements[elem_count] != *(other_value.val_ptr)->value_elements[elem_count]) return FALSE;
} else return FALSE;
} else {
if ((other_value.val_ptr)->value_elements[elem_count] != NULL) return FALSE;
}
}
return TRUE;
}

Can::CANFD__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame using a negative index: %d.", index_value);
if (val_ptr == NULL) {
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
} else if (val_ptr->ref_count > 1) {
struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
new_val_ptr->ref_count = 1;
new_val_ptr->n_elements = (index_value >= val_ptr->n_elements) ? index_value + 1 : val_ptr->n_elements;
new_val_ptr->value_elements = (Can::CANFD__frame**)allocate_pointers(new_val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++){
if (val_ptr->value_elements[elem_count] != NULL){
new_val_ptr->value_elements[elem_count] = new Can::CANFD__frame(*(val_ptr->value_elements[elem_count]));
}
}
clean_up();
val_ptr = new_val_ptr;
}
if (index_value >= val_ptr->n_elements) set_size(index_value + 1);
if (val_ptr->value_elements[index_value] == NULL) {
val_ptr->value_elements[index_value] = new Can::CANFD__frame;
}
return *val_ptr->value_elements[index_value];
}

Can::CANFD__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return (*this)[(int)index_value];
}

const Can::CANFD__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator[](int index_value) const
{
if (val_ptr == NULL)
TTCN_error("Accessing an element in an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (index_value < 0) TTCN_error("Accessing an element of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame using a negative index: %d.", index_value);
if (index_value >= val_ptr->n_elements) TTCN_error("Index overflow in a value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame: The index is %d, but the value has only %d elements.", index_value, val_ptr->n_elements);
return (val_ptr->value_elements[index_value] == NULL) ?
UNBOUND_ELEM : *val_ptr->value_elements[index_value];
}

const Can::CANFD__frame& SocketCAN__bcm__frame_frames_canfd__frame::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return (*this)[(int)index_value];
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::operator<<=(int rotate_count) const
{
return *this >>= (-rotate_count);
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::operator<<=(const INTEGER& rotate_count) const
{
rotate_count.must_bound("Unbound integer operand of rotate left operator.");
return *this >>= (int)(-rotate_count);
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::operator>>=(const INTEGER& rotate_count) const
{
rotate_count.must_bound("Unbound integer operand of rotate right operator.");
return *this >>= (int)rotate_count;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::operator>>=(int rotate_count) const
{
if (val_ptr == NULL) TTCN_error("Performing rotation operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (val_ptr->n_elements == 0) return *this;
int rc;
if (rotate_count>=0) rc = rotate_count % val_ptr->n_elements;
else rc = val_ptr->n_elements - ((-rotate_count) % val_ptr->n_elements);
if (rc == 0) return *this;
SocketCAN__bcm__frame_frames_canfd__frame ret_val;
ret_val.set_size(val_ptr->n_elements);
for (int i=0; i<val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[(i+rc)%val_ptr->n_elements] =new Can::CANFD__frame(*val_ptr->value_elements[i]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::operator+(const SocketCAN__bcm__frame_frames_canfd__frame& other_value) const
{
if (val_ptr == NULL || other_value.val_ptr == NULL) TTCN_error("Unbound operand of @Bcm.SocketCAN_bcm_frame.frames.canfd_frame concatenation.");
if (val_ptr->n_elements == 0) return other_value;
if (other_value.val_ptr->n_elements == 0) return *this;
SocketCAN__bcm__frame_frames_canfd__frame ret_val;
ret_val.set_size(val_ptr->n_elements+other_value.val_ptr->n_elements);
for (int i=0; i<val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CANFD__frame(*val_ptr->value_elements[i]);
}
}
for (int i=0; i<other_value.val_ptr->n_elements; i++) {
if (other_value.val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i+val_ptr->n_elements] = new Can::CANFD__frame(*other_value.val_ptr->value_elements[i]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::substr(int index, int returncount) const
{
if (val_ptr == NULL) TTCN_error("The first argument of substr() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
check_substr_arguments(val_ptr->n_elements, index, returncount, "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame","element");
SocketCAN__bcm__frame_frames_canfd__frame ret_val;
ret_val.set_size(returncount);
for (int i=0; i<returncount; i++) {
if (val_ptr->value_elements[i+index] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CANFD__frame(*val_ptr->value_elements[i+index]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::replace(int index, int len, const SocketCAN__bcm__frame_frames_canfd__frame& repl) const
{
if (val_ptr == NULL) TTCN_error("The first argument of replace() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (repl.val_ptr == NULL) TTCN_error("The fourth argument of replace() is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
check_replace_arguments(val_ptr->n_elements, index, len, "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame","element");
SocketCAN__bcm__frame_frames_canfd__frame ret_val;
ret_val.set_size(val_ptr->n_elements + repl.val_ptr->n_elements - len);
for (int i = 0; i < index; i++) {
if (val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i] = new Can::CANFD__frame(*val_ptr->value_elements[i]);
}
}
for (int i = 0; i < repl.val_ptr->n_elements; i++) {
if (repl.val_ptr->value_elements[i] != NULL) {
ret_val.val_ptr->value_elements[i+index] = new Can::CANFD__frame(*repl.val_ptr->value_elements[i]);
}
}
for (int i = 0; i < val_ptr->n_elements - index - len; i++) {
if (val_ptr->value_elements[index+i+len] != NULL) {
ret_val.val_ptr->value_elements[index+i+repl.val_ptr->n_elements] = new Can::CANFD__frame(*val_ptr->value_elements[index+i+len]);
}
}
return ret_val;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame::replace(int index, int len, const SocketCAN__bcm__frame_frames_canfd__frame_template& repl) const
{
if (!repl.is_value()) TTCN_error("The fourth argument of function replace() is a template with non-specific value.");
return replace(index, len, repl.valueof());
}

void SocketCAN__bcm__frame_frames_canfd__frame::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (val_ptr == NULL) {
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = 0;
val_ptr->value_elements = NULL;
} else if (val_ptr->ref_count > 1) {
struct recordof_setof_struct *new_val_ptr = new recordof_setof_struct;
new_val_ptr->ref_count = 1;
new_val_ptr->n_elements = (new_size < val_ptr->n_elements) ? new_size : val_ptr->n_elements;
new_val_ptr->value_elements = (Can::CANFD__frame**)allocate_pointers(new_val_ptr->n_elements);
for (int elem_count = 0; elem_count < new_val_ptr->n_elements; elem_count++) {
if (val_ptr->value_elements[elem_count] != NULL){
new_val_ptr->value_elements[elem_count] = new Can::CANFD__frame(*(val_ptr->value_elements[elem_count]));
}
}
clean_up();
val_ptr = new_val_ptr;
}
if (new_size > val_ptr->n_elements) {
val_ptr->value_elements = (Can::CANFD__frame**)reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
#ifdef TITAN_MEMORY_DEBUG_SET_RECORD_OF
if((val_ptr->n_elements/1000)!=(new_size/1000)) TTCN_warning("New size of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame: %d",new_size);
#endif
val_ptr->n_elements = new_size;
} else if (new_size < val_ptr->n_elements) {
for (int elem_count = new_size; elem_count < val_ptr->n_elements; elem_count++)
if (val_ptr->value_elements[elem_count] != NULL)delete val_ptr->value_elements[elem_count];
val_ptr->value_elements = (Can::CANFD__frame**)reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
val_ptr->n_elements = new_size;
}
}

boolean SocketCAN__bcm__frame_frames_canfd__frame::is_value() const
{
if (val_ptr == NULL) return FALSE;
for(int i = 0; i < val_ptr->n_elements; ++i) {
if (val_ptr->value_elements[i] == NULL || !val_ptr->value_elements[i]->is_value()) return FALSE;
}
return TRUE;
}

int SocketCAN__bcm__frame_frames_canfd__frame::size_of() const
{
if (val_ptr == NULL) TTCN_error("Performing sizeof operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return val_ptr->n_elements;
}

int SocketCAN__bcm__frame_frames_canfd__frame::lengthof() const
{
if (val_ptr == NULL) TTCN_error("Performing lengthof operation on an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
for (int my_length=val_ptr->n_elements; my_length>0; my_length--) if (val_ptr->value_elements[my_length-1] != NULL) return my_length;
return 0;
}

void SocketCAN__bcm__frame_frames_canfd__frame::log() const
{
if (val_ptr == NULL) {;
TTCN_Logger::log_event_unbound();
return;
}
switch (val_ptr->n_elements) {
case 0:
TTCN_Logger::log_event_str("{ }");
break;
default:
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
(*this)[elem_count].log();
}
TTCN_Logger::log_event_str(" }");
}
}

void SocketCAN__bcm__frame_frames_canfd__frame::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "record of value");
  switch (param.get_operation_type()) {
  case Module_Param::OT_ASSIGN:
    if (param.get_type()==Module_Param::MP_Value_List && param.get_size()==0) {
      *this = NULL_VALUE;
      return;
    }
    switch (param.get_type()) {
    case Module_Param::MP_Value_List:
      set_size(param.get_size());
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        if (curr->get_type()!=Module_Param::MP_NotUsed) {
          (*this)[i].set_param(*curr);
          if (!(*this)[i].is_bound()) {
            delete val_ptr->value_elements[i];
            val_ptr->value_elements[i] = NULL;
          }
        }
      }
      break;
    case Module_Param::MP_Indexed_List:
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        (*this)[curr->get_id()->get_index()].set_param(*curr);
        if (!(*this)[curr->get_id()->get_index()].is_bound()) {
          delete val_ptr->value_elements[curr->get_id()->get_index()];
          val_ptr->value_elements[curr->get_id()->get_index()] = NULL;
        }
      }
      break;
    default:
      param.type_error("record of value", "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
    }
    break;
  case Module_Param::OT_CONCAT:
    switch (param.get_type()) {
    case Module_Param::MP_Value_List: {
      if (!is_bound()) *this = NULL_VALUE;
      int start_idx = lengthof();
      for (size_t i=0; i<param.get_size(); ++i) {
        Module_Param* const curr = param.get_elem(i);
        if ((curr->get_type()!=Module_Param::MP_NotUsed)) {
          (*this)[start_idx+(int)i].set_param(*curr);
        }
      }
    } break;
    case Module_Param::MP_Indexed_List:
      param.error("Cannot concatenate an indexed value list");
      break;
    default:
      param.type_error("record of value", "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
    }
    break;
  default:
    TTCN_error("Internal error: Unknown operation type.");
  }
}

void SocketCAN__bcm__frame_frames_canfd__frame::set_implicit_omit()
{
if (val_ptr == NULL) return;
for (int i = 0; i < val_ptr->n_elements; i++) {
if (val_ptr->value_elements[i] != NULL) val_ptr->value_elements[i]->set_implicit_omit();
}
}

void SocketCAN__bcm__frame_frames_canfd__frame::encode_text(Text_Buf& text_buf) const
{
if (val_ptr == NULL) TTCN_error("Text encoder: Encoding an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
text_buf.push_int(val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++)
(*this)[elem_count].encode_text(text_buf);
}

void SocketCAN__bcm__frame_frames_canfd__frame::decode_text(Text_Buf& text_buf)
{
clean_up();
val_ptr = new recordof_setof_struct;
val_ptr->ref_count = 1;
val_ptr->n_elements = text_buf.pull_int().get_val();
if (val_ptr->n_elements < 0) TTCN_error("Text decoder: Negative size was received for a value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
val_ptr->value_elements = (Can::CANFD__frame**)allocate_pointers(val_ptr->n_elements);
for (int elem_count = 0; elem_count < val_ptr->n_elements; elem_count++) {
val_ptr->value_elements[elem_count] = new Can::CANFD__frame;
val_ptr->value_elements[elem_count]->decode_text(text_buf);
}
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::copy_value(const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
if (!other_value.is_bound()) TTCN_error("Initialization of a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame with an unbound value.");
single_value.n_elements = other_value.size_of();
single_value.value_elements = (Can::CANFD__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (other_value[elem_count].is_bound()) {
single_value.value_elements[elem_count] = new Can::CANFD__frame_template(other_value[elem_count]);
} else {
single_value.value_elements[elem_count] = new Can::CANFD__frame_template;
}
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::copy_template(const SocketCAN__bcm__frame_frames_canfd__frame_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value.n_elements = other_value.single_value.n_elements;
single_value.value_elements = (Can::CANFD__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (UNINITIALIZED_TEMPLATE != other_value.single_value.value_elements[elem_count]->get_selection()) {
single_value.value_elements[elem_count] = new Can::CANFD__frame_template(*other_value.single_value.value_elements[elem_count]);
} else {
single_value.value_elements[elem_count] = new Can::CANFD__frame_template;
}
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new SocketCAN__bcm__frame_frames_canfd__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
break;
}
set_selection(other_value);
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::match_function_specific(const Base_Type *value_ptr, int value_index, const Restricted_Length_Template *template_ptr, int template_index, boolean legacy)
{
if (value_index >= 0) return ((const SocketCAN__bcm__frame_frames_canfd__frame_template*)template_ptr)->single_value.value_elements[template_index]->match((*(const SocketCAN__bcm__frame_frames_canfd__frame*)value_ptr)[value_index], legacy);
else return ((const SocketCAN__bcm__frame_frames_canfd__frame_template*)template_ptr)->single_value.value_elements[template_index]->is_any_or_omit();
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template()
{
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template(template_sel other_value)
 : Record_Of_Template(other_value)
{
check_single_selection(other_value);
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template(null_type)
 : Record_Of_Template(SPECIFIC_VALUE)
{
single_value.n_elements = 0;
single_value.value_elements = NULL;
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template(const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
copy_value(other_value);
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template(const OPTIONAL<SocketCAN__bcm__frame_frames_canfd__frame>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames_canfd__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame from an unbound optional field.");
}
}

SocketCAN__bcm__frame_frames_canfd__frame_template::SocketCAN__bcm__frame_frames_canfd__frame_template(const SocketCAN__bcm__frame_frames_canfd__frame_template& other_value)
 : Record_Of_Template()
{
copy_template(other_value);
}

SocketCAN__bcm__frame_frames_canfd__frame_template::~SocketCAN__bcm__frame_frames_canfd__frame_template()
{
clean_up();
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
delete single_value.value_elements[elem_count];
free_pointers((void**)single_value.value_elements);
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator=(null_type)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value.n_elements = 0;
single_value.value_elements = NULL;
return *this;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator=(const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator=(const OPTIONAL<SocketCAN__bcm__frame_frames_canfd__frame>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame_frames_canfd__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
}
return *this;
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator=(const SocketCAN__bcm__frame_frames_canfd__frame_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

Can::CANFD__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame using a negative index: %d.", index_value);
switch (template_selection)
{
  case SPECIFIC_VALUE:
    if(index_value < single_value.n_elements) break;
    // no break
  case OMIT_VALUE:
  case ANY_VALUE:
  case ANY_OR_OMIT:
  case UNINITIALIZED_TEMPLATE:
    set_size(index_value + 1);
    break;
  default:
    TTCN_error("Accessing an element of a non-specific template for type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
    break;
}
return *single_value.value_elements[index_value];
}

Can::CANFD__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return (*this)[(int)index_value];
}

const Can::CANFD__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator[](int index_value) const
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame using a negative index: %d.", index_value);
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing an element of a non-specific template for type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (index_value >= single_value.n_elements) TTCN_error("Index overflow in a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame: The index is %d, but the template has only %d elements.", index_value, single_value.n_elements);
return *single_value.value_elements[index_value];
}

const Can::CANFD__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return (*this)[(int)index_value];
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
template_sel old_selection = template_selection;
if (old_selection != SPECIFIC_VALUE) {
clean_up();
set_selection(SPECIFIC_VALUE);
single_value.n_elements = 0;
single_value.value_elements = NULL;
}
if (new_size > single_value.n_elements) {
single_value.value_elements = (Can::CANFD__frame_template**)reallocate_pointers((void**)single_value.value_elements, single_value.n_elements, new_size);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
for (int elem_count = single_value.n_elements; elem_count < new_size; elem_count++)
single_value.value_elements[elem_count] = new Can::CANFD__frame_template(ANY_VALUE);
} else {
for (int elem_count = single_value.n_elements; elem_count < new_size; elem_count++)
single_value.value_elements[elem_count] = new Can::CANFD__frame_template;
}
single_value.n_elements = new_size;
} else if (new_size < single_value.n_elements) {
for (int elem_count = new_size; elem_count < single_value.n_elements; elem_count++)
delete single_value.value_elements[elem_count];
single_value.value_elements = (Can::CANFD__frame_template**)reallocate_pointers((void**)single_value.value_elements, single_value.n_elements, new_size);
single_value.n_elements = new_size;
}
}

int SocketCAN__bcm__frame_frames_canfd__frame_template::n_elem() const
{
  switch (template_selection) {
  case SPECIFIC_VALUE:
    return single_value.n_elements;
    break;
  case VALUE_LIST:
    return value_list.n_values;
    break;
  default:
    TTCN_error("Performing n_elem");
  }
}

int SocketCAN__bcm__frame_frames_canfd__frame_template::size_of(boolean is_size) const
{
const char* op_name = is_size ? "size" : "length";
int min_size;
boolean has_any_or_none;
if (is_ifpresent) TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame which has an ifpresent attribute.", op_name);
switch (template_selection)
{
case SPECIFIC_VALUE: {
  min_size = 0;
  has_any_or_none = FALSE;
  int elem_count = single_value.n_elements;
  if (!is_size) { while (elem_count>0 && !single_value.value_elements[elem_count-1]->is_bound()) elem_count--; }
  for (int i=0; i<elem_count; i++) {
    switch (single_value.value_elements[i]->get_selection()) {
    case OMIT_VALUE:
      TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame containing omit element.", op_name);
    case ANY_OR_OMIT:
      has_any_or_none = TRUE;
      break;
    default:
      min_size++;
      break;
    }
  }
} break;
case OMIT_VALUE:
  TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame containing omit value.", op_name);
case ANY_VALUE:
case ANY_OR_OMIT:
  min_size = 0;
  has_any_or_none = TRUE;
  break;
case VALUE_LIST:
{
  if (value_list.n_values<1)
    TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame containing an empty list.", op_name);
  int item_size = value_list.list_value[0].size_of(is_size);
  for (unsigned int i = 1; i < value_list.n_values; i++) {
    if (value_list.list_value[i].size_of(is_size)!=item_size)
      TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame containing a value list with different sizes.", op_name);
  }
  min_size = item_size;
  has_any_or_none = FALSE;
  break;
}
case COMPLEMENTED_LIST:
  TTCN_error("Performing %sof() operation on a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame containing complemented list.", op_name);
default:
  TTCN_error("Performing %sof() operation on an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.", op_name);
}
return check_section_is_single(min_size, has_any_or_none, op_name, "a", "template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::match(const SocketCAN__bcm__frame_frames_canfd__frame& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
int value_length = other_value.size_of();
if (!match_length(value_length)) return FALSE;
switch (template_selection) {
case SPECIFIC_VALUE:
return match_record_of(&other_value, value_length, this, single_value.n_elements, match_function_specific, legacy);
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching with an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
}
return FALSE;
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
if (!single_value.value_elements[elem_count]->is_value()) return FALSE;
return TRUE;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
SocketCAN__bcm__frame_frames_canfd__frame ret_val;
ret_val.set_size(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
if (single_value.value_elements[elem_count]->is_bound()) {
ret_val[elem_count] = single_value.value_elements[elem_count]->valueof();
}
return ret_val;
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame_template::substr(int index, int returncount) const
{
if (!is_value()) TTCN_error("The first argument of function substr() is a template with non-specific value.");
return valueof().substr(index, returncount);
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame_template::replace(int index, int len, const SocketCAN__bcm__frame_frames_canfd__frame_template& repl) const
{
if (!is_value()) TTCN_error("The first argument of function replace() is a template with non-specific value.");
if (!repl.is_value()) TTCN_error("The fourth argument of function replace() is a template with non-specific value.");
return valueof().replace(index, len, repl.valueof());
}

SocketCAN__bcm__frame_frames_canfd__frame SocketCAN__bcm__frame_frames_canfd__frame_template::replace(int index, int len, const SocketCAN__bcm__frame_frames_canfd__frame& repl) const
{
if (!is_value()) TTCN_error("The first argument of function replace() is a template with non-specific value.");
return valueof().replace(index, len, repl);
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::set_type(template_sel template_type, unsigned int list_length)
{
clean_up();
switch (template_type) {
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bcm__frame_frames_canfd__frame_template[list_length];
break;
default:
TTCN_error("Internal error: Setting an invalid type for a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
}
set_selection(template_type);
}

SocketCAN__bcm__frame_frames_canfd__frame_template& SocketCAN__bcm__frame_frames_canfd__frame_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Internal error: Accessing a list element of a non-list template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return value_list.list_value[list_index];
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.n_elements > 0) {
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
if (permutation_starts_at(elem_count)) TTCN_Logger::log_event_str("permutation(");
single_value.value_elements[elem_count]->log();
if (permutation_ends_at(elem_count)) TTCN_Logger::log_char(')');
}
TTCN_Logger::log_event_str(" }");
} else TTCN_Logger::log_event_str("{ }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_restricted();
log_ifpresent();
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::log_match(const SocketCAN__bcm__frame_frames_canfd__frame& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
}else{
if (template_selection == SPECIFIC_VALUE && single_value.n_elements > 0 && get_number_of_permutations() == 0 && single_value.n_elements == match_value.size_of()) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if(!single_value.value_elements[elem_count]->match(match_value[elem_count], legacy)){
TTCN_Logger::log_logmatch_info("[%d]", elem_count);
single_value.value_elements[elem_count]->log_match(match_value[elem_count], legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}
log_match_length(single_value.n_elements);
} else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE && single_value.n_elements > 0 && get_number_of_permutations() == 0 && single_value.n_elements == match_value.size_of()) {
TTCN_Logger::log_event_str("{ ");
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
single_value.value_elements[elem_count]->log_match(match_value[elem_count], legacy);
}
TTCN_Logger::log_event_str(" }");
log_match_length(single_value.n_elements);
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::encode_text(Text_Buf& text_buf) const
{
encode_text_permutation(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++)
single_value.value_elements[elem_count]->encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
}
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_permutation(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value.n_elements = text_buf.pull_int().get_val();
if (single_value.n_elements < 0) TTCN_error("Text decoder: Negative size was received for a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
single_value.value_elements = (Can::CANFD__frame_template**)allocate_pointers(single_value.n_elements);
for (int elem_count = 0; elem_count < single_value.n_elements; elem_count++) {
single_value.value_elements[elem_count] = new Can::CANFD__frame_template;
single_value.value_elements[elem_count]->decode_text(text_buf);
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new SocketCAN__bcm__frame_frames_canfd__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
}
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE|Module_Param::BC_LIST, "record of template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    SocketCAN__bcm__frame_frames_canfd__frame_template temp;
    temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = temp;
    break; }
  case Module_Param::MP_Indexed_List:
    if (template_selection!=SPECIFIC_VALUE) set_size(0);
    for (size_t p_i=0; p_i<param.get_size(); ++p_i) {
      (*this)[(int)(param.get_elem(p_i)->get_id()->get_index())].set_param(*param.get_elem(p_i));
    }
    break;
  case Module_Param::MP_Value_List: {
    set_size(param.get_size());
    int curr_idx = 0;
    for (size_t p_i=0; p_i<param.get_size(); ++p_i) {
      switch (param.get_elem(p_i)->get_type()) {
      case Module_Param::MP_NotUsed:
        curr_idx++;
        break;
      case Module_Param::MP_Permutation_Template: {
        int perm_start_idx = curr_idx;
        Module_Param* param_i = param.get_elem(p_i);
        for (size_t perm_i=0; perm_i<param_i->get_size(); perm_i++) {
          (*this)[curr_idx].set_param(*(param_i->get_elem(perm_i)));
          curr_idx++;
        }
        int perm_end_idx = curr_idx - 1;
        add_permutation(perm_start_idx, perm_end_idx);
      } break;
      default:
        (*this)[curr_idx].set_param(*param.get_elem(p_i));
        curr_idx++;
      }
    }
  } break;
  default:
    param.type_error("record of template", "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
  }
  is_ifpresent = param.get_ifpresent();
  set_length_range(param);
}

void SocketCAN__bcm__frame_frames_canfd__frame_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
for (int i=0; i<single_value.n_elements; i++) single_value.value_elements[i]->check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.SocketCAN_bcm_frame.frames.canfd_frame");
}

boolean SocketCAN__bcm__frame_frames_canfd__frame_template::get_istemplate_kind(const char* type) const {
if (!strcmp(type, "AnyElement")) {
  if (template_selection != SPECIFIC_VALUE) {
    return FALSE;
  }
  for (int i = 0; i < single_value.n_elements; i++) {
    if (single_value.value_elements[i]->get_selection() == ANY_VALUE) {
      return TRUE;
    }
  }
  return FALSE;
} else if (!strcmp(type, "AnyElementsOrNone")) {
  if (template_selection != SPECIFIC_VALUE) {
    return FALSE;
  }
  for (int i = 0; i < single_value.n_elements; i++) {
    if (single_value.value_elements[i]->get_selection() == ANY_OR_OMIT) {
      return TRUE;
    }
  }
  return FALSE;
} else if (!strcmp(type, "permutation")) {
  return number_of_permutations;
} else if (!strcmp(type, "length")) {
  return length_restriction_type != NO_LENGTH_RESTRICTION;
} else {
  return Base_Template::get_istemplate_kind(type);
}
}
SocketCAN__bcm__frame::SocketCAN__bcm__frame()
{
}

SocketCAN__bcm__frame::SocketCAN__bcm__frame(const OCTETSTRING& par_opcode,
    const BITSTRING& par_flags,
    const INTEGER& par_count,
    const Bcm__timeval& par_ival1,
    const Bcm__timeval& par_ival2,
    const OCTETSTRING& par_can__id,
    const SocketCAN__bcm__frame_frames& par_frames)
  :   field_opcode(par_opcode),
  field_flags(par_flags),
  field_count(par_count),
  field_ival1(par_ival1),
  field_ival2(par_ival2),
  field_can__id(par_can__id),
  field_frames(par_frames)
{
}

SocketCAN__bcm__frame::SocketCAN__bcm__frame(const SocketCAN__bcm__frame& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Bcm.SocketCAN_bcm_frame.");
if (other_value.opcode().is_bound()) field_opcode = other_value.opcode();
else field_opcode.clean_up();
if (other_value.flags().is_bound()) field_flags = other_value.flags();
else field_flags.clean_up();
if (other_value.count().is_bound()) field_count = other_value.count();
else field_count.clean_up();
if (other_value.ival1().is_bound()) field_ival1 = other_value.ival1();
else field_ival1.clean_up();
if (other_value.ival2().is_bound()) field_ival2 = other_value.ival2();
else field_ival2.clean_up();
if (other_value.can__id().is_bound()) field_can__id = other_value.can__id();
else field_can__id.clean_up();
if (other_value.frames().is_bound()) field_frames = other_value.frames();
else field_frames.clean_up();
}

void SocketCAN__bcm__frame::clean_up()
{
field_opcode.clean_up();
field_flags.clean_up();
field_count.clean_up();
field_ival1.clean_up();
field_ival2.clean_up();
field_can__id.clean_up();
field_frames.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__bcm__frame::get_descriptor() const { return &SocketCAN__bcm__frame_descr_; }
SocketCAN__bcm__frame& SocketCAN__bcm__frame::operator=(const SocketCAN__bcm__frame& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Bcm.SocketCAN_bcm_frame.");
  if (other_value.opcode().is_bound()) field_opcode = other_value.opcode();
  else field_opcode.clean_up();
  if (other_value.flags().is_bound()) field_flags = other_value.flags();
  else field_flags.clean_up();
  if (other_value.count().is_bound()) field_count = other_value.count();
  else field_count.clean_up();
  if (other_value.ival1().is_bound()) field_ival1 = other_value.ival1();
  else field_ival1.clean_up();
  if (other_value.ival2().is_bound()) field_ival2 = other_value.ival2();
  else field_ival2.clean_up();
  if (other_value.can__id().is_bound()) field_can__id = other_value.can__id();
  else field_can__id.clean_up();
  if (other_value.frames().is_bound()) field_frames = other_value.frames();
  else field_frames.clean_up();
}
return *this;
}

boolean SocketCAN__bcm__frame::operator==(const SocketCAN__bcm__frame& other_value) const
{
return field_opcode==other_value.field_opcode
  && field_flags==other_value.field_flags
  && field_count==other_value.field_count
  && field_ival1==other_value.field_ival1
  && field_ival2==other_value.field_ival2
  && field_can__id==other_value.field_can__id
  && field_frames==other_value.field_frames;
}

boolean SocketCAN__bcm__frame::is_bound() const
{
return (field_opcode.is_bound())
  || (field_flags.is_bound())
  || (field_count.is_bound())
  || (field_ival1.is_bound())
  || (field_ival2.is_bound())
  || (field_can__id.is_bound())
  || (field_frames.is_bound());
}
boolean SocketCAN__bcm__frame::is_value() const
{
return field_opcode.is_value()
  && field_flags.is_value()
  && field_count.is_value()
  && field_ival1.is_value()
  && field_ival2.is_value()
  && field_can__id.is_value()
  && field_frames.is_value();
}
void SocketCAN__bcm__frame::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ opcode := ");
field_opcode.log();
TTCN_Logger::log_event_str(", flags := ");
field_flags.log();
TTCN_Logger::log_event_str(", count := ");
field_count.log();
TTCN_Logger::log_event_str(", ival1 := ");
field_ival1.log();
TTCN_Logger::log_event_str(", ival2 := ");
field_ival2.log();
TTCN_Logger::log_event_str(", can_id := ");
field_can__id.log();
TTCN_Logger::log_event_str(", frames := ");
field_frames.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__bcm__frame::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (7<param.get_size()) {
      param.error("record value of type @Bcm.SocketCAN_bcm_frame has 7 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) opcode().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) flags().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) count().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) ival1().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ival2().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) can__id().set_param(*param.get_elem(5));
    if (param.get_size()>6 && param.get_elem(6)->get_type()!=Module_Param::MP_NotUsed) frames().set_param(*param.get_elem(6));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "opcode")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          opcode().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "flags")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          flags().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "count")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          count().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ival1")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ival1().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ival2")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ival2().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__id().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "frames")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frames().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @Bcm.SocketCAN_bcm_frame: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Bcm.SocketCAN_bcm_frame");
  }
}

void SocketCAN__bcm__frame::set_implicit_omit()
{
if (opcode().is_bound()) opcode().set_implicit_omit();
if (flags().is_bound()) flags().set_implicit_omit();
if (count().is_bound()) count().set_implicit_omit();
if (ival1().is_bound()) ival1().set_implicit_omit();
if (ival2().is_bound()) ival2().set_implicit_omit();
if (can__id().is_bound()) can__id().set_implicit_omit();
if (frames().is_bound()) frames().set_implicit_omit();
}

void SocketCAN__bcm__frame::encode_text(Text_Buf& text_buf) const
{
field_opcode.encode_text(text_buf);
field_flags.encode_text(text_buf);
field_count.encode_text(text_buf);
field_ival1.encode_text(text_buf);
field_ival2.encode_text(text_buf);
field_can__id.encode_text(text_buf);
field_frames.encode_text(text_buf);
}

void SocketCAN__bcm__frame::decode_text(Text_Buf& text_buf)
{
field_opcode.decode_text(text_buf);
field_flags.decode_text(text_buf);
field_count.decode_text(text_buf);
field_ival1.decode_text(text_buf);
field_ival2.decode_text(text_buf);
field_can__id.decode_text(text_buf);
field_frames.decode_text(text_buf);
}

struct SocketCAN__bcm__frame_template::single_value_struct {
OCTETSTRING_template field_opcode;
BITSTRING_template field_flags;
INTEGER_template field_count;
Bcm__timeval_template field_ival1;
Bcm__timeval_template field_ival2;
OCTETSTRING_template field_can__id;
SocketCAN__bcm__frame_frames_template field_frames;
};

void SocketCAN__bcm__frame_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_opcode = ANY_VALUE;
single_value->field_flags = ANY_VALUE;
single_value->field_count = ANY_VALUE;
single_value->field_ival1 = ANY_VALUE;
single_value->field_ival2 = ANY_VALUE;
single_value->field_can__id = ANY_VALUE;
single_value->field_frames = ANY_VALUE;
}
}
}

void SocketCAN__bcm__frame_template::copy_value(const SocketCAN__bcm__frame& other_value)
{
single_value = new single_value_struct;
if (other_value.opcode().is_bound()) {
  single_value->field_opcode = other_value.opcode();
} else {
  single_value->field_opcode.clean_up();
}
if (other_value.flags().is_bound()) {
  single_value->field_flags = other_value.flags();
} else {
  single_value->field_flags.clean_up();
}
if (other_value.count().is_bound()) {
  single_value->field_count = other_value.count();
} else {
  single_value->field_count.clean_up();
}
if (other_value.ival1().is_bound()) {
  single_value->field_ival1 = other_value.ival1();
} else {
  single_value->field_ival1.clean_up();
}
if (other_value.ival2().is_bound()) {
  single_value->field_ival2 = other_value.ival2();
} else {
  single_value->field_ival2.clean_up();
}
if (other_value.can__id().is_bound()) {
  single_value->field_can__id = other_value.can__id();
} else {
  single_value->field_can__id.clean_up();
}
if (other_value.frames().is_bound()) {
  single_value->field_frames = other_value.frames();
} else {
  single_value->field_frames.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bcm__frame_template::copy_template(const SocketCAN__bcm__frame_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.opcode().get_selection()) {
single_value->field_opcode = other_value.opcode();
} else {
single_value->field_opcode.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.flags().get_selection()) {
single_value->field_flags = other_value.flags();
} else {
single_value->field_flags.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.count().get_selection()) {
single_value->field_count = other_value.count();
} else {
single_value->field_count.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ival1().get_selection()) {
single_value->field_ival1 = other_value.ival1();
} else {
single_value->field_ival1.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ival2().get_selection()) {
single_value->field_ival2 = other_value.ival2();
} else {
single_value->field_ival2.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.can__id().get_selection()) {
single_value->field_can__id = other_value.can__id();
} else {
single_value->field_can__id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.frames().get_selection()) {
single_value->field_frames = other_value.frames();
} else {
single_value->field_frames.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new SocketCAN__bcm__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.");
break;
}
set_selection(other_value);
}

SocketCAN__bcm__frame_template::SocketCAN__bcm__frame_template()
{
}

SocketCAN__bcm__frame_template::SocketCAN__bcm__frame_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

SocketCAN__bcm__frame_template::SocketCAN__bcm__frame_template(const SocketCAN__bcm__frame& other_value)
{
copy_value(other_value);
}

SocketCAN__bcm__frame_template::SocketCAN__bcm__frame_template(const OPTIONAL<SocketCAN__bcm__frame>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @Bcm.SocketCAN_bcm_frame from an unbound optional field.");
}
}

SocketCAN__bcm__frame_template::SocketCAN__bcm__frame_template(const SocketCAN__bcm__frame_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

SocketCAN__bcm__frame_template::~SocketCAN__bcm__frame_template()
{
clean_up();
}

SocketCAN__bcm__frame_template& SocketCAN__bcm__frame_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

SocketCAN__bcm__frame_template& SocketCAN__bcm__frame_template::operator=(const SocketCAN__bcm__frame& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

SocketCAN__bcm__frame_template& SocketCAN__bcm__frame_template::operator=(const OPTIONAL<SocketCAN__bcm__frame>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bcm__frame&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @Bcm.SocketCAN_bcm_frame.");
}
return *this;
}

SocketCAN__bcm__frame_template& SocketCAN__bcm__frame_template::operator=(const SocketCAN__bcm__frame_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean SocketCAN__bcm__frame_template::match(const SocketCAN__bcm__frame& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.opcode().is_bound()) return FALSE;
if(!single_value->field_opcode.match(other_value.opcode(), legacy))return FALSE;
if(!other_value.flags().is_bound()) return FALSE;
if(!single_value->field_flags.match(other_value.flags(), legacy))return FALSE;
if(!other_value.count().is_bound()) return FALSE;
if(!single_value->field_count.match(other_value.count(), legacy))return FALSE;
if(!other_value.ival1().is_bound()) return FALSE;
if(!single_value->field_ival1.match(other_value.ival1(), legacy))return FALSE;
if(!other_value.ival2().is_bound()) return FALSE;
if(!single_value->field_ival2.match(other_value.ival2(), legacy))return FALSE;
if(!other_value.can__id().is_bound()) return FALSE;
if(!single_value->field_can__id.match(other_value.can__id(), legacy))return FALSE;
if(!other_value.frames().is_bound()) return FALSE;
if(!single_value->field_frames.match(other_value.frames(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.");
}
return FALSE;
}

boolean SocketCAN__bcm__frame_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_opcode.is_bound()

 ||single_value->field_flags.is_bound()

 ||single_value->field_count.is_bound()

 ||single_value->field_ival1.is_bound()

 ||single_value->field_ival2.is_bound()

 ||single_value->field_can__id.is_bound()

 ||single_value->field_frames.is_bound()
;
}

boolean SocketCAN__bcm__frame_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_opcode.is_value()
 &&single_value->field_flags.is_value()
 &&single_value->field_count.is_value()
 &&single_value->field_ival1.is_value()
 &&single_value->field_ival2.is_value()
 &&single_value->field_can__id.is_value()
 &&single_value->field_frames.is_value();
}

void SocketCAN__bcm__frame_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

SocketCAN__bcm__frame SocketCAN__bcm__frame_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
SocketCAN__bcm__frame ret_val;
if (single_value->field_opcode.is_bound()) {
ret_val.opcode() = single_value->field_opcode.valueof();
}
if (single_value->field_flags.is_bound()) {
ret_val.flags() = single_value->field_flags.valueof();
}
if (single_value->field_count.is_bound()) {
ret_val.count() = single_value->field_count.valueof();
}
if (single_value->field_ival1.is_bound()) {
ret_val.ival1() = single_value->field_ival1.valueof();
}
if (single_value->field_ival2.is_bound()) {
ret_val.ival2() = single_value->field_ival2.valueof();
}
if (single_value->field_can__id.is_bound()) {
ret_val.can__id() = single_value->field_can__id.valueof();
}
if (single_value->field_frames.is_bound()) {
ret_val.frames() = single_value->field_frames.valueof();
}
return ret_val;
}

void SocketCAN__bcm__frame_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @Bcm.SocketCAN_bcm_frame.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bcm__frame_template[list_length];
}

SocketCAN__bcm__frame_template& SocketCAN__bcm__frame_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @Bcm.SocketCAN_bcm_frame.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @Bcm.SocketCAN_bcm_frame.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& SocketCAN__bcm__frame_template::opcode()
{
set_specific();
return single_value->field_opcode;
}

const OCTETSTRING_template& SocketCAN__bcm__frame_template::opcode() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field opcode of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_opcode;
}

BITSTRING_template& SocketCAN__bcm__frame_template::flags()
{
set_specific();
return single_value->field_flags;
}

const BITSTRING_template& SocketCAN__bcm__frame_template::flags() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field flags of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_flags;
}

INTEGER_template& SocketCAN__bcm__frame_template::count()
{
set_specific();
return single_value->field_count;
}

const INTEGER_template& SocketCAN__bcm__frame_template::count() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field count of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_count;
}

Bcm__timeval_template& SocketCAN__bcm__frame_template::ival1()
{
set_specific();
return single_value->field_ival1;
}

const Bcm__timeval_template& SocketCAN__bcm__frame_template::ival1() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ival1 of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_ival1;
}

Bcm__timeval_template& SocketCAN__bcm__frame_template::ival2()
{
set_specific();
return single_value->field_ival2;
}

const Bcm__timeval_template& SocketCAN__bcm__frame_template::ival2() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ival2 of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_ival2;
}

OCTETSTRING_template& SocketCAN__bcm__frame_template::can__id()
{
set_specific();
return single_value->field_can__id;
}

const OCTETSTRING_template& SocketCAN__bcm__frame_template::can__id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field can_id of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_can__id;
}

SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_template::frames()
{
set_specific();
return single_value->field_frames;
}

const SocketCAN__bcm__frame_frames_template& SocketCAN__bcm__frame_template::frames() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field frames of a non-specific template of type @Bcm.SocketCAN_bcm_frame.");
return single_value->field_frames;
}

int SocketCAN__bcm__frame_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 7;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @Bcm.SocketCAN_bcm_frame containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.");
  }
  return 0;
}

void SocketCAN__bcm__frame_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ opcode := ");
single_value->field_opcode.log();
TTCN_Logger::log_event_str(", flags := ");
single_value->field_flags.log();
TTCN_Logger::log_event_str(", count := ");
single_value->field_count.log();
TTCN_Logger::log_event_str(", ival1 := ");
single_value->field_ival1.log();
TTCN_Logger::log_event_str(", ival2 := ");
single_value->field_ival2.log();
TTCN_Logger::log_event_str(", can_id := ");
single_value->field_can__id.log();
TTCN_Logger::log_event_str(", frames := ");
single_value->field_frames.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void SocketCAN__bcm__frame_template::log_match(const SocketCAN__bcm__frame& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_opcode.match(match_value.opcode(), legacy)){
TTCN_Logger::log_logmatch_info(".opcode");
single_value->field_opcode.log_match(match_value.opcode(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_flags.match(match_value.flags(), legacy)){
TTCN_Logger::log_logmatch_info(".flags");
single_value->field_flags.log_match(match_value.flags(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_count.match(match_value.count(), legacy)){
TTCN_Logger::log_logmatch_info(".count");
single_value->field_count.log_match(match_value.count(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ival1.match(match_value.ival1(), legacy)){
TTCN_Logger::log_logmatch_info(".ival1");
single_value->field_ival1.log_match(match_value.ival1(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ival2.match(match_value.ival2(), legacy)){
TTCN_Logger::log_logmatch_info(".ival2");
single_value->field_ival2.log_match(match_value.ival2(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_can__id.match(match_value.can__id(), legacy)){
TTCN_Logger::log_logmatch_info(".can_id");
single_value->field_can__id.log_match(match_value.can__id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_frames.match(match_value.frames(), legacy)){
TTCN_Logger::log_logmatch_info(".frames");
single_value->field_frames.log_match(match_value.frames(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ opcode := ");
single_value->field_opcode.log_match(match_value.opcode(), legacy);
TTCN_Logger::log_event_str(", flags := ");
single_value->field_flags.log_match(match_value.flags(), legacy);
TTCN_Logger::log_event_str(", count := ");
single_value->field_count.log_match(match_value.count(), legacy);
TTCN_Logger::log_event_str(", ival1 := ");
single_value->field_ival1.log_match(match_value.ival1(), legacy);
TTCN_Logger::log_event_str(", ival2 := ");
single_value->field_ival2.log_match(match_value.ival2(), legacy);
TTCN_Logger::log_event_str(", can_id := ");
single_value->field_can__id.log_match(match_value.can__id(), legacy);
TTCN_Logger::log_event_str(", frames := ");
single_value->field_frames.log_match(match_value.frames(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void SocketCAN__bcm__frame_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_opcode.encode_text(text_buf);
single_value->field_flags.encode_text(text_buf);
single_value->field_count.encode_text(text_buf);
single_value->field_ival1.encode_text(text_buf);
single_value->field_ival2.encode_text(text_buf);
single_value->field_can__id.encode_text(text_buf);
single_value->field_frames.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @Bcm.SocketCAN_bcm_frame.");
}
}

void SocketCAN__bcm__frame_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_opcode.decode_text(text_buf);
single_value->field_flags.decode_text(text_buf);
single_value->field_count.decode_text(text_buf);
single_value->field_ival1.decode_text(text_buf);
single_value->field_ival2.decode_text(text_buf);
single_value->field_can__id.decode_text(text_buf);
single_value->field_frames.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new SocketCAN__bcm__frame_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @Bcm.SocketCAN_bcm_frame.");
}
}

void SocketCAN__bcm__frame_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    SocketCAN__bcm__frame_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (7<param.get_size()) {
      param.error("record template of type @Bcm.SocketCAN_bcm_frame has 7 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) opcode().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) flags().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) count().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) ival1().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ival2().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) can__id().set_param(*param.get_elem(5));
    if (param.get_size()>6 && param.get_elem(6)->get_type()!=Module_Param::MP_NotUsed) frames().set_param(*param.get_elem(6));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "opcode")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          opcode().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "flags")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          flags().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "count")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          count().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ival1")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ival1().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ival2")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ival2().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__id().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "frames")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frames().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @Bcm.SocketCAN_bcm_frame: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Bcm.SocketCAN_bcm_frame");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bcm__frame_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_opcode.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_flags.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_count.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_ival1.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_ival2.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_can__id.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
single_value->field_frames.check_restriction(t_res, t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@Bcm.SocketCAN_bcm_frame");
}

boolean SocketCAN__bcm__frame_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean SocketCAN__bcm__frame_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}


/* Bodies of functions, altsteps and testcases */

boolean operator==(null_type, const SocketCAN__bcm__frame_frames_can__frame& other_value)
{
if (other_value.val_ptr == NULL)
TTCN_error("The right operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.can_frame.");
return other_value.val_ptr->n_elements == 0;
}

boolean operator==(null_type, const SocketCAN__bcm__frame_frames_canfd__frame& other_value)
{
if (other_value.val_ptr == NULL)
TTCN_error("The right operand of comparison is an unbound value of type @Bcm.SocketCAN_bcm_frame.frames.canfd_frame.");
return other_value.val_ptr->n_elements == 0;
}


/* Bodies of static functions */

static void pre_init_module()
{
TTCN_Location current_location("../src/Bcm.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "Bcm");
Can::module_object.pre_init_module();
current_location.update_lineno(19);
#line 19 "../src/Bcm.ttcn"
const_CAN__FRAME__MAX__NUMBER = 256;
}

static void post_init_module()
{
TTCN_Location current_location("../src/Bcm.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "Bcm");
Can::module_object.post_init_module();
}


} /* end of namespace */
