// 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 "SocketCAN_Types.hh"

namespace SocketCAN__Types {

/* Prototypes of static functions */

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

/* Literal string constants */

static const unsigned char module_checksum[] = { 0x17, 0xa2, 0xfc, 0xbb, 0xb1, 0x49, 0x47, 0xfa, 0x84, 0xf5, 0x7a, 0x2b, 0x20, 0x15, 0x8e, 0x7d };

/* Global variable definitions */

const XERdescriptor_t       SocketCAN__socketid_xer_ = { {"SocketCAN_socketid>\n", "SocketCAN_socketid>\n"}, {20, 20}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__socketid_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__socketid_descr_ = { "@SocketCAN_Types.SocketCAN_socketid", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__socketid_xer_, &INTEGER_json_, &SocketCAN__socketid_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__if__name_xer_ = { {"SocketCAN_if_name>\n", "SocketCAN_if_name>\n"}, {19, 19}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_Typedescriptor_t SocketCAN__if__name_descr_ = { "@SocketCAN_Types.SocketCAN_if_name", NULL, &CHARSTRING_raw_, &CHARSTRING_text_, &SocketCAN__if__name_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__if__index_xer_ = { {"SocketCAN_if_index>\n", "SocketCAN_if_index>\n"}, {20, 20}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__if__index_descr_ = { "@SocketCAN_Types.SocketCAN_if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__if__index_xer_, &INTEGER_json_, &SocketCAN__if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__Isotp__PDU_xer_ = { {"SocketCAN_Isotp_PDU>\n", "SocketCAN_Isotp_PDU>\n"}, {21, 21}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__Isotp__PDU_oer_ext_arr_[0] = {};
const int SocketCAN__Isotp__PDU_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__Isotp__PDU_oer_ = { -1, TRUE, -1, FALSE, 0, 0, SocketCAN__Isotp__PDU_oer_ext_arr_, 0, SocketCAN__Isotp__PDU_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__Isotp__PDU_descr_ = { "@SocketCAN_Types.SocketCAN_Isotp_PDU", &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &SocketCAN__Isotp__PDU_xer_, &OCTETSTRING_json_, &SocketCAN__Isotp__PDU_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__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 SocketCAN__timeval_tv__sec_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__timeval_tv__sec_descr_ = { "@SocketCAN_Types.SocketCAN_timeval.tv_sec", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__timeval_tv__sec_xer_, &INTEGER_json_, &SocketCAN__timeval_tv__sec_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__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 SocketCAN__timeval_tv__usec_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__timeval_tv__usec_descr_ = { "@SocketCAN_Types.SocketCAN_timeval.tv_usec", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__timeval_tv__usec_xer_, &INTEGER_json_, &SocketCAN__timeval_tv__usec_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__timeval
const TTCN_Typedescriptor_t SocketCAN__timeval_descr_ = { "@SocketCAN_Types.SocketCAN_timeval", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__CAN__or__CAN__FD__frame
const TTCN_Typedescriptor_t SocketCAN__CAN__or__CAN__FD__frame_descr_ = { "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__ifr
const TTCN_Typedescriptor_t SocketCAN__ifr_descr_ = { "@SocketCAN_Types.SocketCAN_ifr", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__ifr_if__name_xer_ = { {"if_name>\n", "if_name>\n"}, {9, 9}, 0 |FORM_UNQUALIFIED |XER_OPTIONAL, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_Typedescriptor_t SocketCAN__ifr_if__name_descr_ = { "@SocketCAN_Types.SocketCAN_ifr.if_name", NULL, &CHARSTRING_raw_, &CHARSTRING_text_, &SocketCAN__ifr_if__name_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__ifr_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED |XER_OPTIONAL, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__ifr_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__ifr_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_ifr.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__ifr_if__index_xer_, &INTEGER_json_, &SocketCAN__ifr_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__if__any
const TTCN_Typedescriptor_t SocketCAN__if__any_descr_ = { "@SocketCAN_Types.SocketCAN_if_any", NULL, NULL, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__send__data__ifu
const TTCN_Typedescriptor_t SocketCAN__send__data__ifu_descr_ = { "@SocketCAN_Types.SocketCAN_send_data_ifu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__send__data__ifu_if__name_xer_ = { {"if_name>\n", "if_name>\n"}, {9, 9}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_Typedescriptor_t SocketCAN__send__data__ifu_if__name_descr_ = { "@SocketCAN_Types.SocketCAN_send_data_ifu.if_name", NULL, &CHARSTRING_raw_, &CHARSTRING_text_, &SocketCAN__send__data__ifu_if__name_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__send__data__ifu_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__send__data__ifu_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__send__data__ifu_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_send_data_ifu.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__send__data__ifu_if__index_xer_, &INTEGER_json_, &SocketCAN__send__data__ifu_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__ioctl__ifu
const TTCN_Typedescriptor_t SocketCAN__ioctl__ifu_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl_ifu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__ioctl__ifu_if__name_xer_ = { {"if_name>\n", "if_name>\n"}, {9, 9}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_Typedescriptor_t SocketCAN__ioctl__ifu_if__name_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl_ifu.if_name", NULL, &CHARSTRING_raw_, &CHARSTRING_text_, &SocketCAN__ioctl__ifu_if__name_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__ioctl__ifu_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__ioctl__ifu_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__ioctl__ifu_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl_ifu.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__ioctl__ifu_if__index_xer_, &INTEGER_json_, &SocketCAN__ioctl__ifu_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__Result__code
const TTCN_Typedescriptor_t SocketCAN__Result__code_descr_ = { "@SocketCAN_Types.SocketCAN_Result_code", NULL, NULL, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__Result
const TTCN_Typedescriptor_t SocketCAN__Result_descr_ = { "@SocketCAN_Types.SocketCAN_Result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__Result_err_xer_ = { {"err>\n", "err>\n"}, {5, 5}, 0 |FORM_UNQUALIFIED |XER_OPTIONAL, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__Result_err_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__Result_err_descr_ = { "@SocketCAN_Types.SocketCAN_Result.err", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__Result_err_xer_, &INTEGER_json_, &SocketCAN__Result_err_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__Result_err__text_xer_ = { {"err_text>\n", "err_text>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED |XER_OPTIONAL, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_Typedescriptor_t SocketCAN__Result_err__text_descr_ = { "@SocketCAN_Types.SocketCAN_Result.err_text", NULL, &CHARSTRING_raw_, &CHARSTRING_text_, &SocketCAN__Result_err__text_xer_, &CHARSTRING_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__socket
const TTCN_Typedescriptor_t SocketCAN__socket_descr_ = { "@SocketCAN_Types.SocketCAN_socket", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__socket__result_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__socket__result_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__socket__result_id_descr_ = { "@SocketCAN_Types.SocketCAN_socket_result.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__socket__result_id_xer_, &INTEGER_json_, &SocketCAN__socket__result_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__socket__result
const TTCN_Typedescriptor_t SocketCAN__socket__result_descr_ = { "@SocketCAN_Types.SocketCAN_socket_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__ioctl_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__ioctl_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__ioctl_id_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__ioctl_id_xer_, &INTEGER_json_, &SocketCAN__ioctl_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__ioctl
const TTCN_Typedescriptor_t SocketCAN__ioctl_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__ioctl__result
const TTCN_Typedescriptor_t SocketCAN__ioctl__result_descr_ = { "@SocketCAN_Types.SocketCAN_ioctl_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__connectu
const TTCN_Typedescriptor_t SocketCAN__connectu_descr_ = { "@SocketCAN_Types.SocketCAN_connectu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__connect__bcm_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__connect__bcm_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__connect__bcm_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_connect_bcm.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__connect__bcm_if__index_xer_, &INTEGER_json_, &SocketCAN__connect__bcm_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__connect__bcm
const TTCN_Typedescriptor_t SocketCAN__connect__bcm_descr_ = { "@SocketCAN_Types.SocketCAN_connect_bcm", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__connect_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__connect_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__connect_id_descr_ = { "@SocketCAN_Types.SocketCAN_connect.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__connect_id_xer_, &INTEGER_json_, &SocketCAN__connect_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__connect
const TTCN_Typedescriptor_t SocketCAN__connect_descr_ = { "@SocketCAN_Types.SocketCAN_connect", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__connect__result
const TTCN_Typedescriptor_t SocketCAN__connect__result_descr_ = { "@SocketCAN_Types.SocketCAN_connect_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bind__raw_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__bind__raw_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__bind__raw_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_bind_raw.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__bind__raw_if__index_xer_, &INTEGER_json_, &SocketCAN__bind__raw_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bind__raw
const TTCN_Typedescriptor_t SocketCAN__bind__raw_descr_ = { "@SocketCAN_Types.SocketCAN_bind_raw", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bind__isotp_if__index_xer_ = { {"if_index>\n", "if_index>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__bind__isotp_if__index_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__bind__isotp_if__index_descr_ = { "@SocketCAN_Types.SocketCAN_bind_isotp.if_index", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__bind__isotp_if__index_xer_, &INTEGER_json_, &SocketCAN__bind__isotp_if__index_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bind__isotp_rx__can__id_xer_ = { {"rx_can_id>\n", "rx_can_id>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__bind__isotp_rx__can__id_oer_ext_arr_[0] = {};
const int SocketCAN__bind__isotp_rx__can__id_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__bind__isotp_rx__can__id_oer_ = { -1, TRUE, 4, FALSE, 0, 0, SocketCAN__bind__isotp_rx__can__id_oer_ext_arr_, 0, SocketCAN__bind__isotp_rx__can__id_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__bind__isotp_rx__can__id_descr_ = { "@SocketCAN_Types.SocketCAN_bind_isotp.rx_can_id", &OCTETSTRING_ber_, &Can::CAN__id_raw_, &OCTETSTRING_text_, &SocketCAN__bind__isotp_rx__can__id_xer_, &OCTETSTRING_json_, &SocketCAN__bind__isotp_rx__can__id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bind__isotp_tx__can__id_xer_ = { {"tx_can_id>\n", "tx_can_id>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__bind__isotp_tx__can__id_oer_ext_arr_[0] = {};
const int SocketCAN__bind__isotp_tx__can__id_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__bind__isotp_tx__can__id_oer_ = { -1, TRUE, 4, FALSE, 0, 0, SocketCAN__bind__isotp_tx__can__id_oer_ext_arr_, 0, SocketCAN__bind__isotp_tx__can__id_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__bind__isotp_tx__can__id_descr_ = { "@SocketCAN_Types.SocketCAN_bind_isotp.tx_can_id", &OCTETSTRING_ber_, &Can::CAN__id_raw_, &OCTETSTRING_text_, &SocketCAN__bind__isotp_tx__can__id_xer_, &OCTETSTRING_json_, &SocketCAN__bind__isotp_tx__can__id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bind__isotp
const TTCN_Typedescriptor_t SocketCAN__bind__isotp_descr_ = { "@SocketCAN_Types.SocketCAN_bind_isotp", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bindu
const TTCN_Typedescriptor_t SocketCAN__bindu_descr_ = { "@SocketCAN_Types.SocketCAN_bindu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__bind_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__bind_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__bind_id_descr_ = { "@SocketCAN_Types.SocketCAN_bind.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__bind_id_xer_, &INTEGER_json_, &SocketCAN__bind_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bind
const TTCN_Typedescriptor_t SocketCAN__bind_descr_ = { "@SocketCAN_Types.SocketCAN_bind", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__bind__result
const TTCN_Typedescriptor_t SocketCAN__bind__result_descr_ = { "@SocketCAN_Types.SocketCAN_bind_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__send__data_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__send__data_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__send__data_id_descr_ = { "@SocketCAN_Types.SocketCAN_send_data.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__send__data_id_xer_, &INTEGER_json_, &SocketCAN__send__data_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__send__data
const TTCN_Typedescriptor_t SocketCAN__send__data_descr_ = { "@SocketCAN_Types.SocketCAN_send_data", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__send__data__result
const TTCN_Typedescriptor_t SocketCAN__send__data__result_descr_ = { "@SocketCAN_Types.SocketCAN_send_data_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__write__data_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__write__data_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__write__data_id_descr_ = { "@SocketCAN_Types.SocketCAN_write_data.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__write__data_id_xer_, &INTEGER_json_, &SocketCAN__write__data_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__write__data
const TTCN_Typedescriptor_t SocketCAN__write__data_descr_ = { "@SocketCAN_Types.SocketCAN_write_data", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__write__data__result
const TTCN_Typedescriptor_t SocketCAN__write__data__result_descr_ = { "@SocketCAN_Types.SocketCAN_write_data_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__write__isotp_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__write__isotp_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__write__isotp_id_descr_ = { "@SocketCAN_Types.SocketCAN_write_isotp.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__write__isotp_id_xer_, &INTEGER_json_, &SocketCAN__write__isotp_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__write__isotp_pdu_xer_ = { {"pdu>\n", "pdu>\n"}, {5, 5}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__write__isotp_pdu_oer_ext_arr_[0] = {};
const int SocketCAN__write__isotp_pdu_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__write__isotp_pdu_oer_ = { -1, TRUE, -1, FALSE, 0, 0, SocketCAN__write__isotp_pdu_oer_ext_arr_, 0, SocketCAN__write__isotp_pdu_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__write__isotp_pdu_descr_ = { "@SocketCAN_Types.SocketCAN_write_isotp.pdu", &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &SocketCAN__write__isotp_pdu_xer_, &OCTETSTRING_json_, &SocketCAN__write__isotp_pdu_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__write__isotp
const TTCN_Typedescriptor_t SocketCAN__write__isotp_descr_ = { "@SocketCAN_Types.SocketCAN_write_isotp", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__write__isotp__result
const TTCN_Typedescriptor_t SocketCAN__write__isotp__result_descr_ = { "@SocketCAN_Types.SocketCAN_write_isotp_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__receive__CAN__or__CAN__FD__frame_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__receive__CAN__or__CAN__FD__frame_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__receive__CAN__or__CAN__FD__frame_id_descr_ = { "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__receive__CAN__or__CAN__FD__frame_id_xer_, &INTEGER_json_, &SocketCAN__receive__CAN__or__CAN__FD__frame_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__receive__CAN__or__CAN__FD__frame
const TTCN_Typedescriptor_t SocketCAN__receive__CAN__or__CAN__FD__frame_descr_ = { "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__receive__BCM__message_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__receive__BCM__message_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__receive__BCM__message_id_descr_ = { "@SocketCAN_Types.SocketCAN_receive_BCM_message.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__receive__BCM__message_id_xer_, &INTEGER_json_, &SocketCAN__receive__BCM__message_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__receive__BCM__message
const TTCN_Typedescriptor_t SocketCAN__receive__BCM__message_descr_ = { "@SocketCAN_Types.SocketCAN_receive_BCM_message", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__receive__isotp__pdu_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__receive__isotp__pdu_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__receive__isotp__pdu_id_descr_ = { "@SocketCAN_Types.SocketCAN_receive_isotp_pdu.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__receive__isotp__pdu_id_xer_, &INTEGER_json_, &SocketCAN__receive__isotp__pdu_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__receive__isotp__pdu_pdu_xer_ = { {"pdu>\n", "pdu>\n"}, {5, 5}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int SocketCAN__receive__isotp__pdu_pdu_oer_ext_arr_[0] = {};
const int SocketCAN__receive__isotp__pdu_pdu_oer_p_[0] = {};
const TTCN_OERdescriptor_t SocketCAN__receive__isotp__pdu_pdu_oer_ = { -1, TRUE, -1, FALSE, 0, 0, SocketCAN__receive__isotp__pdu_pdu_oer_ext_arr_, 0, SocketCAN__receive__isotp__pdu_pdu_oer_p_};
const TTCN_Typedescriptor_t SocketCAN__receive__isotp__pdu_pdu_descr_ = { "@SocketCAN_Types.SocketCAN_receive_isotp_pdu.pdu", &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &SocketCAN__receive__isotp__pdu_pdu_xer_, &OCTETSTRING_json_, &SocketCAN__receive__isotp__pdu_pdu_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__receive__isotp__pdu
const TTCN_Typedescriptor_t SocketCAN__receive__isotp__pdu_descr_ = { "@SocketCAN_Types.SocketCAN_receive_isotp_pdu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for CAN__RAW__filters
const TTCN_Typedescriptor_t CAN__RAW__filters_descr_ = { "@SocketCAN_Types.CAN_RAW_filters", NULL, NULL, NULL, NULL, NULL, NULL, &Raw::CAN__RAW__filter_descr_, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__setsockopt__commandu
const TTCN_Typedescriptor_t SocketCAN__setsockopt__commandu_descr_ = { "@SocketCAN_Types.SocketCAN_setsockopt_commandu", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__setsockopt__commandu_err__mask_xer_ = { {"err_mask>\n", "err_mask>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__setsockopt__commandu_err__mask_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__setsockopt__commandu_err__mask_descr_ = { "@SocketCAN_Types.SocketCAN_setsockopt_commandu.err_mask", &BITSTRING_ber_, &Raw::CAN__RAW__err__mask_raw_, NULL, &SocketCAN__setsockopt__commandu_err__mask_xer_, &BITSTRING_json_, &SocketCAN__setsockopt__commandu_err__mask_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__setsockopt_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__setsockopt_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__setsockopt_id_descr_ = { "@SocketCAN_Types.SocketCAN_setsockopt.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__setsockopt_id_xer_, &INTEGER_json_, &SocketCAN__setsockopt_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__setsockopt
const TTCN_Typedescriptor_t SocketCAN__setsockopt_descr_ = { "@SocketCAN_Types.SocketCAN_setsockopt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__setsockopt__result
const TTCN_Typedescriptor_t SocketCAN__setsockopt__result_descr_ = { "@SocketCAN_Types.SocketCAN_setsockopt_result", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       SocketCAN__close_id_xer_ = { {"id>\n", "id>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SocketCAN__close_id_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SocketCAN__close_id_descr_ = { "@SocketCAN_Types.SocketCAN_close.id", &INTEGER_ber_, &INTEGER_raw_, &INTEGER_text_, &SocketCAN__close_id_xer_, &INTEGER_json_, &SocketCAN__close_id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
// No XER for SocketCAN__close
const TTCN_Typedescriptor_t SocketCAN__close_descr_ = { "@SocketCAN_Types.SocketCAN_close", NULL, NULL, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
TTCN_Module module_object("SocketCAN_Types", __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 */

SocketCAN__timeval::SocketCAN__timeval()
{
}

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

SocketCAN__timeval::SocketCAN__timeval(const SocketCAN__timeval& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_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 SocketCAN__timeval::clean_up()
{
field_tv__sec.clean_up();
field_tv__usec.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__timeval::get_descriptor() const { return &SocketCAN__timeval_descr_; }
SocketCAN__timeval& SocketCAN__timeval::operator=(const SocketCAN__timeval& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_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 SocketCAN__timeval::operator==(const SocketCAN__timeval& other_value) const
{
return field_tv__sec==other_value.field_tv__sec
  && field_tv__usec==other_value.field_tv__usec;
}

boolean SocketCAN__timeval::is_bound() const
{
return (field_tv__sec.is_bound())
  || (field_tv__usec.is_bound());
}
boolean SocketCAN__timeval::is_value() const
{
return field_tv__sec.is_value()
  && field_tv__usec.is_value();
}
void SocketCAN__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 SocketCAN__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 @SocketCAN_Types.SocketCAN_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 @SocketCAN_Types.SocketCAN_timeval: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_timeval");
  }
}

void SocketCAN__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 SocketCAN__timeval::encode_text(Text_Buf& text_buf) const
{
field_tv__sec.encode_text(text_buf);
field_tv__usec.encode_text(text_buf);
}

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

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

void SocketCAN__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 SocketCAN__timeval_template::copy_value(const SocketCAN__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 SocketCAN__timeval_template::copy_template(const SocketCAN__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 SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
break;
}
set_selection(other_value);
}

SocketCAN__timeval_template::SocketCAN__timeval_template()
{
}

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

SocketCAN__timeval_template::SocketCAN__timeval_template(const SocketCAN__timeval& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__timeval_template& SocketCAN__timeval_template::operator=(const OPTIONAL<SocketCAN__timeval>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
}
return *this;
}

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

boolean SocketCAN__timeval_template::match(const SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
}
return FALSE;
}

boolean SocketCAN__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 SocketCAN__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 SocketCAN__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;
}

SocketCAN__timeval SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
SocketCAN__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 SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__timeval_template[list_length];
}

SocketCAN__timeval_template& SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_timeval.");
return value_list.list_value[list_index];
}

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

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

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

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

int SocketCAN__timeval_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_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 @SocketCAN_Types.SocketCAN_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 @SocketCAN_Types.SocketCAN_timeval containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_timeval containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_timeval containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_timeval containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_timeval.");
  }
  return 0;
}

void SocketCAN__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 SocketCAN__timeval_template::log_match(const SocketCAN__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 SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
}
}

void SocketCAN__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 SocketCAN__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 @SocketCAN_Types.SocketCAN_timeval.");
}
}

void SocketCAN__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: {
    SocketCAN__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 @SocketCAN_Types.SocketCAN_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 @SocketCAN_Types.SocketCAN_timeval: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_timeval");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__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 : "@SocketCAN_Types.SocketCAN_timeval");
single_value->field_tv__usec.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_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 : "@SocketCAN_Types.SocketCAN_timeval");
}

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

boolean SocketCAN__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__CAN__or__CAN__FD__frame::copy_value(const SocketCAN__CAN__or__CAN__FD__frame& other_value)
{
switch (other_value.union_selection) {
case ALT_can__frame:
field_can__frame = new Can::CAN__frame(*other_value.field_can__frame);
break;
case ALT_canfd__frame:
field_canfd__frame = new Can::CANFD__frame(*other_value.field_canfd__frame);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__CAN__or__CAN__FD__frame::operator==(const SocketCAN__CAN__or__CAN__FD__frame& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
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;
}
}

Can::CAN__frame& SocketCAN__CAN__or__CAN__FD__frame::can__frame()
{
if (union_selection != ALT_can__frame) {
clean_up();
field_can__frame = new Can::CAN__frame;
union_selection = ALT_can__frame;
}
return *field_can__frame;
}

const Can::CAN__frame& SocketCAN__CAN__or__CAN__FD__frame::can__frame() const
{
if (union_selection != ALT_can__frame) TTCN_error("Using non-selected field can_frame in a value of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return *field_can__frame;
}

Can::CANFD__frame& SocketCAN__CAN__or__CAN__FD__frame::canfd__frame()
{
if (union_selection != ALT_canfd__frame) {
clean_up();
field_canfd__frame = new Can::CANFD__frame;
union_selection = ALT_canfd__frame;
}
return *field_canfd__frame;
}

const Can::CANFD__frame& SocketCAN__CAN__or__CAN__FD__frame::canfd__frame() const
{
if (union_selection != ALT_canfd__frame) TTCN_error("Using non-selected field canfd_frame in a value of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return *field_canfd__frame;
}

boolean SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.", last_name);
}

void SocketCAN__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}

void SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}

void SocketCAN__CAN__or__CAN__FD__frame_template::copy_value(const SocketCAN__CAN__or__CAN__FD__frame& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
single_value.field_can__frame = new Can::CAN__frame_template(other_value.can__frame());
break;
case SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame:
single_value.field_canfd__frame = new Can::CANFD__frame_template(other_value.canfd__frame());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__CAN__or__CAN__FD__frame_template::copy_template(const SocketCAN__CAN__or__CAN__FD__frame_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__CAN__or__CAN__FD__frame::ALT_can__frame:
single_value.field_can__frame = new Can::CAN__frame_template(*other_value.single_value.field_can__frame);
break;
case SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame:
single_value.field_canfd__frame = new Can::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
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__CAN__or__CAN__FD__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 template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
set_selection(other_value);
}

SocketCAN__CAN__or__CAN__FD__frame_template::SocketCAN__CAN__or__CAN__FD__frame_template()
{
}

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

SocketCAN__CAN__or__CAN__FD__frame_template::SocketCAN__CAN__or__CAN__FD__frame_template(const SocketCAN__CAN__or__CAN__FD__frame& other_value)
{
copy_value(other_value);
}

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

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

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

void SocketCAN__CAN__or__CAN__FD__frame_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
delete single_value.field_can__frame;
break;
case SocketCAN__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

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

SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::operator=(const OPTIONAL<SocketCAN__CAN__or__CAN__FD__frame>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__CAN__or__CAN__FD__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 union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
return *this;
}

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

boolean SocketCAN__CAN__or__CAN__FD__frame_template::match(const SocketCAN__CAN__or__CAN__FD__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:
{
SocketCAN__CAN__or__CAN__FD__frame::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__CAN__or__CAN__FD__frame::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
return single_value.field_can__frame->match(other_value.can__frame(), legacy);
case SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}
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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
return FALSE;
}

boolean SocketCAN__CAN__or__CAN__FD__frame_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
return single_value.field_can__frame->is_value();
case SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}

SocketCAN__CAN__or__CAN__FD__frame SocketCAN__CAN__or__CAN__FD__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 union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
SocketCAN__CAN__or__CAN__FD__frame ret_val;
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
ret_val.can__frame() = single_value.field_can__frame->valueof();
break;
case SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
return ret_val;
}

SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__CAN__or__CAN__FD__frame_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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return value_list.list_value[list_index];
}
void SocketCAN__CAN__or__CAN__FD__frame_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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__CAN__or__CAN__FD__frame_template[list_length];
}

Can::CAN__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::can__frame()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__CAN__or__CAN__FD__frame::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 Can::CAN__frame_template(ANY_VALUE);
else single_value.field_can__frame = new Can::CAN__frame_template;
single_value.union_selection = SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_can__frame;
}

const Can::CAN__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::can__frame() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field can_frame in a non-specific template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
if (single_value.union_selection != SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame) TTCN_error("Accessing non-selected field can_frame in a template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return *single_value.field_can__frame;
}

Can::CANFD__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::canfd__frame()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__CAN__or__CAN__FD__frame::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 Can::CANFD__frame_template(ANY_VALUE);
else single_value.field_canfd__frame = new Can::CANFD__frame_template;
single_value.union_selection = SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_canfd__frame;
}

const Can::CANFD__frame_template& SocketCAN__CAN__or__CAN__FD__frame_template::canfd__frame() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field canfd_frame in a non-specific template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
if (single_value.union_selection != SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame) TTCN_error("Accessing non-selected field canfd_frame in a template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
return *single_value.field_canfd__frame;
}

boolean SocketCAN__CAN__or__CAN__FD__frame_template::ischosen(SocketCAN__CAN__or__CAN__FD__frame::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__CAN__or__CAN__FD__frame::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__CAN__or__CAN__FD__frame::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame 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__CAN__or__CAN__FD__frame_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
TTCN_Logger::log_event_str("{ can_frame := ");
single_value.field_can__frame->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame_template::log_match(const SocketCAN__CAN__or__CAN__FD__frame& 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__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame::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__CAN__or__CAN__FD__frame_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__CAN__or__CAN__FD__frame::ALT_can__frame:
single_value.field_can__frame->encode_text(text_buf);
break;
case SocketCAN__CAN__or__CAN__FD__frame::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}

void SocketCAN__CAN__or__CAN__FD__frame_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__CAN__or__CAN__FD__frame::UNBOUND_VALUE;
SocketCAN__CAN__or__CAN__FD__frame::union_selection_type new_selection = (SocketCAN__CAN__or__CAN__FD__frame::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
single_value.field_can__frame = new Can::CAN__frame_template;
single_value.field_can__frame->decode_text(text_buf);
break;
case SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame:
single_value.field_canfd__frame = new Can::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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
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__CAN__or__CAN__FD__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: Unrecognized selector was received in a template of type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
}

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

boolean SocketCAN__CAN__or__CAN__FD__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 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__CAN__or__CAN__FD__frame_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 `@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame'");
    }
    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 `@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame'", 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__CAN__or__CAN__FD__frame_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", "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame");
    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 @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__CAN__or__CAN__FD__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;
switch (single_value.union_selection) {
case SocketCAN__CAN__or__CAN__FD__frame::ALT_can__frame:
single_value.field_can__frame->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame");
return;
case SocketCAN__CAN__or__CAN__FD__frame::ALT_canfd__frame:
single_value.field_canfd__frame->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame.");
}
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 : "@SocketCAN_Types.SocketCAN_CAN_or_CAN_FD_frame");
}

SocketCAN__ifr::SocketCAN__ifr()
{
}

SocketCAN__ifr::SocketCAN__ifr(const OPTIONAL<CHARSTRING>& par_if__name,
    const OPTIONAL<INTEGER>& par_if__index)
  :   field_if__name(par_if__name),
  field_if__index(par_if__index)
{
}

SocketCAN__ifr::SocketCAN__ifr(const SocketCAN__ifr& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_ifr.");
if (other_value.if__name().is_bound()) field_if__name = other_value.if__name();
else field_if__name.clean_up();
if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
else field_if__index.clean_up();
}

void SocketCAN__ifr::clean_up()
{
field_if__name.clean_up();
field_if__index.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__ifr::get_descriptor() const { return &SocketCAN__ifr_descr_; }
SocketCAN__ifr& SocketCAN__ifr::operator=(const SocketCAN__ifr& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_ifr.");
  if (other_value.if__name().is_bound()) field_if__name = other_value.if__name();
  else field_if__name.clean_up();
  if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
  else field_if__index.clean_up();
}
return *this;
}

boolean SocketCAN__ifr::operator==(const SocketCAN__ifr& other_value) const
{
return field_if__name==other_value.field_if__name
  && field_if__index==other_value.field_if__index;
}

boolean SocketCAN__ifr::is_bound() const
{
return (OPTIONAL_OMIT == field_if__name.get_selection() || field_if__name.is_bound())
  || (OPTIONAL_OMIT == field_if__index.get_selection() || field_if__index.is_bound());
}
boolean SocketCAN__ifr::is_value() const
{
return (OPTIONAL_OMIT == field_if__name.get_selection() || field_if__name.is_value())
  && (OPTIONAL_OMIT == field_if__index.get_selection() || field_if__index.is_value());
}
int SocketCAN__ifr::size_of() const
{
  int ret_val = 0;
  if (field_if__name.ispresent()) ret_val++;
  if (field_if__index.ispresent()) ret_val++;
  return ret_val;
}

void SocketCAN__ifr::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ if_name := ");
field_if__name.log();
TTCN_Logger::log_event_str(", if_index := ");
field_if__index.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__ifr::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 @SocketCAN_Types.SocketCAN_ifr 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) if__name().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) if__index().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(), "if_name")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__name().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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_ifr: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_ifr");
  }
}

void SocketCAN__ifr::set_implicit_omit()
{
if (!if__name().is_bound()) if__name() = OMIT_VALUE;
else if__name().set_implicit_omit();
if (!if__index().is_bound()) if__index() = OMIT_VALUE;
else if__index().set_implicit_omit();
}

void SocketCAN__ifr::encode_text(Text_Buf& text_buf) const
{
field_if__name.encode_text(text_buf);
field_if__index.encode_text(text_buf);
}

void SocketCAN__ifr::decode_text(Text_Buf& text_buf)
{
field_if__name.decode_text(text_buf);
field_if__index.decode_text(text_buf);
}

struct SocketCAN__ifr_template::single_value_struct {
CHARSTRING_template field_if__name;
INTEGER_template field_if__index;
};

void SocketCAN__ifr_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_if__name = ANY_OR_OMIT;
single_value->field_if__index = ANY_OR_OMIT;
}
}
}

void SocketCAN__ifr_template::copy_value(const SocketCAN__ifr& other_value)
{
single_value = new single_value_struct;
if (other_value.if__name().is_bound()) {
  if (other_value.if__name().ispresent()) single_value->field_if__name = other_value.if__name()();
  else single_value->field_if__name = OMIT_VALUE;
} else {
  single_value->field_if__name.clean_up();
}
if (other_value.if__index().is_bound()) {
  if (other_value.if__index().ispresent()) single_value->field_if__index = other_value.if__index()();
  else single_value->field_if__index = OMIT_VALUE;
} else {
  single_value->field_if__index.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__ifr_template::copy_template(const SocketCAN__ifr_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.if__name().get_selection()) {
single_value->field_if__name = other_value.if__name();
} else {
single_value->field_if__name.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.if__index().get_selection()) {
single_value->field_if__index = other_value.if__index();
} else {
single_value->field_if__index.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__ifr_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 @SocketCAN_Types.SocketCAN_ifr.");
break;
}
set_selection(other_value);
}

SocketCAN__ifr_template::SocketCAN__ifr_template()
{
}

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

SocketCAN__ifr_template::SocketCAN__ifr_template(const SocketCAN__ifr& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__ifr_template& SocketCAN__ifr_template::operator=(const OPTIONAL<SocketCAN__ifr>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__ifr&)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 @SocketCAN_Types.SocketCAN_ifr.");
}
return *this;
}

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

boolean SocketCAN__ifr_template::match(const SocketCAN__ifr& 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.if__name().is_bound()) return FALSE;
if((other_value.if__name().ispresent() ? !single_value->field_if__name.match((const CHARSTRING&)other_value.if__name(), legacy) : !single_value->field_if__name.match_omit(legacy)))return FALSE;
if(!other_value.if__index().is_bound()) return FALSE;
if((other_value.if__index().ispresent() ? !single_value->field_if__index.match((const INTEGER&)other_value.if__index(), legacy) : !single_value->field_if__index.match_omit(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 @SocketCAN_Types.SocketCAN_ifr.");
}
return FALSE;
}

boolean SocketCAN__ifr_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return (single_value->field_if__name.is_omit() || single_value->field_if__name.is_bound())

 ||(single_value->field_if__index.is_omit() || single_value->field_if__index.is_bound())
;
}

boolean SocketCAN__ifr_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return (single_value->field_if__name.is_omit() || single_value->field_if__name.is_value())
 &&(single_value->field_if__index.is_omit() || single_value->field_if__index.is_value());
}

void SocketCAN__ifr_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__ifr SocketCAN__ifr_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 @SocketCAN_Types.SocketCAN_ifr.");
SocketCAN__ifr ret_val;
if (single_value->field_if__name.is_omit()) ret_val.if__name() = OMIT_VALUE;
else if (single_value->field_if__name.is_bound()) {
ret_val.if__name() = single_value->field_if__name.valueof();
}
if (single_value->field_if__index.is_omit()) ret_val.if__index() = OMIT_VALUE;
else if (single_value->field_if__index.is_bound()) {
ret_val.if__index() = single_value->field_if__index.valueof();
}
return ret_val;
}

void SocketCAN__ifr_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 @SocketCAN_Types.SocketCAN_ifr.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__ifr_template[list_length];
}

SocketCAN__ifr_template& SocketCAN__ifr_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 @SocketCAN_Types.SocketCAN_ifr.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_ifr.");
return value_list.list_value[list_index];
}

CHARSTRING_template& SocketCAN__ifr_template::if__name()
{
set_specific();
return single_value->field_if__name;
}

const CHARSTRING_template& SocketCAN__ifr_template::if__name() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field if_name of a non-specific template of type @SocketCAN_Types.SocketCAN_ifr.");
return single_value->field_if__name;
}

INTEGER_template& SocketCAN__ifr_template::if__index()
{
set_specific();
return single_value->field_if__index;
}

const INTEGER_template& SocketCAN__ifr_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field if_index of a non-specific template of type @SocketCAN_Types.SocketCAN_ifr.");
return single_value->field_if__index;
}

int SocketCAN__ifr_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ifr which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
  {    int ret_val = 0;
      if (single_value->field_if__name.is_present()) ret_val++;
      if (single_value->field_if__index.is_present()) ret_val++;
      return ret_val;
    }
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ifr 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 @SocketCAN_Types.SocketCAN_ifr containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ifr containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ifr containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ifr containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_ifr.");
  }
  return 0;
}

void SocketCAN__ifr_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ if_name := ");
single_value->field_if__name.log();
TTCN_Logger::log_event_str(", if_index := ");
single_value->field_if__index.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__ifr_template::log_match(const SocketCAN__ifr& 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 (match_value.if__name().ispresent()){
if(!single_value->field_if__name.match(match_value.if__name(), legacy)){
TTCN_Logger::log_logmatch_info(".if_name");
single_value->field_if__name.log_match(match_value.if__name(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_if__name.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".if_name := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_if__name.log();
TTCN_Logger::log_event_str(" unmatched");
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}
if (match_value.if__index().ispresent()){
if(!single_value->field_if__index.match(match_value.if__index(), legacy)){
TTCN_Logger::log_logmatch_info(".if_index");
single_value->field_if__index.log_match(match_value.if__index(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_if__index.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".if_index := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_if__index.log();
TTCN_Logger::log_event_str(" unmatched");
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("{ if_name := ");
if (match_value.if__name().ispresent()) single_value->field_if__name.log_match(match_value.if__name(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_if__name.log();
if (single_value->field_if__name.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
TTCN_Logger::log_event_str(", if_index := ");
if (match_value.if__index().ispresent()) single_value->field_if__index.log_match(match_value.if__index(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_if__index.log();
if (single_value->field_if__index.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
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__ifr_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_if__name.encode_text(text_buf);
single_value->field_if__index.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 @SocketCAN_Types.SocketCAN_ifr.");
}
}

void SocketCAN__ifr_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_if__name.decode_text(text_buf);
single_value->field_if__index.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__ifr_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 @SocketCAN_Types.SocketCAN_ifr.");
}
}

void SocketCAN__ifr_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__ifr_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 @SocketCAN_Types.SocketCAN_ifr 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) if__name().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) if__index().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(), "if_name")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__name().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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_ifr: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_ifr");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__ifr_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_if__name.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ifr");
single_value->field_if__index.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ifr");
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 : "@SocketCAN_Types.SocketCAN_ifr");
}

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

boolean SocketCAN__ifr_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;
}

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

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

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

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

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

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

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

boolean SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.");
return enum_value == other_value;
}

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

boolean SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.");
return enum_value < other_value;
}

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

boolean SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.");
return enum_value > other_value;
}

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

const char *SocketCAN__if__any::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case ANY__INTERFACE: return "ANY_INTERFACE";
default: return "<unknown>";
}
}

SocketCAN__if__any::enum_type SocketCAN__if__any::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "ANY_INTERFACE")) return ANY__INTERFACE;
else return UNKNOWN_VALUE;
}

boolean SocketCAN__if__any::is_valid_enum(int int_par)
{
switch (int_par) {
case 0:
return TRUE;
default:
return FALSE;
}
}

int SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int SocketCAN__if__any::enum2int(const SocketCAN__if__any& 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 @SocketCAN_Types.SocketCAN_if_any.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

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

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

void SocketCAN__if__any::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 SocketCAN__if__any::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", "@SocketCAN_Types.SocketCAN_if_any");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @SocketCAN_Types.SocketCAN_if_any.");
  }
}

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

void SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.", enum_value);
}

void SocketCAN__if__any_template::copy_template(const SocketCAN__if__any_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 SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
}
}

SocketCAN__if__any_template::SocketCAN__if__any_template()
{
}

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

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

SocketCAN__if__any_template::SocketCAN__if__any_template(SocketCAN__if__any::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

SocketCAN__if__any_template::SocketCAN__if__any_template(const SocketCAN__if__any& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == SocketCAN__if__any::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @SocketCAN_Types.SocketCAN_if_any.");
single_value = other_value.enum_value;
}

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

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

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

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

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

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

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

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

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

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

SocketCAN__if__any_template& SocketCAN__if__any_template::operator=(const OPTIONAL<SocketCAN__if__any>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (SocketCAN__if__any::enum_type)(const SocketCAN__if__any&)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 @SocketCAN_Types.SocketCAN_if_any.");
}
return *this;
}

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

boolean SocketCAN__if__any_template::match(SocketCAN__if__any::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 @SocketCAN_Types.SocketCAN_if_any.");
}
return FALSE;
}

boolean SocketCAN__if__any_template::match(const SocketCAN__if__any& other_value, boolean) const
{
if (other_value.enum_value == SocketCAN__if__any::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @SocketCAN_Types.SocketCAN_if_any with an unbound value.");
return match(other_value.enum_value);
}

SocketCAN__if__any::enum_type SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
return single_value;
}

void SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__if__any_template[list_length];
}

SocketCAN__if__any_template& SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @SocketCAN_Types.SocketCAN_if_any.");
return value_list.list_value[list_index];
}

void SocketCAN__if__any_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(SocketCAN__if__any::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 SocketCAN__if__any_template::log_match(const SocketCAN__if__any& 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 SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
}
}

void SocketCAN__if__any_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (SocketCAN__if__any::enum_type)text_buf.pull_int().get_val();
if (!SocketCAN__if__any::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @SocketCAN_Types.SocketCAN_if_any.", 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 SocketCAN__if__any_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 @SocketCAN_Types.SocketCAN_if_any.");
}
}

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

boolean SocketCAN__if__any_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__if__any_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: {
    SocketCAN__if__any_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: {
    SocketCAN__if__any::enum_type enum_val = SocketCAN__if__any::str_to_enum(m_p->get_enumerated());
    if (!SocketCAN__if__any::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @SocketCAN_Types.SocketCAN_if_any.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@SocketCAN_Types.SocketCAN_if_any");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__if__any_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 : "@SocketCAN_Types.SocketCAN_if_any");
}

void SocketCAN__send__data__ifu::copy_value(const SocketCAN__send__data__ifu& other_value)
{
switch (other_value.union_selection) {
case ALT_if__name:
field_if__name = new CHARSTRING(*other_value.field_if__name);
break;
case ALT_if__index:
field_if__index = new INTEGER(*other_value.field_if__index);
break;
case ALT_if__any:
field_if__any = new SocketCAN__if__any(*other_value.field_if__any);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__send__data__ifu::operator==(const SocketCAN__send__data__ifu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_if__name:
return *field_if__name == *other_value.field_if__name;
case ALT_if__index:
return *field_if__index == *other_value.field_if__index;
case ALT_if__any:
return *field_if__any == *other_value.field_if__any;
default:
return FALSE;
}
}

CHARSTRING& SocketCAN__send__data__ifu::if__name()
{
if (union_selection != ALT_if__name) {
clean_up();
field_if__name = new CHARSTRING;
union_selection = ALT_if__name;
}
return *field_if__name;
}

const CHARSTRING& SocketCAN__send__data__ifu::if__name() const
{
if (union_selection != ALT_if__name) TTCN_error("Using non-selected field if_name in a value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *field_if__name;
}

INTEGER& SocketCAN__send__data__ifu::if__index()
{
if (union_selection != ALT_if__index) {
clean_up();
field_if__index = new INTEGER;
union_selection = ALT_if__index;
}
return *field_if__index;
}

const INTEGER& SocketCAN__send__data__ifu::if__index() const
{
if (union_selection != ALT_if__index) TTCN_error("Using non-selected field if_index in a value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *field_if__index;
}

SocketCAN__if__any& SocketCAN__send__data__ifu::if__any()
{
if (union_selection != ALT_if__any) {
clean_up();
field_if__any = new SocketCAN__if__any;
union_selection = ALT_if__any;
}
return *field_if__any;
}

const SocketCAN__if__any& SocketCAN__send__data__ifu::if__any() const
{
if (union_selection != ALT_if__any) TTCN_error("Using non-selected field if_any in a value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *field_if__any;
}

boolean SocketCAN__send__data__ifu::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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__send__data__ifu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_if__name: return field_if__name->is_value();
case ALT_if__index: return field_if__index->is_value();
case ALT_if__any: return field_if__any->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__send__data__ifu::clean_up()
{
switch (union_selection) {
case ALT_if__name:
  delete field_if__name;
  break;
case ALT_if__index:
  delete field_if__index;
  break;
case ALT_if__any:
  delete field_if__any;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__send__data__ifu::log() const
{
switch (union_selection) {
case ALT_if__name:
TTCN_Logger::log_event_str("{ if_name := ");
field_if__name->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_if__index:
TTCN_Logger::log_event_str("{ if_index := ");
field_if__index->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_if__any:
TTCN_Logger::log_event_str("{ if_any := ");
field_if__any->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__send__data__ifu::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, "if_name")) {
    if__name().set_param(*mp_last);
    if (!if__name().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "if_index")) {
    if__index().set_param(*mp_last);
    if (!if__index().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "if_any")) {
    if__any().set_param(*mp_last);
    if (!if__any().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_send_data_ifu.", last_name);
}

void SocketCAN__send__data__ifu::set_implicit_omit()
{
switch (union_selection) {
case ALT_if__name:
field_if__name->set_implicit_omit(); break;
case ALT_if__index:
field_if__index->set_implicit_omit(); break;
case ALT_if__any:
field_if__any->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__send__data__ifu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_if__name:
field_if__name->encode_text(text_buf);
break;
case ALT_if__index:
field_if__index->encode_text(text_buf);
break;
case ALT_if__any:
field_if__any->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}

void SocketCAN__send__data__ifu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_if__name:
if__name().decode_text(text_buf);
break;
case ALT_if__index:
if__index().decode_text(text_buf);
break;
case ALT_if__any:
if__any().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}

void SocketCAN__send__data__ifu_template::copy_value(const SocketCAN__send__data__ifu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template(other_value.if__name());
break;
case SocketCAN__send__data__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template(other_value.if__index());
break;
case SocketCAN__send__data__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template(other_value.if__any());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__send__data__ifu_template::copy_template(const SocketCAN__send__data__ifu_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__send__data__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template(*other_value.single_value.field_if__name);
break;
case SocketCAN__send__data__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template(*other_value.single_value.field_if__index);
break;
case SocketCAN__send__data__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template(*other_value.single_value.field_if__any);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
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__send__data__ifu_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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
set_selection(other_value);
}

SocketCAN__send__data__ifu_template::SocketCAN__send__data__ifu_template()
{
}

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

SocketCAN__send__data__ifu_template::SocketCAN__send__data__ifu_template(const SocketCAN__send__data__ifu& other_value)
{
copy_value(other_value);
}

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

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

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

void SocketCAN__send__data__ifu_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
delete single_value.field_if__name;
break;
case SocketCAN__send__data__ifu::ALT_if__index:
delete single_value.field_if__index;
break;
case SocketCAN__send__data__ifu::ALT_if__any:
delete single_value.field_if__any;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

SocketCAN__send__data__ifu_template& SocketCAN__send__data__ifu_template::operator=(const OPTIONAL<SocketCAN__send__data__ifu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__send__data__ifu&)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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
return *this;
}

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

boolean SocketCAN__send__data__ifu_template::match(const SocketCAN__send__data__ifu& 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__send__data__ifu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__send__data__ifu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
return single_value.field_if__name->match(other_value.if__name(), legacy);
case SocketCAN__send__data__ifu::ALT_if__index:
return single_value.field_if__index->match(other_value.if__index(), legacy);
case SocketCAN__send__data__ifu::ALT_if__any:
return single_value.field_if__any->match(other_value.if__any(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}
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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
return FALSE;
}

boolean SocketCAN__send__data__ifu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
return single_value.field_if__name->is_value();
case SocketCAN__send__data__ifu::ALT_if__index:
return single_value.field_if__index->is_value();
case SocketCAN__send__data__ifu::ALT_if__any:
return single_value.field_if__any->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}

SocketCAN__send__data__ifu SocketCAN__send__data__ifu_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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
SocketCAN__send__data__ifu ret_val;
switch (single_value.union_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
ret_val.if__name() = single_value.field_if__name->valueof();
break;
case SocketCAN__send__data__ifu::ALT_if__index:
ret_val.if__index() = single_value.field_if__index->valueof();
break;
case SocketCAN__send__data__ifu::ALT_if__any:
ret_val.if__any() = single_value.field_if__any->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
return ret_val;
}

SocketCAN__send__data__ifu_template& SocketCAN__send__data__ifu_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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return value_list.list_value[list_index];
}
void SocketCAN__send__data__ifu_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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__send__data__ifu_template[list_length];
}

CHARSTRING_template& SocketCAN__send__data__ifu_template::if__name()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__name) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__name = new CHARSTRING_template(ANY_VALUE);
else single_value.field_if__name = new CHARSTRING_template;
single_value.union_selection = SocketCAN__send__data__ifu::ALT_if__name;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__name;
}

const CHARSTRING_template& SocketCAN__send__data__ifu_template::if__name() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_name in a non-specific template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__name) TTCN_error("Accessing non-selected field if_name in a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *single_value.field_if__name;
}

INTEGER_template& SocketCAN__send__data__ifu_template::if__index()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__index) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__index = new INTEGER_template(ANY_VALUE);
else single_value.field_if__index = new INTEGER_template;
single_value.union_selection = SocketCAN__send__data__ifu::ALT_if__index;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__index;
}

const INTEGER_template& SocketCAN__send__data__ifu_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_index in a non-specific template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__index) TTCN_error("Accessing non-selected field if_index in a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *single_value.field_if__index;
}

SocketCAN__if__any_template& SocketCAN__send__data__ifu_template::if__any()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__any) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__any = new SocketCAN__if__any_template(ANY_VALUE);
else single_value.field_if__any = new SocketCAN__if__any_template;
single_value.union_selection = SocketCAN__send__data__ifu::ALT_if__any;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__any;
}

const SocketCAN__if__any_template& SocketCAN__send__data__ifu_template::if__any() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_any in a non-specific template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
if (single_value.union_selection != SocketCAN__send__data__ifu::ALT_if__any) TTCN_error("Accessing non-selected field if_any in a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
return *single_value.field_if__any;
}

boolean SocketCAN__send__data__ifu_template::ischosen(SocketCAN__send__data__ifu::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__send__data__ifu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__send__data__ifu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
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 @SocketCAN_Types.SocketCAN_send_data_ifu 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__send__data__ifu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
TTCN_Logger::log_event_str("{ if_name := ");
single_value.field_if__name->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__send__data__ifu::ALT_if__index:
TTCN_Logger::log_event_str("{ if_index := ");
single_value.field_if__index->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__send__data__ifu::ALT_if__any:
TTCN_Logger::log_event_str("{ if_any := ");
single_value.field_if__any->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__send__data__ifu_template::log_match(const SocketCAN__send__data__ifu& 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__send__data__ifu::ALT_if__name:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_name");
single_value.field_if__name->log_match(match_value.if__name(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_name := ");
single_value.field_if__name->log_match(match_value.if__name(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__send__data__ifu::ALT_if__index:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_index");
single_value.field_if__index->log_match(match_value.if__index(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_index := ");
single_value.field_if__index->log_match(match_value.if__index(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__send__data__ifu::ALT_if__any:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_any");
single_value.field_if__any->log_match(match_value.if__any(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_any := ");
single_value.field_if__any->log_match(match_value.if__any(), 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__send__data__ifu_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__send__data__ifu::ALT_if__name:
single_value.field_if__name->encode_text(text_buf);
break;
case SocketCAN__send__data__ifu::ALT_if__index:
single_value.field_if__index->encode_text(text_buf);
break;
case SocketCAN__send__data__ifu::ALT_if__any:
single_value.field_if__any->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}

void SocketCAN__send__data__ifu_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__send__data__ifu::UNBOUND_VALUE;
SocketCAN__send__data__ifu::union_selection_type new_selection = (SocketCAN__send__data__ifu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__send__data__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template;
single_value.field_if__name->decode_text(text_buf);
break;
case SocketCAN__send__data__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template;
single_value.field_if__index->decode_text(text_buf);
break;
case SocketCAN__send__data__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template;
single_value.field_if__any->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
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__send__data__ifu_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 @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
}

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

boolean SocketCAN__send__data__ifu_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__send__data__ifu_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 `@SocketCAN_Types.SocketCAN_send_data_ifu'");
    }
    if (strcmp("if_name", param_field) == 0) {
      if__name().set_param(param);
      return;
    } else if (strcmp("if_index", param_field) == 0) {
      if__index().set_param(param);
      return;
    } else if (strcmp("if_any", param_field) == 0) {
      if__any().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@SocketCAN_Types.SocketCAN_send_data_ifu'", 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__send__data__ifu_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", "@SocketCAN_Types.SocketCAN_send_data_ifu");
    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, "if_name")) {
      if__name().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "if_index")) {
      if__index().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "if_any")) {
      if__any().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_send_data_ifu.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_send_data_ifu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__send__data__ifu_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__send__data__ifu::ALT_if__name:
single_value.field_if__name->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data_ifu");
return;
case SocketCAN__send__data__ifu::ALT_if__index:
single_value.field_if__index->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data_ifu");
return;
case SocketCAN__send__data__ifu::ALT_if__any:
single_value.field_if__any->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data_ifu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_send_data_ifu.");
}
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 : "@SocketCAN_Types.SocketCAN_send_data_ifu");
}

void SocketCAN__ioctl__ifu::copy_value(const SocketCAN__ioctl__ifu& other_value)
{
switch (other_value.union_selection) {
case ALT_if__name:
field_if__name = new CHARSTRING(*other_value.field_if__name);
break;
case ALT_if__index:
field_if__index = new INTEGER(*other_value.field_if__index);
break;
case ALT_if__any:
field_if__any = new SocketCAN__if__any(*other_value.field_if__any);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__ioctl__ifu::operator==(const SocketCAN__ioctl__ifu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_if__name:
return *field_if__name == *other_value.field_if__name;
case ALT_if__index:
return *field_if__index == *other_value.field_if__index;
case ALT_if__any:
return *field_if__any == *other_value.field_if__any;
default:
return FALSE;
}
}

CHARSTRING& SocketCAN__ioctl__ifu::if__name()
{
if (union_selection != ALT_if__name) {
clean_up();
field_if__name = new CHARSTRING;
union_selection = ALT_if__name;
}
return *field_if__name;
}

const CHARSTRING& SocketCAN__ioctl__ifu::if__name() const
{
if (union_selection != ALT_if__name) TTCN_error("Using non-selected field if_name in a value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *field_if__name;
}

INTEGER& SocketCAN__ioctl__ifu::if__index()
{
if (union_selection != ALT_if__index) {
clean_up();
field_if__index = new INTEGER;
union_selection = ALT_if__index;
}
return *field_if__index;
}

const INTEGER& SocketCAN__ioctl__ifu::if__index() const
{
if (union_selection != ALT_if__index) TTCN_error("Using non-selected field if_index in a value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *field_if__index;
}

SocketCAN__if__any& SocketCAN__ioctl__ifu::if__any()
{
if (union_selection != ALT_if__any) {
clean_up();
field_if__any = new SocketCAN__if__any;
union_selection = ALT_if__any;
}
return *field_if__any;
}

const SocketCAN__if__any& SocketCAN__ioctl__ifu::if__any() const
{
if (union_selection != ALT_if__any) TTCN_error("Using non-selected field if_any in a value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *field_if__any;
}

boolean SocketCAN__ioctl__ifu::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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__ioctl__ifu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_if__name: return field_if__name->is_value();
case ALT_if__index: return field_if__index->is_value();
case ALT_if__any: return field_if__any->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__ioctl__ifu::clean_up()
{
switch (union_selection) {
case ALT_if__name:
  delete field_if__name;
  break;
case ALT_if__index:
  delete field_if__index;
  break;
case ALT_if__any:
  delete field_if__any;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__ioctl__ifu::log() const
{
switch (union_selection) {
case ALT_if__name:
TTCN_Logger::log_event_str("{ if_name := ");
field_if__name->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_if__index:
TTCN_Logger::log_event_str("{ if_index := ");
field_if__index->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_if__any:
TTCN_Logger::log_event_str("{ if_any := ");
field_if__any->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__ioctl__ifu::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, "if_name")) {
    if__name().set_param(*mp_last);
    if (!if__name().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "if_index")) {
    if__index().set_param(*mp_last);
    if (!if__index().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "if_any")) {
    if__any().set_param(*mp_last);
    if (!if__any().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_ioctl_ifu.", last_name);
}

void SocketCAN__ioctl__ifu::set_implicit_omit()
{
switch (union_selection) {
case ALT_if__name:
field_if__name->set_implicit_omit(); break;
case ALT_if__index:
field_if__index->set_implicit_omit(); break;
case ALT_if__any:
field_if__any->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__ioctl__ifu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_if__name:
field_if__name->encode_text(text_buf);
break;
case ALT_if__index:
field_if__index->encode_text(text_buf);
break;
case ALT_if__any:
field_if__any->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}

void SocketCAN__ioctl__ifu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_if__name:
if__name().decode_text(text_buf);
break;
case ALT_if__index:
if__index().decode_text(text_buf);
break;
case ALT_if__any:
if__any().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}

void SocketCAN__ioctl__ifu_template::copy_value(const SocketCAN__ioctl__ifu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template(other_value.if__name());
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template(other_value.if__index());
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template(other_value.if__any());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__ioctl__ifu_template::copy_template(const SocketCAN__ioctl__ifu_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__ioctl__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template(*other_value.single_value.field_if__name);
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template(*other_value.single_value.field_if__index);
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template(*other_value.single_value.field_if__any);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
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__ioctl__ifu_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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
set_selection(other_value);
}

SocketCAN__ioctl__ifu_template::SocketCAN__ioctl__ifu_template()
{
}

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

SocketCAN__ioctl__ifu_template::SocketCAN__ioctl__ifu_template(const SocketCAN__ioctl__ifu& other_value)
{
copy_value(other_value);
}

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

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

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

void SocketCAN__ioctl__ifu_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
delete single_value.field_if__name;
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
delete single_value.field_if__index;
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
delete single_value.field_if__any;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

SocketCAN__ioctl__ifu_template& SocketCAN__ioctl__ifu_template::operator=(const OPTIONAL<SocketCAN__ioctl__ifu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__ioctl__ifu&)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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
return *this;
}

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

boolean SocketCAN__ioctl__ifu_template::match(const SocketCAN__ioctl__ifu& 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__ioctl__ifu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__ioctl__ifu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
return single_value.field_if__name->match(other_value.if__name(), legacy);
case SocketCAN__ioctl__ifu::ALT_if__index:
return single_value.field_if__index->match(other_value.if__index(), legacy);
case SocketCAN__ioctl__ifu::ALT_if__any:
return single_value.field_if__any->match(other_value.if__any(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}
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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
return FALSE;
}

boolean SocketCAN__ioctl__ifu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
return single_value.field_if__name->is_value();
case SocketCAN__ioctl__ifu::ALT_if__index:
return single_value.field_if__index->is_value();
case SocketCAN__ioctl__ifu::ALT_if__any:
return single_value.field_if__any->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}

SocketCAN__ioctl__ifu SocketCAN__ioctl__ifu_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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
SocketCAN__ioctl__ifu ret_val;
switch (single_value.union_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
ret_val.if__name() = single_value.field_if__name->valueof();
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
ret_val.if__index() = single_value.field_if__index->valueof();
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
ret_val.if__any() = single_value.field_if__any->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
return ret_val;
}

SocketCAN__ioctl__ifu_template& SocketCAN__ioctl__ifu_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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return value_list.list_value[list_index];
}
void SocketCAN__ioctl__ifu_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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__ioctl__ifu_template[list_length];
}

CHARSTRING_template& SocketCAN__ioctl__ifu_template::if__name()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__name) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__name = new CHARSTRING_template(ANY_VALUE);
else single_value.field_if__name = new CHARSTRING_template;
single_value.union_selection = SocketCAN__ioctl__ifu::ALT_if__name;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__name;
}

const CHARSTRING_template& SocketCAN__ioctl__ifu_template::if__name() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_name in a non-specific template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__name) TTCN_error("Accessing non-selected field if_name in a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *single_value.field_if__name;
}

INTEGER_template& SocketCAN__ioctl__ifu_template::if__index()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__index) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__index = new INTEGER_template(ANY_VALUE);
else single_value.field_if__index = new INTEGER_template;
single_value.union_selection = SocketCAN__ioctl__ifu::ALT_if__index;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__index;
}

const INTEGER_template& SocketCAN__ioctl__ifu_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_index in a non-specific template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__index) TTCN_error("Accessing non-selected field if_index in a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *single_value.field_if__index;
}

SocketCAN__if__any_template& SocketCAN__ioctl__ifu_template::if__any()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__any) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_if__any = new SocketCAN__if__any_template(ANY_VALUE);
else single_value.field_if__any = new SocketCAN__if__any_template;
single_value.union_selection = SocketCAN__ioctl__ifu::ALT_if__any;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_if__any;
}

const SocketCAN__if__any_template& SocketCAN__ioctl__ifu_template::if__any() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field if_any in a non-specific template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
if (single_value.union_selection != SocketCAN__ioctl__ifu::ALT_if__any) TTCN_error("Accessing non-selected field if_any in a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
return *single_value.field_if__any;
}

boolean SocketCAN__ioctl__ifu_template::ischosen(SocketCAN__ioctl__ifu::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__ioctl__ifu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__ioctl__ifu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
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 @SocketCAN_Types.SocketCAN_ioctl_ifu 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__ioctl__ifu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
TTCN_Logger::log_event_str("{ if_name := ");
single_value.field_if__name->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
TTCN_Logger::log_event_str("{ if_index := ");
single_value.field_if__index->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
TTCN_Logger::log_event_str("{ if_any := ");
single_value.field_if__any->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__ioctl__ifu_template::log_match(const SocketCAN__ioctl__ifu& 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__ioctl__ifu::ALT_if__name:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_name");
single_value.field_if__name->log_match(match_value.if__name(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_name := ");
single_value.field_if__name->log_match(match_value.if__name(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_index");
single_value.field_if__index->log_match(match_value.if__index(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_index := ");
single_value.field_if__index->log_match(match_value.if__index(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".if_any");
single_value.field_if__any->log_match(match_value.if__any(), legacy);
} else {
TTCN_Logger::log_event_str("{ if_any := ");
single_value.field_if__any->log_match(match_value.if__any(), 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__ioctl__ifu_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__ioctl__ifu::ALT_if__name:
single_value.field_if__name->encode_text(text_buf);
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
single_value.field_if__index->encode_text(text_buf);
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
single_value.field_if__any->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}

void SocketCAN__ioctl__ifu_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__ioctl__ifu::UNBOUND_VALUE;
SocketCAN__ioctl__ifu::union_selection_type new_selection = (SocketCAN__ioctl__ifu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__ioctl__ifu::ALT_if__name:
single_value.field_if__name = new CHARSTRING_template;
single_value.field_if__name->decode_text(text_buf);
break;
case SocketCAN__ioctl__ifu::ALT_if__index:
single_value.field_if__index = new INTEGER_template;
single_value.field_if__index->decode_text(text_buf);
break;
case SocketCAN__ioctl__ifu::ALT_if__any:
single_value.field_if__any = new SocketCAN__if__any_template;
single_value.field_if__any->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
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__ioctl__ifu_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 @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
}

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

boolean SocketCAN__ioctl__ifu_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__ioctl__ifu_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 `@SocketCAN_Types.SocketCAN_ioctl_ifu'");
    }
    if (strcmp("if_name", param_field) == 0) {
      if__name().set_param(param);
      return;
    } else if (strcmp("if_index", param_field) == 0) {
      if__index().set_param(param);
      return;
    } else if (strcmp("if_any", param_field) == 0) {
      if__any().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@SocketCAN_Types.SocketCAN_ioctl_ifu'", 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__ioctl__ifu_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", "@SocketCAN_Types.SocketCAN_ioctl_ifu");
    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, "if_name")) {
      if__name().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "if_index")) {
      if__index().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "if_any")) {
      if__any().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_ioctl_ifu.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_ioctl_ifu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__ioctl__ifu_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__ioctl__ifu::ALT_if__name:
single_value.field_if__name->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl_ifu");
return;
case SocketCAN__ioctl__ifu::ALT_if__index:
single_value.field_if__index->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl_ifu");
return;
case SocketCAN__ioctl__ifu::ALT_if__any:
single_value.field_if__any->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl_ifu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_ioctl_ifu.");
}
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 : "@SocketCAN_Types.SocketCAN_ioctl_ifu");
}

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

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

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

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

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

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

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

boolean SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.");
return enum_value == other_value;
}

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

boolean SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.");
return enum_value < other_value;
}

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

boolean SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.");
return enum_value > other_value;
}

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

const char *SocketCAN__Result__code::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case SocketCAN__ERROR: return "SocketCAN_ERROR";
case SocketCAN__SUCCESS: return "SocketCAN_SUCCESS";
default: return "<unknown>";
}
}

SocketCAN__Result__code::enum_type SocketCAN__Result__code::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "SocketCAN_ERROR")) return SocketCAN__ERROR;
else if (!strcmp(str_par, "SocketCAN_SUCCESS")) return SocketCAN__SUCCESS;
else return UNKNOWN_VALUE;
}

boolean SocketCAN__Result__code::is_valid_enum(int int_par)
{
switch (int_par) {
case 0:
case 1:
return TRUE;
default:
return FALSE;
}
}

int SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int SocketCAN__Result__code::enum2int(const SocketCAN__Result__code& 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 @SocketCAN_Types.SocketCAN_Result_code.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

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

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

void SocketCAN__Result__code::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 SocketCAN__Result__code::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", "@SocketCAN_Types.SocketCAN_Result_code");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @SocketCAN_Types.SocketCAN_Result_code.");
  }
}

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

void SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.", enum_value);
}

void SocketCAN__Result__code_template::copy_template(const SocketCAN__Result__code_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 SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
}
}

SocketCAN__Result__code_template::SocketCAN__Result__code_template()
{
}

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

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

SocketCAN__Result__code_template::SocketCAN__Result__code_template(SocketCAN__Result__code::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

SocketCAN__Result__code_template::SocketCAN__Result__code_template(const SocketCAN__Result__code& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == SocketCAN__Result__code::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @SocketCAN_Types.SocketCAN_Result_code.");
single_value = other_value.enum_value;
}

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

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

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

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

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

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

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

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

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

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

SocketCAN__Result__code_template& SocketCAN__Result__code_template::operator=(const OPTIONAL<SocketCAN__Result__code>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (SocketCAN__Result__code::enum_type)(const SocketCAN__Result__code&)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 @SocketCAN_Types.SocketCAN_Result_code.");
}
return *this;
}

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

boolean SocketCAN__Result__code_template::match(SocketCAN__Result__code::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 @SocketCAN_Types.SocketCAN_Result_code.");
}
return FALSE;
}

boolean SocketCAN__Result__code_template::match(const SocketCAN__Result__code& other_value, boolean) const
{
if (other_value.enum_value == SocketCAN__Result__code::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @SocketCAN_Types.SocketCAN_Result_code with an unbound value.");
return match(other_value.enum_value);
}

SocketCAN__Result__code::enum_type SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
return single_value;
}

void SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__Result__code_template[list_length];
}

SocketCAN__Result__code_template& SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @SocketCAN_Types.SocketCAN_Result_code.");
return value_list.list_value[list_index];
}

void SocketCAN__Result__code_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(SocketCAN__Result__code::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 SocketCAN__Result__code_template::log_match(const SocketCAN__Result__code& 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 SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
}
}

void SocketCAN__Result__code_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (SocketCAN__Result__code::enum_type)text_buf.pull_int().get_val();
if (!SocketCAN__Result__code::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @SocketCAN_Types.SocketCAN_Result_code.", 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 SocketCAN__Result__code_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 @SocketCAN_Types.SocketCAN_Result_code.");
}
}

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

boolean SocketCAN__Result__code_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__Result__code_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: {
    SocketCAN__Result__code_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: {
    SocketCAN__Result__code::enum_type enum_val = SocketCAN__Result__code::str_to_enum(m_p->get_enumerated());
    if (!SocketCAN__Result__code::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @SocketCAN_Types.SocketCAN_Result_code.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@SocketCAN_Types.SocketCAN_Result_code");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__Result__code_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 : "@SocketCAN_Types.SocketCAN_Result_code");
}

SocketCAN__Result::SocketCAN__Result()
{
}

SocketCAN__Result::SocketCAN__Result(const SocketCAN__Result__code& par_result__code,
    const OPTIONAL<INTEGER>& par_err,
    const OPTIONAL<CHARSTRING>& par_err__text)
  :   field_result__code(par_result__code),
  field_err(par_err),
  field_err__text(par_err__text)
{
}

SocketCAN__Result::SocketCAN__Result(const SocketCAN__Result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_Result.");
if (other_value.result__code().is_bound()) field_result__code = other_value.result__code();
else field_result__code.clean_up();
if (other_value.err().is_bound()) field_err = other_value.err();
else field_err.clean_up();
if (other_value.err__text().is_bound()) field_err__text = other_value.err__text();
else field_err__text.clean_up();
}

void SocketCAN__Result::clean_up()
{
field_result__code.clean_up();
field_err.clean_up();
field_err__text.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__Result::get_descriptor() const { return &SocketCAN__Result_descr_; }
SocketCAN__Result& SocketCAN__Result::operator=(const SocketCAN__Result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_Result.");
  if (other_value.result__code().is_bound()) field_result__code = other_value.result__code();
  else field_result__code.clean_up();
  if (other_value.err().is_bound()) field_err = other_value.err();
  else field_err.clean_up();
  if (other_value.err__text().is_bound()) field_err__text = other_value.err__text();
  else field_err__text.clean_up();
}
return *this;
}

boolean SocketCAN__Result::operator==(const SocketCAN__Result& other_value) const
{
return field_result__code==other_value.field_result__code
  && field_err==other_value.field_err
  && field_err__text==other_value.field_err__text;
}

boolean SocketCAN__Result::is_bound() const
{
return (field_result__code.is_bound())
  || (OPTIONAL_OMIT == field_err.get_selection() || field_err.is_bound())
  || (OPTIONAL_OMIT == field_err__text.get_selection() || field_err__text.is_bound());
}
boolean SocketCAN__Result::is_value() const
{
return field_result__code.is_value()
  && (OPTIONAL_OMIT == field_err.get_selection() || field_err.is_value())
  && (OPTIONAL_OMIT == field_err__text.get_selection() || field_err__text.is_value());
}
int SocketCAN__Result::size_of() const
{
  int ret_val = 1;
  if (field_err.ispresent()) ret_val++;
  if (field_err__text.ispresent()) ret_val++;
  return ret_val;
}

void SocketCAN__Result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result_code := ");
field_result__code.log();
TTCN_Logger::log_event_str(", err := ");
field_err.log();
TTCN_Logger::log_event_str(", err_text := ");
field_err__text.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__Result::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_Result has 3 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) result__code().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) err().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) err__text().set_param(*param.get_elem(2));
    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(), "result_code")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result__code().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(), "err")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          err().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(), "err_text")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          err__text().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 @SocketCAN_Types.SocketCAN_Result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_Result");
  }
}

void SocketCAN__Result::set_implicit_omit()
{
if (result__code().is_bound()) result__code().set_implicit_omit();
if (!err().is_bound()) err() = OMIT_VALUE;
else err().set_implicit_omit();
if (!err__text().is_bound()) err__text() = OMIT_VALUE;
else err__text().set_implicit_omit();
}

void SocketCAN__Result::encode_text(Text_Buf& text_buf) const
{
field_result__code.encode_text(text_buf);
field_err.encode_text(text_buf);
field_err__text.encode_text(text_buf);
}

void SocketCAN__Result::decode_text(Text_Buf& text_buf)
{
field_result__code.decode_text(text_buf);
field_err.decode_text(text_buf);
field_err__text.decode_text(text_buf);
}

struct SocketCAN__Result_template::single_value_struct {
SocketCAN__Result__code_template field_result__code;
INTEGER_template field_err;
CHARSTRING_template field_err__text;
};

void SocketCAN__Result_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_result__code = ANY_VALUE;
single_value->field_err = ANY_OR_OMIT;
single_value->field_err__text = ANY_OR_OMIT;
}
}
}

void SocketCAN__Result_template::copy_value(const SocketCAN__Result& other_value)
{
single_value = new single_value_struct;
if (other_value.result__code().is_bound()) {
  single_value->field_result__code = other_value.result__code();
} else {
  single_value->field_result__code.clean_up();
}
if (other_value.err().is_bound()) {
  if (other_value.err().ispresent()) single_value->field_err = other_value.err()();
  else single_value->field_err = OMIT_VALUE;
} else {
  single_value->field_err.clean_up();
}
if (other_value.err__text().is_bound()) {
  if (other_value.err__text().ispresent()) single_value->field_err__text = other_value.err__text()();
  else single_value->field_err__text = OMIT_VALUE;
} else {
  single_value->field_err__text.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__Result_template::copy_template(const SocketCAN__Result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result__code().get_selection()) {
single_value->field_result__code = other_value.result__code();
} else {
single_value->field_result__code.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.err().get_selection()) {
single_value->field_err = other_value.err();
} else {
single_value->field_err.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.err__text().get_selection()) {
single_value->field_err__text = other_value.err__text();
} else {
single_value->field_err__text.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__Result_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 @SocketCAN_Types.SocketCAN_Result.");
break;
}
set_selection(other_value);
}

SocketCAN__Result_template::SocketCAN__Result_template()
{
}

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

SocketCAN__Result_template::SocketCAN__Result_template(const SocketCAN__Result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__Result_template& SocketCAN__Result_template::operator=(const OPTIONAL<SocketCAN__Result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__Result&)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 @SocketCAN_Types.SocketCAN_Result.");
}
return *this;
}

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

boolean SocketCAN__Result_template::match(const SocketCAN__Result& 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.result__code().is_bound()) return FALSE;
if(!single_value->field_result__code.match(other_value.result__code(), legacy))return FALSE;
if(!other_value.err().is_bound()) return FALSE;
if((other_value.err().ispresent() ? !single_value->field_err.match((const INTEGER&)other_value.err(), legacy) : !single_value->field_err.match_omit(legacy)))return FALSE;
if(!other_value.err__text().is_bound()) return FALSE;
if((other_value.err__text().ispresent() ? !single_value->field_err__text.match((const CHARSTRING&)other_value.err__text(), legacy) : !single_value->field_err__text.match_omit(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 @SocketCAN_Types.SocketCAN_Result.");
}
return FALSE;
}

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

 ||(single_value->field_err.is_omit() || single_value->field_err.is_bound())

 ||(single_value->field_err__text.is_omit() || single_value->field_err__text.is_bound())
;
}

boolean SocketCAN__Result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result__code.is_value()
 &&(single_value->field_err.is_omit() || single_value->field_err.is_value())
 &&(single_value->field_err__text.is_omit() || single_value->field_err__text.is_value());
}

void SocketCAN__Result_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__Result SocketCAN__Result_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 @SocketCAN_Types.SocketCAN_Result.");
SocketCAN__Result ret_val;
if (single_value->field_result__code.is_bound()) {
ret_val.result__code() = single_value->field_result__code.valueof();
}
if (single_value->field_err.is_omit()) ret_val.err() = OMIT_VALUE;
else if (single_value->field_err.is_bound()) {
ret_val.err() = single_value->field_err.valueof();
}
if (single_value->field_err__text.is_omit()) ret_val.err__text() = OMIT_VALUE;
else if (single_value->field_err__text.is_bound()) {
ret_val.err__text() = single_value->field_err__text.valueof();
}
return ret_val;
}

void SocketCAN__Result_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 @SocketCAN_Types.SocketCAN_Result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__Result_template[list_length];
}

SocketCAN__Result_template& SocketCAN__Result_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 @SocketCAN_Types.SocketCAN_Result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_Result.");
return value_list.list_value[list_index];
}

SocketCAN__Result__code_template& SocketCAN__Result_template::result__code()
{
set_specific();
return single_value->field_result__code;
}

const SocketCAN__Result__code_template& SocketCAN__Result_template::result__code() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result_code of a non-specific template of type @SocketCAN_Types.SocketCAN_Result.");
return single_value->field_result__code;
}

INTEGER_template& SocketCAN__Result_template::err()
{
set_specific();
return single_value->field_err;
}

const INTEGER_template& SocketCAN__Result_template::err() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field err of a non-specific template of type @SocketCAN_Types.SocketCAN_Result.");
return single_value->field_err;
}

CHARSTRING_template& SocketCAN__Result_template::err__text()
{
set_specific();
return single_value->field_err__text;
}

const CHARSTRING_template& SocketCAN__Result_template::err__text() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field err_text of a non-specific template of type @SocketCAN_Types.SocketCAN_Result.");
return single_value->field_err__text;
}

int SocketCAN__Result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_Result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
  {    int ret_val = 1;
      if (single_value->field_err.is_present()) ret_val++;
      if (single_value->field_err__text.is_present()) ret_val++;
      return ret_val;
    }
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_Result 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 @SocketCAN_Types.SocketCAN_Result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_Result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_Result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_Result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_Result.");
  }
  return 0;
}

void SocketCAN__Result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result_code := ");
single_value->field_result__code.log();
TTCN_Logger::log_event_str(", err := ");
single_value->field_err.log();
TTCN_Logger::log_event_str(", err_text := ");
single_value->field_err__text.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__Result_template::log_match(const SocketCAN__Result& 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_result__code.match(match_value.result__code(), legacy)){
TTCN_Logger::log_logmatch_info(".result_code");
single_value->field_result__code.log_match(match_value.result__code(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if (match_value.err().ispresent()){
if(!single_value->field_err.match(match_value.err(), legacy)){
TTCN_Logger::log_logmatch_info(".err");
single_value->field_err.log_match(match_value.err(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_err.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".err := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_err.log();
TTCN_Logger::log_event_str(" unmatched");
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}
if (match_value.err__text().ispresent()){
if(!single_value->field_err__text.match(match_value.err__text(), legacy)){
TTCN_Logger::log_logmatch_info(".err_text");
single_value->field_err__text.log_match(match_value.err__text(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_err__text.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".err_text := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_err__text.log();
TTCN_Logger::log_event_str(" unmatched");
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("{ result_code := ");
single_value->field_result__code.log_match(match_value.result__code(), legacy);
TTCN_Logger::log_event_str(", err := ");
if (match_value.err().ispresent()) single_value->field_err.log_match(match_value.err(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_err.log();
if (single_value->field_err.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
TTCN_Logger::log_event_str(", err_text := ");
if (match_value.err__text().ispresent()) single_value->field_err__text.log_match(match_value.err__text(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_err__text.log();
if (single_value->field_err__text.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
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__Result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result__code.encode_text(text_buf);
single_value->field_err.encode_text(text_buf);
single_value->field_err__text.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 @SocketCAN_Types.SocketCAN_Result.");
}
}

void SocketCAN__Result_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_result__code.decode_text(text_buf);
single_value->field_err.decode_text(text_buf);
single_value->field_err__text.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__Result_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 @SocketCAN_Types.SocketCAN_Result.");
}
}

void SocketCAN__Result_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__Result_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_Result has 3 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) result__code().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) err().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) err__text().set_param(*param.get_elem(2));
    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(), "result_code")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result__code().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(), "err")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          err().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(), "err_text")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          err__text().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 @SocketCAN_Types.SocketCAN_Result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_Result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__Result_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_result__code.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_Result");
single_value->field_err.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_Result");
single_value->field_err__text.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_Result");
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 : "@SocketCAN_Types.SocketCAN_Result");
}

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

boolean SocketCAN__Result_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;
}

SocketCAN__socket::SocketCAN__socket()
{
}

SocketCAN__socket::SocketCAN__socket(const Can::AdresseFamily__enum& par_domain,
    const Can::ProtocolFamily__enum& par_ptype,
    const Can::PF__CAN__protocols__enum& par_protocol)
  :   field_domain(par_domain),
  field_ptype(par_ptype),
  field_protocol(par_protocol)
{
}

SocketCAN__socket::SocketCAN__socket(const SocketCAN__socket& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_socket.");
if (other_value.domain().is_bound()) field_domain = other_value.domain();
else field_domain.clean_up();
if (other_value.ptype().is_bound()) field_ptype = other_value.ptype();
else field_ptype.clean_up();
if (other_value.protocol().is_bound()) field_protocol = other_value.protocol();
else field_protocol.clean_up();
}

void SocketCAN__socket::clean_up()
{
field_domain.clean_up();
field_ptype.clean_up();
field_protocol.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__socket::get_descriptor() const { return &SocketCAN__socket_descr_; }
SocketCAN__socket& SocketCAN__socket::operator=(const SocketCAN__socket& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_socket.");
  if (other_value.domain().is_bound()) field_domain = other_value.domain();
  else field_domain.clean_up();
  if (other_value.ptype().is_bound()) field_ptype = other_value.ptype();
  else field_ptype.clean_up();
  if (other_value.protocol().is_bound()) field_protocol = other_value.protocol();
  else field_protocol.clean_up();
}
return *this;
}

boolean SocketCAN__socket::operator==(const SocketCAN__socket& other_value) const
{
return field_domain==other_value.field_domain
  && field_ptype==other_value.field_ptype
  && field_protocol==other_value.field_protocol;
}

boolean SocketCAN__socket::is_bound() const
{
return (field_domain.is_bound())
  || (field_ptype.is_bound())
  || (field_protocol.is_bound());
}
boolean SocketCAN__socket::is_value() const
{
return field_domain.is_value()
  && field_ptype.is_value()
  && field_protocol.is_value();
}
void SocketCAN__socket::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ domain := ");
field_domain.log();
TTCN_Logger::log_event_str(", ptype := ");
field_ptype.log();
TTCN_Logger::log_event_str(", protocol := ");
field_protocol.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__socket::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_socket has 3 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) domain().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ptype().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) protocol().set_param(*param.get_elem(2));
    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(), "domain")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          domain().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(), "ptype")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ptype().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(), "protocol")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          protocol().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 @SocketCAN_Types.SocketCAN_socket: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_socket");
  }
}

void SocketCAN__socket::set_implicit_omit()
{
if (domain().is_bound()) domain().set_implicit_omit();
if (ptype().is_bound()) ptype().set_implicit_omit();
if (protocol().is_bound()) protocol().set_implicit_omit();
}

void SocketCAN__socket::encode_text(Text_Buf& text_buf) const
{
field_domain.encode_text(text_buf);
field_ptype.encode_text(text_buf);
field_protocol.encode_text(text_buf);
}

void SocketCAN__socket::decode_text(Text_Buf& text_buf)
{
field_domain.decode_text(text_buf);
field_ptype.decode_text(text_buf);
field_protocol.decode_text(text_buf);
}

struct SocketCAN__socket_template::single_value_struct {
Can::AdresseFamily__enum_template field_domain;
Can::ProtocolFamily__enum_template field_ptype;
Can::PF__CAN__protocols__enum_template field_protocol;
};

void SocketCAN__socket_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_domain = ANY_VALUE;
single_value->field_ptype = ANY_VALUE;
single_value->field_protocol = ANY_VALUE;
}
}
}

void SocketCAN__socket_template::copy_value(const SocketCAN__socket& other_value)
{
single_value = new single_value_struct;
if (other_value.domain().is_bound()) {
  single_value->field_domain = other_value.domain();
} else {
  single_value->field_domain.clean_up();
}
if (other_value.ptype().is_bound()) {
  single_value->field_ptype = other_value.ptype();
} else {
  single_value->field_ptype.clean_up();
}
if (other_value.protocol().is_bound()) {
  single_value->field_protocol = other_value.protocol();
} else {
  single_value->field_protocol.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__socket_template::copy_template(const SocketCAN__socket_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.domain().get_selection()) {
single_value->field_domain = other_value.domain();
} else {
single_value->field_domain.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ptype().get_selection()) {
single_value->field_ptype = other_value.ptype();
} else {
single_value->field_ptype.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.protocol().get_selection()) {
single_value->field_protocol = other_value.protocol();
} else {
single_value->field_protocol.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__socket_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 @SocketCAN_Types.SocketCAN_socket.");
break;
}
set_selection(other_value);
}

SocketCAN__socket_template::SocketCAN__socket_template()
{
}

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

SocketCAN__socket_template::SocketCAN__socket_template(const SocketCAN__socket& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__socket_template& SocketCAN__socket_template::operator=(const OPTIONAL<SocketCAN__socket>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__socket&)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 @SocketCAN_Types.SocketCAN_socket.");
}
return *this;
}

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

boolean SocketCAN__socket_template::match(const SocketCAN__socket& 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.domain().is_bound()) return FALSE;
if(!single_value->field_domain.match(other_value.domain(), legacy))return FALSE;
if(!other_value.ptype().is_bound()) return FALSE;
if(!single_value->field_ptype.match(other_value.ptype(), legacy))return FALSE;
if(!other_value.protocol().is_bound()) return FALSE;
if(!single_value->field_protocol.match(other_value.protocol(), 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 @SocketCAN_Types.SocketCAN_socket.");
}
return FALSE;
}

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

 ||single_value->field_ptype.is_bound()

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

boolean SocketCAN__socket_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_domain.is_value()
 &&single_value->field_ptype.is_value()
 &&single_value->field_protocol.is_value();
}

void SocketCAN__socket_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__socket SocketCAN__socket_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 @SocketCAN_Types.SocketCAN_socket.");
SocketCAN__socket ret_val;
if (single_value->field_domain.is_bound()) {
ret_val.domain() = single_value->field_domain.valueof();
}
if (single_value->field_ptype.is_bound()) {
ret_val.ptype() = single_value->field_ptype.valueof();
}
if (single_value->field_protocol.is_bound()) {
ret_val.protocol() = single_value->field_protocol.valueof();
}
return ret_val;
}

void SocketCAN__socket_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 @SocketCAN_Types.SocketCAN_socket.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__socket_template[list_length];
}

SocketCAN__socket_template& SocketCAN__socket_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 @SocketCAN_Types.SocketCAN_socket.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_socket.");
return value_list.list_value[list_index];
}

Can::AdresseFamily__enum_template& SocketCAN__socket_template::domain()
{
set_specific();
return single_value->field_domain;
}

const Can::AdresseFamily__enum_template& SocketCAN__socket_template::domain() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field domain of a non-specific template of type @SocketCAN_Types.SocketCAN_socket.");
return single_value->field_domain;
}

Can::ProtocolFamily__enum_template& SocketCAN__socket_template::ptype()
{
set_specific();
return single_value->field_ptype;
}

const Can::ProtocolFamily__enum_template& SocketCAN__socket_template::ptype() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ptype of a non-specific template of type @SocketCAN_Types.SocketCAN_socket.");
return single_value->field_ptype;
}

Can::PF__CAN__protocols__enum_template& SocketCAN__socket_template::protocol()
{
set_specific();
return single_value->field_protocol;
}

const Can::PF__CAN__protocols__enum_template& SocketCAN__socket_template::protocol() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field protocol of a non-specific template of type @SocketCAN_Types.SocketCAN_socket.");
return single_value->field_protocol;
}

int SocketCAN__socket_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket 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 @SocketCAN_Types.SocketCAN_socket containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_socket.");
  }
  return 0;
}

void SocketCAN__socket_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ domain := ");
single_value->field_domain.log();
TTCN_Logger::log_event_str(", ptype := ");
single_value->field_ptype.log();
TTCN_Logger::log_event_str(", protocol := ");
single_value->field_protocol.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__socket_template::log_match(const SocketCAN__socket& 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_domain.match(match_value.domain(), legacy)){
TTCN_Logger::log_logmatch_info(".domain");
single_value->field_domain.log_match(match_value.domain(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ptype.match(match_value.ptype(), legacy)){
TTCN_Logger::log_logmatch_info(".ptype");
single_value->field_ptype.log_match(match_value.ptype(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_protocol.match(match_value.protocol(), legacy)){
TTCN_Logger::log_logmatch_info(".protocol");
single_value->field_protocol.log_match(match_value.protocol(), 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("{ domain := ");
single_value->field_domain.log_match(match_value.domain(), legacy);
TTCN_Logger::log_event_str(", ptype := ");
single_value->field_ptype.log_match(match_value.ptype(), legacy);
TTCN_Logger::log_event_str(", protocol := ");
single_value->field_protocol.log_match(match_value.protocol(), 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__socket_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_domain.encode_text(text_buf);
single_value->field_ptype.encode_text(text_buf);
single_value->field_protocol.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 @SocketCAN_Types.SocketCAN_socket.");
}
}

void SocketCAN__socket_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_domain.decode_text(text_buf);
single_value->field_ptype.decode_text(text_buf);
single_value->field_protocol.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__socket_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 @SocketCAN_Types.SocketCAN_socket.");
}
}

void SocketCAN__socket_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__socket_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_socket has 3 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) domain().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ptype().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) protocol().set_param(*param.get_elem(2));
    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(), "domain")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          domain().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(), "ptype")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ptype().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(), "protocol")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          protocol().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 @SocketCAN_Types.SocketCAN_socket: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_socket");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__socket_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_domain.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_socket");
single_value->field_ptype.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_socket");
single_value->field_protocol.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_socket");
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 : "@SocketCAN_Types.SocketCAN_socket");
}

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

boolean SocketCAN__socket_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;
}

SocketCAN__socket__result::SocketCAN__socket__result()
{
}

SocketCAN__socket__result::SocketCAN__socket__result(const INTEGER& par_id,
    const SocketCAN__Result& par_result)
  :   field_id(par_id),
  field_result(par_result)
{
}

SocketCAN__socket__result::SocketCAN__socket__result(const SocketCAN__socket__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_socket_result.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__socket__result::clean_up()
{
field_id.clean_up();
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__socket__result::get_descriptor() const { return &SocketCAN__socket__result_descr_; }
SocketCAN__socket__result& SocketCAN__socket__result::operator=(const SocketCAN__socket__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_socket_result.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__socket__result::operator==(const SocketCAN__socket__result& other_value) const
{
return field_id==other_value.field_id
  && field_result==other_value.field_result;
}

boolean SocketCAN__socket__result::is_bound() const
{
return (field_id.is_bound())
  || (field_result.is_bound());
}
boolean SocketCAN__socket__result::is_value() const
{
return field_id.is_value()
  && field_result.is_value();
}
void SocketCAN__socket__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__socket__result::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 @SocketCAN_Types.SocketCAN_socket_result 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) result().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_socket_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_socket_result");
  }
}

void SocketCAN__socket__result::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__socket__result::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_result.encode_text(text_buf);
}

void SocketCAN__socket__result::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_result.decode_text(text_buf);
}

struct SocketCAN__socket__result_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__Result_template field_result;
};

void SocketCAN__socket__result_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_id = ANY_VALUE;
single_value->field_result = ANY_VALUE;
}
}
}

void SocketCAN__socket__result_template::copy_value(const SocketCAN__socket__result& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__socket__result_template::copy_template(const SocketCAN__socket__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result.");
break;
}
set_selection(other_value);
}

SocketCAN__socket__result_template::SocketCAN__socket__result_template()
{
}

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

SocketCAN__socket__result_template::SocketCAN__socket__result_template(const SocketCAN__socket__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__socket__result_template& SocketCAN__socket__result_template::operator=(const OPTIONAL<SocketCAN__socket__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__socket__result&)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 @SocketCAN_Types.SocketCAN_socket_result.");
}
return *this;
}

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

boolean SocketCAN__socket__result_template::match(const SocketCAN__socket__result& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_socket_result.");
}
return FALSE;
}

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

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

boolean SocketCAN__socket__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_result.is_value();
}

void SocketCAN__socket__result_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__socket__result SocketCAN__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result.");
SocketCAN__socket__result ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__socket__result_template[list_length];
}

SocketCAN__socket__result_template& SocketCAN__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_socket_result.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__socket__result_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__socket__result_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_socket_result.");
return single_value->field_id;
}

SocketCAN__Result_template& SocketCAN__socket__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__socket__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_socket_result.");
return single_value->field_result;
}

int SocketCAN__socket__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket_result 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 @SocketCAN_Types.SocketCAN_socket_result 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 @SocketCAN_Types.SocketCAN_socket_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_socket_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_socket_result.");
  }
  return 0;
}

void SocketCAN__socket__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", result := ");
single_value->field_result.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__socket__result_template::log_match(const SocketCAN__socket__result& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", result := ");
single_value->field_result.log_match(match_value.result(), 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__socket__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_result.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 @SocketCAN_Types.SocketCAN_socket_result.");
}
}

void SocketCAN__socket__result_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_id.decode_text(text_buf);
single_value->field_result.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__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result.");
}
}

void SocketCAN__socket__result_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__socket__result_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 @SocketCAN_Types.SocketCAN_socket_result 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) result().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_socket_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_socket_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__socket__result_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_socket_result");
single_value->field_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_socket_result");
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 : "@SocketCAN_Types.SocketCAN_socket_result");
}

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

boolean SocketCAN__socket__result_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;
}

SocketCAN__ioctl::SocketCAN__ioctl()
{
}

SocketCAN__ioctl::SocketCAN__ioctl(const INTEGER& par_id,
    const OPTIONAL<SocketCAN__ioctl__ifu>& par_ifu)
  :   field_id(par_id),
  field_ifu(par_ifu)
{
}

SocketCAN__ioctl::SocketCAN__ioctl(const SocketCAN__ioctl& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_ioctl.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.ifu().is_bound()) field_ifu = other_value.ifu();
else field_ifu.clean_up();
}

void SocketCAN__ioctl::clean_up()
{
field_id.clean_up();
field_ifu.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__ioctl::get_descriptor() const { return &SocketCAN__ioctl_descr_; }
SocketCAN__ioctl& SocketCAN__ioctl::operator=(const SocketCAN__ioctl& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_ioctl.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.ifu().is_bound()) field_ifu = other_value.ifu();
  else field_ifu.clean_up();
}
return *this;
}

boolean SocketCAN__ioctl::operator==(const SocketCAN__ioctl& other_value) const
{
return field_id==other_value.field_id
  && field_ifu==other_value.field_ifu;
}

boolean SocketCAN__ioctl::is_bound() const
{
return (field_id.is_bound())
  || (OPTIONAL_OMIT == field_ifu.get_selection() || field_ifu.is_bound());
}
boolean SocketCAN__ioctl::is_value() const
{
return field_id.is_value()
  && (OPTIONAL_OMIT == field_ifu.get_selection() || field_ifu.is_value());
}
int SocketCAN__ioctl::size_of() const
{
  int ret_val = 1;
  if (field_ifu.ispresent()) ret_val++;
  return ret_val;
}

void SocketCAN__ioctl::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", ifu := ");
field_ifu.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__ioctl::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 @SocketCAN_Types.SocketCAN_ioctl 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifu().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 @SocketCAN_Types.SocketCAN_ioctl: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_ioctl");
  }
}

void SocketCAN__ioctl::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (!ifu().is_bound()) ifu() = OMIT_VALUE;
else ifu().set_implicit_omit();
}

void SocketCAN__ioctl::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_ifu.encode_text(text_buf);
}

void SocketCAN__ioctl::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_ifu.decode_text(text_buf);
}

struct SocketCAN__ioctl_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__ioctl__ifu_template field_ifu;
};

void SocketCAN__ioctl_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_id = ANY_VALUE;
single_value->field_ifu = ANY_OR_OMIT;
}
}
}

void SocketCAN__ioctl_template::copy_value(const SocketCAN__ioctl& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.ifu().is_bound()) {
  if (other_value.ifu().ispresent()) single_value->field_ifu = other_value.ifu()();
  else single_value->field_ifu = OMIT_VALUE;
} else {
  single_value->field_ifu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__ioctl_template::copy_template(const SocketCAN__ioctl_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ifu().get_selection()) {
single_value->field_ifu = other_value.ifu();
} else {
single_value->field_ifu.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__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl.");
break;
}
set_selection(other_value);
}

SocketCAN__ioctl_template::SocketCAN__ioctl_template()
{
}

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

SocketCAN__ioctl_template::SocketCAN__ioctl_template(const SocketCAN__ioctl& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__ioctl_template& SocketCAN__ioctl_template::operator=(const OPTIONAL<SocketCAN__ioctl>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__ioctl&)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 @SocketCAN_Types.SocketCAN_ioctl.");
}
return *this;
}

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

boolean SocketCAN__ioctl_template::match(const SocketCAN__ioctl& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.ifu().is_bound()) return FALSE;
if((other_value.ifu().ispresent() ? !single_value->field_ifu.match((const SocketCAN__ioctl__ifu&)other_value.ifu(), legacy) : !single_value->field_ifu.match_omit(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 @SocketCAN_Types.SocketCAN_ioctl.");
}
return FALSE;
}

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

 ||(single_value->field_ifu.is_omit() || single_value->field_ifu.is_bound())
;
}

boolean SocketCAN__ioctl_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&(single_value->field_ifu.is_omit() || single_value->field_ifu.is_value());
}

void SocketCAN__ioctl_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__ioctl SocketCAN__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl.");
SocketCAN__ioctl ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_ifu.is_omit()) ret_val.ifu() = OMIT_VALUE;
else if (single_value->field_ifu.is_bound()) {
ret_val.ifu() = single_value->field_ifu.valueof();
}
return ret_val;
}

void SocketCAN__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__ioctl_template[list_length];
}

SocketCAN__ioctl_template& SocketCAN__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_ioctl.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__ioctl_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__ioctl_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_ioctl.");
return single_value->field_id;
}

SocketCAN__ioctl__ifu_template& SocketCAN__ioctl_template::ifu()
{
set_specific();
return single_value->field_ifu;
}

const SocketCAN__ioctl__ifu_template& SocketCAN__ioctl_template::ifu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifu of a non-specific template of type @SocketCAN_Types.SocketCAN_ioctl.");
return single_value->field_ifu;
}

int SocketCAN__ioctl_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
  {    int ret_val = 1;
      if (single_value->field_ifu.is_present()) ret_val++;
      return ret_val;
    }
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl 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 @SocketCAN_Types.SocketCAN_ioctl containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_ioctl.");
  }
  return 0;
}

void SocketCAN__ioctl_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", ifu := ");
single_value->field_ifu.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__ioctl_template::log_match(const SocketCAN__ioctl& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if (match_value.ifu().ispresent()){
if(!single_value->field_ifu.match(match_value.ifu(), legacy)){
TTCN_Logger::log_logmatch_info(".ifu");
single_value->field_ifu.log_match(match_value.ifu(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_ifu.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".ifu := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_ifu.log();
TTCN_Logger::log_event_str(" unmatched");
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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", ifu := ");
if (match_value.ifu().ispresent()) single_value->field_ifu.log_match(match_value.ifu(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_ifu.log();
if (single_value->field_ifu.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
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__ioctl_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_ifu.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 @SocketCAN_Types.SocketCAN_ioctl.");
}
}

void SocketCAN__ioctl_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_id.decode_text(text_buf);
single_value->field_ifu.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__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl.");
}
}

void SocketCAN__ioctl_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__ioctl_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 @SocketCAN_Types.SocketCAN_ioctl 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifu().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 @SocketCAN_Types.SocketCAN_ioctl: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_ioctl");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__ioctl_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl");
single_value->field_ifu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl");
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 : "@SocketCAN_Types.SocketCAN_ioctl");
}

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

boolean SocketCAN__ioctl_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;
}

SocketCAN__ioctl__result::SocketCAN__ioctl__result()
{
}

SocketCAN__ioctl__result::SocketCAN__ioctl__result(const SocketCAN__ifr& par_ifr,
    const SocketCAN__Result& par_result)
  :   field_ifr(par_ifr),
  field_result(par_result)
{
}

SocketCAN__ioctl__result::SocketCAN__ioctl__result(const SocketCAN__ioctl__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_ioctl_result.");
if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
else field_ifr.clean_up();
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__ioctl__result::clean_up()
{
field_ifr.clean_up();
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__ioctl__result::get_descriptor() const { return &SocketCAN__ioctl__result_descr_; }
SocketCAN__ioctl__result& SocketCAN__ioctl__result::operator=(const SocketCAN__ioctl__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_ioctl_result.");
  if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
  else field_ifr.clean_up();
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__ioctl__result::operator==(const SocketCAN__ioctl__result& other_value) const
{
return field_ifr==other_value.field_ifr
  && field_result==other_value.field_result;
}

boolean SocketCAN__ioctl__result::is_bound() const
{
return (field_ifr.is_bound())
  || (field_result.is_bound());
}
boolean SocketCAN__ioctl__result::is_value() const
{
return field_ifr.is_value()
  && field_result.is_value();
}
void SocketCAN__ioctl__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ifr := ");
field_ifr.log();
TTCN_Logger::log_event_str(", result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__ioctl__result::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 @SocketCAN_Types.SocketCAN_ioctl_result 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) ifr().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) result().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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_ioctl_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_ioctl_result");
  }
}

void SocketCAN__ioctl__result::set_implicit_omit()
{
if (ifr().is_bound()) ifr().set_implicit_omit();
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__ioctl__result::encode_text(Text_Buf& text_buf) const
{
field_ifr.encode_text(text_buf);
field_result.encode_text(text_buf);
}

void SocketCAN__ioctl__result::decode_text(Text_Buf& text_buf)
{
field_ifr.decode_text(text_buf);
field_result.decode_text(text_buf);
}

struct SocketCAN__ioctl__result_template::single_value_struct {
SocketCAN__ifr_template field_ifr;
SocketCAN__Result_template field_result;
};

void SocketCAN__ioctl__result_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_ifr = ANY_VALUE;
single_value->field_result = ANY_VALUE;
}
}
}

void SocketCAN__ioctl__result_template::copy_value(const SocketCAN__ioctl__result& other_value)
{
single_value = new single_value_struct;
if (other_value.ifr().is_bound()) {
  single_value->field_ifr = other_value.ifr();
} else {
  single_value->field_ifr.clean_up();
}
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__ioctl__result_template::copy_template(const SocketCAN__ioctl__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ifr().get_selection()) {
single_value->field_ifr = other_value.ifr();
} else {
single_value->field_ifr.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result.");
break;
}
set_selection(other_value);
}

SocketCAN__ioctl__result_template::SocketCAN__ioctl__result_template()
{
}

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

SocketCAN__ioctl__result_template::SocketCAN__ioctl__result_template(const SocketCAN__ioctl__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__ioctl__result_template& SocketCAN__ioctl__result_template::operator=(const OPTIONAL<SocketCAN__ioctl__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__ioctl__result&)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 @SocketCAN_Types.SocketCAN_ioctl_result.");
}
return *this;
}

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

boolean SocketCAN__ioctl__result_template::match(const SocketCAN__ioctl__result& 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.ifr().is_bound()) return FALSE;
if(!single_value->field_ifr.match(other_value.ifr(), legacy))return FALSE;
if(!other_value.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_ioctl_result.");
}
return FALSE;
}

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

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

boolean SocketCAN__ioctl__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ifr.is_value()
 &&single_value->field_result.is_value();
}

void SocketCAN__ioctl__result_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__ioctl__result SocketCAN__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result.");
SocketCAN__ioctl__result ret_val;
if (single_value->field_ifr.is_bound()) {
ret_val.ifr() = single_value->field_ifr.valueof();
}
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__ioctl__result_template[list_length];
}

SocketCAN__ioctl__result_template& SocketCAN__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_ioctl_result.");
return value_list.list_value[list_index];
}

SocketCAN__ifr_template& SocketCAN__ioctl__result_template::ifr()
{
set_specific();
return single_value->field_ifr;
}

const SocketCAN__ifr_template& SocketCAN__ioctl__result_template::ifr() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifr of a non-specific template of type @SocketCAN_Types.SocketCAN_ioctl_result.");
return single_value->field_ifr;
}

SocketCAN__Result_template& SocketCAN__ioctl__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__ioctl__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_ioctl_result.");
return single_value->field_result;
}

int SocketCAN__ioctl__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl_result 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 @SocketCAN_Types.SocketCAN_ioctl_result 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 @SocketCAN_Types.SocketCAN_ioctl_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_ioctl_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_ioctl_result.");
  }
  return 0;
}

void SocketCAN__ioctl__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ifr := ");
single_value->field_ifr.log();
TTCN_Logger::log_event_str(", result := ");
single_value->field_result.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__ioctl__result_template::log_match(const SocketCAN__ioctl__result& 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_ifr.match(match_value.ifr(), legacy)){
TTCN_Logger::log_logmatch_info(".ifr");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ ifr := ");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::log_event_str(", result := ");
single_value->field_result.log_match(match_value.result(), 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__ioctl__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ifr.encode_text(text_buf);
single_value->field_result.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 @SocketCAN_Types.SocketCAN_ioctl_result.");
}
}

void SocketCAN__ioctl__result_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_ifr.decode_text(text_buf);
single_value->field_result.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__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result.");
}
}

void SocketCAN__ioctl__result_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__ioctl__result_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 @SocketCAN_Types.SocketCAN_ioctl_result 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) ifr().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) result().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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_ioctl_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_ioctl_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__ioctl__result_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_ifr.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl_result");
single_value->field_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_ioctl_result");
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 : "@SocketCAN_Types.SocketCAN_ioctl_result");
}

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

boolean SocketCAN__ioctl__result_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__connectu::copy_value(const SocketCAN__connectu& other_value)
{
switch (other_value.union_selection) {
case ALT_bcm:
field_bcm = new SocketCAN__connect__bcm(*other_value.field_bcm);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_connectu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__connectu::operator==(const SocketCAN__connectu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_connectu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_connectu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_bcm:
return *field_bcm == *other_value.field_bcm;
default:
return FALSE;
}
}

SocketCAN__connect__bcm& SocketCAN__connectu::bcm()
{
if (union_selection != ALT_bcm) {
clean_up();
field_bcm = new SocketCAN__connect__bcm;
union_selection = ALT_bcm;
}
return *field_bcm;
}

const SocketCAN__connect__bcm& SocketCAN__connectu::bcm() const
{
if (union_selection != ALT_bcm) TTCN_error("Using non-selected field bcm in a value of union type @SocketCAN_Types.SocketCAN_connectu.");
return *field_bcm;
}

boolean SocketCAN__connectu::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 @SocketCAN_Types.SocketCAN_connectu.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__connectu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_bcm: return field_bcm->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__connectu::clean_up()
{
switch (union_selection) {
case ALT_bcm:
  delete field_bcm;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__connectu::log() const
{
switch (union_selection) {
case ALT_bcm:
TTCN_Logger::log_event_str("{ bcm := ");
field_bcm->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__connectu::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, "bcm")) {
    bcm().set_param(*mp_last);
    if (!bcm().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_connectu.", last_name);
}

void SocketCAN__connectu::set_implicit_omit()
{
switch (union_selection) {
case ALT_bcm:
field_bcm->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__connectu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_bcm:
field_bcm->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @SocketCAN_Types.SocketCAN_connectu.");
}
}

void SocketCAN__connectu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_bcm:
bcm().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @SocketCAN_Types.SocketCAN_connectu.");
}
}

void SocketCAN__connectu_template::copy_value(const SocketCAN__connectu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__connectu::ALT_bcm:
single_value.field_bcm = new SocketCAN__connect__bcm_template(other_value.bcm());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_connectu.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__connectu_template::copy_template(const SocketCAN__connectu_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__connectu::ALT_bcm:
single_value.field_bcm = new SocketCAN__connect__bcm_template(*other_value.single_value.field_bcm);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @SocketCAN_Types.SocketCAN_connectu.");
}
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__connectu_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 @SocketCAN_Types.SocketCAN_connectu.");
}
set_selection(other_value);
}

SocketCAN__connectu_template::SocketCAN__connectu_template()
{
}

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

SocketCAN__connectu_template::SocketCAN__connectu_template(const SocketCAN__connectu& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

SocketCAN__connectu_template& SocketCAN__connectu_template::operator=(const OPTIONAL<SocketCAN__connectu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__connectu&)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 @SocketCAN_Types.SocketCAN_connectu.");
}
return *this;
}

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

boolean SocketCAN__connectu_template::match(const SocketCAN__connectu& 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__connectu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__connectu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__connectu::ALT_bcm:
return single_value.field_bcm->match(other_value.bcm(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @SocketCAN_Types.SocketCAN_connectu.");
}
}
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 @SocketCAN_Types.SocketCAN_connectu.");
}
return FALSE;
}

boolean SocketCAN__connectu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__connectu::ALT_bcm:
return single_value.field_bcm->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @SocketCAN_Types.SocketCAN_connectu.");
}
}

SocketCAN__connectu SocketCAN__connectu_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 @SocketCAN_Types.SocketCAN_connectu.");
SocketCAN__connectu ret_val;
switch (single_value.union_selection) {
case SocketCAN__connectu::ALT_bcm:
ret_val.bcm() = single_value.field_bcm->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @SocketCAN_Types.SocketCAN_connectu.");
}
return ret_val;
}

SocketCAN__connectu_template& SocketCAN__connectu_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 @SocketCAN_Types.SocketCAN_connectu.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_connectu.");
return value_list.list_value[list_index];
}
void SocketCAN__connectu_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 @SocketCAN_Types.SocketCAN_connectu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__connectu_template[list_length];
}

SocketCAN__connect__bcm_template& SocketCAN__connectu_template::bcm()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__connectu::ALT_bcm) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_bcm = new SocketCAN__connect__bcm_template(ANY_VALUE);
else single_value.field_bcm = new SocketCAN__connect__bcm_template;
single_value.union_selection = SocketCAN__connectu::ALT_bcm;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_bcm;
}

const SocketCAN__connect__bcm_template& SocketCAN__connectu_template::bcm() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field bcm in a non-specific template of union type @SocketCAN_Types.SocketCAN_connectu.");
if (single_value.union_selection != SocketCAN__connectu::ALT_bcm) TTCN_error("Accessing non-selected field bcm in a template of union type @SocketCAN_Types.SocketCAN_connectu.");
return *single_value.field_bcm;
}

boolean SocketCAN__connectu_template::ischosen(SocketCAN__connectu::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__connectu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_connectu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__connectu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_connectu.");
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 @SocketCAN_Types.SocketCAN_connectu 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__connectu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__connectu::ALT_bcm:
TTCN_Logger::log_event_str("{ bcm := ");
single_value.field_bcm->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__connectu_template::log_match(const SocketCAN__connectu& 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__connectu::ALT_bcm:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".bcm");
single_value.field_bcm->log_match(match_value.bcm(), legacy);
} else {
TTCN_Logger::log_event_str("{ bcm := ");
single_value.field_bcm->log_match(match_value.bcm(), 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__connectu_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__connectu::ALT_bcm:
single_value.field_bcm->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @SocketCAN_Types.SocketCAN_connectu.");
}
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 @SocketCAN_Types.SocketCAN_connectu.");
}
}

void SocketCAN__connectu_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__connectu::UNBOUND_VALUE;
SocketCAN__connectu::union_selection_type new_selection = (SocketCAN__connectu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__connectu::ALT_bcm:
single_value.field_bcm = new SocketCAN__connect__bcm_template;
single_value.field_bcm->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @SocketCAN_Types.SocketCAN_connectu.");
}
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__connectu_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 @SocketCAN_Types.SocketCAN_connectu.");
}
}

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

boolean SocketCAN__connectu_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__connectu_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 `@SocketCAN_Types.SocketCAN_connectu'");
    }
    if (strcmp("bcm", param_field) == 0) {
      bcm().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@SocketCAN_Types.SocketCAN_connectu'", 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__connectu_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", "@SocketCAN_Types.SocketCAN_connectu");
    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, "bcm")) {
      bcm().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_connectu.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_connectu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__connectu_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__connectu::ALT_bcm:
single_value.field_bcm->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_connectu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_connectu.");
}
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 : "@SocketCAN_Types.SocketCAN_connectu");
}

SocketCAN__connect__bcm::SocketCAN__connect__bcm()
{
}

SocketCAN__connect__bcm::SocketCAN__connect__bcm(const INTEGER& par_if__index)
  :   field_if__index(par_if__index)
{
}

SocketCAN__connect__bcm::SocketCAN__connect__bcm(const SocketCAN__connect__bcm& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_connect_bcm.");
if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
else field_if__index.clean_up();
}

void SocketCAN__connect__bcm::clean_up()
{
field_if__index.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__connect__bcm::get_descriptor() const { return &SocketCAN__connect__bcm_descr_; }
SocketCAN__connect__bcm& SocketCAN__connect__bcm::operator=(const SocketCAN__connect__bcm& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_connect_bcm.");
  if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
  else field_if__index.clean_up();
}
return *this;
}

boolean SocketCAN__connect__bcm::operator==(const SocketCAN__connect__bcm& other_value) const
{
return field_if__index==other_value.field_if__index;
}

boolean SocketCAN__connect__bcm::is_bound() const
{
return (field_if__index.is_bound());
}
boolean SocketCAN__connect__bcm::is_value() const
{
return field_if__index.is_value();
}
void SocketCAN__connect__bcm::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ if_index := ");
field_if__index.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__connect__bcm::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_connect_bcm has 1 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) if__index().set_param(*param.get_elem(0));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_connect_bcm: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_connect_bcm");
  }
}

void SocketCAN__connect__bcm::set_implicit_omit()
{
if (if__index().is_bound()) if__index().set_implicit_omit();
}

void SocketCAN__connect__bcm::encode_text(Text_Buf& text_buf) const
{
field_if__index.encode_text(text_buf);
}

void SocketCAN__connect__bcm::decode_text(Text_Buf& text_buf)
{
field_if__index.decode_text(text_buf);
}

struct SocketCAN__connect__bcm_template::single_value_struct {
INTEGER_template field_if__index;
};

void SocketCAN__connect__bcm_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_if__index = ANY_VALUE;
}
}
}

void SocketCAN__connect__bcm_template::copy_value(const SocketCAN__connect__bcm& other_value)
{
single_value = new single_value_struct;
if (other_value.if__index().is_bound()) {
  single_value->field_if__index = other_value.if__index();
} else {
  single_value->field_if__index.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__connect__bcm_template::copy_template(const SocketCAN__connect__bcm_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.if__index().get_selection()) {
single_value->field_if__index = other_value.if__index();
} else {
single_value->field_if__index.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__connect__bcm_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 @SocketCAN_Types.SocketCAN_connect_bcm.");
break;
}
set_selection(other_value);
}

SocketCAN__connect__bcm_template::SocketCAN__connect__bcm_template()
{
}

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

SocketCAN__connect__bcm_template::SocketCAN__connect__bcm_template(const SocketCAN__connect__bcm& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__connect__bcm_template& SocketCAN__connect__bcm_template::operator=(const OPTIONAL<SocketCAN__connect__bcm>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__connect__bcm&)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 @SocketCAN_Types.SocketCAN_connect_bcm.");
}
return *this;
}

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

boolean SocketCAN__connect__bcm_template::match(const SocketCAN__connect__bcm& 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.if__index().is_bound()) return FALSE;
if(!single_value->field_if__index.match(other_value.if__index(), 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 @SocketCAN_Types.SocketCAN_connect_bcm.");
}
return FALSE;
}

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

boolean SocketCAN__connect__bcm_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_if__index.is_value();
}

void SocketCAN__connect__bcm_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__connect__bcm SocketCAN__connect__bcm_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 @SocketCAN_Types.SocketCAN_connect_bcm.");
SocketCAN__connect__bcm ret_val;
if (single_value->field_if__index.is_bound()) {
ret_val.if__index() = single_value->field_if__index.valueof();
}
return ret_val;
}

void SocketCAN__connect__bcm_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 @SocketCAN_Types.SocketCAN_connect_bcm.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__connect__bcm_template[list_length];
}

SocketCAN__connect__bcm_template& SocketCAN__connect__bcm_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 @SocketCAN_Types.SocketCAN_connect_bcm.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_connect_bcm.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__connect__bcm_template::if__index()
{
set_specific();
return single_value->field_if__index;
}

const INTEGER_template& SocketCAN__connect__bcm_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field if_index of a non-specific template of type @SocketCAN_Types.SocketCAN_connect_bcm.");
return single_value->field_if__index;
}

int SocketCAN__connect__bcm_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_bcm which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_bcm 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 @SocketCAN_Types.SocketCAN_connect_bcm containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_bcm containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_bcm containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_bcm containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_connect_bcm.");
  }
  return 0;
}

void SocketCAN__connect__bcm_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ if_index := ");
single_value->field_if__index.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__connect__bcm_template::log_match(const SocketCAN__connect__bcm& 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_if__index.match(match_value.if__index(), legacy)){
TTCN_Logger::log_logmatch_info(".if_index");
single_value->field_if__index.log_match(match_value.if__index(), 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("{ if_index := ");
single_value->field_if__index.log_match(match_value.if__index(), 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__connect__bcm_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_if__index.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 @SocketCAN_Types.SocketCAN_connect_bcm.");
}
}

void SocketCAN__connect__bcm_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_if__index.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__connect__bcm_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 @SocketCAN_Types.SocketCAN_connect_bcm.");
}
}

void SocketCAN__connect__bcm_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__connect__bcm_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_connect_bcm has 1 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) if__index().set_param(*param.get_elem(0));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_connect_bcm: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_connect_bcm");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__connect__bcm_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_if__index.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_connect_bcm");
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 : "@SocketCAN_Types.SocketCAN_connect_bcm");
}

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

boolean SocketCAN__connect__bcm_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;
}

SocketCAN__connect::SocketCAN__connect()
{
}

SocketCAN__connect::SocketCAN__connect(const INTEGER& par_id,
    const SocketCAN__connectu& par_connectu)
  :   field_id(par_id),
  field_connectu(par_connectu)
{
}

SocketCAN__connect::SocketCAN__connect(const SocketCAN__connect& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_connect.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.connectu().is_bound()) field_connectu = other_value.connectu();
else field_connectu.clean_up();
}

void SocketCAN__connect::clean_up()
{
field_id.clean_up();
field_connectu.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__connect::get_descriptor() const { return &SocketCAN__connect_descr_; }
SocketCAN__connect& SocketCAN__connect::operator=(const SocketCAN__connect& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_connect.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.connectu().is_bound()) field_connectu = other_value.connectu();
  else field_connectu.clean_up();
}
return *this;
}

boolean SocketCAN__connect::operator==(const SocketCAN__connect& other_value) const
{
return field_id==other_value.field_id
  && field_connectu==other_value.field_connectu;
}

boolean SocketCAN__connect::is_bound() const
{
return (field_id.is_bound())
  || (field_connectu.is_bound());
}
boolean SocketCAN__connect::is_value() const
{
return field_id.is_value()
  && field_connectu.is_value();
}
void SocketCAN__connect::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", connectu := ");
field_connectu.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__connect::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 @SocketCAN_Types.SocketCAN_connect 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "connectu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectu().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 @SocketCAN_Types.SocketCAN_connect: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_connect");
  }
}

void SocketCAN__connect::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (connectu().is_bound()) connectu().set_implicit_omit();
}

void SocketCAN__connect::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_connectu.encode_text(text_buf);
}

void SocketCAN__connect::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_connectu.decode_text(text_buf);
}

struct SocketCAN__connect_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__connectu_template field_connectu;
};

void SocketCAN__connect_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_id = ANY_VALUE;
single_value->field_connectu = ANY_VALUE;
}
}
}

void SocketCAN__connect_template::copy_value(const SocketCAN__connect& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.connectu().is_bound()) {
  single_value->field_connectu = other_value.connectu();
} else {
  single_value->field_connectu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__connect_template::copy_template(const SocketCAN__connect_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.connectu().get_selection()) {
single_value->field_connectu = other_value.connectu();
} else {
single_value->field_connectu.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__connect_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 @SocketCAN_Types.SocketCAN_connect.");
break;
}
set_selection(other_value);
}

SocketCAN__connect_template::SocketCAN__connect_template()
{
}

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

SocketCAN__connect_template::SocketCAN__connect_template(const SocketCAN__connect& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__connect_template& SocketCAN__connect_template::operator=(const OPTIONAL<SocketCAN__connect>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__connect&)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 @SocketCAN_Types.SocketCAN_connect.");
}
return *this;
}

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

boolean SocketCAN__connect_template::match(const SocketCAN__connect& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.connectu().is_bound()) return FALSE;
if(!single_value->field_connectu.match(other_value.connectu(), 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 @SocketCAN_Types.SocketCAN_connect.");
}
return FALSE;
}

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

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

boolean SocketCAN__connect_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_connectu.is_value();
}

void SocketCAN__connect_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__connect SocketCAN__connect_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 @SocketCAN_Types.SocketCAN_connect.");
SocketCAN__connect ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_connectu.is_bound()) {
ret_val.connectu() = single_value->field_connectu.valueof();
}
return ret_val;
}

void SocketCAN__connect_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 @SocketCAN_Types.SocketCAN_connect.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__connect_template[list_length];
}

SocketCAN__connect_template& SocketCAN__connect_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 @SocketCAN_Types.SocketCAN_connect.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_connect.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__connect_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__connect_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_connect.");
return single_value->field_id;
}

SocketCAN__connectu_template& SocketCAN__connect_template::connectu()
{
set_specific();
return single_value->field_connectu;
}

const SocketCAN__connectu_template& SocketCAN__connect_template::connectu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field connectu of a non-specific template of type @SocketCAN_Types.SocketCAN_connect.");
return single_value->field_connectu;
}

int SocketCAN__connect_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect 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 @SocketCAN_Types.SocketCAN_connect 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 @SocketCAN_Types.SocketCAN_connect containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_connect.");
  }
  return 0;
}

void SocketCAN__connect_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", connectu := ");
single_value->field_connectu.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__connect_template::log_match(const SocketCAN__connect& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_connectu.match(match_value.connectu(), legacy)){
TTCN_Logger::log_logmatch_info(".connectu");
single_value->field_connectu.log_match(match_value.connectu(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", connectu := ");
single_value->field_connectu.log_match(match_value.connectu(), 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__connect_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_connectu.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 @SocketCAN_Types.SocketCAN_connect.");
}
}

void SocketCAN__connect_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_id.decode_text(text_buf);
single_value->field_connectu.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__connect_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 @SocketCAN_Types.SocketCAN_connect.");
}
}

void SocketCAN__connect_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__connect_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 @SocketCAN_Types.SocketCAN_connect 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "connectu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectu().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 @SocketCAN_Types.SocketCAN_connect: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_connect");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__connect_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_connect");
single_value->field_connectu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_connect");
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 : "@SocketCAN_Types.SocketCAN_connect");
}

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

boolean SocketCAN__connect_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;
}

SocketCAN__connect__result::SocketCAN__connect__result()
{
}

SocketCAN__connect__result::SocketCAN__connect__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__connect__result::SocketCAN__connect__result(const SocketCAN__connect__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_connect_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__connect__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__connect__result::get_descriptor() const { return &SocketCAN__connect__result_descr_; }
SocketCAN__connect__result& SocketCAN__connect__result::operator=(const SocketCAN__connect__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_connect_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__connect__result::operator==(const SocketCAN__connect__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__connect__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__connect__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__connect__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__connect__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_connect_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_connect_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_connect_result");
  }
}

void SocketCAN__connect__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__connect__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__connect__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__connect__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__connect__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__connect__result_template::copy_value(const SocketCAN__connect__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__connect__result_template::copy_template(const SocketCAN__connect__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__connect__result_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 @SocketCAN_Types.SocketCAN_connect_result.");
break;
}
set_selection(other_value);
}

SocketCAN__connect__result_template::SocketCAN__connect__result_template()
{
}

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

SocketCAN__connect__result_template::SocketCAN__connect__result_template(const SocketCAN__connect__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__connect__result_template& SocketCAN__connect__result_template::operator=(const OPTIONAL<SocketCAN__connect__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__connect__result&)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 @SocketCAN_Types.SocketCAN_connect_result.");
}
return *this;
}

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

boolean SocketCAN__connect__result_template::match(const SocketCAN__connect__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_connect_result.");
}
return FALSE;
}

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

boolean SocketCAN__connect__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__connect__result_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__connect__result SocketCAN__connect__result_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 @SocketCAN_Types.SocketCAN_connect_result.");
SocketCAN__connect__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__connect__result_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 @SocketCAN_Types.SocketCAN_connect_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__connect__result_template[list_length];
}

SocketCAN__connect__result_template& SocketCAN__connect__result_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 @SocketCAN_Types.SocketCAN_connect_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_connect_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__connect__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__connect__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_connect_result.");
return single_value->field_result;
}

int SocketCAN__connect__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_result 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 @SocketCAN_Types.SocketCAN_connect_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_connect_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_connect_result.");
  }
  return 0;
}

void SocketCAN__connect__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__connect__result_template::log_match(const SocketCAN__connect__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__connect__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_connect_result.");
}
}

void SocketCAN__connect__result_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_result.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__connect__result_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 @SocketCAN_Types.SocketCAN_connect_result.");
}
}

void SocketCAN__connect__result_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__connect__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_connect_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_connect_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_connect_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__connect__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_connect_result");
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 : "@SocketCAN_Types.SocketCAN_connect_result");
}

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

boolean SocketCAN__connect__result_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;
}

SocketCAN__bind__raw::SocketCAN__bind__raw()
{
}

SocketCAN__bind__raw::SocketCAN__bind__raw(const INTEGER& par_if__index)
  :   field_if__index(par_if__index)
{
}

SocketCAN__bind__raw::SocketCAN__bind__raw(const SocketCAN__bind__raw& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_bind_raw.");
if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
else field_if__index.clean_up();
}

void SocketCAN__bind__raw::clean_up()
{
field_if__index.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__bind__raw::get_descriptor() const { return &SocketCAN__bind__raw_descr_; }
SocketCAN__bind__raw& SocketCAN__bind__raw::operator=(const SocketCAN__bind__raw& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_bind_raw.");
  if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
  else field_if__index.clean_up();
}
return *this;
}

boolean SocketCAN__bind__raw::operator==(const SocketCAN__bind__raw& other_value) const
{
return field_if__index==other_value.field_if__index;
}

boolean SocketCAN__bind__raw::is_bound() const
{
return (field_if__index.is_bound());
}
boolean SocketCAN__bind__raw::is_value() const
{
return field_if__index.is_value();
}
void SocketCAN__bind__raw::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ if_index := ");
field_if__index.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__bind__raw::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_bind_raw has 1 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) if__index().set_param(*param.get_elem(0));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_bind_raw: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_bind_raw");
  }
}

void SocketCAN__bind__raw::set_implicit_omit()
{
if (if__index().is_bound()) if__index().set_implicit_omit();
}

void SocketCAN__bind__raw::encode_text(Text_Buf& text_buf) const
{
field_if__index.encode_text(text_buf);
}

void SocketCAN__bind__raw::decode_text(Text_Buf& text_buf)
{
field_if__index.decode_text(text_buf);
}

struct SocketCAN__bind__raw_template::single_value_struct {
INTEGER_template field_if__index;
};

void SocketCAN__bind__raw_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_if__index = ANY_VALUE;
}
}
}

void SocketCAN__bind__raw_template::copy_value(const SocketCAN__bind__raw& other_value)
{
single_value = new single_value_struct;
if (other_value.if__index().is_bound()) {
  single_value->field_if__index = other_value.if__index();
} else {
  single_value->field_if__index.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bind__raw_template::copy_template(const SocketCAN__bind__raw_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.if__index().get_selection()) {
single_value->field_if__index = other_value.if__index();
} else {
single_value->field_if__index.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__bind__raw_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 @SocketCAN_Types.SocketCAN_bind_raw.");
break;
}
set_selection(other_value);
}

SocketCAN__bind__raw_template::SocketCAN__bind__raw_template()
{
}

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

SocketCAN__bind__raw_template::SocketCAN__bind__raw_template(const SocketCAN__bind__raw& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__bind__raw_template& SocketCAN__bind__raw_template::operator=(const OPTIONAL<SocketCAN__bind__raw>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bind__raw&)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 @SocketCAN_Types.SocketCAN_bind_raw.");
}
return *this;
}

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

boolean SocketCAN__bind__raw_template::match(const SocketCAN__bind__raw& 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.if__index().is_bound()) return FALSE;
if(!single_value->field_if__index.match(other_value.if__index(), 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 @SocketCAN_Types.SocketCAN_bind_raw.");
}
return FALSE;
}

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

boolean SocketCAN__bind__raw_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_if__index.is_value();
}

void SocketCAN__bind__raw_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__bind__raw SocketCAN__bind__raw_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 @SocketCAN_Types.SocketCAN_bind_raw.");
SocketCAN__bind__raw ret_val;
if (single_value->field_if__index.is_bound()) {
ret_val.if__index() = single_value->field_if__index.valueof();
}
return ret_val;
}

void SocketCAN__bind__raw_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 @SocketCAN_Types.SocketCAN_bind_raw.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bind__raw_template[list_length];
}

SocketCAN__bind__raw_template& SocketCAN__bind__raw_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 @SocketCAN_Types.SocketCAN_bind_raw.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_bind_raw.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__bind__raw_template::if__index()
{
set_specific();
return single_value->field_if__index;
}

const INTEGER_template& SocketCAN__bind__raw_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field if_index of a non-specific template of type @SocketCAN_Types.SocketCAN_bind_raw.");
return single_value->field_if__index;
}

int SocketCAN__bind__raw_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_raw which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_raw 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 @SocketCAN_Types.SocketCAN_bind_raw containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_raw containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_raw containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_raw containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_bind_raw.");
  }
  return 0;
}

void SocketCAN__bind__raw_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ if_index := ");
single_value->field_if__index.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__bind__raw_template::log_match(const SocketCAN__bind__raw& 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_if__index.match(match_value.if__index(), legacy)){
TTCN_Logger::log_logmatch_info(".if_index");
single_value->field_if__index.log_match(match_value.if__index(), 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("{ if_index := ");
single_value->field_if__index.log_match(match_value.if__index(), 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__bind__raw_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_if__index.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 @SocketCAN_Types.SocketCAN_bind_raw.");
}
}

void SocketCAN__bind__raw_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_if__index.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__bind__raw_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 @SocketCAN_Types.SocketCAN_bind_raw.");
}
}

void SocketCAN__bind__raw_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__bind__raw_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_bind_raw has 1 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) if__index().set_param(*param.get_elem(0));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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 @SocketCAN_Types.SocketCAN_bind_raw: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_bind_raw");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bind__raw_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_if__index.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind_raw");
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 : "@SocketCAN_Types.SocketCAN_bind_raw");
}

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

boolean SocketCAN__bind__raw_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;
}

SocketCAN__bind__isotp::SocketCAN__bind__isotp()
{
}

SocketCAN__bind__isotp::SocketCAN__bind__isotp(const INTEGER& par_if__index,
    const OCTETSTRING& par_rx__can__id,
    const OCTETSTRING& par_tx__can__id)
  :   field_if__index(par_if__index),
  field_rx__can__id(par_rx__can__id),
  field_tx__can__id(par_tx__can__id)
{
}

SocketCAN__bind__isotp::SocketCAN__bind__isotp(const SocketCAN__bind__isotp& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_bind_isotp.");
if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
else field_if__index.clean_up();
if (other_value.rx__can__id().is_bound()) field_rx__can__id = other_value.rx__can__id();
else field_rx__can__id.clean_up();
if (other_value.tx__can__id().is_bound()) field_tx__can__id = other_value.tx__can__id();
else field_tx__can__id.clean_up();
}

void SocketCAN__bind__isotp::clean_up()
{
field_if__index.clean_up();
field_rx__can__id.clean_up();
field_tx__can__id.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__bind__isotp::get_descriptor() const { return &SocketCAN__bind__isotp_descr_; }
SocketCAN__bind__isotp& SocketCAN__bind__isotp::operator=(const SocketCAN__bind__isotp& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_bind_isotp.");
  if (other_value.if__index().is_bound()) field_if__index = other_value.if__index();
  else field_if__index.clean_up();
  if (other_value.rx__can__id().is_bound()) field_rx__can__id = other_value.rx__can__id();
  else field_rx__can__id.clean_up();
  if (other_value.tx__can__id().is_bound()) field_tx__can__id = other_value.tx__can__id();
  else field_tx__can__id.clean_up();
}
return *this;
}

boolean SocketCAN__bind__isotp::operator==(const SocketCAN__bind__isotp& other_value) const
{
return field_if__index==other_value.field_if__index
  && field_rx__can__id==other_value.field_rx__can__id
  && field_tx__can__id==other_value.field_tx__can__id;
}

boolean SocketCAN__bind__isotp::is_bound() const
{
return (field_if__index.is_bound())
  || (field_rx__can__id.is_bound())
  || (field_tx__can__id.is_bound());
}
boolean SocketCAN__bind__isotp::is_value() const
{
return field_if__index.is_value()
  && field_rx__can__id.is_value()
  && field_tx__can__id.is_value();
}
void SocketCAN__bind__isotp::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ if_index := ");
field_if__index.log();
TTCN_Logger::log_event_str(", rx_can_id := ");
field_rx__can__id.log();
TTCN_Logger::log_event_str(", tx_can_id := ");
field_tx__can__id.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__bind__isotp::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_bind_isotp has 3 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) if__index().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) rx__can__id().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) tx__can__id().set_param(*param.get_elem(2));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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(), "rx_can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          rx__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(), "tx_can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tx__can__id().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 @SocketCAN_Types.SocketCAN_bind_isotp: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_bind_isotp");
  }
}

void SocketCAN__bind__isotp::set_implicit_omit()
{
if (if__index().is_bound()) if__index().set_implicit_omit();
if (rx__can__id().is_bound()) rx__can__id().set_implicit_omit();
if (tx__can__id().is_bound()) tx__can__id().set_implicit_omit();
}

void SocketCAN__bind__isotp::encode_text(Text_Buf& text_buf) const
{
field_if__index.encode_text(text_buf);
field_rx__can__id.encode_text(text_buf);
field_tx__can__id.encode_text(text_buf);
}

void SocketCAN__bind__isotp::decode_text(Text_Buf& text_buf)
{
field_if__index.decode_text(text_buf);
field_rx__can__id.decode_text(text_buf);
field_tx__can__id.decode_text(text_buf);
}

struct SocketCAN__bind__isotp_template::single_value_struct {
INTEGER_template field_if__index;
OCTETSTRING_template field_rx__can__id;
OCTETSTRING_template field_tx__can__id;
};

void SocketCAN__bind__isotp_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_if__index = ANY_VALUE;
single_value->field_rx__can__id = ANY_VALUE;
single_value->field_tx__can__id = ANY_VALUE;
}
}
}

void SocketCAN__bind__isotp_template::copy_value(const SocketCAN__bind__isotp& other_value)
{
single_value = new single_value_struct;
if (other_value.if__index().is_bound()) {
  single_value->field_if__index = other_value.if__index();
} else {
  single_value->field_if__index.clean_up();
}
if (other_value.rx__can__id().is_bound()) {
  single_value->field_rx__can__id = other_value.rx__can__id();
} else {
  single_value->field_rx__can__id.clean_up();
}
if (other_value.tx__can__id().is_bound()) {
  single_value->field_tx__can__id = other_value.tx__can__id();
} else {
  single_value->field_tx__can__id.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bind__isotp_template::copy_template(const SocketCAN__bind__isotp_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.if__index().get_selection()) {
single_value->field_if__index = other_value.if__index();
} else {
single_value->field_if__index.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.rx__can__id().get_selection()) {
single_value->field_rx__can__id = other_value.rx__can__id();
} else {
single_value->field_rx__can__id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.tx__can__id().get_selection()) {
single_value->field_tx__can__id = other_value.tx__can__id();
} else {
single_value->field_tx__can__id.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__bind__isotp_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 @SocketCAN_Types.SocketCAN_bind_isotp.");
break;
}
set_selection(other_value);
}

SocketCAN__bind__isotp_template::SocketCAN__bind__isotp_template()
{
}

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

SocketCAN__bind__isotp_template::SocketCAN__bind__isotp_template(const SocketCAN__bind__isotp& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__bind__isotp_template& SocketCAN__bind__isotp_template::operator=(const OPTIONAL<SocketCAN__bind__isotp>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bind__isotp&)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 @SocketCAN_Types.SocketCAN_bind_isotp.");
}
return *this;
}

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

boolean SocketCAN__bind__isotp_template::match(const SocketCAN__bind__isotp& 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.if__index().is_bound()) return FALSE;
if(!single_value->field_if__index.match(other_value.if__index(), legacy))return FALSE;
if(!other_value.rx__can__id().is_bound()) return FALSE;
if(!single_value->field_rx__can__id.match(other_value.rx__can__id(), legacy))return FALSE;
if(!other_value.tx__can__id().is_bound()) return FALSE;
if(!single_value->field_tx__can__id.match(other_value.tx__can__id(), 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 @SocketCAN_Types.SocketCAN_bind_isotp.");
}
return FALSE;
}

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

 ||single_value->field_rx__can__id.is_bound()

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

boolean SocketCAN__bind__isotp_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_if__index.is_value()
 &&single_value->field_rx__can__id.is_value()
 &&single_value->field_tx__can__id.is_value();
}

void SocketCAN__bind__isotp_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__bind__isotp SocketCAN__bind__isotp_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 @SocketCAN_Types.SocketCAN_bind_isotp.");
SocketCAN__bind__isotp ret_val;
if (single_value->field_if__index.is_bound()) {
ret_val.if__index() = single_value->field_if__index.valueof();
}
if (single_value->field_rx__can__id.is_bound()) {
ret_val.rx__can__id() = single_value->field_rx__can__id.valueof();
}
if (single_value->field_tx__can__id.is_bound()) {
ret_val.tx__can__id() = single_value->field_tx__can__id.valueof();
}
return ret_val;
}

void SocketCAN__bind__isotp_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 @SocketCAN_Types.SocketCAN_bind_isotp.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bind__isotp_template[list_length];
}

SocketCAN__bind__isotp_template& SocketCAN__bind__isotp_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 @SocketCAN_Types.SocketCAN_bind_isotp.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_bind_isotp.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__bind__isotp_template::if__index()
{
set_specific();
return single_value->field_if__index;
}

const INTEGER_template& SocketCAN__bind__isotp_template::if__index() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field if_index of a non-specific template of type @SocketCAN_Types.SocketCAN_bind_isotp.");
return single_value->field_if__index;
}

OCTETSTRING_template& SocketCAN__bind__isotp_template::rx__can__id()
{
set_specific();
return single_value->field_rx__can__id;
}

const OCTETSTRING_template& SocketCAN__bind__isotp_template::rx__can__id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field rx_can_id of a non-specific template of type @SocketCAN_Types.SocketCAN_bind_isotp.");
return single_value->field_rx__can__id;
}

OCTETSTRING_template& SocketCAN__bind__isotp_template::tx__can__id()
{
set_specific();
return single_value->field_tx__can__id;
}

const OCTETSTRING_template& SocketCAN__bind__isotp_template::tx__can__id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field tx_can_id of a non-specific template of type @SocketCAN_Types.SocketCAN_bind_isotp.");
return single_value->field_tx__can__id;
}

int SocketCAN__bind__isotp_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_isotp which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_isotp 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 @SocketCAN_Types.SocketCAN_bind_isotp containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_isotp containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_isotp containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_isotp containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_bind_isotp.");
  }
  return 0;
}

void SocketCAN__bind__isotp_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ if_index := ");
single_value->field_if__index.log();
TTCN_Logger::log_event_str(", rx_can_id := ");
single_value->field_rx__can__id.log();
TTCN_Logger::log_event_str(", tx_can_id := ");
single_value->field_tx__can__id.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__bind__isotp_template::log_match(const SocketCAN__bind__isotp& 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_if__index.match(match_value.if__index(), legacy)){
TTCN_Logger::log_logmatch_info(".if_index");
single_value->field_if__index.log_match(match_value.if__index(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_rx__can__id.match(match_value.rx__can__id(), legacy)){
TTCN_Logger::log_logmatch_info(".rx_can_id");
single_value->field_rx__can__id.log_match(match_value.rx__can__id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_tx__can__id.match(match_value.tx__can__id(), legacy)){
TTCN_Logger::log_logmatch_info(".tx_can_id");
single_value->field_tx__can__id.log_match(match_value.tx__can__id(), 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("{ if_index := ");
single_value->field_if__index.log_match(match_value.if__index(), legacy);
TTCN_Logger::log_event_str(", rx_can_id := ");
single_value->field_rx__can__id.log_match(match_value.rx__can__id(), legacy);
TTCN_Logger::log_event_str(", tx_can_id := ");
single_value->field_tx__can__id.log_match(match_value.tx__can__id(), 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__bind__isotp_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_if__index.encode_text(text_buf);
single_value->field_rx__can__id.encode_text(text_buf);
single_value->field_tx__can__id.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 @SocketCAN_Types.SocketCAN_bind_isotp.");
}
}

void SocketCAN__bind__isotp_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_if__index.decode_text(text_buf);
single_value->field_rx__can__id.decode_text(text_buf);
single_value->field_tx__can__id.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__bind__isotp_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 @SocketCAN_Types.SocketCAN_bind_isotp.");
}
}

void SocketCAN__bind__isotp_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__bind__isotp_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_bind_isotp has 3 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) if__index().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) rx__can__id().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) tx__can__id().set_param(*param.get_elem(2));
    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(), "if_index")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          if__index().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(), "rx_can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          rx__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(), "tx_can_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          tx__can__id().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 @SocketCAN_Types.SocketCAN_bind_isotp: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_bind_isotp");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bind__isotp_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_if__index.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind_isotp");
single_value->field_rx__can__id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind_isotp");
single_value->field_tx__can__id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind_isotp");
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 : "@SocketCAN_Types.SocketCAN_bind_isotp");
}

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

boolean SocketCAN__bind__isotp_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__bindu::copy_value(const SocketCAN__bindu& other_value)
{
switch (other_value.union_selection) {
case ALT_raw:
field_raw = new SocketCAN__bind__raw(*other_value.field_raw);
break;
case ALT_isotp:
field_isotp = new SocketCAN__bind__isotp(*other_value.field_isotp);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_bindu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__bindu::operator==(const SocketCAN__bindu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_bindu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_bindu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_raw:
return *field_raw == *other_value.field_raw;
case ALT_isotp:
return *field_isotp == *other_value.field_isotp;
default:
return FALSE;
}
}

SocketCAN__bind__raw& SocketCAN__bindu::raw()
{
if (union_selection != ALT_raw) {
clean_up();
field_raw = new SocketCAN__bind__raw;
union_selection = ALT_raw;
}
return *field_raw;
}

const SocketCAN__bind__raw& SocketCAN__bindu::raw() const
{
if (union_selection != ALT_raw) TTCN_error("Using non-selected field raw in a value of union type @SocketCAN_Types.SocketCAN_bindu.");
return *field_raw;
}

SocketCAN__bind__isotp& SocketCAN__bindu::isotp()
{
if (union_selection != ALT_isotp) {
clean_up();
field_isotp = new SocketCAN__bind__isotp;
union_selection = ALT_isotp;
}
return *field_isotp;
}

const SocketCAN__bind__isotp& SocketCAN__bindu::isotp() const
{
if (union_selection != ALT_isotp) TTCN_error("Using non-selected field isotp in a value of union type @SocketCAN_Types.SocketCAN_bindu.");
return *field_isotp;
}

boolean SocketCAN__bindu::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 @SocketCAN_Types.SocketCAN_bindu.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__bindu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_raw: return field_raw->is_value();
case ALT_isotp: return field_isotp->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__bindu::clean_up()
{
switch (union_selection) {
case ALT_raw:
  delete field_raw;
  break;
case ALT_isotp:
  delete field_isotp;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__bindu::log() const
{
switch (union_selection) {
case ALT_raw:
TTCN_Logger::log_event_str("{ raw := ");
field_raw->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_isotp:
TTCN_Logger::log_event_str("{ isotp := ");
field_isotp->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__bindu::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, "raw")) {
    raw().set_param(*mp_last);
    if (!raw().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "isotp")) {
    isotp().set_param(*mp_last);
    if (!isotp().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_bindu.", last_name);
}

void SocketCAN__bindu::set_implicit_omit()
{
switch (union_selection) {
case ALT_raw:
field_raw->set_implicit_omit(); break;
case ALT_isotp:
field_isotp->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__bindu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_raw:
field_raw->encode_text(text_buf);
break;
case ALT_isotp:
field_isotp->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @SocketCAN_Types.SocketCAN_bindu.");
}
}

void SocketCAN__bindu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_raw:
raw().decode_text(text_buf);
break;
case ALT_isotp:
isotp().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @SocketCAN_Types.SocketCAN_bindu.");
}
}

void SocketCAN__bindu_template::copy_value(const SocketCAN__bindu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__bindu::ALT_raw:
single_value.field_raw = new SocketCAN__bind__raw_template(other_value.raw());
break;
case SocketCAN__bindu::ALT_isotp:
single_value.field_isotp = new SocketCAN__bind__isotp_template(other_value.isotp());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_bindu.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bindu_template::copy_template(const SocketCAN__bindu_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__bindu::ALT_raw:
single_value.field_raw = new SocketCAN__bind__raw_template(*other_value.single_value.field_raw);
break;
case SocketCAN__bindu::ALT_isotp:
single_value.field_isotp = new SocketCAN__bind__isotp_template(*other_value.single_value.field_isotp);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @SocketCAN_Types.SocketCAN_bindu.");
}
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__bindu_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 @SocketCAN_Types.SocketCAN_bindu.");
}
set_selection(other_value);
}

SocketCAN__bindu_template::SocketCAN__bindu_template()
{
}

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

SocketCAN__bindu_template::SocketCAN__bindu_template(const SocketCAN__bindu& other_value)
{
copy_value(other_value);
}

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

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

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

void SocketCAN__bindu_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__bindu::ALT_raw:
delete single_value.field_raw;
break;
case SocketCAN__bindu::ALT_isotp:
delete single_value.field_isotp;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

SocketCAN__bindu_template& SocketCAN__bindu_template::operator=(const OPTIONAL<SocketCAN__bindu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bindu&)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 @SocketCAN_Types.SocketCAN_bindu.");
}
return *this;
}

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

boolean SocketCAN__bindu_template::match(const SocketCAN__bindu& 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__bindu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__bindu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__bindu::ALT_raw:
return single_value.field_raw->match(other_value.raw(), legacy);
case SocketCAN__bindu::ALT_isotp:
return single_value.field_isotp->match(other_value.isotp(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @SocketCAN_Types.SocketCAN_bindu.");
}
}
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 @SocketCAN_Types.SocketCAN_bindu.");
}
return FALSE;
}

boolean SocketCAN__bindu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__bindu::ALT_raw:
return single_value.field_raw->is_value();
case SocketCAN__bindu::ALT_isotp:
return single_value.field_isotp->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @SocketCAN_Types.SocketCAN_bindu.");
}
}

SocketCAN__bindu SocketCAN__bindu_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 @SocketCAN_Types.SocketCAN_bindu.");
SocketCAN__bindu ret_val;
switch (single_value.union_selection) {
case SocketCAN__bindu::ALT_raw:
ret_val.raw() = single_value.field_raw->valueof();
break;
case SocketCAN__bindu::ALT_isotp:
ret_val.isotp() = single_value.field_isotp->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @SocketCAN_Types.SocketCAN_bindu.");
}
return ret_val;
}

SocketCAN__bindu_template& SocketCAN__bindu_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 @SocketCAN_Types.SocketCAN_bindu.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_bindu.");
return value_list.list_value[list_index];
}
void SocketCAN__bindu_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 @SocketCAN_Types.SocketCAN_bindu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bindu_template[list_length];
}

SocketCAN__bind__raw_template& SocketCAN__bindu_template::raw()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__bindu::ALT_raw) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_raw = new SocketCAN__bind__raw_template(ANY_VALUE);
else single_value.field_raw = new SocketCAN__bind__raw_template;
single_value.union_selection = SocketCAN__bindu::ALT_raw;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_raw;
}

const SocketCAN__bind__raw_template& SocketCAN__bindu_template::raw() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field raw in a non-specific template of union type @SocketCAN_Types.SocketCAN_bindu.");
if (single_value.union_selection != SocketCAN__bindu::ALT_raw) TTCN_error("Accessing non-selected field raw in a template of union type @SocketCAN_Types.SocketCAN_bindu.");
return *single_value.field_raw;
}

SocketCAN__bind__isotp_template& SocketCAN__bindu_template::isotp()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__bindu::ALT_isotp) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_isotp = new SocketCAN__bind__isotp_template(ANY_VALUE);
else single_value.field_isotp = new SocketCAN__bind__isotp_template;
single_value.union_selection = SocketCAN__bindu::ALT_isotp;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_isotp;
}

const SocketCAN__bind__isotp_template& SocketCAN__bindu_template::isotp() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field isotp in a non-specific template of union type @SocketCAN_Types.SocketCAN_bindu.");
if (single_value.union_selection != SocketCAN__bindu::ALT_isotp) TTCN_error("Accessing non-selected field isotp in a template of union type @SocketCAN_Types.SocketCAN_bindu.");
return *single_value.field_isotp;
}

boolean SocketCAN__bindu_template::ischosen(SocketCAN__bindu::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__bindu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_bindu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__bindu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_bindu.");
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 @SocketCAN_Types.SocketCAN_bindu 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__bindu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__bindu::ALT_raw:
TTCN_Logger::log_event_str("{ raw := ");
single_value.field_raw->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__bindu::ALT_isotp:
TTCN_Logger::log_event_str("{ isotp := ");
single_value.field_isotp->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__bindu_template::log_match(const SocketCAN__bindu& 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__bindu::ALT_raw:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".raw");
single_value.field_raw->log_match(match_value.raw(), legacy);
} else {
TTCN_Logger::log_event_str("{ raw := ");
single_value.field_raw->log_match(match_value.raw(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__bindu::ALT_isotp:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".isotp");
single_value.field_isotp->log_match(match_value.isotp(), legacy);
} else {
TTCN_Logger::log_event_str("{ isotp := ");
single_value.field_isotp->log_match(match_value.isotp(), 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__bindu_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__bindu::ALT_raw:
single_value.field_raw->encode_text(text_buf);
break;
case SocketCAN__bindu::ALT_isotp:
single_value.field_isotp->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @SocketCAN_Types.SocketCAN_bindu.");
}
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 @SocketCAN_Types.SocketCAN_bindu.");
}
}

void SocketCAN__bindu_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__bindu::UNBOUND_VALUE;
SocketCAN__bindu::union_selection_type new_selection = (SocketCAN__bindu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__bindu::ALT_raw:
single_value.field_raw = new SocketCAN__bind__raw_template;
single_value.field_raw->decode_text(text_buf);
break;
case SocketCAN__bindu::ALT_isotp:
single_value.field_isotp = new SocketCAN__bind__isotp_template;
single_value.field_isotp->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @SocketCAN_Types.SocketCAN_bindu.");
}
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__bindu_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 @SocketCAN_Types.SocketCAN_bindu.");
}
}

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

boolean SocketCAN__bindu_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__bindu_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 `@SocketCAN_Types.SocketCAN_bindu'");
    }
    if (strcmp("raw", param_field) == 0) {
      raw().set_param(param);
      return;
    } else if (strcmp("isotp", param_field) == 0) {
      isotp().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@SocketCAN_Types.SocketCAN_bindu'", 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__bindu_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", "@SocketCAN_Types.SocketCAN_bindu");
    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, "raw")) {
      raw().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "isotp")) {
      isotp().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_bindu.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_bindu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bindu_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__bindu::ALT_raw:
single_value.field_raw->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bindu");
return;
case SocketCAN__bindu::ALT_isotp:
single_value.field_isotp->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bindu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_bindu.");
}
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 : "@SocketCAN_Types.SocketCAN_bindu");
}

SocketCAN__bind::SocketCAN__bind()
{
}

SocketCAN__bind::SocketCAN__bind(const INTEGER& par_id,
    const SocketCAN__bindu& par_bindu)
  :   field_id(par_id),
  field_bindu(par_bindu)
{
}

SocketCAN__bind::SocketCAN__bind(const SocketCAN__bind& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_bind.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.bindu().is_bound()) field_bindu = other_value.bindu();
else field_bindu.clean_up();
}

void SocketCAN__bind::clean_up()
{
field_id.clean_up();
field_bindu.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__bind::get_descriptor() const { return &SocketCAN__bind_descr_; }
SocketCAN__bind& SocketCAN__bind::operator=(const SocketCAN__bind& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_bind.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.bindu().is_bound()) field_bindu = other_value.bindu();
  else field_bindu.clean_up();
}
return *this;
}

boolean SocketCAN__bind::operator==(const SocketCAN__bind& other_value) const
{
return field_id==other_value.field_id
  && field_bindu==other_value.field_bindu;
}

boolean SocketCAN__bind::is_bound() const
{
return (field_id.is_bound())
  || (field_bindu.is_bound());
}
boolean SocketCAN__bind::is_value() const
{
return field_id.is_value()
  && field_bindu.is_value();
}
void SocketCAN__bind::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", bindu := ");
field_bindu.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__bind::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 @SocketCAN_Types.SocketCAN_bind 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) bindu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "bindu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          bindu().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 @SocketCAN_Types.SocketCAN_bind: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_bind");
  }
}

void SocketCAN__bind::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (bindu().is_bound()) bindu().set_implicit_omit();
}

void SocketCAN__bind::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_bindu.encode_text(text_buf);
}

void SocketCAN__bind::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_bindu.decode_text(text_buf);
}

struct SocketCAN__bind_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__bindu_template field_bindu;
};

void SocketCAN__bind_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_id = ANY_VALUE;
single_value->field_bindu = ANY_VALUE;
}
}
}

void SocketCAN__bind_template::copy_value(const SocketCAN__bind& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.bindu().is_bound()) {
  single_value->field_bindu = other_value.bindu();
} else {
  single_value->field_bindu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bind_template::copy_template(const SocketCAN__bind_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.bindu().get_selection()) {
single_value->field_bindu = other_value.bindu();
} else {
single_value->field_bindu.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__bind_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 @SocketCAN_Types.SocketCAN_bind.");
break;
}
set_selection(other_value);
}

SocketCAN__bind_template::SocketCAN__bind_template()
{
}

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

SocketCAN__bind_template::SocketCAN__bind_template(const SocketCAN__bind& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__bind_template& SocketCAN__bind_template::operator=(const OPTIONAL<SocketCAN__bind>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bind&)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 @SocketCAN_Types.SocketCAN_bind.");
}
return *this;
}

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

boolean SocketCAN__bind_template::match(const SocketCAN__bind& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.bindu().is_bound()) return FALSE;
if(!single_value->field_bindu.match(other_value.bindu(), 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 @SocketCAN_Types.SocketCAN_bind.");
}
return FALSE;
}

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

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

boolean SocketCAN__bind_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_bindu.is_value();
}

void SocketCAN__bind_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__bind SocketCAN__bind_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 @SocketCAN_Types.SocketCAN_bind.");
SocketCAN__bind ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_bindu.is_bound()) {
ret_val.bindu() = single_value->field_bindu.valueof();
}
return ret_val;
}

void SocketCAN__bind_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 @SocketCAN_Types.SocketCAN_bind.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bind_template[list_length];
}

SocketCAN__bind_template& SocketCAN__bind_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 @SocketCAN_Types.SocketCAN_bind.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_bind.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__bind_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__bind_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_bind.");
return single_value->field_id;
}

SocketCAN__bindu_template& SocketCAN__bind_template::bindu()
{
set_specific();
return single_value->field_bindu;
}

const SocketCAN__bindu_template& SocketCAN__bind_template::bindu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field bindu of a non-specific template of type @SocketCAN_Types.SocketCAN_bind.");
return single_value->field_bindu;
}

int SocketCAN__bind_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind 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 @SocketCAN_Types.SocketCAN_bind 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 @SocketCAN_Types.SocketCAN_bind containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_bind.");
  }
  return 0;
}

void SocketCAN__bind_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", bindu := ");
single_value->field_bindu.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__bind_template::log_match(const SocketCAN__bind& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_bindu.match(match_value.bindu(), legacy)){
TTCN_Logger::log_logmatch_info(".bindu");
single_value->field_bindu.log_match(match_value.bindu(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", bindu := ");
single_value->field_bindu.log_match(match_value.bindu(), 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__bind_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_bindu.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 @SocketCAN_Types.SocketCAN_bind.");
}
}

void SocketCAN__bind_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_id.decode_text(text_buf);
single_value->field_bindu.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__bind_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 @SocketCAN_Types.SocketCAN_bind.");
}
}

void SocketCAN__bind_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__bind_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 @SocketCAN_Types.SocketCAN_bind 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) bindu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "bindu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          bindu().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 @SocketCAN_Types.SocketCAN_bind: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_bind");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bind_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind");
single_value->field_bindu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind");
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 : "@SocketCAN_Types.SocketCAN_bind");
}

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

boolean SocketCAN__bind_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;
}

SocketCAN__bind__result::SocketCAN__bind__result()
{
}

SocketCAN__bind__result::SocketCAN__bind__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__bind__result::SocketCAN__bind__result(const SocketCAN__bind__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_bind_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__bind__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__bind__result::get_descriptor() const { return &SocketCAN__bind__result_descr_; }
SocketCAN__bind__result& SocketCAN__bind__result::operator=(const SocketCAN__bind__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_bind_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__bind__result::operator==(const SocketCAN__bind__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__bind__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__bind__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__bind__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__bind__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_bind_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_bind_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_bind_result");
  }
}

void SocketCAN__bind__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__bind__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__bind__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__bind__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__bind__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__bind__result_template::copy_value(const SocketCAN__bind__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__bind__result_template::copy_template(const SocketCAN__bind__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__bind__result_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 @SocketCAN_Types.SocketCAN_bind_result.");
break;
}
set_selection(other_value);
}

SocketCAN__bind__result_template::SocketCAN__bind__result_template()
{
}

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

SocketCAN__bind__result_template::SocketCAN__bind__result_template(const SocketCAN__bind__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__bind__result_template& SocketCAN__bind__result_template::operator=(const OPTIONAL<SocketCAN__bind__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__bind__result&)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 @SocketCAN_Types.SocketCAN_bind_result.");
}
return *this;
}

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

boolean SocketCAN__bind__result_template::match(const SocketCAN__bind__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_bind_result.");
}
return FALSE;
}

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

boolean SocketCAN__bind__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__bind__result_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__bind__result SocketCAN__bind__result_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 @SocketCAN_Types.SocketCAN_bind_result.");
SocketCAN__bind__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__bind__result_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 @SocketCAN_Types.SocketCAN_bind_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__bind__result_template[list_length];
}

SocketCAN__bind__result_template& SocketCAN__bind__result_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 @SocketCAN_Types.SocketCAN_bind_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_bind_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__bind__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__bind__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_bind_result.");
return single_value->field_result;
}

int SocketCAN__bind__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_result 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 @SocketCAN_Types.SocketCAN_bind_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_bind_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_bind_result.");
  }
  return 0;
}

void SocketCAN__bind__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__bind__result_template::log_match(const SocketCAN__bind__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__bind__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_bind_result.");
}
}

void SocketCAN__bind__result_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_result.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__bind__result_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 @SocketCAN_Types.SocketCAN_bind_result.");
}
}

void SocketCAN__bind__result_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__bind__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_bind_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_bind_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_bind_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__bind__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_bind_result");
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 : "@SocketCAN_Types.SocketCAN_bind_result");
}

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

boolean SocketCAN__bind__result_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;
}

SocketCAN__send__data::SocketCAN__send__data()
{
}

SocketCAN__send__data::SocketCAN__send__data(const INTEGER& par_id,
    const OPTIONAL<SocketCAN__send__data__ifu>& par_ifu,
    const SocketCAN__CAN__or__CAN__FD__frame& par_frame)
  :   field_id(par_id),
  field_ifu(par_ifu),
  field_frame(par_frame)
{
}

SocketCAN__send__data::SocketCAN__send__data(const SocketCAN__send__data& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_send_data.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.ifu().is_bound()) field_ifu = other_value.ifu();
else field_ifu.clean_up();
if (other_value.frame().is_bound()) field_frame = other_value.frame();
else field_frame.clean_up();
}

void SocketCAN__send__data::clean_up()
{
field_id.clean_up();
field_ifu.clean_up();
field_frame.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__send__data::get_descriptor() const { return &SocketCAN__send__data_descr_; }
SocketCAN__send__data& SocketCAN__send__data::operator=(const SocketCAN__send__data& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_send_data.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.ifu().is_bound()) field_ifu = other_value.ifu();
  else field_ifu.clean_up();
  if (other_value.frame().is_bound()) field_frame = other_value.frame();
  else field_frame.clean_up();
}
return *this;
}

boolean SocketCAN__send__data::operator==(const SocketCAN__send__data& other_value) const
{
return field_id==other_value.field_id
  && field_ifu==other_value.field_ifu
  && field_frame==other_value.field_frame;
}

boolean SocketCAN__send__data::is_bound() const
{
return (field_id.is_bound())
  || (OPTIONAL_OMIT == field_ifu.get_selection() || field_ifu.is_bound())
  || (field_frame.is_bound());
}
boolean SocketCAN__send__data::is_value() const
{
return field_id.is_value()
  && (OPTIONAL_OMIT == field_ifu.get_selection() || field_ifu.is_value())
  && field_frame.is_value();
}
int SocketCAN__send__data::size_of() const
{
  int ret_val = 2;
  if (field_ifu.ispresent()) ret_val++;
  return ret_val;
}

void SocketCAN__send__data::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", ifu := ");
field_ifu.log();
TTCN_Logger::log_event_str(", frame := ");
field_frame.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__send__data::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_send_data has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifu().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifu().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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 @SocketCAN_Types.SocketCAN_send_data: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_send_data");
  }
}

void SocketCAN__send__data::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (!ifu().is_bound()) ifu() = OMIT_VALUE;
else ifu().set_implicit_omit();
if (frame().is_bound()) frame().set_implicit_omit();
}

void SocketCAN__send__data::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_ifu.encode_text(text_buf);
field_frame.encode_text(text_buf);
}

void SocketCAN__send__data::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_ifu.decode_text(text_buf);
field_frame.decode_text(text_buf);
}

struct SocketCAN__send__data_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__send__data__ifu_template field_ifu;
SocketCAN__CAN__or__CAN__FD__frame_template field_frame;
};

void SocketCAN__send__data_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_id = ANY_VALUE;
single_value->field_ifu = ANY_OR_OMIT;
single_value->field_frame = ANY_VALUE;
}
}
}

void SocketCAN__send__data_template::copy_value(const SocketCAN__send__data& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.ifu().is_bound()) {
  if (other_value.ifu().ispresent()) single_value->field_ifu = other_value.ifu()();
  else single_value->field_ifu = OMIT_VALUE;
} else {
  single_value->field_ifu.clean_up();
}
if (other_value.frame().is_bound()) {
  single_value->field_frame = other_value.frame();
} else {
  single_value->field_frame.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__send__data_template::copy_template(const SocketCAN__send__data_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ifu().get_selection()) {
single_value->field_ifu = other_value.ifu();
} else {
single_value->field_ifu.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.frame().get_selection()) {
single_value->field_frame = other_value.frame();
} else {
single_value->field_frame.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__send__data_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 @SocketCAN_Types.SocketCAN_send_data.");
break;
}
set_selection(other_value);
}

SocketCAN__send__data_template::SocketCAN__send__data_template()
{
}

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

SocketCAN__send__data_template::SocketCAN__send__data_template(const SocketCAN__send__data& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__send__data_template& SocketCAN__send__data_template::operator=(const OPTIONAL<SocketCAN__send__data>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__send__data&)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 @SocketCAN_Types.SocketCAN_send_data.");
}
return *this;
}

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

boolean SocketCAN__send__data_template::match(const SocketCAN__send__data& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.ifu().is_bound()) return FALSE;
if((other_value.ifu().ispresent() ? !single_value->field_ifu.match((const SocketCAN__send__data__ifu&)other_value.ifu(), legacy) : !single_value->field_ifu.match_omit(legacy)))return FALSE;
if(!other_value.frame().is_bound()) return FALSE;
if(!single_value->field_frame.match(other_value.frame(), 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 @SocketCAN_Types.SocketCAN_send_data.");
}
return FALSE;
}

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

 ||(single_value->field_ifu.is_omit() || single_value->field_ifu.is_bound())

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

boolean SocketCAN__send__data_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&(single_value->field_ifu.is_omit() || single_value->field_ifu.is_value())
 &&single_value->field_frame.is_value();
}

void SocketCAN__send__data_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__send__data SocketCAN__send__data_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 @SocketCAN_Types.SocketCAN_send_data.");
SocketCAN__send__data ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_ifu.is_omit()) ret_val.ifu() = OMIT_VALUE;
else if (single_value->field_ifu.is_bound()) {
ret_val.ifu() = single_value->field_ifu.valueof();
}
if (single_value->field_frame.is_bound()) {
ret_val.frame() = single_value->field_frame.valueof();
}
return ret_val;
}

void SocketCAN__send__data_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 @SocketCAN_Types.SocketCAN_send_data.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__send__data_template[list_length];
}

SocketCAN__send__data_template& SocketCAN__send__data_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 @SocketCAN_Types.SocketCAN_send_data.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_send_data.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__send__data_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__send__data_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_send_data.");
return single_value->field_id;
}

SocketCAN__send__data__ifu_template& SocketCAN__send__data_template::ifu()
{
set_specific();
return single_value->field_ifu;
}

const SocketCAN__send__data__ifu_template& SocketCAN__send__data_template::ifu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifu of a non-specific template of type @SocketCAN_Types.SocketCAN_send_data.");
return single_value->field_ifu;
}

SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__send__data_template::frame()
{
set_specific();
return single_value->field_frame;
}

const SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__send__data_template::frame() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field frame of a non-specific template of type @SocketCAN_Types.SocketCAN_send_data.");
return single_value->field_frame;
}

int SocketCAN__send__data_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
  {    int ret_val = 2;
      if (single_value->field_ifu.is_present()) ret_val++;
      return ret_val;
    }
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data 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 @SocketCAN_Types.SocketCAN_send_data containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_send_data.");
  }
  return 0;
}

void SocketCAN__send__data_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", ifu := ");
single_value->field_ifu.log();
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.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__send__data_template::log_match(const SocketCAN__send__data& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if (match_value.ifu().ispresent()){
if(!single_value->field_ifu.match(match_value.ifu(), legacy)){
TTCN_Logger::log_logmatch_info(".ifu");
single_value->field_ifu.log_match(match_value.ifu(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
} else {
if (!single_value->field_ifu.match_omit(legacy)){
 TTCN_Logger::log_logmatch_info(".ifu := omit with ");
TTCN_Logger::print_logmatch_buffer();
single_value->field_ifu.log();
TTCN_Logger::log_event_str(" unmatched");
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}
if(!single_value->field_frame.match(match_value.frame(), legacy)){
TTCN_Logger::log_logmatch_info(".frame");
single_value->field_frame.log_match(match_value.frame(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", ifu := ");
if (match_value.ifu().ispresent()) single_value->field_ifu.log_match(match_value.ifu(), legacy);
else {
TTCN_Logger::log_event_str("omit with ");
single_value->field_ifu.log();
if (single_value->field_ifu.match_omit(legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.log_match(match_value.frame(), 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__send__data_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_ifu.encode_text(text_buf);
single_value->field_frame.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 @SocketCAN_Types.SocketCAN_send_data.");
}
}

void SocketCAN__send__data_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_id.decode_text(text_buf);
single_value->field_ifu.decode_text(text_buf);
single_value->field_frame.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__send__data_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 @SocketCAN_Types.SocketCAN_send_data.");
}
}

void SocketCAN__send__data_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__send__data_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_send_data has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifu().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifu().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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 @SocketCAN_Types.SocketCAN_send_data: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_send_data");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__send__data_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data");
single_value->field_ifu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data");
single_value->field_frame.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data");
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 : "@SocketCAN_Types.SocketCAN_send_data");
}

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

boolean SocketCAN__send__data_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;
}

SocketCAN__send__data__result::SocketCAN__send__data__result()
{
}

SocketCAN__send__data__result::SocketCAN__send__data__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__send__data__result::SocketCAN__send__data__result(const SocketCAN__send__data__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_send_data_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__send__data__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__send__data__result::get_descriptor() const { return &SocketCAN__send__data__result_descr_; }
SocketCAN__send__data__result& SocketCAN__send__data__result::operator=(const SocketCAN__send__data__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_send_data_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__send__data__result::operator==(const SocketCAN__send__data__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__send__data__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__send__data__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__send__data__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__send__data__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_send_data_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_send_data_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_send_data_result");
  }
}

void SocketCAN__send__data__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__send__data__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__send__data__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__send__data__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__send__data__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__send__data__result_template::copy_value(const SocketCAN__send__data__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__send__data__result_template::copy_template(const SocketCAN__send__data__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__send__data__result_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 @SocketCAN_Types.SocketCAN_send_data_result.");
break;
}
set_selection(other_value);
}

SocketCAN__send__data__result_template::SocketCAN__send__data__result_template()
{
}

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

SocketCAN__send__data__result_template::SocketCAN__send__data__result_template(const SocketCAN__send__data__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__send__data__result_template& SocketCAN__send__data__result_template::operator=(const OPTIONAL<SocketCAN__send__data__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__send__data__result&)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 @SocketCAN_Types.SocketCAN_send_data_result.");
}
return *this;
}

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

boolean SocketCAN__send__data__result_template::match(const SocketCAN__send__data__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_send_data_result.");
}
return FALSE;
}

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

boolean SocketCAN__send__data__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__send__data__result_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__send__data__result SocketCAN__send__data__result_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 @SocketCAN_Types.SocketCAN_send_data_result.");
SocketCAN__send__data__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__send__data__result_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 @SocketCAN_Types.SocketCAN_send_data_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__send__data__result_template[list_length];
}

SocketCAN__send__data__result_template& SocketCAN__send__data__result_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 @SocketCAN_Types.SocketCAN_send_data_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_send_data_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__send__data__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__send__data__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_send_data_result.");
return single_value->field_result;
}

int SocketCAN__send__data__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data_result 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 @SocketCAN_Types.SocketCAN_send_data_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_send_data_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_send_data_result.");
  }
  return 0;
}

void SocketCAN__send__data__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__send__data__result_template::log_match(const SocketCAN__send__data__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__send__data__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_send_data_result.");
}
}

void SocketCAN__send__data__result_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_result.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__send__data__result_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 @SocketCAN_Types.SocketCAN_send_data_result.");
}
}

void SocketCAN__send__data__result_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__send__data__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_send_data_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_send_data_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_send_data_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__send__data__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_send_data_result");
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 : "@SocketCAN_Types.SocketCAN_send_data_result");
}

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

boolean SocketCAN__send__data__result_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;
}

SocketCAN__write__data::SocketCAN__write__data()
{
}

SocketCAN__write__data::SocketCAN__write__data(const INTEGER& par_id,
    const Bcm::SocketCAN__bcm__frame& par_bcm__tx__msg)
  :   field_id(par_id),
  field_bcm__tx__msg(par_bcm__tx__msg)
{
}

SocketCAN__write__data::SocketCAN__write__data(const SocketCAN__write__data& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_write_data.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.bcm__tx__msg().is_bound()) field_bcm__tx__msg = other_value.bcm__tx__msg();
else field_bcm__tx__msg.clean_up();
}

void SocketCAN__write__data::clean_up()
{
field_id.clean_up();
field_bcm__tx__msg.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__write__data::get_descriptor() const { return &SocketCAN__write__data_descr_; }
SocketCAN__write__data& SocketCAN__write__data::operator=(const SocketCAN__write__data& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_write_data.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.bcm__tx__msg().is_bound()) field_bcm__tx__msg = other_value.bcm__tx__msg();
  else field_bcm__tx__msg.clean_up();
}
return *this;
}

boolean SocketCAN__write__data::operator==(const SocketCAN__write__data& other_value) const
{
return field_id==other_value.field_id
  && field_bcm__tx__msg==other_value.field_bcm__tx__msg;
}

boolean SocketCAN__write__data::is_bound() const
{
return (field_id.is_bound())
  || (field_bcm__tx__msg.is_bound());
}
boolean SocketCAN__write__data::is_value() const
{
return field_id.is_value()
  && field_bcm__tx__msg.is_value();
}
void SocketCAN__write__data::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", bcm_tx_msg := ");
field_bcm__tx__msg.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__write__data::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 @SocketCAN_Types.SocketCAN_write_data 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) bcm__tx__msg().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "bcm_tx_msg")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          bcm__tx__msg().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 @SocketCAN_Types.SocketCAN_write_data: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_write_data");
  }
}

void SocketCAN__write__data::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (bcm__tx__msg().is_bound()) bcm__tx__msg().set_implicit_omit();
}

void SocketCAN__write__data::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_bcm__tx__msg.encode_text(text_buf);
}

void SocketCAN__write__data::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_bcm__tx__msg.decode_text(text_buf);
}

struct SocketCAN__write__data_template::single_value_struct {
INTEGER_template field_id;
Bcm::SocketCAN__bcm__frame_template field_bcm__tx__msg;
};

void SocketCAN__write__data_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_id = ANY_VALUE;
single_value->field_bcm__tx__msg = ANY_VALUE;
}
}
}

void SocketCAN__write__data_template::copy_value(const SocketCAN__write__data& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.bcm__tx__msg().is_bound()) {
  single_value->field_bcm__tx__msg = other_value.bcm__tx__msg();
} else {
  single_value->field_bcm__tx__msg.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__write__data_template::copy_template(const SocketCAN__write__data_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.bcm__tx__msg().get_selection()) {
single_value->field_bcm__tx__msg = other_value.bcm__tx__msg();
} else {
single_value->field_bcm__tx__msg.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__write__data_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 @SocketCAN_Types.SocketCAN_write_data.");
break;
}
set_selection(other_value);
}

SocketCAN__write__data_template::SocketCAN__write__data_template()
{
}

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

SocketCAN__write__data_template::SocketCAN__write__data_template(const SocketCAN__write__data& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__write__data_template& SocketCAN__write__data_template::operator=(const OPTIONAL<SocketCAN__write__data>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__write__data&)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 @SocketCAN_Types.SocketCAN_write_data.");
}
return *this;
}

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

boolean SocketCAN__write__data_template::match(const SocketCAN__write__data& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.bcm__tx__msg().is_bound()) return FALSE;
if(!single_value->field_bcm__tx__msg.match(other_value.bcm__tx__msg(), 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 @SocketCAN_Types.SocketCAN_write_data.");
}
return FALSE;
}

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

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

boolean SocketCAN__write__data_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_bcm__tx__msg.is_value();
}

void SocketCAN__write__data_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__write__data SocketCAN__write__data_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 @SocketCAN_Types.SocketCAN_write_data.");
SocketCAN__write__data ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_bcm__tx__msg.is_bound()) {
ret_val.bcm__tx__msg() = single_value->field_bcm__tx__msg.valueof();
}
return ret_val;
}

void SocketCAN__write__data_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 @SocketCAN_Types.SocketCAN_write_data.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__write__data_template[list_length];
}

SocketCAN__write__data_template& SocketCAN__write__data_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 @SocketCAN_Types.SocketCAN_write_data.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_write_data.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__write__data_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__write__data_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_write_data.");
return single_value->field_id;
}

Bcm::SocketCAN__bcm__frame_template& SocketCAN__write__data_template::bcm__tx__msg()
{
set_specific();
return single_value->field_bcm__tx__msg;
}

const Bcm::SocketCAN__bcm__frame_template& SocketCAN__write__data_template::bcm__tx__msg() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field bcm_tx_msg of a non-specific template of type @SocketCAN_Types.SocketCAN_write_data.");
return single_value->field_bcm__tx__msg;
}

int SocketCAN__write__data_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data 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 @SocketCAN_Types.SocketCAN_write_data 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 @SocketCAN_Types.SocketCAN_write_data containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_write_data.");
  }
  return 0;
}

void SocketCAN__write__data_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", bcm_tx_msg := ");
single_value->field_bcm__tx__msg.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__write__data_template::log_match(const SocketCAN__write__data& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_bcm__tx__msg.match(match_value.bcm__tx__msg(), legacy)){
TTCN_Logger::log_logmatch_info(".bcm_tx_msg");
single_value->field_bcm__tx__msg.log_match(match_value.bcm__tx__msg(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", bcm_tx_msg := ");
single_value->field_bcm__tx__msg.log_match(match_value.bcm__tx__msg(), 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__write__data_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_bcm__tx__msg.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 @SocketCAN_Types.SocketCAN_write_data.");
}
}

void SocketCAN__write__data_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_id.decode_text(text_buf);
single_value->field_bcm__tx__msg.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__write__data_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 @SocketCAN_Types.SocketCAN_write_data.");
}
}

void SocketCAN__write__data_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__write__data_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 @SocketCAN_Types.SocketCAN_write_data 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) bcm__tx__msg().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "bcm_tx_msg")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          bcm__tx__msg().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 @SocketCAN_Types.SocketCAN_write_data: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_write_data");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__write__data_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_data");
single_value->field_bcm__tx__msg.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_data");
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 : "@SocketCAN_Types.SocketCAN_write_data");
}

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

boolean SocketCAN__write__data_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;
}

SocketCAN__write__data__result::SocketCAN__write__data__result()
{
}

SocketCAN__write__data__result::SocketCAN__write__data__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__write__data__result::SocketCAN__write__data__result(const SocketCAN__write__data__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_write_data_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__write__data__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__write__data__result::get_descriptor() const { return &SocketCAN__write__data__result_descr_; }
SocketCAN__write__data__result& SocketCAN__write__data__result::operator=(const SocketCAN__write__data__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_write_data_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__write__data__result::operator==(const SocketCAN__write__data__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__write__data__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__write__data__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__write__data__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__write__data__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_write_data_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_write_data_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_write_data_result");
  }
}

void SocketCAN__write__data__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__write__data__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__write__data__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__write__data__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__write__data__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__write__data__result_template::copy_value(const SocketCAN__write__data__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__write__data__result_template::copy_template(const SocketCAN__write__data__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__write__data__result_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 @SocketCAN_Types.SocketCAN_write_data_result.");
break;
}
set_selection(other_value);
}

SocketCAN__write__data__result_template::SocketCAN__write__data__result_template()
{
}

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

SocketCAN__write__data__result_template::SocketCAN__write__data__result_template(const SocketCAN__write__data__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__write__data__result_template& SocketCAN__write__data__result_template::operator=(const OPTIONAL<SocketCAN__write__data__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__write__data__result&)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 @SocketCAN_Types.SocketCAN_write_data_result.");
}
return *this;
}

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

boolean SocketCAN__write__data__result_template::match(const SocketCAN__write__data__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_write_data_result.");
}
return FALSE;
}

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

boolean SocketCAN__write__data__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__write__data__result_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__write__data__result SocketCAN__write__data__result_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 @SocketCAN_Types.SocketCAN_write_data_result.");
SocketCAN__write__data__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__write__data__result_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 @SocketCAN_Types.SocketCAN_write_data_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__write__data__result_template[list_length];
}

SocketCAN__write__data__result_template& SocketCAN__write__data__result_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 @SocketCAN_Types.SocketCAN_write_data_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_write_data_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__write__data__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__write__data__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_write_data_result.");
return single_value->field_result;
}

int SocketCAN__write__data__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data_result 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 @SocketCAN_Types.SocketCAN_write_data_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_data_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_write_data_result.");
  }
  return 0;
}

void SocketCAN__write__data__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__write__data__result_template::log_match(const SocketCAN__write__data__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__write__data__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_write_data_result.");
}
}

void SocketCAN__write__data__result_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_result.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__write__data__result_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 @SocketCAN_Types.SocketCAN_write_data_result.");
}
}

void SocketCAN__write__data__result_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__write__data__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_write_data_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_write_data_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_write_data_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__write__data__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_data_result");
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 : "@SocketCAN_Types.SocketCAN_write_data_result");
}

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

boolean SocketCAN__write__data__result_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;
}

SocketCAN__write__isotp::SocketCAN__write__isotp()
{
}

SocketCAN__write__isotp::SocketCAN__write__isotp(const INTEGER& par_id,
    const OCTETSTRING& par_pdu)
  :   field_id(par_id),
  field_pdu(par_pdu)
{
}

SocketCAN__write__isotp::SocketCAN__write__isotp(const SocketCAN__write__isotp& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_write_isotp.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.pdu().is_bound()) field_pdu = other_value.pdu();
else field_pdu.clean_up();
}

void SocketCAN__write__isotp::clean_up()
{
field_id.clean_up();
field_pdu.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__write__isotp::get_descriptor() const { return &SocketCAN__write__isotp_descr_; }
SocketCAN__write__isotp& SocketCAN__write__isotp::operator=(const SocketCAN__write__isotp& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_write_isotp.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.pdu().is_bound()) field_pdu = other_value.pdu();
  else field_pdu.clean_up();
}
return *this;
}

boolean SocketCAN__write__isotp::operator==(const SocketCAN__write__isotp& other_value) const
{
return field_id==other_value.field_id
  && field_pdu==other_value.field_pdu;
}

boolean SocketCAN__write__isotp::is_bound() const
{
return (field_id.is_bound())
  || (field_pdu.is_bound());
}
boolean SocketCAN__write__isotp::is_value() const
{
return field_id.is_value()
  && field_pdu.is_value();
}
void SocketCAN__write__isotp::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", pdu := ");
field_pdu.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__write__isotp::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 @SocketCAN_Types.SocketCAN_write_isotp 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) pdu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pdu().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 @SocketCAN_Types.SocketCAN_write_isotp: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_write_isotp");
  }
}

void SocketCAN__write__isotp::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (pdu().is_bound()) pdu().set_implicit_omit();
}

void SocketCAN__write__isotp::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_pdu.encode_text(text_buf);
}

void SocketCAN__write__isotp::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_pdu.decode_text(text_buf);
}

struct SocketCAN__write__isotp_template::single_value_struct {
INTEGER_template field_id;
OCTETSTRING_template field_pdu;
};

void SocketCAN__write__isotp_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_id = ANY_VALUE;
single_value->field_pdu = ANY_VALUE;
}
}
}

void SocketCAN__write__isotp_template::copy_value(const SocketCAN__write__isotp& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.pdu().is_bound()) {
  single_value->field_pdu = other_value.pdu();
} else {
  single_value->field_pdu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__write__isotp_template::copy_template(const SocketCAN__write__isotp_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pdu().get_selection()) {
single_value->field_pdu = other_value.pdu();
} else {
single_value->field_pdu.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__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp.");
break;
}
set_selection(other_value);
}

SocketCAN__write__isotp_template::SocketCAN__write__isotp_template()
{
}

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

SocketCAN__write__isotp_template::SocketCAN__write__isotp_template(const SocketCAN__write__isotp& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__write__isotp_template& SocketCAN__write__isotp_template::operator=(const OPTIONAL<SocketCAN__write__isotp>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__write__isotp&)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 @SocketCAN_Types.SocketCAN_write_isotp.");
}
return *this;
}

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

boolean SocketCAN__write__isotp_template::match(const SocketCAN__write__isotp& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.pdu().is_bound()) return FALSE;
if(!single_value->field_pdu.match(other_value.pdu(), 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 @SocketCAN_Types.SocketCAN_write_isotp.");
}
return FALSE;
}

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

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

boolean SocketCAN__write__isotp_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_pdu.is_value();
}

void SocketCAN__write__isotp_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__write__isotp SocketCAN__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp.");
SocketCAN__write__isotp ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_pdu.is_bound()) {
ret_val.pdu() = single_value->field_pdu.valueof();
}
return ret_val;
}

void SocketCAN__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__write__isotp_template[list_length];
}

SocketCAN__write__isotp_template& SocketCAN__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_write_isotp.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__write__isotp_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__write__isotp_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_write_isotp.");
return single_value->field_id;
}

OCTETSTRING_template& SocketCAN__write__isotp_template::pdu()
{
set_specific();
return single_value->field_pdu;
}

const OCTETSTRING_template& SocketCAN__write__isotp_template::pdu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pdu of a non-specific template of type @SocketCAN_Types.SocketCAN_write_isotp.");
return single_value->field_pdu;
}

int SocketCAN__write__isotp_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp 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 @SocketCAN_Types.SocketCAN_write_isotp 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 @SocketCAN_Types.SocketCAN_write_isotp containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_write_isotp.");
  }
  return 0;
}

void SocketCAN__write__isotp_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", pdu := ");
single_value->field_pdu.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__write__isotp_template::log_match(const SocketCAN__write__isotp& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pdu.match(match_value.pdu(), legacy)){
TTCN_Logger::log_logmatch_info(".pdu");
single_value->field_pdu.log_match(match_value.pdu(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", pdu := ");
single_value->field_pdu.log_match(match_value.pdu(), 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__write__isotp_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_pdu.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 @SocketCAN_Types.SocketCAN_write_isotp.");
}
}

void SocketCAN__write__isotp_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_id.decode_text(text_buf);
single_value->field_pdu.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__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp.");
}
}

void SocketCAN__write__isotp_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__write__isotp_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 @SocketCAN_Types.SocketCAN_write_isotp 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) pdu().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pdu().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 @SocketCAN_Types.SocketCAN_write_isotp: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_write_isotp");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__write__isotp_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_isotp");
single_value->field_pdu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_isotp");
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 : "@SocketCAN_Types.SocketCAN_write_isotp");
}

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

boolean SocketCAN__write__isotp_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;
}

SocketCAN__write__isotp__result::SocketCAN__write__isotp__result()
{
}

SocketCAN__write__isotp__result::SocketCAN__write__isotp__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__write__isotp__result::SocketCAN__write__isotp__result(const SocketCAN__write__isotp__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_write_isotp_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__write__isotp__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__write__isotp__result::get_descriptor() const { return &SocketCAN__write__isotp__result_descr_; }
SocketCAN__write__isotp__result& SocketCAN__write__isotp__result::operator=(const SocketCAN__write__isotp__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_write_isotp_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__write__isotp__result::operator==(const SocketCAN__write__isotp__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__write__isotp__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__write__isotp__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__write__isotp__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__write__isotp__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_write_isotp_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_write_isotp_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_write_isotp_result");
  }
}

void SocketCAN__write__isotp__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__write__isotp__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__write__isotp__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__write__isotp__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__write__isotp__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__write__isotp__result_template::copy_value(const SocketCAN__write__isotp__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__write__isotp__result_template::copy_template(const SocketCAN__write__isotp__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__write__isotp__result_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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
break;
}
set_selection(other_value);
}

SocketCAN__write__isotp__result_template::SocketCAN__write__isotp__result_template()
{
}

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

SocketCAN__write__isotp__result_template::SocketCAN__write__isotp__result_template(const SocketCAN__write__isotp__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__write__isotp__result_template& SocketCAN__write__isotp__result_template::operator=(const OPTIONAL<SocketCAN__write__isotp__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__write__isotp__result&)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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
}
return *this;
}

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

boolean SocketCAN__write__isotp__result_template::match(const SocketCAN__write__isotp__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
}
return FALSE;
}

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

boolean SocketCAN__write__isotp__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__write__isotp__result_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__write__isotp__result SocketCAN__write__isotp__result_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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
SocketCAN__write__isotp__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__write__isotp__result_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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__write__isotp__result_template[list_length];
}

SocketCAN__write__isotp__result_template& SocketCAN__write__isotp__result_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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_write_isotp_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__write__isotp__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__write__isotp__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_write_isotp_result.");
return single_value->field_result;
}

int SocketCAN__write__isotp__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp_result 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 @SocketCAN_Types.SocketCAN_write_isotp_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_write_isotp_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_write_isotp_result.");
  }
  return 0;
}

void SocketCAN__write__isotp__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__write__isotp__result_template::log_match(const SocketCAN__write__isotp__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__write__isotp__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
}
}

void SocketCAN__write__isotp__result_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_result.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__write__isotp__result_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 @SocketCAN_Types.SocketCAN_write_isotp_result.");
}
}

void SocketCAN__write__isotp__result_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__write__isotp__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_write_isotp_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_write_isotp_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_write_isotp_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__write__isotp__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_write_isotp_result");
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 : "@SocketCAN_Types.SocketCAN_write_isotp_result");
}

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

boolean SocketCAN__write__isotp__result_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;
}

SocketCAN__receive__CAN__or__CAN__FD__frame::SocketCAN__receive__CAN__or__CAN__FD__frame()
{
}

SocketCAN__receive__CAN__or__CAN__FD__frame::SocketCAN__receive__CAN__or__CAN__FD__frame(const INTEGER& par_id,
    const SocketCAN__ifr& par_ifr,
    const SocketCAN__CAN__or__CAN__FD__frame& par_frame,
    const SocketCAN__timeval& par_timestamp)
  :   field_id(par_id),
  field_ifr(par_ifr),
  field_frame(par_frame),
  field_timestamp(par_timestamp)
{
}

SocketCAN__receive__CAN__or__CAN__FD__frame::SocketCAN__receive__CAN__or__CAN__FD__frame(const SocketCAN__receive__CAN__or__CAN__FD__frame& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
else field_ifr.clean_up();
if (other_value.frame().is_bound()) field_frame = other_value.frame();
else field_frame.clean_up();
if (other_value.timestamp().is_bound()) field_timestamp = other_value.timestamp();
else field_timestamp.clean_up();
}

void SocketCAN__receive__CAN__or__CAN__FD__frame::clean_up()
{
field_id.clean_up();
field_ifr.clean_up();
field_frame.clean_up();
field_timestamp.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__receive__CAN__or__CAN__FD__frame::get_descriptor() const { return &SocketCAN__receive__CAN__or__CAN__FD__frame_descr_; }
SocketCAN__receive__CAN__or__CAN__FD__frame& SocketCAN__receive__CAN__or__CAN__FD__frame::operator=(const SocketCAN__receive__CAN__or__CAN__FD__frame& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
  else field_ifr.clean_up();
  if (other_value.frame().is_bound()) field_frame = other_value.frame();
  else field_frame.clean_up();
  if (other_value.timestamp().is_bound()) field_timestamp = other_value.timestamp();
  else field_timestamp.clean_up();
}
return *this;
}

boolean SocketCAN__receive__CAN__or__CAN__FD__frame::operator==(const SocketCAN__receive__CAN__or__CAN__FD__frame& other_value) const
{
return field_id==other_value.field_id
  && field_ifr==other_value.field_ifr
  && field_frame==other_value.field_frame
  && field_timestamp==other_value.field_timestamp;
}

boolean SocketCAN__receive__CAN__or__CAN__FD__frame::is_bound() const
{
return (field_id.is_bound())
  || (field_ifr.is_bound())
  || (field_frame.is_bound())
  || (field_timestamp.is_bound());
}
boolean SocketCAN__receive__CAN__or__CAN__FD__frame::is_value() const
{
return field_id.is_value()
  && field_ifr.is_value()
  && field_frame.is_value()
  && field_timestamp.is_value();
}
void SocketCAN__receive__CAN__or__CAN__FD__frame::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
field_ifr.log();
TTCN_Logger::log_event_str(", frame := ");
field_frame.log();
TTCN_Logger::log_event_str(", timestamp := ");
field_timestamp.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__receive__CAN__or__CAN__FD__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 (4<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame has 4 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) timestamp().set_param(*param.get_elem(3));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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(), "timestamp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          timestamp().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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
  }
}

void SocketCAN__receive__CAN__or__CAN__FD__frame::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (ifr().is_bound()) ifr().set_implicit_omit();
if (frame().is_bound()) frame().set_implicit_omit();
if (timestamp().is_bound()) timestamp().set_implicit_omit();
}

void SocketCAN__receive__CAN__or__CAN__FD__frame::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_ifr.encode_text(text_buf);
field_frame.encode_text(text_buf);
field_timestamp.encode_text(text_buf);
}

void SocketCAN__receive__CAN__or__CAN__FD__frame::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_ifr.decode_text(text_buf);
field_frame.decode_text(text_buf);
field_timestamp.decode_text(text_buf);
}

struct SocketCAN__receive__CAN__or__CAN__FD__frame_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__ifr_template field_ifr;
SocketCAN__CAN__or__CAN__FD__frame_template field_frame;
SocketCAN__timeval_template field_timestamp;
};

void SocketCAN__receive__CAN__or__CAN__FD__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_id = ANY_VALUE;
single_value->field_ifr = ANY_VALUE;
single_value->field_frame = ANY_VALUE;
single_value->field_timestamp = ANY_VALUE;
}
}
}

void SocketCAN__receive__CAN__or__CAN__FD__frame_template::copy_value(const SocketCAN__receive__CAN__or__CAN__FD__frame& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.ifr().is_bound()) {
  single_value->field_ifr = other_value.ifr();
} else {
  single_value->field_ifr.clean_up();
}
if (other_value.frame().is_bound()) {
  single_value->field_frame = other_value.frame();
} else {
  single_value->field_frame.clean_up();
}
if (other_value.timestamp().is_bound()) {
  single_value->field_timestamp = other_value.timestamp();
} else {
  single_value->field_timestamp.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__receive__CAN__or__CAN__FD__frame_template::copy_template(const SocketCAN__receive__CAN__or__CAN__FD__frame_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ifr().get_selection()) {
single_value->field_ifr = other_value.ifr();
} else {
single_value->field_ifr.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.frame().get_selection()) {
single_value->field_frame = other_value.frame();
} else {
single_value->field_frame.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.timestamp().get_selection()) {
single_value->field_timestamp = other_value.timestamp();
} else {
single_value->field_timestamp.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__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
break;
}
set_selection(other_value);
}

SocketCAN__receive__CAN__or__CAN__FD__frame_template::SocketCAN__receive__CAN__or__CAN__FD__frame_template()
{
}

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

SocketCAN__receive__CAN__or__CAN__FD__frame_template::SocketCAN__receive__CAN__or__CAN__FD__frame_template(const SocketCAN__receive__CAN__or__CAN__FD__frame& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__receive__CAN__or__CAN__FD__frame_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::operator=(const OPTIONAL<SocketCAN__receive__CAN__or__CAN__FD__frame>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
}
return *this;
}

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

boolean SocketCAN__receive__CAN__or__CAN__FD__frame_template::match(const SocketCAN__receive__CAN__or__CAN__FD__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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.ifr().is_bound()) return FALSE;
if(!single_value->field_ifr.match(other_value.ifr(), legacy))return FALSE;
if(!other_value.frame().is_bound()) return FALSE;
if(!single_value->field_frame.match(other_value.frame(), legacy))return FALSE;
if(!other_value.timestamp().is_bound()) return FALSE;
if(!single_value->field_timestamp.match(other_value.timestamp(), 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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
}
return FALSE;
}

boolean SocketCAN__receive__CAN__or__CAN__FD__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_id.is_bound()

 ||single_value->field_ifr.is_bound()

 ||single_value->field_frame.is_bound()

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

boolean SocketCAN__receive__CAN__or__CAN__FD__frame_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_ifr.is_value()
 &&single_value->field_frame.is_value()
 &&single_value->field_timestamp.is_value();
}

void SocketCAN__receive__CAN__or__CAN__FD__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__receive__CAN__or__CAN__FD__frame SocketCAN__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
SocketCAN__receive__CAN__or__CAN__FD__frame ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_ifr.is_bound()) {
ret_val.ifr() = single_value->field_ifr.valueof();
}
if (single_value->field_frame.is_bound()) {
ret_val.frame() = single_value->field_frame.valueof();
}
if (single_value->field_timestamp.is_bound()) {
ret_val.timestamp() = single_value->field_timestamp.valueof();
}
return ret_val;
}

void SocketCAN__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__receive__CAN__or__CAN__FD__frame_template[list_length];
}

SocketCAN__receive__CAN__or__CAN__FD__frame_template& SocketCAN__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
return single_value->field_id;
}

SocketCAN__ifr_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::ifr()
{
set_specific();
return single_value->field_ifr;
}

const SocketCAN__ifr_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::ifr() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifr of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
return single_value->field_ifr;
}

SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::frame()
{
set_specific();
return single_value->field_frame;
}

const SocketCAN__CAN__or__CAN__FD__frame_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::frame() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field frame of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
return single_value->field_frame;
}

SocketCAN__timeval_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::timestamp()
{
set_specific();
return single_value->field_timestamp;
}

const SocketCAN__timeval_template& SocketCAN__receive__CAN__or__CAN__FD__frame_template::timestamp() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field timestamp of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
return single_value->field_timestamp;
}

int SocketCAN__receive__CAN__or__CAN__FD__frame_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 4;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
  }
  return 0;
}

void SocketCAN__receive__CAN__or__CAN__FD__frame_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log();
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.log();
TTCN_Logger::log_event_str(", timestamp := ");
single_value->field_timestamp.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__receive__CAN__or__CAN__FD__frame_template::log_match(const SocketCAN__receive__CAN__or__CAN__FD__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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ifr.match(match_value.ifr(), legacy)){
TTCN_Logger::log_logmatch_info(".ifr");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_frame.match(match_value.frame(), legacy)){
TTCN_Logger::log_logmatch_info(".frame");
single_value->field_frame.log_match(match_value.frame(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_timestamp.match(match_value.timestamp(), legacy)){
TTCN_Logger::log_logmatch_info(".timestamp");
single_value->field_timestamp.log_match(match_value.timestamp(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.log_match(match_value.frame(), legacy);
TTCN_Logger::log_event_str(", timestamp := ");
single_value->field_timestamp.log_match(match_value.timestamp(), 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__receive__CAN__or__CAN__FD__frame_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_ifr.encode_text(text_buf);
single_value->field_frame.encode_text(text_buf);
single_value->field_timestamp.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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
}
}

void SocketCAN__receive__CAN__or__CAN__FD__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_id.decode_text(text_buf);
single_value->field_ifr.decode_text(text_buf);
single_value->field_frame.decode_text(text_buf);
single_value->field_timestamp.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__receive__CAN__or__CAN__FD__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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.");
}
}

void SocketCAN__receive__CAN__or__CAN__FD__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__receive__CAN__or__CAN__FD__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 (4<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame has 4 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) timestamp().set_param(*param.get_elem(3));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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(), "timestamp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          timestamp().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 @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__receive__CAN__or__CAN__FD__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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
single_value->field_ifr.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
single_value->field_frame.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
single_value->field_timestamp.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_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 : "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame");
}

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

boolean SocketCAN__receive__CAN__or__CAN__FD__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;
}

SocketCAN__receive__BCM__message::SocketCAN__receive__BCM__message()
{
}

SocketCAN__receive__BCM__message::SocketCAN__receive__BCM__message(const INTEGER& par_id,
    const SocketCAN__ifr& par_ifr,
    const Bcm::SocketCAN__bcm__frame& par_frame)
  :   field_id(par_id),
  field_ifr(par_ifr),
  field_frame(par_frame)
{
}

SocketCAN__receive__BCM__message::SocketCAN__receive__BCM__message(const SocketCAN__receive__BCM__message& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
else field_ifr.clean_up();
if (other_value.frame().is_bound()) field_frame = other_value.frame();
else field_frame.clean_up();
}

void SocketCAN__receive__BCM__message::clean_up()
{
field_id.clean_up();
field_ifr.clean_up();
field_frame.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__receive__BCM__message::get_descriptor() const { return &SocketCAN__receive__BCM__message_descr_; }
SocketCAN__receive__BCM__message& SocketCAN__receive__BCM__message::operator=(const SocketCAN__receive__BCM__message& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
  else field_ifr.clean_up();
  if (other_value.frame().is_bound()) field_frame = other_value.frame();
  else field_frame.clean_up();
}
return *this;
}

boolean SocketCAN__receive__BCM__message::operator==(const SocketCAN__receive__BCM__message& other_value) const
{
return field_id==other_value.field_id
  && field_ifr==other_value.field_ifr
  && field_frame==other_value.field_frame;
}

boolean SocketCAN__receive__BCM__message::is_bound() const
{
return (field_id.is_bound())
  || (field_ifr.is_bound())
  || (field_frame.is_bound());
}
boolean SocketCAN__receive__BCM__message::is_value() const
{
return field_id.is_value()
  && field_ifr.is_value()
  && field_frame.is_value();
}
void SocketCAN__receive__BCM__message::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
field_ifr.log();
TTCN_Logger::log_event_str(", frame := ");
field_frame.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__receive__BCM__message::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_receive_BCM_message has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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 @SocketCAN_Types.SocketCAN_receive_BCM_message: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_receive_BCM_message");
  }
}

void SocketCAN__receive__BCM__message::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (ifr().is_bound()) ifr().set_implicit_omit();
if (frame().is_bound()) frame().set_implicit_omit();
}

void SocketCAN__receive__BCM__message::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_ifr.encode_text(text_buf);
field_frame.encode_text(text_buf);
}

void SocketCAN__receive__BCM__message::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_ifr.decode_text(text_buf);
field_frame.decode_text(text_buf);
}

struct SocketCAN__receive__BCM__message_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__ifr_template field_ifr;
Bcm::SocketCAN__bcm__frame_template field_frame;
};

void SocketCAN__receive__BCM__message_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_id = ANY_VALUE;
single_value->field_ifr = ANY_VALUE;
single_value->field_frame = ANY_VALUE;
}
}
}

void SocketCAN__receive__BCM__message_template::copy_value(const SocketCAN__receive__BCM__message& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.ifr().is_bound()) {
  single_value->field_ifr = other_value.ifr();
} else {
  single_value->field_ifr.clean_up();
}
if (other_value.frame().is_bound()) {
  single_value->field_frame = other_value.frame();
} else {
  single_value->field_frame.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__receive__BCM__message_template::copy_template(const SocketCAN__receive__BCM__message_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ifr().get_selection()) {
single_value->field_ifr = other_value.ifr();
} else {
single_value->field_ifr.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.frame().get_selection()) {
single_value->field_frame = other_value.frame();
} else {
single_value->field_frame.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__receive__BCM__message_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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
break;
}
set_selection(other_value);
}

SocketCAN__receive__BCM__message_template::SocketCAN__receive__BCM__message_template()
{
}

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

SocketCAN__receive__BCM__message_template::SocketCAN__receive__BCM__message_template(const SocketCAN__receive__BCM__message& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__receive__BCM__message_template& SocketCAN__receive__BCM__message_template::operator=(const OPTIONAL<SocketCAN__receive__BCM__message>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__receive__BCM__message&)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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
}
return *this;
}

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

boolean SocketCAN__receive__BCM__message_template::match(const SocketCAN__receive__BCM__message& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.ifr().is_bound()) return FALSE;
if(!single_value->field_ifr.match(other_value.ifr(), legacy))return FALSE;
if(!other_value.frame().is_bound()) return FALSE;
if(!single_value->field_frame.match(other_value.frame(), 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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
}
return FALSE;
}

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

 ||single_value->field_ifr.is_bound()

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

boolean SocketCAN__receive__BCM__message_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_ifr.is_value()
 &&single_value->field_frame.is_value();
}

void SocketCAN__receive__BCM__message_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__receive__BCM__message SocketCAN__receive__BCM__message_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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
SocketCAN__receive__BCM__message ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_ifr.is_bound()) {
ret_val.ifr() = single_value->field_ifr.valueof();
}
if (single_value->field_frame.is_bound()) {
ret_val.frame() = single_value->field_frame.valueof();
}
return ret_val;
}

void SocketCAN__receive__BCM__message_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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__receive__BCM__message_template[list_length];
}

SocketCAN__receive__BCM__message_template& SocketCAN__receive__BCM__message_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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__receive__BCM__message_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__receive__BCM__message_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
return single_value->field_id;
}

SocketCAN__ifr_template& SocketCAN__receive__BCM__message_template::ifr()
{
set_specific();
return single_value->field_ifr;
}

const SocketCAN__ifr_template& SocketCAN__receive__BCM__message_template::ifr() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifr of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
return single_value->field_ifr;
}

Bcm::SocketCAN__bcm__frame_template& SocketCAN__receive__BCM__message_template::frame()
{
set_specific();
return single_value->field_frame;
}

const Bcm::SocketCAN__bcm__frame_template& SocketCAN__receive__BCM__message_template::frame() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field frame of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
return single_value->field_frame;
}

int SocketCAN__receive__BCM__message_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_BCM_message which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_BCM_message 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 @SocketCAN_Types.SocketCAN_receive_BCM_message containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_BCM_message containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_BCM_message containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_BCM_message containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_receive_BCM_message.");
  }
  return 0;
}

void SocketCAN__receive__BCM__message_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log();
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.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__receive__BCM__message_template::log_match(const SocketCAN__receive__BCM__message& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ifr.match(match_value.ifr(), legacy)){
TTCN_Logger::log_logmatch_info(".ifr");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_frame.match(match_value.frame(), legacy)){
TTCN_Logger::log_logmatch_info(".frame");
single_value->field_frame.log_match(match_value.frame(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::log_event_str(", frame := ");
single_value->field_frame.log_match(match_value.frame(), 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__receive__BCM__message_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_ifr.encode_text(text_buf);
single_value->field_frame.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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
}
}

void SocketCAN__receive__BCM__message_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_id.decode_text(text_buf);
single_value->field_ifr.decode_text(text_buf);
single_value->field_frame.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__receive__BCM__message_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 @SocketCAN_Types.SocketCAN_receive_BCM_message.");
}
}

void SocketCAN__receive__BCM__message_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__receive__BCM__message_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_receive_BCM_message has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) frame().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "frame")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          frame().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 @SocketCAN_Types.SocketCAN_receive_BCM_message: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_receive_BCM_message");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__receive__BCM__message_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_BCM_message");
single_value->field_ifr.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_BCM_message");
single_value->field_frame.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_BCM_message");
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 : "@SocketCAN_Types.SocketCAN_receive_BCM_message");
}

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

boolean SocketCAN__receive__BCM__message_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;
}

SocketCAN__receive__isotp__pdu::SocketCAN__receive__isotp__pdu()
{
}

SocketCAN__receive__isotp__pdu::SocketCAN__receive__isotp__pdu(const INTEGER& par_id,
    const SocketCAN__ifr& par_ifr,
    const OCTETSTRING& par_pdu)
  :   field_id(par_id),
  field_ifr(par_ifr),
  field_pdu(par_pdu)
{
}

SocketCAN__receive__isotp__pdu::SocketCAN__receive__isotp__pdu(const SocketCAN__receive__isotp__pdu& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
else field_ifr.clean_up();
if (other_value.pdu().is_bound()) field_pdu = other_value.pdu();
else field_pdu.clean_up();
}

void SocketCAN__receive__isotp__pdu::clean_up()
{
field_id.clean_up();
field_ifr.clean_up();
field_pdu.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__receive__isotp__pdu::get_descriptor() const { return &SocketCAN__receive__isotp__pdu_descr_; }
SocketCAN__receive__isotp__pdu& SocketCAN__receive__isotp__pdu::operator=(const SocketCAN__receive__isotp__pdu& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.ifr().is_bound()) field_ifr = other_value.ifr();
  else field_ifr.clean_up();
  if (other_value.pdu().is_bound()) field_pdu = other_value.pdu();
  else field_pdu.clean_up();
}
return *this;
}

boolean SocketCAN__receive__isotp__pdu::operator==(const SocketCAN__receive__isotp__pdu& other_value) const
{
return field_id==other_value.field_id
  && field_ifr==other_value.field_ifr
  && field_pdu==other_value.field_pdu;
}

boolean SocketCAN__receive__isotp__pdu::is_bound() const
{
return (field_id.is_bound())
  || (field_ifr.is_bound())
  || (field_pdu.is_bound());
}
boolean SocketCAN__receive__isotp__pdu::is_value() const
{
return field_id.is_value()
  && field_ifr.is_value()
  && field_pdu.is_value();
}
void SocketCAN__receive__isotp__pdu::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
field_ifr.log();
TTCN_Logger::log_event_str(", pdu := ");
field_pdu.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__receive__isotp__pdu::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 (3<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pdu().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pdu().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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
  }
}

void SocketCAN__receive__isotp__pdu::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (ifr().is_bound()) ifr().set_implicit_omit();
if (pdu().is_bound()) pdu().set_implicit_omit();
}

void SocketCAN__receive__isotp__pdu::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_ifr.encode_text(text_buf);
field_pdu.encode_text(text_buf);
}

void SocketCAN__receive__isotp__pdu::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_ifr.decode_text(text_buf);
field_pdu.decode_text(text_buf);
}

struct SocketCAN__receive__isotp__pdu_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__ifr_template field_ifr;
OCTETSTRING_template field_pdu;
};

void SocketCAN__receive__isotp__pdu_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_id = ANY_VALUE;
single_value->field_ifr = ANY_VALUE;
single_value->field_pdu = ANY_VALUE;
}
}
}

void SocketCAN__receive__isotp__pdu_template::copy_value(const SocketCAN__receive__isotp__pdu& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.ifr().is_bound()) {
  single_value->field_ifr = other_value.ifr();
} else {
  single_value->field_ifr.clean_up();
}
if (other_value.pdu().is_bound()) {
  single_value->field_pdu = other_value.pdu();
} else {
  single_value->field_pdu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__receive__isotp__pdu_template::copy_template(const SocketCAN__receive__isotp__pdu_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ifr().get_selection()) {
single_value->field_ifr = other_value.ifr();
} else {
single_value->field_ifr.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pdu().get_selection()) {
single_value->field_pdu = other_value.pdu();
} else {
single_value->field_pdu.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__receive__isotp__pdu_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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
break;
}
set_selection(other_value);
}

SocketCAN__receive__isotp__pdu_template::SocketCAN__receive__isotp__pdu_template()
{
}

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

SocketCAN__receive__isotp__pdu_template::SocketCAN__receive__isotp__pdu_template(const SocketCAN__receive__isotp__pdu& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__receive__isotp__pdu_template& SocketCAN__receive__isotp__pdu_template::operator=(const OPTIONAL<SocketCAN__receive__isotp__pdu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__receive__isotp__pdu&)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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
}
return *this;
}

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

boolean SocketCAN__receive__isotp__pdu_template::match(const SocketCAN__receive__isotp__pdu& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.ifr().is_bound()) return FALSE;
if(!single_value->field_ifr.match(other_value.ifr(), legacy))return FALSE;
if(!other_value.pdu().is_bound()) return FALSE;
if(!single_value->field_pdu.match(other_value.pdu(), 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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
}
return FALSE;
}

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

 ||single_value->field_ifr.is_bound()

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

boolean SocketCAN__receive__isotp__pdu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_ifr.is_value()
 &&single_value->field_pdu.is_value();
}

void SocketCAN__receive__isotp__pdu_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__receive__isotp__pdu SocketCAN__receive__isotp__pdu_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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
SocketCAN__receive__isotp__pdu ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_ifr.is_bound()) {
ret_val.ifr() = single_value->field_ifr.valueof();
}
if (single_value->field_pdu.is_bound()) {
ret_val.pdu() = single_value->field_pdu.valueof();
}
return ret_val;
}

void SocketCAN__receive__isotp__pdu_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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__receive__isotp__pdu_template[list_length];
}

SocketCAN__receive__isotp__pdu_template& SocketCAN__receive__isotp__pdu_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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__receive__isotp__pdu_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__receive__isotp__pdu_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
return single_value->field_id;
}

SocketCAN__ifr_template& SocketCAN__receive__isotp__pdu_template::ifr()
{
set_specific();
return single_value->field_ifr;
}

const SocketCAN__ifr_template& SocketCAN__receive__isotp__pdu_template::ifr() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ifr of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
return single_value->field_ifr;
}

OCTETSTRING_template& SocketCAN__receive__isotp__pdu_template::pdu()
{
set_specific();
return single_value->field_pdu;
}

const OCTETSTRING_template& SocketCAN__receive__isotp__pdu_template::pdu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pdu of a non-specific template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
return single_value->field_pdu;
}

int SocketCAN__receive__isotp__pdu_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu 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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
  }
  return 0;
}

void SocketCAN__receive__isotp__pdu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log();
TTCN_Logger::log_event_str(", pdu := ");
single_value->field_pdu.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__receive__isotp__pdu_template::log_match(const SocketCAN__receive__isotp__pdu& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ifr.match(match_value.ifr(), legacy)){
TTCN_Logger::log_logmatch_info(".ifr");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pdu.match(match_value.pdu(), legacy)){
TTCN_Logger::log_logmatch_info(".pdu");
single_value->field_pdu.log_match(match_value.pdu(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", ifr := ");
single_value->field_ifr.log_match(match_value.ifr(), legacy);
TTCN_Logger::log_event_str(", pdu := ");
single_value->field_pdu.log_match(match_value.pdu(), 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__receive__isotp__pdu_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_ifr.encode_text(text_buf);
single_value->field_pdu.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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
}
}

void SocketCAN__receive__isotp__pdu_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_id.decode_text(text_buf);
single_value->field_ifr.decode_text(text_buf);
single_value->field_pdu.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__receive__isotp__pdu_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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu.");
}
}

void SocketCAN__receive__isotp__pdu_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__receive__isotp__pdu_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 (3<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_receive_isotp_pdu has 3 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) ifr().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pdu().set_param(*param.get_elem(2));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "ifr")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ifr().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(), "pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pdu().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 @SocketCAN_Types.SocketCAN_receive_isotp_pdu: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__receive__isotp__pdu_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
single_value->field_ifr.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
single_value->field_pdu.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
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 : "@SocketCAN_Types.SocketCAN_receive_isotp_pdu");
}

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

boolean SocketCAN__receive__isotp__pdu_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;
}


const Raw::CAN__RAW__filter CAN__RAW__filters::UNBOUND_ELEM;
CAN__RAW__filters::CAN__RAW__filters()
{
val_ptr = NULL;
}

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

CAN__RAW__filters::CAN__RAW__filters(const CAN__RAW__filters& other_value)
{
if (!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
val_ptr = other_value.val_ptr;
val_ptr->ref_count++;
}

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

void CAN__RAW__filters::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.");
}
}

CAN__RAW__filters& CAN__RAW__filters::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;
}

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

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

boolean CAN__RAW__filters::operator==(const CAN__RAW__filters& other_value) const
{
if (val_ptr == NULL) TTCN_error("The left operand of comparison is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
if (other_value.val_ptr == NULL) TTCN_error("The right operand of comparison is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
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;
}

Raw::CAN__RAW__filter& CAN__RAW__filters::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of type @SocketCAN_Types.CAN_RAW_filters 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 = (Raw::CAN__RAW__filter**)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 Raw::CAN__RAW__filter(*(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 Raw::CAN__RAW__filter;
}
return *val_ptr->value_elements[index_value];
}

Raw::CAN__RAW__filter& CAN__RAW__filters::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @SocketCAN_Types.CAN_RAW_filters.");
return (*this)[(int)index_value];
}

const Raw::CAN__RAW__filter& CAN__RAW__filters::operator[](int index_value) const
{
if (val_ptr == NULL)
TTCN_error("Accessing an element in an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
if (index_value < 0) TTCN_error("Accessing an element of type @SocketCAN_Types.CAN_RAW_filters using a negative index: %d.", index_value);
if (index_value >= val_ptr->n_elements) TTCN_error("Index overflow in a value of type @SocketCAN_Types.CAN_RAW_filters: 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 Raw::CAN__RAW__filter& CAN__RAW__filters::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a value of type @SocketCAN_Types.CAN_RAW_filters.");
return (*this)[(int)index_value];
}

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

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

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

CAN__RAW__filters CAN__RAW__filters::operator>>=(int rotate_count) const
{
if (val_ptr == NULL) TTCN_error("Performing rotation operation on an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
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;
CAN__RAW__filters 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 Raw::CAN__RAW__filter(*val_ptr->value_elements[i]);
}
}
return ret_val;
}

CAN__RAW__filters CAN__RAW__filters::operator+(const CAN__RAW__filters& other_value) const
{
if (val_ptr == NULL || other_value.val_ptr == NULL) TTCN_error("Unbound operand of @SocketCAN_Types.CAN_RAW_filters concatenation.");
if (val_ptr->n_elements == 0) return other_value;
if (other_value.val_ptr->n_elements == 0) return *this;
CAN__RAW__filters 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 Raw::CAN__RAW__filter(*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 Raw::CAN__RAW__filter(*other_value.val_ptr->value_elements[i]);
}
}
return ret_val;
}

CAN__RAW__filters CAN__RAW__filters::substr(int index, int returncount) const
{
if (val_ptr == NULL) TTCN_error("The first argument of substr() is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
check_substr_arguments(val_ptr->n_elements, index, returncount, "@SocketCAN_Types.CAN_RAW_filters","element");
CAN__RAW__filters 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 Raw::CAN__RAW__filter(*val_ptr->value_elements[i+index]);
}
}
return ret_val;
}

CAN__RAW__filters CAN__RAW__filters::replace(int index, int len, const CAN__RAW__filters& repl) const
{
if (val_ptr == NULL) TTCN_error("The first argument of replace() is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
if (repl.val_ptr == NULL) TTCN_error("The fourth argument of replace() is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
check_replace_arguments(val_ptr->n_elements, index, len, "@SocketCAN_Types.CAN_RAW_filters","element");
CAN__RAW__filters 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 Raw::CAN__RAW__filter(*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 Raw::CAN__RAW__filter(*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 Raw::CAN__RAW__filter(*val_ptr->value_elements[index+i+len]);
}
}
return ret_val;
}

CAN__RAW__filters CAN__RAW__filters::replace(int index, int len, const CAN__RAW__filters_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 CAN__RAW__filters::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a value of type @SocketCAN_Types.CAN_RAW_filters.");
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 = (Raw::CAN__RAW__filter**)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 Raw::CAN__RAW__filter(*(val_ptr->value_elements[elem_count]));
}
}
clean_up();
val_ptr = new_val_ptr;
}
if (new_size > val_ptr->n_elements) {
val_ptr->value_elements = (Raw::CAN__RAW__filter**)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 @SocketCAN_Types.CAN_RAW_filters: %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 = (Raw::CAN__RAW__filter**)reallocate_pointers((void**)val_ptr->value_elements, val_ptr->n_elements, new_size);
val_ptr->n_elements = new_size;
}
}

boolean CAN__RAW__filters::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 CAN__RAW__filters::size_of() const
{
if (val_ptr == NULL) TTCN_error("Performing sizeof operation on an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
return val_ptr->n_elements;
}

int CAN__RAW__filters::lengthof() const
{
if (val_ptr == NULL) TTCN_error("Performing lengthof operation on an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
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 CAN__RAW__filters::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 CAN__RAW__filters::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", "@SocketCAN_Types.CAN_RAW_filters");
    }
    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", "@SocketCAN_Types.CAN_RAW_filters");
    }
    break;
  default:
    TTCN_error("Internal error: Unknown operation type.");
  }
}

void CAN__RAW__filters::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 CAN__RAW__filters::encode_text(Text_Buf& text_buf) const
{
if (val_ptr == NULL) TTCN_error("Text encoder: Encoding an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
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 CAN__RAW__filters::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 @SocketCAN_Types.CAN_RAW_filters.");
val_ptr->value_elements = (Raw::CAN__RAW__filter**)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 Raw::CAN__RAW__filter;
val_ptr->value_elements[elem_count]->decode_text(text_buf);
}
}

void CAN__RAW__filters_template::copy_value(const CAN__RAW__filters& other_value)
{
if (!other_value.is_bound()) TTCN_error("Initialization of a template of type @SocketCAN_Types.CAN_RAW_filters with an unbound value.");
single_value.n_elements = other_value.size_of();
single_value.value_elements = (Raw::CAN__RAW__filter_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 Raw::CAN__RAW__filter_template(other_value[elem_count]);
} else {
single_value.value_elements[elem_count] = new Raw::CAN__RAW__filter_template;
}
}
set_selection(SPECIFIC_VALUE);
}

void CAN__RAW__filters_template::copy_template(const CAN__RAW__filters_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 = (Raw::CAN__RAW__filter_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 Raw::CAN__RAW__filter_template(*other_value.single_value.value_elements[elem_count]);
} else {
single_value.value_elements[elem_count] = new Raw::CAN__RAW__filter_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 CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
break;
}
set_selection(other_value);
}

boolean CAN__RAW__filters_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 CAN__RAW__filters_template*)template_ptr)->single_value.value_elements[template_index]->match((*(const CAN__RAW__filters*)value_ptr)[value_index], legacy);
else return ((const CAN__RAW__filters_template*)template_ptr)->single_value.value_elements[template_index]->is_any_or_omit();
}

CAN__RAW__filters_template::CAN__RAW__filters_template()
{
}

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

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

CAN__RAW__filters_template::CAN__RAW__filters_template(const CAN__RAW__filters& other_value)
{
copy_value(other_value);
}

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

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

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

void CAN__RAW__filters_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;
}

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

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

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

CAN__RAW__filters_template& CAN__RAW__filters_template::operator=(const OPTIONAL<CAN__RAW__filters>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const CAN__RAW__filters&)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 @SocketCAN_Types.CAN_RAW_filters.");
}
return *this;
}

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

Raw::CAN__RAW__filter_template& CAN__RAW__filters_template::operator[](int index_value)
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters.");
    break;
}
return *single_value.value_elements[index_value];
}

Raw::CAN__RAW__filter_template& CAN__RAW__filters_template::operator[](const INTEGER& index_value)
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @SocketCAN_Types.CAN_RAW_filters.");
return (*this)[(int)index_value];
}

const Raw::CAN__RAW__filter_template& CAN__RAW__filters_template::operator[](int index_value) const
{
if (index_value < 0) TTCN_error("Accessing an element of a template for type @SocketCAN_Types.CAN_RAW_filters using a negative index: %d.", index_value);
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing an element of a non-specific template for type @SocketCAN_Types.CAN_RAW_filters.");
if (index_value >= single_value.n_elements) TTCN_error("Index overflow in a template of type @SocketCAN_Types.CAN_RAW_filters: 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 Raw::CAN__RAW__filter_template& CAN__RAW__filters_template::operator[](const INTEGER& index_value) const
{
index_value.must_bound("Using an unbound integer value for indexing a template of type @SocketCAN_Types.CAN_RAW_filters.");
return (*this)[(int)index_value];
}

void CAN__RAW__filters_template::set_size(int new_size)
{
if (new_size < 0) TTCN_error("Internal error: Setting a negative size for a template of type @SocketCAN_Types.CAN_RAW_filters.");
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 = (Raw::CAN__RAW__filter_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 Raw::CAN__RAW__filter_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 Raw::CAN__RAW__filter_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 = (Raw::CAN__RAW__filter_template**)reallocate_pointers((void**)single_value.value_elements, single_value.n_elements, new_size);
single_value.n_elements = new_size;
}
}

int CAN__RAW__filters_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 CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters 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 @SocketCAN_Types.CAN_RAW_filters containing complemented list.", op_name);
default:
  TTCN_error("Performing %sof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.CAN_RAW_filters.", op_name);
}
return check_section_is_single(min_size, has_any_or_none, op_name, "a", "template of type @SocketCAN_Types.CAN_RAW_filters");
}

boolean CAN__RAW__filters_template::match(const CAN__RAW__filters& 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 @SocketCAN_Types.CAN_RAW_filters.");
}
return FALSE;
}

boolean CAN__RAW__filters_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;
}

CAN__RAW__filters CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
CAN__RAW__filters 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;
}

CAN__RAW__filters CAN__RAW__filters_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);
}

CAN__RAW__filters CAN__RAW__filters_template::replace(int index, int len, const CAN__RAW__filters_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());
}

CAN__RAW__filters CAN__RAW__filters_template::replace(int index, int len, const CAN__RAW__filters& 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 CAN__RAW__filters_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 CAN__RAW__filters_template[list_length];
break;
default:
TTCN_error("Internal error: Setting an invalid type for a template of type @SocketCAN_Types.CAN_RAW_filters.");
}
set_selection(template_type);
}

CAN__RAW__filters_template& CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of type @SocketCAN_Types.CAN_RAW_filters.");
return value_list.list_value[list_index];
}

void CAN__RAW__filters_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 CAN__RAW__filters_template::log_match(const CAN__RAW__filters& 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 CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
}
}

void CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
single_value.value_elements = (Raw::CAN__RAW__filter_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 Raw::CAN__RAW__filter_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 CAN__RAW__filters_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 @SocketCAN_Types.CAN_RAW_filters.");
}
}

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

boolean CAN__RAW__filters_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 CAN__RAW__filters_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: {
    CAN__RAW__filters_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", "@SocketCAN_Types.CAN_RAW_filters");
  }
  is_ifpresent = param.get_ifpresent();
  set_length_range(param);
}

void CAN__RAW__filters_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 : "@SocketCAN_Types.CAN_RAW_filters");
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 : "@SocketCAN_Types.CAN_RAW_filters");
}

boolean CAN__RAW__filters_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);
}
}
void SocketCAN__setsockopt__commandu::copy_value(const SocketCAN__setsockopt__commandu& other_value)
{
switch (other_value.union_selection) {
case ALT_rfilter:
field_rfilter = new CAN__RAW__filters(*other_value.field_rfilter);
break;
case ALT_err__mask:
field_err__mask = new BITSTRING(*other_value.field_err__mask);
break;
case ALT_loopback:
field_loopback = new Raw::DisableEnable__enum(*other_value.field_loopback);
break;
case ALT_recv__own__msgs:
field_recv__own__msgs = new Raw::DisableEnable__enum(*other_value.field_recv__own__msgs);
break;
case ALT_fd__frames:
field_fd__frames = new Raw::DisableEnable__enum(*other_value.field_fd__frames);
break;
case ALT_join__filters:
field_join__filters = new Raw::DisableEnable__enum(*other_value.field_join__filters);
break;
default:
TTCN_error("Assignment of an unbound union value of type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean SocketCAN__setsockopt__commandu::operator==(const SocketCAN__setsockopt__commandu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_rfilter:
return *field_rfilter == *other_value.field_rfilter;
case ALT_err__mask:
return *field_err__mask == *other_value.field_err__mask;
case ALT_loopback:
return *field_loopback == *other_value.field_loopback;
case ALT_recv__own__msgs:
return *field_recv__own__msgs == *other_value.field_recv__own__msgs;
case ALT_fd__frames:
return *field_fd__frames == *other_value.field_fd__frames;
case ALT_join__filters:
return *field_join__filters == *other_value.field_join__filters;
default:
return FALSE;
}
}

CAN__RAW__filters& SocketCAN__setsockopt__commandu::rfilter()
{
if (union_selection != ALT_rfilter) {
clean_up();
field_rfilter = new CAN__RAW__filters;
union_selection = ALT_rfilter;
}
return *field_rfilter;
}

const CAN__RAW__filters& SocketCAN__setsockopt__commandu::rfilter() const
{
if (union_selection != ALT_rfilter) TTCN_error("Using non-selected field rfilter in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_rfilter;
}

BITSTRING& SocketCAN__setsockopt__commandu::err__mask()
{
if (union_selection != ALT_err__mask) {
clean_up();
field_err__mask = new BITSTRING;
union_selection = ALT_err__mask;
}
return *field_err__mask;
}

const BITSTRING& SocketCAN__setsockopt__commandu::err__mask() const
{
if (union_selection != ALT_err__mask) TTCN_error("Using non-selected field err_mask in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_err__mask;
}

Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::loopback()
{
if (union_selection != ALT_loopback) {
clean_up();
field_loopback = new Raw::DisableEnable__enum;
union_selection = ALT_loopback;
}
return *field_loopback;
}

const Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::loopback() const
{
if (union_selection != ALT_loopback) TTCN_error("Using non-selected field loopback in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_loopback;
}

Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::recv__own__msgs()
{
if (union_selection != ALT_recv__own__msgs) {
clean_up();
field_recv__own__msgs = new Raw::DisableEnable__enum;
union_selection = ALT_recv__own__msgs;
}
return *field_recv__own__msgs;
}

const Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::recv__own__msgs() const
{
if (union_selection != ALT_recv__own__msgs) TTCN_error("Using non-selected field recv_own_msgs in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_recv__own__msgs;
}

Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::fd__frames()
{
if (union_selection != ALT_fd__frames) {
clean_up();
field_fd__frames = new Raw::DisableEnable__enum;
union_selection = ALT_fd__frames;
}
return *field_fd__frames;
}

const Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::fd__frames() const
{
if (union_selection != ALT_fd__frames) TTCN_error("Using non-selected field fd_frames in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_fd__frames;
}

Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::join__filters()
{
if (union_selection != ALT_join__filters) {
clean_up();
field_join__filters = new Raw::DisableEnable__enum;
union_selection = ALT_join__filters;
}
return *field_join__filters;
}

const Raw::DisableEnable__enum& SocketCAN__setsockopt__commandu::join__filters() const
{
if (union_selection != ALT_join__filters) TTCN_error("Using non-selected field join_filters in a value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *field_join__filters;
}

boolean SocketCAN__setsockopt__commandu::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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return union_selection == checked_selection;
}

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

boolean SocketCAN__setsockopt__commandu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_rfilter: return field_rfilter->is_value();
case ALT_err__mask: return field_err__mask->is_value();
case ALT_loopback: return field_loopback->is_value();
case ALT_recv__own__msgs: return field_recv__own__msgs->is_value();
case ALT_fd__frames: return field_fd__frames->is_value();
case ALT_join__filters: return field_join__filters->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void SocketCAN__setsockopt__commandu::clean_up()
{
switch (union_selection) {
case ALT_rfilter:
  delete field_rfilter;
  break;
case ALT_err__mask:
  delete field_err__mask;
  break;
case ALT_loopback:
  delete field_loopback;
  break;
case ALT_recv__own__msgs:
  delete field_recv__own__msgs;
  break;
case ALT_fd__frames:
  delete field_fd__frames;
  break;
case ALT_join__filters:
  delete field_join__filters;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void SocketCAN__setsockopt__commandu::log() const
{
switch (union_selection) {
case ALT_rfilter:
TTCN_Logger::log_event_str("{ rfilter := ");
field_rfilter->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_err__mask:
TTCN_Logger::log_event_str("{ err_mask := ");
field_err__mask->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_loopback:
TTCN_Logger::log_event_str("{ loopback := ");
field_loopback->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_recv__own__msgs:
TTCN_Logger::log_event_str("{ recv_own_msgs := ");
field_recv__own__msgs->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_fd__frames:
TTCN_Logger::log_event_str("{ fd_frames := ");
field_fd__frames->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_join__filters:
TTCN_Logger::log_event_str("{ join_filters := ");
field_join__filters->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void SocketCAN__setsockopt__commandu::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, "rfilter")) {
    rfilter().set_param(*mp_last);
    if (!rfilter().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "err_mask")) {
    err__mask().set_param(*mp_last);
    if (!err__mask().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "loopback")) {
    loopback().set_param(*mp_last);
    if (!loopback().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "recv_own_msgs")) {
    recv__own__msgs().set_param(*mp_last);
    if (!recv__own__msgs().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "fd_frames")) {
    fd__frames().set_param(*mp_last);
    if (!fd__frames().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "join_filters")) {
    join__filters().set_param(*mp_last);
    if (!join__filters().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_setsockopt_commandu.", last_name);
}

void SocketCAN__setsockopt__commandu::set_implicit_omit()
{
switch (union_selection) {
case ALT_rfilter:
field_rfilter->set_implicit_omit(); break;
case ALT_err__mask:
field_err__mask->set_implicit_omit(); break;
case ALT_loopback:
field_loopback->set_implicit_omit(); break;
case ALT_recv__own__msgs:
field_recv__own__msgs->set_implicit_omit(); break;
case ALT_fd__frames:
field_fd__frames->set_implicit_omit(); break;
case ALT_join__filters:
field_join__filters->set_implicit_omit(); break;
default: break;
}
}

void SocketCAN__setsockopt__commandu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_rfilter:
field_rfilter->encode_text(text_buf);
break;
case ALT_err__mask:
field_err__mask->encode_text(text_buf);
break;
case ALT_loopback:
field_loopback->encode_text(text_buf);
break;
case ALT_recv__own__msgs:
field_recv__own__msgs->encode_text(text_buf);
break;
case ALT_fd__frames:
field_fd__frames->encode_text(text_buf);
break;
case ALT_join__filters:
field_join__filters->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}

void SocketCAN__setsockopt__commandu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_rfilter:
rfilter().decode_text(text_buf);
break;
case ALT_err__mask:
err__mask().decode_text(text_buf);
break;
case ALT_loopback:
loopback().decode_text(text_buf);
break;
case ALT_recv__own__msgs:
recv__own__msgs().decode_text(text_buf);
break;
case ALT_fd__frames:
fd__frames().decode_text(text_buf);
break;
case ALT_join__filters:
join__filters().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}

void SocketCAN__setsockopt__commandu_template::copy_value(const SocketCAN__setsockopt__commandu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
single_value.field_rfilter = new CAN__RAW__filters_template(other_value.rfilter());
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
single_value.field_err__mask = new BITSTRING_template(other_value.err__mask());
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
single_value.field_loopback = new Raw::DisableEnable__enum_template(other_value.loopback());
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
single_value.field_recv__own__msgs = new Raw::DisableEnable__enum_template(other_value.recv__own__msgs());
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
single_value.field_fd__frames = new Raw::DisableEnable__enum_template(other_value.fd__frames());
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
single_value.field_join__filters = new Raw::DisableEnable__enum_template(other_value.join__filters());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__setsockopt__commandu_template::copy_template(const SocketCAN__setsockopt__commandu_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__setsockopt__commandu::ALT_rfilter:
single_value.field_rfilter = new CAN__RAW__filters_template(*other_value.single_value.field_rfilter);
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
single_value.field_err__mask = new BITSTRING_template(*other_value.single_value.field_err__mask);
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
single_value.field_loopback = new Raw::DisableEnable__enum_template(*other_value.single_value.field_loopback);
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
single_value.field_recv__own__msgs = new Raw::DisableEnable__enum_template(*other_value.single_value.field_recv__own__msgs);
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
single_value.field_fd__frames = new Raw::DisableEnable__enum_template(*other_value.single_value.field_fd__frames);
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
single_value.field_join__filters = new Raw::DisableEnable__enum_template(*other_value.single_value.field_join__filters);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
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__setsockopt__commandu_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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
set_selection(other_value);
}

SocketCAN__setsockopt__commandu_template::SocketCAN__setsockopt__commandu_template()
{
}

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

SocketCAN__setsockopt__commandu_template::SocketCAN__setsockopt__commandu_template(const SocketCAN__setsockopt__commandu& other_value)
{
copy_value(other_value);
}

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

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

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

void SocketCAN__setsockopt__commandu_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
delete single_value.field_rfilter;
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
delete single_value.field_err__mask;
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
delete single_value.field_loopback;
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
delete single_value.field_recv__own__msgs;
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
delete single_value.field_fd__frames;
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
delete single_value.field_join__filters;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

SocketCAN__setsockopt__commandu_template& SocketCAN__setsockopt__commandu_template::operator=(const OPTIONAL<SocketCAN__setsockopt__commandu>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__setsockopt__commandu&)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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
return *this;
}

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

boolean SocketCAN__setsockopt__commandu_template::match(const SocketCAN__setsockopt__commandu& 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__setsockopt__commandu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == SocketCAN__setsockopt__commandu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
return single_value.field_rfilter->match(other_value.rfilter(), legacy);
case SocketCAN__setsockopt__commandu::ALT_err__mask:
return single_value.field_err__mask->match(other_value.err__mask(), legacy);
case SocketCAN__setsockopt__commandu::ALT_loopback:
return single_value.field_loopback->match(other_value.loopback(), legacy);
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
return single_value.field_recv__own__msgs->match(other_value.recv__own__msgs(), legacy);
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
return single_value.field_fd__frames->match(other_value.fd__frames(), legacy);
case SocketCAN__setsockopt__commandu::ALT_join__filters:
return single_value.field_join__filters->match(other_value.join__filters(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}
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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
return FALSE;
}

boolean SocketCAN__setsockopt__commandu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
return single_value.field_rfilter->is_value();
case SocketCAN__setsockopt__commandu::ALT_err__mask:
return single_value.field_err__mask->is_value();
case SocketCAN__setsockopt__commandu::ALT_loopback:
return single_value.field_loopback->is_value();
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
return single_value.field_recv__own__msgs->is_value();
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
return single_value.field_fd__frames->is_value();
case SocketCAN__setsockopt__commandu::ALT_join__filters:
return single_value.field_join__filters->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}

SocketCAN__setsockopt__commandu SocketCAN__setsockopt__commandu_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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
SocketCAN__setsockopt__commandu ret_val;
switch (single_value.union_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
ret_val.rfilter() = single_value.field_rfilter->valueof();
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
ret_val.err__mask() = single_value.field_err__mask->valueof();
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
ret_val.loopback() = single_value.field_loopback->valueof();
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
ret_val.recv__own__msgs() = single_value.field_recv__own__msgs->valueof();
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
ret_val.fd__frames() = single_value.field_fd__frames->valueof();
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
ret_val.join__filters() = single_value.field_join__filters->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
return ret_val;
}

SocketCAN__setsockopt__commandu_template& SocketCAN__setsockopt__commandu_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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return value_list.list_value[list_index];
}
void SocketCAN__setsockopt__commandu_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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__setsockopt__commandu_template[list_length];
}

CAN__RAW__filters_template& SocketCAN__setsockopt__commandu_template::rfilter()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_rfilter) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_rfilter = new CAN__RAW__filters_template(ANY_VALUE);
else single_value.field_rfilter = new CAN__RAW__filters_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_rfilter;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_rfilter;
}

const CAN__RAW__filters_template& SocketCAN__setsockopt__commandu_template::rfilter() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field rfilter in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_rfilter) TTCN_error("Accessing non-selected field rfilter in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_rfilter;
}

BITSTRING_template& SocketCAN__setsockopt__commandu_template::err__mask()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_err__mask) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_err__mask = new BITSTRING_template(ANY_VALUE);
else single_value.field_err__mask = new BITSTRING_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_err__mask;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_err__mask;
}

const BITSTRING_template& SocketCAN__setsockopt__commandu_template::err__mask() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field err_mask in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_err__mask) TTCN_error("Accessing non-selected field err_mask in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_err__mask;
}

Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::loopback()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_loopback) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_loopback = new Raw::DisableEnable__enum_template(ANY_VALUE);
else single_value.field_loopback = new Raw::DisableEnable__enum_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_loopback;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_loopback;
}

const Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::loopback() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field loopback in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_loopback) TTCN_error("Accessing non-selected field loopback in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_loopback;
}

Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::recv__own__msgs()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_recv__own__msgs) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_recv__own__msgs = new Raw::DisableEnable__enum_template(ANY_VALUE);
else single_value.field_recv__own__msgs = new Raw::DisableEnable__enum_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_recv__own__msgs;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_recv__own__msgs;
}

const Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::recv__own__msgs() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field recv_own_msgs in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_recv__own__msgs) TTCN_error("Accessing non-selected field recv_own_msgs in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_recv__own__msgs;
}

Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::fd__frames()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_fd__frames) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_fd__frames = new Raw::DisableEnable__enum_template(ANY_VALUE);
else single_value.field_fd__frames = new Raw::DisableEnable__enum_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_fd__frames;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_fd__frames;
}

const Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::fd__frames() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field fd_frames in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_fd__frames) TTCN_error("Accessing non-selected field fd_frames in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_fd__frames;
}

Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::join__filters()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_join__filters) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_join__filters = new Raw::DisableEnable__enum_template(ANY_VALUE);
else single_value.field_join__filters = new Raw::DisableEnable__enum_template;
single_value.union_selection = SocketCAN__setsockopt__commandu::ALT_join__filters;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_join__filters;
}

const Raw::DisableEnable__enum_template& SocketCAN__setsockopt__commandu_template::join__filters() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field join_filters in a non-specific template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
if (single_value.union_selection != SocketCAN__setsockopt__commandu::ALT_join__filters) TTCN_error("Accessing non-selected field join_filters in a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
return *single_value.field_join__filters;
}

boolean SocketCAN__setsockopt__commandu_template::ischosen(SocketCAN__setsockopt__commandu::union_selection_type checked_selection) const
{
if (checked_selection == SocketCAN__setsockopt__commandu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == SocketCAN__setsockopt__commandu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
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 @SocketCAN_Types.SocketCAN_setsockopt_commandu 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__setsockopt__commandu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
TTCN_Logger::log_event_str("{ rfilter := ");
single_value.field_rfilter->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
TTCN_Logger::log_event_str("{ err_mask := ");
single_value.field_err__mask->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
TTCN_Logger::log_event_str("{ loopback := ");
single_value.field_loopback->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
TTCN_Logger::log_event_str("{ recv_own_msgs := ");
single_value.field_recv__own__msgs->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
TTCN_Logger::log_event_str("{ fd_frames := ");
single_value.field_fd__frames->log();
TTCN_Logger::log_event_str(" }");
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
TTCN_Logger::log_event_str("{ join_filters := ");
single_value.field_join__filters->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__setsockopt__commandu_template::log_match(const SocketCAN__setsockopt__commandu& 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__setsockopt__commandu::ALT_rfilter:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".rfilter");
single_value.field_rfilter->log_match(match_value.rfilter(), legacy);
} else {
TTCN_Logger::log_event_str("{ rfilter := ");
single_value.field_rfilter->log_match(match_value.rfilter(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".err_mask");
single_value.field_err__mask->log_match(match_value.err__mask(), legacy);
} else {
TTCN_Logger::log_event_str("{ err_mask := ");
single_value.field_err__mask->log_match(match_value.err__mask(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".loopback");
single_value.field_loopback->log_match(match_value.loopback(), legacy);
} else {
TTCN_Logger::log_event_str("{ loopback := ");
single_value.field_loopback->log_match(match_value.loopback(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".recv_own_msgs");
single_value.field_recv__own__msgs->log_match(match_value.recv__own__msgs(), legacy);
} else {
TTCN_Logger::log_event_str("{ recv_own_msgs := ");
single_value.field_recv__own__msgs->log_match(match_value.recv__own__msgs(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".fd_frames");
single_value.field_fd__frames->log_match(match_value.fd__frames(), legacy);
} else {
TTCN_Logger::log_event_str("{ fd_frames := ");
single_value.field_fd__frames->log_match(match_value.fd__frames(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".join_filters");
single_value.field_join__filters->log_match(match_value.join__filters(), legacy);
} else {
TTCN_Logger::log_event_str("{ join_filters := ");
single_value.field_join__filters->log_match(match_value.join__filters(), 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__setsockopt__commandu_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__setsockopt__commandu::ALT_rfilter:
single_value.field_rfilter->encode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
single_value.field_err__mask->encode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
single_value.field_loopback->encode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
single_value.field_recv__own__msgs->encode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
single_value.field_fd__frames->encode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
single_value.field_join__filters->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}

void SocketCAN__setsockopt__commandu_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__setsockopt__commandu::UNBOUND_VALUE;
SocketCAN__setsockopt__commandu::union_selection_type new_selection = (SocketCAN__setsockopt__commandu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case SocketCAN__setsockopt__commandu::ALT_rfilter:
single_value.field_rfilter = new CAN__RAW__filters_template;
single_value.field_rfilter->decode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
single_value.field_err__mask = new BITSTRING_template;
single_value.field_err__mask->decode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_loopback:
single_value.field_loopback = new Raw::DisableEnable__enum_template;
single_value.field_loopback->decode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
single_value.field_recv__own__msgs = new Raw::DisableEnable__enum_template;
single_value.field_recv__own__msgs->decode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
single_value.field_fd__frames = new Raw::DisableEnable__enum_template;
single_value.field_fd__frames->decode_text(text_buf);
break;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
single_value.field_join__filters = new Raw::DisableEnable__enum_template;
single_value.field_join__filters->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
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__setsockopt__commandu_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 @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
}

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

boolean SocketCAN__setsockopt__commandu_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__setsockopt__commandu_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 `@SocketCAN_Types.SocketCAN_setsockopt_commandu'");
    }
    if (strcmp("rfilter", param_field) == 0) {
      rfilter().set_param(param);
      return;
    } else if (strcmp("err_mask", param_field) == 0) {
      err__mask().set_param(param);
      return;
    } else if (strcmp("loopback", param_field) == 0) {
      loopback().set_param(param);
      return;
    } else if (strcmp("recv_own_msgs", param_field) == 0) {
      recv__own__msgs().set_param(param);
      return;
    } else if (strcmp("fd_frames", param_field) == 0) {
      fd__frames().set_param(param);
      return;
    } else if (strcmp("join_filters", param_field) == 0) {
      join__filters().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@SocketCAN_Types.SocketCAN_setsockopt_commandu'", 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__setsockopt__commandu_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", "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
    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, "rfilter")) {
      rfilter().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "err_mask")) {
      err__mask().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "loopback")) {
      loopback().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "recv_own_msgs")) {
      recv__own__msgs().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "fd_frames")) {
      fd__frames().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "join_filters")) {
      join__filters().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @SocketCAN_Types.SocketCAN_setsockopt_commandu.", last_name);
  } break;
  default:
    param.type_error("union template", "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__setsockopt__commandu_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__setsockopt__commandu::ALT_rfilter:
single_value.field_rfilter->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
case SocketCAN__setsockopt__commandu::ALT_err__mask:
single_value.field_err__mask->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
case SocketCAN__setsockopt__commandu::ALT_loopback:
single_value.field_loopback->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
case SocketCAN__setsockopt__commandu::ALT_recv__own__msgs:
single_value.field_recv__own__msgs->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
case SocketCAN__setsockopt__commandu::ALT_fd__frames:
single_value.field_fd__frames->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
case SocketCAN__setsockopt__commandu::ALT_join__filters:
single_value.field_join__filters->check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @SocketCAN_Types.SocketCAN_setsockopt_commandu.");
}
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 : "@SocketCAN_Types.SocketCAN_setsockopt_commandu");
}

SocketCAN__setsockopt::SocketCAN__setsockopt()
{
}

SocketCAN__setsockopt::SocketCAN__setsockopt(const INTEGER& par_id,
    const SocketCAN__setsockopt__commandu& par_command)
  :   field_id(par_id),
  field_command(par_command)
{
}

SocketCAN__setsockopt::SocketCAN__setsockopt(const SocketCAN__setsockopt& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_setsockopt.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
if (other_value.command().is_bound()) field_command = other_value.command();
else field_command.clean_up();
}

void SocketCAN__setsockopt::clean_up()
{
field_id.clean_up();
field_command.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__setsockopt::get_descriptor() const { return &SocketCAN__setsockopt_descr_; }
SocketCAN__setsockopt& SocketCAN__setsockopt::operator=(const SocketCAN__setsockopt& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_setsockopt.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
  if (other_value.command().is_bound()) field_command = other_value.command();
  else field_command.clean_up();
}
return *this;
}

boolean SocketCAN__setsockopt::operator==(const SocketCAN__setsockopt& other_value) const
{
return field_id==other_value.field_id
  && field_command==other_value.field_command;
}

boolean SocketCAN__setsockopt::is_bound() const
{
return (field_id.is_bound())
  || (field_command.is_bound());
}
boolean SocketCAN__setsockopt::is_value() const
{
return field_id.is_value()
  && field_command.is_value();
}
void SocketCAN__setsockopt::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(", command := ");
field_command.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__setsockopt::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 @SocketCAN_Types.SocketCAN_setsockopt 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) command().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "command")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          command().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 @SocketCAN_Types.SocketCAN_setsockopt: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_setsockopt");
  }
}

void SocketCAN__setsockopt::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
if (command().is_bound()) command().set_implicit_omit();
}

void SocketCAN__setsockopt::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
field_command.encode_text(text_buf);
}

void SocketCAN__setsockopt::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
field_command.decode_text(text_buf);
}

struct SocketCAN__setsockopt_template::single_value_struct {
INTEGER_template field_id;
SocketCAN__setsockopt__commandu_template field_command;
};

void SocketCAN__setsockopt_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_id = ANY_VALUE;
single_value->field_command = ANY_VALUE;
}
}
}

void SocketCAN__setsockopt_template::copy_value(const SocketCAN__setsockopt& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
if (other_value.command().is_bound()) {
  single_value->field_command = other_value.command();
} else {
  single_value->field_command.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__setsockopt_template::copy_template(const SocketCAN__setsockopt_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.command().get_selection()) {
single_value->field_command = other_value.command();
} else {
single_value->field_command.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__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt.");
break;
}
set_selection(other_value);
}

SocketCAN__setsockopt_template::SocketCAN__setsockopt_template()
{
}

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

SocketCAN__setsockopt_template::SocketCAN__setsockopt_template(const SocketCAN__setsockopt& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__setsockopt_template& SocketCAN__setsockopt_template::operator=(const OPTIONAL<SocketCAN__setsockopt>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__setsockopt&)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 @SocketCAN_Types.SocketCAN_setsockopt.");
}
return *this;
}

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

boolean SocketCAN__setsockopt_template::match(const SocketCAN__setsockopt& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), legacy))return FALSE;
if(!other_value.command().is_bound()) return FALSE;
if(!single_value->field_command.match(other_value.command(), 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 @SocketCAN_Types.SocketCAN_setsockopt.");
}
return FALSE;
}

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

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

boolean SocketCAN__setsockopt_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value()
 &&single_value->field_command.is_value();
}

void SocketCAN__setsockopt_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__setsockopt SocketCAN__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt.");
SocketCAN__setsockopt ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
if (single_value->field_command.is_bound()) {
ret_val.command() = single_value->field_command.valueof();
}
return ret_val;
}

void SocketCAN__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__setsockopt_template[list_length];
}

SocketCAN__setsockopt_template& SocketCAN__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_setsockopt.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__setsockopt_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__setsockopt_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_setsockopt.");
return single_value->field_id;
}

SocketCAN__setsockopt__commandu_template& SocketCAN__setsockopt_template::command()
{
set_specific();
return single_value->field_command;
}

const SocketCAN__setsockopt__commandu_template& SocketCAN__setsockopt_template::command() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field command of a non-specific template of type @SocketCAN_Types.SocketCAN_setsockopt.");
return single_value->field_command;
}

int SocketCAN__setsockopt_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt 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 @SocketCAN_Types.SocketCAN_setsockopt 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 @SocketCAN_Types.SocketCAN_setsockopt containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_setsockopt.");
  }
  return 0;
}

void SocketCAN__setsockopt_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.log();
TTCN_Logger::log_event_str(", command := ");
single_value->field_command.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__setsockopt_template::log_match(const SocketCAN__setsockopt& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_command.match(match_value.command(), legacy)){
TTCN_Logger::log_logmatch_info(".command");
single_value->field_command.log_match(match_value.command(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), legacy);
TTCN_Logger::log_event_str(", command := ");
single_value->field_command.log_match(match_value.command(), 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__setsockopt_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.encode_text(text_buf);
single_value->field_command.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 @SocketCAN_Types.SocketCAN_setsockopt.");
}
}

void SocketCAN__setsockopt_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_id.decode_text(text_buf);
single_value->field_command.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__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt.");
}
}

void SocketCAN__setsockopt_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__setsockopt_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 @SocketCAN_Types.SocketCAN_setsockopt 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) id().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) command().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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          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(), "command")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          command().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 @SocketCAN_Types.SocketCAN_setsockopt: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_setsockopt");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__setsockopt_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt");
single_value->field_command.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt");
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 : "@SocketCAN_Types.SocketCAN_setsockopt");
}

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

boolean SocketCAN__setsockopt_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;
}

SocketCAN__setsockopt__result::SocketCAN__setsockopt__result()
{
}

SocketCAN__setsockopt__result::SocketCAN__setsockopt__result(const SocketCAN__Result& par_result)
  :   field_result(par_result)
{
}

SocketCAN__setsockopt__result::SocketCAN__setsockopt__result(const SocketCAN__setsockopt__result& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_setsockopt_result.");
if (other_value.result().is_bound()) field_result = other_value.result();
else field_result.clean_up();
}

void SocketCAN__setsockopt__result::clean_up()
{
field_result.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__setsockopt__result::get_descriptor() const { return &SocketCAN__setsockopt__result_descr_; }
SocketCAN__setsockopt__result& SocketCAN__setsockopt__result::operator=(const SocketCAN__setsockopt__result& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_setsockopt_result.");
  if (other_value.result().is_bound()) field_result = other_value.result();
  else field_result.clean_up();
}
return *this;
}

boolean SocketCAN__setsockopt__result::operator==(const SocketCAN__setsockopt__result& other_value) const
{
return field_result==other_value.field_result;
}

boolean SocketCAN__setsockopt__result::is_bound() const
{
return (field_result.is_bound());
}
boolean SocketCAN__setsockopt__result::is_value() const
{
return field_result.is_value();
}
void SocketCAN__setsockopt__result::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ result := ");
field_result.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__setsockopt__result::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_setsockopt_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_setsockopt_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_setsockopt_result");
  }
}

void SocketCAN__setsockopt__result::set_implicit_omit()
{
if (result().is_bound()) result().set_implicit_omit();
}

void SocketCAN__setsockopt__result::encode_text(Text_Buf& text_buf) const
{
field_result.encode_text(text_buf);
}

void SocketCAN__setsockopt__result::decode_text(Text_Buf& text_buf)
{
field_result.decode_text(text_buf);
}

struct SocketCAN__setsockopt__result_template::single_value_struct {
SocketCAN__Result_template field_result;
};

void SocketCAN__setsockopt__result_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_result = ANY_VALUE;
}
}
}

void SocketCAN__setsockopt__result_template::copy_value(const SocketCAN__setsockopt__result& other_value)
{
single_value = new single_value_struct;
if (other_value.result().is_bound()) {
  single_value->field_result = other_value.result();
} else {
  single_value->field_result.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__setsockopt__result_template::copy_template(const SocketCAN__setsockopt__result_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.result().get_selection()) {
single_value->field_result = other_value.result();
} else {
single_value->field_result.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__setsockopt__result_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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
break;
}
set_selection(other_value);
}

SocketCAN__setsockopt__result_template::SocketCAN__setsockopt__result_template()
{
}

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

SocketCAN__setsockopt__result_template::SocketCAN__setsockopt__result_template(const SocketCAN__setsockopt__result& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__setsockopt__result_template& SocketCAN__setsockopt__result_template::operator=(const OPTIONAL<SocketCAN__setsockopt__result>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__setsockopt__result&)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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
}
return *this;
}

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

boolean SocketCAN__setsockopt__result_template::match(const SocketCAN__setsockopt__result& 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.result().is_bound()) return FALSE;
if(!single_value->field_result.match(other_value.result(), 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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
}
return FALSE;
}

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

boolean SocketCAN__setsockopt__result_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_result.is_value();
}

void SocketCAN__setsockopt__result_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__setsockopt__result SocketCAN__setsockopt__result_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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
SocketCAN__setsockopt__result ret_val;
if (single_value->field_result.is_bound()) {
ret_val.result() = single_value->field_result.valueof();
}
return ret_val;
}

void SocketCAN__setsockopt__result_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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__setsockopt__result_template[list_length];
}

SocketCAN__setsockopt__result_template& SocketCAN__setsockopt__result_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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_setsockopt_result.");
return value_list.list_value[list_index];
}

SocketCAN__Result_template& SocketCAN__setsockopt__result_template::result()
{
set_specific();
return single_value->field_result;
}

const SocketCAN__Result_template& SocketCAN__setsockopt__result_template::result() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field result of a non-specific template of type @SocketCAN_Types.SocketCAN_setsockopt_result.");
return single_value->field_result;
}

int SocketCAN__setsockopt__result_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt_result which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt_result 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 @SocketCAN_Types.SocketCAN_setsockopt_result containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt_result containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt_result containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_setsockopt_result containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_setsockopt_result.");
  }
  return 0;
}

void SocketCAN__setsockopt__result_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ result := ");
single_value->field_result.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__setsockopt__result_template::log_match(const SocketCAN__setsockopt__result& 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_result.match(match_value.result(), legacy)){
TTCN_Logger::log_logmatch_info(".result");
single_value->field_result.log_match(match_value.result(), 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("{ result := ");
single_value->field_result.log_match(match_value.result(), 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__setsockopt__result_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_result.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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
}
}

void SocketCAN__setsockopt__result_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_result.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__setsockopt__result_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 @SocketCAN_Types.SocketCAN_setsockopt_result.");
}
}

void SocketCAN__setsockopt__result_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__setsockopt__result_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_setsockopt_result has 1 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) result().set_param(*param.get_elem(0));
    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(), "result")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          result().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 @SocketCAN_Types.SocketCAN_setsockopt_result: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_setsockopt_result");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__setsockopt__result_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_result.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_setsockopt_result");
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 : "@SocketCAN_Types.SocketCAN_setsockopt_result");
}

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

boolean SocketCAN__setsockopt__result_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;
}

SocketCAN__close::SocketCAN__close()
{
}

SocketCAN__close::SocketCAN__close(const INTEGER& par_id)
  :   field_id(par_id)
{
}

SocketCAN__close::SocketCAN__close(const SocketCAN__close& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @SocketCAN_Types.SocketCAN_close.");
if (other_value.id().is_bound()) field_id = other_value.id();
else field_id.clean_up();
}

void SocketCAN__close::clean_up()
{
field_id.clean_up();
}

const TTCN_Typedescriptor_t* SocketCAN__close::get_descriptor() const { return &SocketCAN__close_descr_; }
SocketCAN__close& SocketCAN__close::operator=(const SocketCAN__close& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @SocketCAN_Types.SocketCAN_close.");
  if (other_value.id().is_bound()) field_id = other_value.id();
  else field_id.clean_up();
}
return *this;
}

boolean SocketCAN__close::operator==(const SocketCAN__close& other_value) const
{
return field_id==other_value.field_id;
}

boolean SocketCAN__close::is_bound() const
{
return (field_id.is_bound());
}
boolean SocketCAN__close::is_value() const
{
return field_id.is_value();
}
void SocketCAN__close::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ id := ");
field_id.log();
TTCN_Logger::log_event_str(" }");
}

void SocketCAN__close::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 (1<param.get_size()) {
      param.error("record value of type @SocketCAN_Types.SocketCAN_close has 1 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) id().set_param(*param.get_elem(0));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          id().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 @SocketCAN_Types.SocketCAN_close: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@SocketCAN_Types.SocketCAN_close");
  }
}

void SocketCAN__close::set_implicit_omit()
{
if (id().is_bound()) id().set_implicit_omit();
}

void SocketCAN__close::encode_text(Text_Buf& text_buf) const
{
field_id.encode_text(text_buf);
}

void SocketCAN__close::decode_text(Text_Buf& text_buf)
{
field_id.decode_text(text_buf);
}

struct SocketCAN__close_template::single_value_struct {
INTEGER_template field_id;
};

void SocketCAN__close_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_id = ANY_VALUE;
}
}
}

void SocketCAN__close_template::copy_value(const SocketCAN__close& other_value)
{
single_value = new single_value_struct;
if (other_value.id().is_bound()) {
  single_value->field_id = other_value.id();
} else {
  single_value->field_id.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void SocketCAN__close_template::copy_template(const SocketCAN__close_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.id().get_selection()) {
single_value->field_id = other_value.id();
} else {
single_value->field_id.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__close_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 @SocketCAN_Types.SocketCAN_close.");
break;
}
set_selection(other_value);
}

SocketCAN__close_template::SocketCAN__close_template()
{
}

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

SocketCAN__close_template::SocketCAN__close_template(const SocketCAN__close& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

SocketCAN__close_template& SocketCAN__close_template::operator=(const OPTIONAL<SocketCAN__close>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const SocketCAN__close&)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 @SocketCAN_Types.SocketCAN_close.");
}
return *this;
}

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

boolean SocketCAN__close_template::match(const SocketCAN__close& 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.id().is_bound()) return FALSE;
if(!single_value->field_id.match(other_value.id(), 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 @SocketCAN_Types.SocketCAN_close.");
}
return FALSE;
}

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

boolean SocketCAN__close_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_id.is_value();
}

void SocketCAN__close_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__close SocketCAN__close_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 @SocketCAN_Types.SocketCAN_close.");
SocketCAN__close ret_val;
if (single_value->field_id.is_bound()) {
ret_val.id() = single_value->field_id.valueof();
}
return ret_val;
}

void SocketCAN__close_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 @SocketCAN_Types.SocketCAN_close.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new SocketCAN__close_template[list_length];
}

SocketCAN__close_template& SocketCAN__close_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 @SocketCAN_Types.SocketCAN_close.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @SocketCAN_Types.SocketCAN_close.");
return value_list.list_value[list_index];
}

INTEGER_template& SocketCAN__close_template::id()
{
set_specific();
return single_value->field_id;
}

const INTEGER_template& SocketCAN__close_template::id() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field id of a non-specific template of type @SocketCAN_Types.SocketCAN_close.");
return single_value->field_id;
}

int SocketCAN__close_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_close which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 1;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_close 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 @SocketCAN_Types.SocketCAN_close containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_close containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_close containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @SocketCAN_Types.SocketCAN_close containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @SocketCAN_Types.SocketCAN_close.");
  }
  return 0;
}

void SocketCAN__close_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ id := ");
single_value->field_id.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__close_template::log_match(const SocketCAN__close& 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_id.match(match_value.id(), legacy)){
TTCN_Logger::log_logmatch_info(".id");
single_value->field_id.log_match(match_value.id(), 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("{ id := ");
single_value->field_id.log_match(match_value.id(), 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__close_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_id.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 @SocketCAN_Types.SocketCAN_close.");
}
}

void SocketCAN__close_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_id.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__close_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 @SocketCAN_Types.SocketCAN_close.");
}
}

void SocketCAN__close_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__close_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 (1<param.get_size()) {
      param.error("record template of type @SocketCAN_Types.SocketCAN_close has 1 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) id().set_param(*param.get_elem(0));
    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(), "id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          id().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 @SocketCAN_Types.SocketCAN_close: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@SocketCAN_Types.SocketCAN_close");
  }
  is_ifpresent = param.get_ifpresent();
}

void SocketCAN__close_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_id.check_restriction(t_res, t_name ? t_name : "@SocketCAN_Types.SocketCAN_close");
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 : "@SocketCAN_Types.SocketCAN_close");
}

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

boolean SocketCAN__close_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 CAN__RAW__filters& other_value)
{
if (other_value.val_ptr == NULL)
TTCN_error("The right operand of comparison is an unbound value of type @SocketCAN_Types.CAN_RAW_filters.");
return other_value.val_ptr->n_elements == 0;
}


/* Bodies of static functions */

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

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


} /* end of namespace */
