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

namespace Isobus {

/* Prototypes of static functions */

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

/* Literal string constants */

static const unsigned char os_19_octets[] = { 0 },
os_23_octets[] = { 0, 0 },
os_16_octets[] = { 0, 0, 0, 255 },
os_15_octets[] = { 0, 0, 255, 0 },
os_14_octets[] = { 0, 255, 0, 0 },
os_13_octets[] = { 1, 0, 0, 0 },
os_12_octets[] = { 2, 0, 0, 0 },
os_11_octets[] = { 28, 0, 0, 0 },
os_0_octets[] = { 199, 0, 0 },
os_1_octets[] = { 200, 0, 0 },
os_18_octets[] = { 216 },
os_2_octets[] = { 230, 0, 0 },
os_3_octets[] = { 231, 0, 0 },
os_4_octets[] = { 234, 0, 0 },
os_5_octets[] = { 235, 0, 0 },
os_6_octets[] = { 236, 0, 0 },
os_7_octets[] = { 237, 0, 0 },
os_20_octets[] = { 238 },
os_9_octets[] = { 238, 255, 0 },
os_8_octets[] = { 238, 255, 254 },
os_17_octets[] = { 254 },
os_10_octets[] = { 254, 216, 0 },
os_21_octets[] = { 255 };
static const OCTETSTRING os_22(0, NULL),
os_19(1, os_19_octets),
os_23(2, os_23_octets),
os_16(4, os_16_octets),
os_15(4, os_15_octets),
os_14(4, os_14_octets),
os_13(4, os_13_octets),
os_12(4, os_12_octets),
os_11(4, os_11_octets),
os_0(3, os_0_octets),
os_1(3, os_1_octets),
os_18(1, os_18_octets),
os_2(3, os_2_octets),
os_3(3, os_3_octets),
os_4(3, os_4_octets),
os_5(3, os_5_octets),
os_6(3, os_6_octets),
os_7(3, os_7_octets),
os_20(1, os_20_octets),
os_9(3, os_9_octets),
os_8(3, os_8_octets),
os_17(1, os_17_octets),
os_10(3, os_10_octets),
os_21(1, os_21_octets);
static const unsigned char module_checksum[] = { 0xf6, 0x9c, 0xa1, 0xef, 0xcb, 0xb0, 0x54, 0x87, 0x7c, 0x99, 0xc2, 0x03, 0x00, 0xfe, 0xf8, 0x32 };

/* Global variable definitions */

static OCTETSTRING const_ISOBUS__PRIORITY__MASK;
const OCTETSTRING& ISOBUS__PRIORITY__MASK = const_ISOBUS__PRIORITY__MASK;
static OCTETSTRING const_ISOBUS__RESERVED__MASK;
const OCTETSTRING& ISOBUS__RESERVED__MASK = const_ISOBUS__RESERVED__MASK;
static OCTETSTRING const_ISOBUS__DATAPAGE__MASK;
const OCTETSTRING& ISOBUS__DATAPAGE__MASK = const_ISOBUS__DATAPAGE__MASK;
static OCTETSTRING const_ISOBUS__PDUFORMAT__MASK;
const OCTETSTRING& ISOBUS__PDUFORMAT__MASK = const_ISOBUS__PDUFORMAT__MASK;
static OCTETSTRING const_ISOBUS__PDUSPECIFIC__MASK;
const OCTETSTRING& ISOBUS__PDUSPECIFIC__MASK = const_ISOBUS__PDUSPECIFIC__MASK;
static OCTETSTRING const_ISOBUS__SOURCEADDRESS__MASK;
const OCTETSTRING& ISOBUS__SOURCEADDRESS__MASK = const_ISOBUS__SOURCEADDRESS__MASK;
const TTCN_RAWdescriptor_t Priority_raw_ = {6,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,6,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       Priority_xer_ = { {"Priority>\n", "Priority>\n"}, {10, 10}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t Priority_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t Priority_descr_ = { "@Isobus.Priority", &BITSTRING_ber_, &Priority_raw_, NULL, &Priority_xer_, &BITSTRING_json_, &Priority_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_prio_raw_ = {6,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,6,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_prio_xer_ = { {"prio>\n", "prio>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939_prio_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939_prio_descr_ = { "@Isobus.J1939.prio", &BITSTRING_ber_, &J1939_prio_raw_, NULL, &J1939_prio_xer_, &BITSTRING_json_, &J1939_prio_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_res_raw_ = {1,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_res_xer_ = { {"res>\n", "res>\n"}, {5, 5}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939_res_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939_res_descr_ = { "@Isobus.J1939.res", &BITSTRING_ber_, &J1939_res_raw_, NULL, &J1939_res_xer_, &BITSTRING_json_, &J1939_res_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_dp_raw_ = {1,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_dp_xer_ = { {"dp>\n", "dp>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939_dp_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939_dp_descr_ = { "@Isobus.J1939.dp", &BITSTRING_ber_, &J1939_dp_raw_, NULL, &J1939_dp_xer_, &BITSTRING_json_, &J1939_dp_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_pf_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_pf_xer_ = { {"pf>\n", "pf>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939_pf_oer_ext_arr_[0] = {};
const int J1939_pf_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939_pf_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939_pf_oer_ext_arr_, 0, J1939_pf_oer_p_};
const TTCN_Typedescriptor_t J1939_pf_descr_ = { "@Isobus.J1939.pf", &OCTETSTRING_ber_, &J1939_pf_raw_, &OCTETSTRING_text_, &J1939_pf_xer_, &OCTETSTRING_json_, &J1939_pf_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_ps_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_ps_xer_ = { {"ps>\n", "ps>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939_ps_oer_ext_arr_[0] = {};
const int J1939_ps_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939_ps_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939_ps_oer_ext_arr_, 0, J1939_ps_oer_p_};
const TTCN_Typedescriptor_t J1939_ps_descr_ = { "@Isobus.J1939.ps", &OCTETSTRING_ber_, &J1939_ps_raw_, &OCTETSTRING_text_, &J1939_ps_xer_, &OCTETSTRING_json_, &J1939_ps_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_sa_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939_sa_xer_ = { {"sa>\n", "sa>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939_sa_oer_ext_arr_[0] = {};
const int J1939_sa_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939_sa_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939_sa_oer_ext_arr_, 0, J1939_sa_oer_p_};
const TTCN_Typedescriptor_t J1939_sa_descr_ = { "@Isobus.J1939.sa", &OCTETSTRING_ber_, &J1939_sa_raw_, &OCTETSTRING_text_, &J1939_sa_xer_, &OCTETSTRING_json_, &J1939_sa_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for J1939
const TTCN_Typedescriptor_t J1939_descr_ = { "@Isobus.J1939", NULL, &J1939_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_prio_raw_ = {6,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,6,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_prio_xer_ = { {"prio>\n", "prio>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939mod_prio_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939mod_prio_descr_ = { "@Isobus.J1939mod.prio", &BITSTRING_ber_, &J1939mod_prio_raw_, NULL, &J1939mod_prio_xer_, &BITSTRING_json_, &J1939mod_prio_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_res_raw_ = {1,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_res_xer_ = { {"res>\n", "res>\n"}, {5, 5}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939mod_res_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939mod_res_descr_ = { "@Isobus.J1939mod.res", &BITSTRING_ber_, &J1939mod_res_raw_, NULL, &J1939mod_res_xer_, &BITSTRING_json_, &J1939mod_res_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_dp_raw_ = {1,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_dp_xer_ = { {"dp>\n", "dp>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t J1939mod_dp_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t J1939mod_dp_descr_ = { "@Isobus.J1939mod.dp", &BITSTRING_ber_, &J1939mod_dp_raw_, NULL, &J1939mod_dp_xer_, &BITSTRING_json_, &J1939mod_dp_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_pf_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_pf_xer_ = { {"pf>\n", "pf>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939mod_pf_oer_ext_arr_[0] = {};
const int J1939mod_pf_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939mod_pf_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939mod_pf_oer_ext_arr_, 0, J1939mod_pf_oer_p_};
const TTCN_Typedescriptor_t J1939mod_pf_descr_ = { "@Isobus.J1939mod.pf", &OCTETSTRING_ber_, &J1939mod_pf_raw_, &OCTETSTRING_text_, &J1939mod_pf_xer_, &OCTETSTRING_json_, &J1939mod_pf_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_ps_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_ps_xer_ = { {"ps>\n", "ps>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939mod_ps_oer_ext_arr_[0] = {};
const int J1939mod_ps_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939mod_ps_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939mod_ps_oer_ext_arr_, 0, J1939mod_ps_oer_p_};
const TTCN_Typedescriptor_t J1939mod_ps_descr_ = { "@Isobus.J1939mod.ps", &OCTETSTRING_ber_, &J1939mod_ps_raw_, &OCTETSTRING_text_, &J1939mod_ps_xer_, &OCTETSTRING_json_, &J1939mod_ps_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_sa_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_sa_xer_ = { {"sa>\n", "sa>\n"}, {4, 4}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939mod_sa_oer_ext_arr_[0] = {};
const int J1939mod_sa_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939mod_sa_oer_ = { -1, TRUE, 1, FALSE, 0, 0, J1939mod_sa_oer_ext_arr_, 0, J1939mod_sa_oer_p_};
const TTCN_Typedescriptor_t J1939mod_sa_descr_ = { "@Isobus.J1939mod.sa", &OCTETSTRING_ber_, &J1939mod_sa_raw_, &OCTETSTRING_text_, &J1939mod_sa_xer_, &OCTETSTRING_json_, &J1939mod_sa_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_comp_raw_ = {24,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,3,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       J1939mod_comp_xer_ = { {"comp>\n", "comp>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int J1939mod_comp_oer_ext_arr_[0] = {};
const int J1939mod_comp_oer_p_[0] = {};
const TTCN_OERdescriptor_t J1939mod_comp_oer_ = { -1, TRUE, 3, FALSE, 0, 0, J1939mod_comp_oer_ext_arr_, 0, J1939mod_comp_oer_p_};
const TTCN_Typedescriptor_t J1939mod_comp_descr_ = { "@Isobus.J1939mod.comp", &OCTETSTRING_ber_, &J1939mod_comp_raw_, &OCTETSTRING_text_, &J1939mod_comp_xer_, &OCTETSTRING_json_, &J1939mod_comp_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t J1939mod_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for J1939mod
const TTCN_Typedescriptor_t J1939mod_descr_ = { "@Isobus.J1939mod", NULL, &J1939mod_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t AnyIsoBusPdu_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for AnyIsoBusPdu
const TTCN_Typedescriptor_t AnyIsoBusPdu_descr_ = { "@Isobus.AnyIsoBusPdu", NULL, &AnyIsoBusPdu_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__frame__j1939_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for CAN__frame__j1939
const TTCN_Typedescriptor_t CAN__frame__j1939_descr_ = { "@Isobus.CAN_frame_j1939", NULL, &CAN__frame__j1939_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__frame__j1939mod_can__pdu_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for CAN__frame__j1939mod_can__pdu
const TTCN_Typedescriptor_t CAN__frame__j1939mod_can__pdu_descr_ = { "@Isobus.CAN_frame_j1939mod.can_pdu", NULL, &CAN__frame__j1939mod_can__pdu_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__frame__j1939mod_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for CAN__frame__j1939mod
const TTCN_Typedescriptor_t CAN__frame__j1939mod_descr_ = { "@Isobus.CAN_frame_j1939mod", NULL, &CAN__frame__j1939mod_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
TTCN_Module module_object("Isobus", __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 */

J1939::J1939()
{
}

J1939::J1939(const BITSTRING& par_prio,
    const BITSTRING& par_res,
    const BITSTRING& par_dp,
    const OCTETSTRING& par_pf,
    const OCTETSTRING& par_ps,
    const OCTETSTRING& par_sa)
  :   field_prio(par_prio),
  field_res(par_res),
  field_dp(par_dp),
  field_pf(par_pf),
  field_ps(par_ps),
  field_sa(par_sa)
{
}

J1939::J1939(const J1939& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Isobus.J1939.");
if (other_value.prio().is_bound()) field_prio = other_value.prio();
else field_prio.clean_up();
if (other_value.res().is_bound()) field_res = other_value.res();
else field_res.clean_up();
if (other_value.dp().is_bound()) field_dp = other_value.dp();
else field_dp.clean_up();
if (other_value.pf().is_bound()) field_pf = other_value.pf();
else field_pf.clean_up();
if (other_value.ps().is_bound()) field_ps = other_value.ps();
else field_ps.clean_up();
if (other_value.sa().is_bound()) field_sa = other_value.sa();
else field_sa.clean_up();
}

void J1939::clean_up()
{
field_prio.clean_up();
field_res.clean_up();
field_dp.clean_up();
field_pf.clean_up();
field_ps.clean_up();
field_sa.clean_up();
}

const TTCN_Typedescriptor_t* J1939::get_descriptor() const { return &J1939_descr_; }
J1939& J1939::operator=(const J1939& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Isobus.J1939.");
  if (other_value.prio().is_bound()) field_prio = other_value.prio();
  else field_prio.clean_up();
  if (other_value.res().is_bound()) field_res = other_value.res();
  else field_res.clean_up();
  if (other_value.dp().is_bound()) field_dp = other_value.dp();
  else field_dp.clean_up();
  if (other_value.pf().is_bound()) field_pf = other_value.pf();
  else field_pf.clean_up();
  if (other_value.ps().is_bound()) field_ps = other_value.ps();
  else field_ps.clean_up();
  if (other_value.sa().is_bound()) field_sa = other_value.sa();
  else field_sa.clean_up();
}
return *this;
}

boolean J1939::operator==(const J1939& other_value) const
{
return field_prio==other_value.field_prio
  && field_res==other_value.field_res
  && field_dp==other_value.field_dp
  && field_pf==other_value.field_pf
  && field_ps==other_value.field_ps
  && field_sa==other_value.field_sa;
}

boolean J1939::is_bound() const
{
return (field_prio.is_bound())
  || (field_res.is_bound())
  || (field_dp.is_bound())
  || (field_pf.is_bound())
  || (field_ps.is_bound())
  || (field_sa.is_bound());
}
boolean J1939::is_value() const
{
return field_prio.is_value()
  && field_res.is_value()
  && field_dp.is_value()
  && field_pf.is_value()
  && field_ps.is_value()
  && field_sa.is_value();
}
void J1939::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ prio := ");
field_prio.log();
TTCN_Logger::log_event_str(", res := ");
field_res.log();
TTCN_Logger::log_event_str(", dp := ");
field_dp.log();
TTCN_Logger::log_event_str(", pf := ");
field_pf.log();
TTCN_Logger::log_event_str(", ps := ");
field_ps.log();
TTCN_Logger::log_event_str(", sa := ");
field_sa.log();
TTCN_Logger::log_event_str(" }");
}

void J1939::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 (6<param.get_size()) {
      param.error("record value of type @Isobus.J1939 has 6 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) prio().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) res().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) dp().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pf().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ps().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) sa().set_param(*param.get_elem(5));
    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(), "prio")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          prio().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(), "res")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          res().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(), "dp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dp().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(), "pf")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pf().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(), "ps")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ps().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(), "sa")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          sa().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 @Isobus.J1939: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Isobus.J1939");
  }
}

void J1939::set_implicit_omit()
{
if (prio().is_bound()) prio().set_implicit_omit();
if (res().is_bound()) res().set_implicit_omit();
if (dp().is_bound()) dp().set_implicit_omit();
if (pf().is_bound()) pf().set_implicit_omit();
if (ps().is_bound()) ps().set_implicit_omit();
if (sa().is_bound()) sa().set_implicit_omit();
}

void J1939::encode_text(Text_Buf& text_buf) const
{
field_prio.encode_text(text_buf);
field_res.encode_text(text_buf);
field_dp.encode_text(text_buf);
field_pf.encode_text(text_buf);
field_ps.encode_text(text_buf);
field_sa.encode_text(text_buf);
}

void J1939::decode_text(Text_Buf& text_buf)
{
field_prio.decode_text(text_buf);
field_res.decode_text(text_buf);
field_dp.decode_text(text_buf);
field_pf.decode_text(text_buf);
field_ps.decode_text(text_buf);
field_sa.decode_text(text_buf);
}

void J1939::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void J1939::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int J1939::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, J1939_prio_descr_.raw->forceomit);
  decoded_field_length = field_prio.RAW_decode(J1939_prio_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, J1939_res_descr_.raw->forceomit);
  decoded_field_length = field_res.RAW_decode(J1939_res_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, J1939_dp_descr_.raw->forceomit);
  decoded_field_length = field_dp.RAW_decode(J1939_dp_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, J1939_pf_descr_.raw->forceomit);
  decoded_field_length = field_pf.RAW_decode(J1939_pf_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, J1939_ps_descr_.raw->forceomit);
  decoded_field_length = field_ps.RAW_decode(J1939_ps_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_5_force_omit(5, force_omit, J1939_sa_descr_.raw->forceomit);
  decoded_field_length = field_sa.RAW_decode(J1939_sa_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_5_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int J1939::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 6;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(6);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, J1939_prio_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, J1939_res_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, J1939_dp_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, J1939_pf_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, J1939_ps_descr_.raw);
  myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 5, J1939_sa_descr_.raw);
  encoded_length += field_prio.RAW_encode(J1939_prio_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_res.RAW_encode(J1939_res_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_dp.RAW_encode(J1939_dp_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_pf.RAW_encode(J1939_pf_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_ps.RAW_encode(J1939_ps_descr_, *myleaf.body.node.nodes[4]);
  encoded_length += field_sa.RAW_encode(J1939_sa_descr_, *myleaf.body.node.nodes[5]);
  return myleaf.length = encoded_length;
}

struct J1939_template::single_value_struct {
BITSTRING_template field_prio;
BITSTRING_template field_res;
BITSTRING_template field_dp;
OCTETSTRING_template field_pf;
OCTETSTRING_template field_ps;
OCTETSTRING_template field_sa;
};

void J1939_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_prio = ANY_VALUE;
single_value->field_res = ANY_VALUE;
single_value->field_dp = ANY_VALUE;
single_value->field_pf = ANY_VALUE;
single_value->field_ps = ANY_VALUE;
single_value->field_sa = ANY_VALUE;
}
}
}

void J1939_template::copy_value(const J1939& other_value)
{
single_value = new single_value_struct;
if (other_value.prio().is_bound()) {
  single_value->field_prio = other_value.prio();
} else {
  single_value->field_prio.clean_up();
}
if (other_value.res().is_bound()) {
  single_value->field_res = other_value.res();
} else {
  single_value->field_res.clean_up();
}
if (other_value.dp().is_bound()) {
  single_value->field_dp = other_value.dp();
} else {
  single_value->field_dp.clean_up();
}
if (other_value.pf().is_bound()) {
  single_value->field_pf = other_value.pf();
} else {
  single_value->field_pf.clean_up();
}
if (other_value.ps().is_bound()) {
  single_value->field_ps = other_value.ps();
} else {
  single_value->field_ps.clean_up();
}
if (other_value.sa().is_bound()) {
  single_value->field_sa = other_value.sa();
} else {
  single_value->field_sa.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void J1939_template::copy_template(const J1939_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.prio().get_selection()) {
single_value->field_prio = other_value.prio();
} else {
single_value->field_prio.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.res().get_selection()) {
single_value->field_res = other_value.res();
} else {
single_value->field_res.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.dp().get_selection()) {
single_value->field_dp = other_value.dp();
} else {
single_value->field_dp.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pf().get_selection()) {
single_value->field_pf = other_value.pf();
} else {
single_value->field_pf.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ps().get_selection()) {
single_value->field_ps = other_value.ps();
} else {
single_value->field_ps.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.sa().get_selection()) {
single_value->field_sa = other_value.sa();
} else {
single_value->field_sa.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 J1939_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 @Isobus.J1939.");
break;
}
set_selection(other_value);
}

J1939_template::J1939_template()
{
}

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

J1939_template::J1939_template(const J1939& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean J1939_template::match(const J1939& 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.prio().is_bound()) return FALSE;
if(!single_value->field_prio.match(other_value.prio(), legacy))return FALSE;
if(!other_value.res().is_bound()) return FALSE;
if(!single_value->field_res.match(other_value.res(), legacy))return FALSE;
if(!other_value.dp().is_bound()) return FALSE;
if(!single_value->field_dp.match(other_value.dp(), legacy))return FALSE;
if(!other_value.pf().is_bound()) return FALSE;
if(!single_value->field_pf.match(other_value.pf(), legacy))return FALSE;
if(!other_value.ps().is_bound()) return FALSE;
if(!single_value->field_ps.match(other_value.ps(), legacy))return FALSE;
if(!other_value.sa().is_bound()) return FALSE;
if(!single_value->field_sa.match(other_value.sa(), 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 @Isobus.J1939.");
}
return FALSE;
}

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

 ||single_value->field_res.is_bound()

 ||single_value->field_dp.is_bound()

 ||single_value->field_pf.is_bound()

 ||single_value->field_ps.is_bound()

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

boolean J1939_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_prio.is_value()
 &&single_value->field_res.is_value()
 &&single_value->field_dp.is_value()
 &&single_value->field_pf.is_value()
 &&single_value->field_ps.is_value()
 &&single_value->field_sa.is_value();
}

void J1939_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;
}

J1939 J1939_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 @Isobus.J1939.");
J1939 ret_val;
if (single_value->field_prio.is_bound()) {
ret_val.prio() = single_value->field_prio.valueof();
}
if (single_value->field_res.is_bound()) {
ret_val.res() = single_value->field_res.valueof();
}
if (single_value->field_dp.is_bound()) {
ret_val.dp() = single_value->field_dp.valueof();
}
if (single_value->field_pf.is_bound()) {
ret_val.pf() = single_value->field_pf.valueof();
}
if (single_value->field_ps.is_bound()) {
ret_val.ps() = single_value->field_ps.valueof();
}
if (single_value->field_sa.is_bound()) {
ret_val.sa() = single_value->field_sa.valueof();
}
return ret_val;
}

void J1939_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 @Isobus.J1939.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new J1939_template[list_length];
}

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

BITSTRING_template& J1939_template::prio()
{
set_specific();
return single_value->field_prio;
}

const BITSTRING_template& J1939_template::prio() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field prio of a non-specific template of type @Isobus.J1939.");
return single_value->field_prio;
}

BITSTRING_template& J1939_template::res()
{
set_specific();
return single_value->field_res;
}

const BITSTRING_template& J1939_template::res() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field res of a non-specific template of type @Isobus.J1939.");
return single_value->field_res;
}

BITSTRING_template& J1939_template::dp()
{
set_specific();
return single_value->field_dp;
}

const BITSTRING_template& J1939_template::dp() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field dp of a non-specific template of type @Isobus.J1939.");
return single_value->field_dp;
}

OCTETSTRING_template& J1939_template::pf()
{
set_specific();
return single_value->field_pf;
}

const OCTETSTRING_template& J1939_template::pf() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pf of a non-specific template of type @Isobus.J1939.");
return single_value->field_pf;
}

OCTETSTRING_template& J1939_template::ps()
{
set_specific();
return single_value->field_ps;
}

const OCTETSTRING_template& J1939_template::ps() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ps of a non-specific template of type @Isobus.J1939.");
return single_value->field_ps;
}

OCTETSTRING_template& J1939_template::sa()
{
set_specific();
return single_value->field_sa;
}

const OCTETSTRING_template& J1939_template::sa() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field sa of a non-specific template of type @Isobus.J1939.");
return single_value->field_sa;
}

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

void J1939_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ prio := ");
single_value->field_prio.log();
TTCN_Logger::log_event_str(", res := ");
single_value->field_res.log();
TTCN_Logger::log_event_str(", dp := ");
single_value->field_dp.log();
TTCN_Logger::log_event_str(", pf := ");
single_value->field_pf.log();
TTCN_Logger::log_event_str(", ps := ");
single_value->field_ps.log();
TTCN_Logger::log_event_str(", sa := ");
single_value->field_sa.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 J1939_template::log_match(const J1939& 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_prio.match(match_value.prio(), legacy)){
TTCN_Logger::log_logmatch_info(".prio");
single_value->field_prio.log_match(match_value.prio(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_res.match(match_value.res(), legacy)){
TTCN_Logger::log_logmatch_info(".res");
single_value->field_res.log_match(match_value.res(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_dp.match(match_value.dp(), legacy)){
TTCN_Logger::log_logmatch_info(".dp");
single_value->field_dp.log_match(match_value.dp(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pf.match(match_value.pf(), legacy)){
TTCN_Logger::log_logmatch_info(".pf");
single_value->field_pf.log_match(match_value.pf(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ps.match(match_value.ps(), legacy)){
TTCN_Logger::log_logmatch_info(".ps");
single_value->field_ps.log_match(match_value.ps(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_sa.match(match_value.sa(), legacy)){
TTCN_Logger::log_logmatch_info(".sa");
single_value->field_sa.log_match(match_value.sa(), 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("{ prio := ");
single_value->field_prio.log_match(match_value.prio(), legacy);
TTCN_Logger::log_event_str(", res := ");
single_value->field_res.log_match(match_value.res(), legacy);
TTCN_Logger::log_event_str(", dp := ");
single_value->field_dp.log_match(match_value.dp(), legacy);
TTCN_Logger::log_event_str(", pf := ");
single_value->field_pf.log_match(match_value.pf(), legacy);
TTCN_Logger::log_event_str(", ps := ");
single_value->field_ps.log_match(match_value.ps(), legacy);
TTCN_Logger::log_event_str(", sa := ");
single_value->field_sa.log_match(match_value.sa(), 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 J1939_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_prio.encode_text(text_buf);
single_value->field_res.encode_text(text_buf);
single_value->field_dp.encode_text(text_buf);
single_value->field_pf.encode_text(text_buf);
single_value->field_ps.encode_text(text_buf);
single_value->field_sa.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 @Isobus.J1939.");
}
}

void J1939_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_prio.decode_text(text_buf);
single_value->field_res.decode_text(text_buf);
single_value->field_dp.decode_text(text_buf);
single_value->field_pf.decode_text(text_buf);
single_value->field_ps.decode_text(text_buf);
single_value->field_sa.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 J1939_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 @Isobus.J1939.");
}
}

void J1939_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: {
    J1939_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 (6<param.get_size()) {
      param.error("record template of type @Isobus.J1939 has 6 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) prio().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) res().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) dp().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pf().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ps().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) sa().set_param(*param.get_elem(5));
    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(), "prio")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          prio().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(), "res")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          res().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(), "dp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dp().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(), "pf")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pf().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(), "ps")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ps().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(), "sa")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          sa().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 @Isobus.J1939: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Isobus.J1939");
  }
  is_ifpresent = param.get_ifpresent();
}

void J1939_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_prio.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
single_value->field_res.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
single_value->field_dp.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
single_value->field_pf.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
single_value->field_ps.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
single_value->field_sa.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939");
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 : "@Isobus.J1939");
}

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

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

J1939mod::J1939mod()
{
}

J1939mod::J1939mod(const BITSTRING& par_prio,
    const BITSTRING& par_res,
    const BITSTRING& par_dp,
    const OCTETSTRING& par_pf,
    const OCTETSTRING& par_ps,
    const OCTETSTRING& par_sa,
    const OCTETSTRING& par_comp)
  :   field_prio(par_prio),
  field_res(par_res),
  field_dp(par_dp),
  field_pf(par_pf),
  field_ps(par_ps),
  field_sa(par_sa),
  field_comp(par_comp)
{
}

J1939mod::J1939mod(const J1939mod& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Isobus.J1939mod.");
if (other_value.prio().is_bound()) field_prio = other_value.prio();
else field_prio.clean_up();
if (other_value.res().is_bound()) field_res = other_value.res();
else field_res.clean_up();
if (other_value.dp().is_bound()) field_dp = other_value.dp();
else field_dp.clean_up();
if (other_value.pf().is_bound()) field_pf = other_value.pf();
else field_pf.clean_up();
if (other_value.ps().is_bound()) field_ps = other_value.ps();
else field_ps.clean_up();
if (other_value.sa().is_bound()) field_sa = other_value.sa();
else field_sa.clean_up();
if (other_value.comp().is_bound()) field_comp = other_value.comp();
else field_comp.clean_up();
}

void J1939mod::clean_up()
{
field_prio.clean_up();
field_res.clean_up();
field_dp.clean_up();
field_pf.clean_up();
field_ps.clean_up();
field_sa.clean_up();
field_comp.clean_up();
}

const TTCN_Typedescriptor_t* J1939mod::get_descriptor() const { return &J1939mod_descr_; }
J1939mod& J1939mod::operator=(const J1939mod& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Isobus.J1939mod.");
  if (other_value.prio().is_bound()) field_prio = other_value.prio();
  else field_prio.clean_up();
  if (other_value.res().is_bound()) field_res = other_value.res();
  else field_res.clean_up();
  if (other_value.dp().is_bound()) field_dp = other_value.dp();
  else field_dp.clean_up();
  if (other_value.pf().is_bound()) field_pf = other_value.pf();
  else field_pf.clean_up();
  if (other_value.ps().is_bound()) field_ps = other_value.ps();
  else field_ps.clean_up();
  if (other_value.sa().is_bound()) field_sa = other_value.sa();
  else field_sa.clean_up();
  if (other_value.comp().is_bound()) field_comp = other_value.comp();
  else field_comp.clean_up();
}
return *this;
}

boolean J1939mod::operator==(const J1939mod& other_value) const
{
return field_prio==other_value.field_prio
  && field_res==other_value.field_res
  && field_dp==other_value.field_dp
  && field_pf==other_value.field_pf
  && field_ps==other_value.field_ps
  && field_sa==other_value.field_sa
  && field_comp==other_value.field_comp;
}

boolean J1939mod::is_bound() const
{
return (field_prio.is_bound())
  || (field_res.is_bound())
  || (field_dp.is_bound())
  || (field_pf.is_bound())
  || (field_ps.is_bound())
  || (field_sa.is_bound())
  || (field_comp.is_bound());
}
boolean J1939mod::is_value() const
{
return field_prio.is_value()
  && field_res.is_value()
  && field_dp.is_value()
  && field_pf.is_value()
  && field_ps.is_value()
  && field_sa.is_value()
  && field_comp.is_value();
}
void J1939mod::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ prio := ");
field_prio.log();
TTCN_Logger::log_event_str(", res := ");
field_res.log();
TTCN_Logger::log_event_str(", dp := ");
field_dp.log();
TTCN_Logger::log_event_str(", pf := ");
field_pf.log();
TTCN_Logger::log_event_str(", ps := ");
field_ps.log();
TTCN_Logger::log_event_str(", sa := ");
field_sa.log();
TTCN_Logger::log_event_str(", comp := ");
field_comp.log();
TTCN_Logger::log_event_str(" }");
}

void J1939mod::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (7<param.get_size()) {
      param.error("record value of type @Isobus.J1939mod has 7 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) prio().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) res().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) dp().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pf().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ps().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) sa().set_param(*param.get_elem(5));
    if (param.get_size()>6 && param.get_elem(6)->get_type()!=Module_Param::MP_NotUsed) comp().set_param(*param.get_elem(6));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "prio")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          prio().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(), "res")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          res().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(), "dp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dp().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(), "pf")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pf().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(), "ps")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ps().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(), "sa")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          sa().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(), "comp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          comp().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 @Isobus.J1939mod: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Isobus.J1939mod");
  }
}

void J1939mod::set_implicit_omit()
{
if (prio().is_bound()) prio().set_implicit_omit();
if (res().is_bound()) res().set_implicit_omit();
if (dp().is_bound()) dp().set_implicit_omit();
if (pf().is_bound()) pf().set_implicit_omit();
if (ps().is_bound()) ps().set_implicit_omit();
if (sa().is_bound()) sa().set_implicit_omit();
if (comp().is_bound()) comp().set_implicit_omit();
}

void J1939mod::encode_text(Text_Buf& text_buf) const
{
field_prio.encode_text(text_buf);
field_res.encode_text(text_buf);
field_dp.encode_text(text_buf);
field_pf.encode_text(text_buf);
field_ps.encode_text(text_buf);
field_sa.encode_text(text_buf);
field_comp.encode_text(text_buf);
}

void J1939mod::decode_text(Text_Buf& text_buf)
{
field_prio.decode_text(text_buf);
field_res.decode_text(text_buf);
field_dp.decode_text(text_buf);
field_pf.decode_text(text_buf);
field_ps.decode_text(text_buf);
field_sa.decode_text(text_buf);
field_comp.decode_text(text_buf);
}

void J1939mod::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void J1939mod::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int J1939mod::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, J1939mod_prio_descr_.raw->forceomit);
  decoded_field_length = field_prio.RAW_decode(J1939mod_prio_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, J1939mod_res_descr_.raw->forceomit);
  decoded_field_length = field_res.RAW_decode(J1939mod_res_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, J1939mod_dp_descr_.raw->forceomit);
  decoded_field_length = field_dp.RAW_decode(J1939mod_dp_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, J1939mod_pf_descr_.raw->forceomit);
  decoded_field_length = field_pf.RAW_decode(J1939mod_pf_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, J1939mod_ps_descr_.raw->forceomit);
  decoded_field_length = field_ps.RAW_decode(J1939mod_ps_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_5_force_omit(5, force_omit, J1939mod_sa_descr_.raw->forceomit);
  decoded_field_length = field_sa.RAW_decode(J1939mod_sa_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_5_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_6_force_omit(6, force_omit, J1939mod_comp_descr_.raw->forceomit);
  decoded_field_length = field_comp.RAW_decode(J1939mod_comp_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_6_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int J1939mod::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 7;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(7);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, J1939mod_prio_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, J1939mod_res_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, J1939mod_dp_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, J1939mod_pf_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, J1939mod_ps_descr_.raw);
  myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 5, J1939mod_sa_descr_.raw);
  myleaf.body.node.nodes[6] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 6, J1939mod_comp_descr_.raw);
  encoded_length += field_prio.RAW_encode(J1939mod_prio_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_res.RAW_encode(J1939mod_res_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_dp.RAW_encode(J1939mod_dp_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_pf.RAW_encode(J1939mod_pf_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_ps.RAW_encode(J1939mod_ps_descr_, *myleaf.body.node.nodes[4]);
  encoded_length += field_sa.RAW_encode(J1939mod_sa_descr_, *myleaf.body.node.nodes[5]);
  encoded_length += field_comp.RAW_encode(J1939mod_comp_descr_, *myleaf.body.node.nodes[6]);
  return myleaf.length = encoded_length;
}

struct J1939mod_template::single_value_struct {
BITSTRING_template field_prio;
BITSTRING_template field_res;
BITSTRING_template field_dp;
OCTETSTRING_template field_pf;
OCTETSTRING_template field_ps;
OCTETSTRING_template field_sa;
OCTETSTRING_template field_comp;
};

void J1939mod_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_prio = ANY_VALUE;
single_value->field_res = ANY_VALUE;
single_value->field_dp = ANY_VALUE;
single_value->field_pf = ANY_VALUE;
single_value->field_ps = ANY_VALUE;
single_value->field_sa = ANY_VALUE;
single_value->field_comp = ANY_VALUE;
}
}
}

void J1939mod_template::copy_value(const J1939mod& other_value)
{
single_value = new single_value_struct;
if (other_value.prio().is_bound()) {
  single_value->field_prio = other_value.prio();
} else {
  single_value->field_prio.clean_up();
}
if (other_value.res().is_bound()) {
  single_value->field_res = other_value.res();
} else {
  single_value->field_res.clean_up();
}
if (other_value.dp().is_bound()) {
  single_value->field_dp = other_value.dp();
} else {
  single_value->field_dp.clean_up();
}
if (other_value.pf().is_bound()) {
  single_value->field_pf = other_value.pf();
} else {
  single_value->field_pf.clean_up();
}
if (other_value.ps().is_bound()) {
  single_value->field_ps = other_value.ps();
} else {
  single_value->field_ps.clean_up();
}
if (other_value.sa().is_bound()) {
  single_value->field_sa = other_value.sa();
} else {
  single_value->field_sa.clean_up();
}
if (other_value.comp().is_bound()) {
  single_value->field_comp = other_value.comp();
} else {
  single_value->field_comp.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void J1939mod_template::copy_template(const J1939mod_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.prio().get_selection()) {
single_value->field_prio = other_value.prio();
} else {
single_value->field_prio.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.res().get_selection()) {
single_value->field_res = other_value.res();
} else {
single_value->field_res.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.dp().get_selection()) {
single_value->field_dp = other_value.dp();
} else {
single_value->field_dp.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pf().get_selection()) {
single_value->field_pf = other_value.pf();
} else {
single_value->field_pf.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.ps().get_selection()) {
single_value->field_ps = other_value.ps();
} else {
single_value->field_ps.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.sa().get_selection()) {
single_value->field_sa = other_value.sa();
} else {
single_value->field_sa.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.comp().get_selection()) {
single_value->field_comp = other_value.comp();
} else {
single_value->field_comp.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 J1939mod_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 @Isobus.J1939mod.");
break;
}
set_selection(other_value);
}

J1939mod_template::J1939mod_template()
{
}

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

J1939mod_template::J1939mod_template(const J1939mod& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean J1939mod_template::match(const J1939mod& 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.prio().is_bound()) return FALSE;
if(!single_value->field_prio.match(other_value.prio(), legacy))return FALSE;
if(!other_value.res().is_bound()) return FALSE;
if(!single_value->field_res.match(other_value.res(), legacy))return FALSE;
if(!other_value.dp().is_bound()) return FALSE;
if(!single_value->field_dp.match(other_value.dp(), legacy))return FALSE;
if(!other_value.pf().is_bound()) return FALSE;
if(!single_value->field_pf.match(other_value.pf(), legacy))return FALSE;
if(!other_value.ps().is_bound()) return FALSE;
if(!single_value->field_ps.match(other_value.ps(), legacy))return FALSE;
if(!other_value.sa().is_bound()) return FALSE;
if(!single_value->field_sa.match(other_value.sa(), legacy))return FALSE;
if(!other_value.comp().is_bound()) return FALSE;
if(!single_value->field_comp.match(other_value.comp(), 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 @Isobus.J1939mod.");
}
return FALSE;
}

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

 ||single_value->field_res.is_bound()

 ||single_value->field_dp.is_bound()

 ||single_value->field_pf.is_bound()

 ||single_value->field_ps.is_bound()

 ||single_value->field_sa.is_bound()

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

boolean J1939mod_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_prio.is_value()
 &&single_value->field_res.is_value()
 &&single_value->field_dp.is_value()
 &&single_value->field_pf.is_value()
 &&single_value->field_ps.is_value()
 &&single_value->field_sa.is_value()
 &&single_value->field_comp.is_value();
}

void J1939mod_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;
}

J1939mod J1939mod_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 @Isobus.J1939mod.");
J1939mod ret_val;
if (single_value->field_prio.is_bound()) {
ret_val.prio() = single_value->field_prio.valueof();
}
if (single_value->field_res.is_bound()) {
ret_val.res() = single_value->field_res.valueof();
}
if (single_value->field_dp.is_bound()) {
ret_val.dp() = single_value->field_dp.valueof();
}
if (single_value->field_pf.is_bound()) {
ret_val.pf() = single_value->field_pf.valueof();
}
if (single_value->field_ps.is_bound()) {
ret_val.ps() = single_value->field_ps.valueof();
}
if (single_value->field_sa.is_bound()) {
ret_val.sa() = single_value->field_sa.valueof();
}
if (single_value->field_comp.is_bound()) {
ret_val.comp() = single_value->field_comp.valueof();
}
return ret_val;
}

void J1939mod_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 @Isobus.J1939mod.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new J1939mod_template[list_length];
}

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

BITSTRING_template& J1939mod_template::prio()
{
set_specific();
return single_value->field_prio;
}

const BITSTRING_template& J1939mod_template::prio() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field prio of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_prio;
}

BITSTRING_template& J1939mod_template::res()
{
set_specific();
return single_value->field_res;
}

const BITSTRING_template& J1939mod_template::res() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field res of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_res;
}

BITSTRING_template& J1939mod_template::dp()
{
set_specific();
return single_value->field_dp;
}

const BITSTRING_template& J1939mod_template::dp() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field dp of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_dp;
}

OCTETSTRING_template& J1939mod_template::pf()
{
set_specific();
return single_value->field_pf;
}

const OCTETSTRING_template& J1939mod_template::pf() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pf of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_pf;
}

OCTETSTRING_template& J1939mod_template::ps()
{
set_specific();
return single_value->field_ps;
}

const OCTETSTRING_template& J1939mod_template::ps() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ps of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_ps;
}

OCTETSTRING_template& J1939mod_template::sa()
{
set_specific();
return single_value->field_sa;
}

const OCTETSTRING_template& J1939mod_template::sa() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field sa of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_sa;
}

OCTETSTRING_template& J1939mod_template::comp()
{
set_specific();
return single_value->field_comp;
}

const OCTETSTRING_template& J1939mod_template::comp() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field comp of a non-specific template of type @Isobus.J1939mod.");
return single_value->field_comp;
}

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

void J1939mod_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ prio := ");
single_value->field_prio.log();
TTCN_Logger::log_event_str(", res := ");
single_value->field_res.log();
TTCN_Logger::log_event_str(", dp := ");
single_value->field_dp.log();
TTCN_Logger::log_event_str(", pf := ");
single_value->field_pf.log();
TTCN_Logger::log_event_str(", ps := ");
single_value->field_ps.log();
TTCN_Logger::log_event_str(", sa := ");
single_value->field_sa.log();
TTCN_Logger::log_event_str(", comp := ");
single_value->field_comp.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 J1939mod_template::log_match(const J1939mod& 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_prio.match(match_value.prio(), legacy)){
TTCN_Logger::log_logmatch_info(".prio");
single_value->field_prio.log_match(match_value.prio(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_res.match(match_value.res(), legacy)){
TTCN_Logger::log_logmatch_info(".res");
single_value->field_res.log_match(match_value.res(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_dp.match(match_value.dp(), legacy)){
TTCN_Logger::log_logmatch_info(".dp");
single_value->field_dp.log_match(match_value.dp(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pf.match(match_value.pf(), legacy)){
TTCN_Logger::log_logmatch_info(".pf");
single_value->field_pf.log_match(match_value.pf(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_ps.match(match_value.ps(), legacy)){
TTCN_Logger::log_logmatch_info(".ps");
single_value->field_ps.log_match(match_value.ps(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_sa.match(match_value.sa(), legacy)){
TTCN_Logger::log_logmatch_info(".sa");
single_value->field_sa.log_match(match_value.sa(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_comp.match(match_value.comp(), legacy)){
TTCN_Logger::log_logmatch_info(".comp");
single_value->field_comp.log_match(match_value.comp(), 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("{ prio := ");
single_value->field_prio.log_match(match_value.prio(), legacy);
TTCN_Logger::log_event_str(", res := ");
single_value->field_res.log_match(match_value.res(), legacy);
TTCN_Logger::log_event_str(", dp := ");
single_value->field_dp.log_match(match_value.dp(), legacy);
TTCN_Logger::log_event_str(", pf := ");
single_value->field_pf.log_match(match_value.pf(), legacy);
TTCN_Logger::log_event_str(", ps := ");
single_value->field_ps.log_match(match_value.ps(), legacy);
TTCN_Logger::log_event_str(", sa := ");
single_value->field_sa.log_match(match_value.sa(), legacy);
TTCN_Logger::log_event_str(", comp := ");
single_value->field_comp.log_match(match_value.comp(), 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 J1939mod_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_prio.encode_text(text_buf);
single_value->field_res.encode_text(text_buf);
single_value->field_dp.encode_text(text_buf);
single_value->field_pf.encode_text(text_buf);
single_value->field_ps.encode_text(text_buf);
single_value->field_sa.encode_text(text_buf);
single_value->field_comp.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 @Isobus.J1939mod.");
}
}

void J1939mod_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_prio.decode_text(text_buf);
single_value->field_res.decode_text(text_buf);
single_value->field_dp.decode_text(text_buf);
single_value->field_pf.decode_text(text_buf);
single_value->field_ps.decode_text(text_buf);
single_value->field_sa.decode_text(text_buf);
single_value->field_comp.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 J1939mod_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 @Isobus.J1939mod.");
}
}

void J1939mod_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: {
    J1939mod_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (7<param.get_size()) {
      param.error("record template of type @Isobus.J1939mod has 7 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) prio().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) res().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) dp().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pf().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) ps().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) sa().set_param(*param.get_elem(5));
    if (param.get_size()>6 && param.get_elem(6)->get_type()!=Module_Param::MP_NotUsed) comp().set_param(*param.get_elem(6));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "prio")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          prio().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(), "res")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          res().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(), "dp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dp().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(), "pf")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pf().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(), "ps")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ps().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(), "sa")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          sa().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(), "comp")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          comp().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 @Isobus.J1939mod: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Isobus.J1939mod");
  }
  is_ifpresent = param.get_ifpresent();
}

void J1939mod_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_prio.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_res.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_dp.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_pf.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_ps.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_sa.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
single_value->field_comp.check_restriction(t_res, t_name ? t_name : "@Isobus.J1939mod");
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 : "@Isobus.J1939mod");
}

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

boolean J1939mod_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 AnyIsoBusPdu::copy_value(const AnyIsoBusPdu& other_value)
{
switch (other_value.union_selection) {
case ALT_etp__dt:
field_etp__dt = new IsobusCMMessageTypes::ETP__DT(*other_value.field_etp__dt);
break;
case ALT_etp__cm:
field_etp__cm = new IsobusCMMessageTypes::ETP__CM(*other_value.field_etp__cm);
break;
case ALT_vt2ecu:
field_vt2ecu = new IsobusVTMessageTypes::VT2ECU(*other_value.field_vt2ecu);
break;
case ALT_ecu2vt:
field_ecu2vt = new IsobusVTMessageTypes::ECU2VT(*other_value.field_ecu2vt);
break;
case ALT_requestForAddressClaimed:
field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed(*other_value.field_requestForAddressClaimed);
break;
case ALT_tp__dt:
field_tp__dt = new IsobusCMMessageTypes::TP__DT(*other_value.field_tp__dt);
break;
case ALT_tp__cm:
field_tp__cm = new IsobusCMMessageTypes::TP__CM(*other_value.field_tp__cm);
break;
case ALT_networkMessage:
field_networkMessage = new IsobusNMMessageTypes::NetworkMessage(*other_value.field_networkMessage);
break;
case ALT_cannotClaimSourceAddress:
field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress(*other_value.field_cannotClaimSourceAddress);
break;
case ALT_addressClaimed:
field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed(*other_value.field_addressClaimed);
break;
case ALT_commandedAddress:
field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress(*other_value.field_commandedAddress);
break;
default:
TTCN_error("Assignment of an unbound union value of type @Isobus.AnyIsoBusPdu.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean AnyIsoBusPdu::operator==(const AnyIsoBusPdu& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @Isobus.AnyIsoBusPdu.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @Isobus.AnyIsoBusPdu.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_etp__dt:
return *field_etp__dt == *other_value.field_etp__dt;
case ALT_etp__cm:
return *field_etp__cm == *other_value.field_etp__cm;
case ALT_vt2ecu:
return *field_vt2ecu == *other_value.field_vt2ecu;
case ALT_ecu2vt:
return *field_ecu2vt == *other_value.field_ecu2vt;
case ALT_requestForAddressClaimed:
return *field_requestForAddressClaimed == *other_value.field_requestForAddressClaimed;
case ALT_tp__dt:
return *field_tp__dt == *other_value.field_tp__dt;
case ALT_tp__cm:
return *field_tp__cm == *other_value.field_tp__cm;
case ALT_networkMessage:
return *field_networkMessage == *other_value.field_networkMessage;
case ALT_cannotClaimSourceAddress:
return *field_cannotClaimSourceAddress == *other_value.field_cannotClaimSourceAddress;
case ALT_addressClaimed:
return *field_addressClaimed == *other_value.field_addressClaimed;
case ALT_commandedAddress:
return *field_commandedAddress == *other_value.field_commandedAddress;
default:
return FALSE;
}
}

IsobusCMMessageTypes::ETP__DT& AnyIsoBusPdu::etp__dt()
{
if (union_selection != ALT_etp__dt) {
clean_up();
field_etp__dt = new IsobusCMMessageTypes::ETP__DT;
union_selection = ALT_etp__dt;
}
return *field_etp__dt;
}

const IsobusCMMessageTypes::ETP__DT& AnyIsoBusPdu::etp__dt() const
{
if (union_selection != ALT_etp__dt) TTCN_error("Using non-selected field etp_dt in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_etp__dt;
}

IsobusCMMessageTypes::ETP__CM& AnyIsoBusPdu::etp__cm()
{
if (union_selection != ALT_etp__cm) {
clean_up();
field_etp__cm = new IsobusCMMessageTypes::ETP__CM;
union_selection = ALT_etp__cm;
}
return *field_etp__cm;
}

const IsobusCMMessageTypes::ETP__CM& AnyIsoBusPdu::etp__cm() const
{
if (union_selection != ALT_etp__cm) TTCN_error("Using non-selected field etp_cm in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_etp__cm;
}

IsobusVTMessageTypes::VT2ECU& AnyIsoBusPdu::vt2ecu()
{
if (union_selection != ALT_vt2ecu) {
clean_up();
field_vt2ecu = new IsobusVTMessageTypes::VT2ECU;
union_selection = ALT_vt2ecu;
}
return *field_vt2ecu;
}

const IsobusVTMessageTypes::VT2ECU& AnyIsoBusPdu::vt2ecu() const
{
if (union_selection != ALT_vt2ecu) TTCN_error("Using non-selected field vt2ecu in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_vt2ecu;
}

IsobusVTMessageTypes::ECU2VT& AnyIsoBusPdu::ecu2vt()
{
if (union_selection != ALT_ecu2vt) {
clean_up();
field_ecu2vt = new IsobusVTMessageTypes::ECU2VT;
union_selection = ALT_ecu2vt;
}
return *field_ecu2vt;
}

const IsobusVTMessageTypes::ECU2VT& AnyIsoBusPdu::ecu2vt() const
{
if (union_selection != ALT_ecu2vt) TTCN_error("Using non-selected field ecu2vt in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_ecu2vt;
}

IsobusNMMessageTypes::RequestForAddressClaimed& AnyIsoBusPdu::requestForAddressClaimed()
{
if (union_selection != ALT_requestForAddressClaimed) {
clean_up();
field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed;
union_selection = ALT_requestForAddressClaimed;
}
return *field_requestForAddressClaimed;
}

const IsobusNMMessageTypes::RequestForAddressClaimed& AnyIsoBusPdu::requestForAddressClaimed() const
{
if (union_selection != ALT_requestForAddressClaimed) TTCN_error("Using non-selected field requestForAddressClaimed in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_requestForAddressClaimed;
}

IsobusCMMessageTypes::TP__DT& AnyIsoBusPdu::tp__dt()
{
if (union_selection != ALT_tp__dt) {
clean_up();
field_tp__dt = new IsobusCMMessageTypes::TP__DT;
union_selection = ALT_tp__dt;
}
return *field_tp__dt;
}

const IsobusCMMessageTypes::TP__DT& AnyIsoBusPdu::tp__dt() const
{
if (union_selection != ALT_tp__dt) TTCN_error("Using non-selected field tp_dt in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_tp__dt;
}

IsobusCMMessageTypes::TP__CM& AnyIsoBusPdu::tp__cm()
{
if (union_selection != ALT_tp__cm) {
clean_up();
field_tp__cm = new IsobusCMMessageTypes::TP__CM;
union_selection = ALT_tp__cm;
}
return *field_tp__cm;
}

const IsobusCMMessageTypes::TP__CM& AnyIsoBusPdu::tp__cm() const
{
if (union_selection != ALT_tp__cm) TTCN_error("Using non-selected field tp_cm in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_tp__cm;
}

IsobusNMMessageTypes::NetworkMessage& AnyIsoBusPdu::networkMessage()
{
if (union_selection != ALT_networkMessage) {
clean_up();
field_networkMessage = new IsobusNMMessageTypes::NetworkMessage;
union_selection = ALT_networkMessage;
}
return *field_networkMessage;
}

const IsobusNMMessageTypes::NetworkMessage& AnyIsoBusPdu::networkMessage() const
{
if (union_selection != ALT_networkMessage) TTCN_error("Using non-selected field networkMessage in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_networkMessage;
}

IsobusNMMessageTypes::CannotClaimSourceAddress& AnyIsoBusPdu::cannotClaimSourceAddress()
{
if (union_selection != ALT_cannotClaimSourceAddress) {
clean_up();
field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress;
union_selection = ALT_cannotClaimSourceAddress;
}
return *field_cannotClaimSourceAddress;
}

const IsobusNMMessageTypes::CannotClaimSourceAddress& AnyIsoBusPdu::cannotClaimSourceAddress() const
{
if (union_selection != ALT_cannotClaimSourceAddress) TTCN_error("Using non-selected field cannotClaimSourceAddress in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_cannotClaimSourceAddress;
}

IsobusNMMessageTypes::AddressClaimed& AnyIsoBusPdu::addressClaimed()
{
if (union_selection != ALT_addressClaimed) {
clean_up();
field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed;
union_selection = ALT_addressClaimed;
}
return *field_addressClaimed;
}

const IsobusNMMessageTypes::AddressClaimed& AnyIsoBusPdu::addressClaimed() const
{
if (union_selection != ALT_addressClaimed) TTCN_error("Using non-selected field addressClaimed in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_addressClaimed;
}

IsobusNMMessageTypes::CommandedAddress& AnyIsoBusPdu::commandedAddress()
{
if (union_selection != ALT_commandedAddress) {
clean_up();
field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress;
union_selection = ALT_commandedAddress;
}
return *field_commandedAddress;
}

const IsobusNMMessageTypes::CommandedAddress& AnyIsoBusPdu::commandedAddress() const
{
if (union_selection != ALT_commandedAddress) TTCN_error("Using non-selected field commandedAddress in a value of union type @Isobus.AnyIsoBusPdu.");
return *field_commandedAddress;
}

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

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

boolean AnyIsoBusPdu::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_etp__dt: return field_etp__dt->is_value();
case ALT_etp__cm: return field_etp__cm->is_value();
case ALT_vt2ecu: return field_vt2ecu->is_value();
case ALT_ecu2vt: return field_ecu2vt->is_value();
case ALT_requestForAddressClaimed: return field_requestForAddressClaimed->is_value();
case ALT_tp__dt: return field_tp__dt->is_value();
case ALT_tp__cm: return field_tp__cm->is_value();
case ALT_networkMessage: return field_networkMessage->is_value();
case ALT_cannotClaimSourceAddress: return field_cannotClaimSourceAddress->is_value();
case ALT_addressClaimed: return field_addressClaimed->is_value();
case ALT_commandedAddress: return field_commandedAddress->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void AnyIsoBusPdu::clean_up()
{
switch (union_selection) {
case ALT_etp__dt:
  delete field_etp__dt;
  break;
case ALT_etp__cm:
  delete field_etp__cm;
  break;
case ALT_vt2ecu:
  delete field_vt2ecu;
  break;
case ALT_ecu2vt:
  delete field_ecu2vt;
  break;
case ALT_requestForAddressClaimed:
  delete field_requestForAddressClaimed;
  break;
case ALT_tp__dt:
  delete field_tp__dt;
  break;
case ALT_tp__cm:
  delete field_tp__cm;
  break;
case ALT_networkMessage:
  delete field_networkMessage;
  break;
case ALT_cannotClaimSourceAddress:
  delete field_cannotClaimSourceAddress;
  break;
case ALT_addressClaimed:
  delete field_addressClaimed;
  break;
case ALT_commandedAddress:
  delete field_commandedAddress;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void AnyIsoBusPdu::log() const
{
switch (union_selection) {
case ALT_etp__dt:
TTCN_Logger::log_event_str("{ etp_dt := ");
field_etp__dt->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_etp__cm:
TTCN_Logger::log_event_str("{ etp_cm := ");
field_etp__cm->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_vt2ecu:
TTCN_Logger::log_event_str("{ vt2ecu := ");
field_vt2ecu->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_ecu2vt:
TTCN_Logger::log_event_str("{ ecu2vt := ");
field_ecu2vt->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_requestForAddressClaimed:
TTCN_Logger::log_event_str("{ requestForAddressClaimed := ");
field_requestForAddressClaimed->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_tp__dt:
TTCN_Logger::log_event_str("{ tp_dt := ");
field_tp__dt->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_tp__cm:
TTCN_Logger::log_event_str("{ tp_cm := ");
field_tp__cm->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_networkMessage:
TTCN_Logger::log_event_str("{ networkMessage := ");
field_networkMessage->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_cannotClaimSourceAddress:
TTCN_Logger::log_event_str("{ cannotClaimSourceAddress := ");
field_cannotClaimSourceAddress->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_addressClaimed:
TTCN_Logger::log_event_str("{ addressClaimed := ");
field_addressClaimed->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_commandedAddress:
TTCN_Logger::log_event_str("{ commandedAddress := ");
field_commandedAddress->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void AnyIsoBusPdu::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, "etp_dt")) {
    etp__dt().set_param(*mp_last);
    if (!etp__dt().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "etp_cm")) {
    etp__cm().set_param(*mp_last);
    if (!etp__cm().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "vt2ecu")) {
    vt2ecu().set_param(*mp_last);
    if (!vt2ecu().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "ecu2vt")) {
    ecu2vt().set_param(*mp_last);
    if (!ecu2vt().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "requestForAddressClaimed")) {
    requestForAddressClaimed().set_param(*mp_last);
    if (!requestForAddressClaimed().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "tp_dt")) {
    tp__dt().set_param(*mp_last);
    if (!tp__dt().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "tp_cm")) {
    tp__cm().set_param(*mp_last);
    if (!tp__cm().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "networkMessage")) {
    networkMessage().set_param(*mp_last);
    if (!networkMessage().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "cannotClaimSourceAddress")) {
    cannotClaimSourceAddress().set_param(*mp_last);
    if (!cannotClaimSourceAddress().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "addressClaimed")) {
    addressClaimed().set_param(*mp_last);
    if (!addressClaimed().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "commandedAddress")) {
    commandedAddress().set_param(*mp_last);
    if (!commandedAddress().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @Isobus.AnyIsoBusPdu.", last_name);
}

void AnyIsoBusPdu::set_implicit_omit()
{
switch (union_selection) {
case ALT_etp__dt:
field_etp__dt->set_implicit_omit(); break;
case ALT_etp__cm:
field_etp__cm->set_implicit_omit(); break;
case ALT_vt2ecu:
field_vt2ecu->set_implicit_omit(); break;
case ALT_ecu2vt:
field_ecu2vt->set_implicit_omit(); break;
case ALT_requestForAddressClaimed:
field_requestForAddressClaimed->set_implicit_omit(); break;
case ALT_tp__dt:
field_tp__dt->set_implicit_omit(); break;
case ALT_tp__cm:
field_tp__cm->set_implicit_omit(); break;
case ALT_networkMessage:
field_networkMessage->set_implicit_omit(); break;
case ALT_cannotClaimSourceAddress:
field_cannotClaimSourceAddress->set_implicit_omit(); break;
case ALT_addressClaimed:
field_addressClaimed->set_implicit_omit(); break;
case ALT_commandedAddress:
field_commandedAddress->set_implicit_omit(); break;
default: break;
}
}

void AnyIsoBusPdu::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_etp__dt:
field_etp__dt->encode_text(text_buf);
break;
case ALT_etp__cm:
field_etp__cm->encode_text(text_buf);
break;
case ALT_vt2ecu:
field_vt2ecu->encode_text(text_buf);
break;
case ALT_ecu2vt:
field_ecu2vt->encode_text(text_buf);
break;
case ALT_requestForAddressClaimed:
field_requestForAddressClaimed->encode_text(text_buf);
break;
case ALT_tp__dt:
field_tp__dt->encode_text(text_buf);
break;
case ALT_tp__cm:
field_tp__cm->encode_text(text_buf);
break;
case ALT_networkMessage:
field_networkMessage->encode_text(text_buf);
break;
case ALT_cannotClaimSourceAddress:
field_cannotClaimSourceAddress->encode_text(text_buf);
break;
case ALT_addressClaimed:
field_addressClaimed->encode_text(text_buf);
break;
case ALT_commandedAddress:
field_commandedAddress->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @Isobus.AnyIsoBusPdu.");
}
}

void AnyIsoBusPdu::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_etp__dt:
etp__dt().decode_text(text_buf);
break;
case ALT_etp__cm:
etp__cm().decode_text(text_buf);
break;
case ALT_vt2ecu:
vt2ecu().decode_text(text_buf);
break;
case ALT_ecu2vt:
ecu2vt().decode_text(text_buf);
break;
case ALT_requestForAddressClaimed:
requestForAddressClaimed().decode_text(text_buf);
break;
case ALT_tp__dt:
tp__dt().decode_text(text_buf);
break;
case ALT_tp__cm:
tp__cm().decode_text(text_buf);
break;
case ALT_networkMessage:
networkMessage().decode_text(text_buf);
break;
case ALT_cannotClaimSourceAddress:
cannotClaimSourceAddress().decode_text(text_buf);
break;
case ALT_addressClaimed:
addressClaimed().decode_text(text_buf);
break;
case ALT_commandedAddress:
commandedAddress().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @Isobus.AnyIsoBusPdu.");
}
}

void AnyIsoBusPdu::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(TRUE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void AnyIsoBusPdu::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int AnyIsoBusPdu::RAW_decode(
const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, 
raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean, const RAW_Force_Omit* force_omit)
{
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  int decoded_length=0;
  int starting_pos=p_buf.get_pos_bit();
  if(sel_field!=-1){
    switch(sel_field){
    case 0: {
      RAW_Force_Omit field_force_omit(0, force_omit, IsobusCMMessageTypes::ETP__DT_descr_.raw->forceomit);
      decoded_length = etp__dt().RAW_decode(IsobusCMMessageTypes::ETP__DT_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 1: {
      RAW_Force_Omit field_force_omit(1, force_omit, IsobusCMMessageTypes::ETP__CM_descr_.raw->forceomit);
      decoded_length = etp__cm().RAW_decode(IsobusCMMessageTypes::ETP__CM_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 2: {
      RAW_Force_Omit field_force_omit(2, force_omit, IsobusVTMessageTypes::VT2ECU_descr_.raw->forceomit);
      decoded_length = vt2ecu().RAW_decode(IsobusVTMessageTypes::VT2ECU_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 3: {
      RAW_Force_Omit field_force_omit(3, force_omit, IsobusVTMessageTypes::ECU2VT_descr_.raw->forceomit);
      decoded_length = ecu2vt().RAW_decode(IsobusVTMessageTypes::ECU2VT_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 4: {
      RAW_Force_Omit field_force_omit(4, force_omit, IsobusNMMessageTypes::RequestForAddressClaimed_descr_.raw->forceomit);
      decoded_length = requestForAddressClaimed().RAW_decode(IsobusNMMessageTypes::RequestForAddressClaimed_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 5: {
      RAW_Force_Omit field_force_omit(5, force_omit, IsobusCMMessageTypes::TP__DT_descr_.raw->forceomit);
      decoded_length = tp__dt().RAW_decode(IsobusCMMessageTypes::TP__DT_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 6: {
      RAW_Force_Omit field_force_omit(6, force_omit, IsobusCMMessageTypes::TP__CM_descr_.raw->forceomit);
      decoded_length = tp__cm().RAW_decode(IsobusCMMessageTypes::TP__CM_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 7: {
      RAW_Force_Omit field_force_omit(7, force_omit, IsobusNMMessageTypes::NetworkMessage_descr_.raw->forceomit);
      decoded_length = networkMessage().RAW_decode(IsobusNMMessageTypes::NetworkMessage_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 8: {
      RAW_Force_Omit field_force_omit(8, force_omit, IsobusNMMessageTypes::CannotClaimSourceAddress_descr_.raw->forceomit);
      decoded_length = cannotClaimSourceAddress().RAW_decode(IsobusNMMessageTypes::CannotClaimSourceAddress_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 9: {
      RAW_Force_Omit field_force_omit(9, force_omit, IsobusNMMessageTypes::AddressClaimed_descr_.raw->forceomit);
      decoded_length = addressClaimed().RAW_decode(IsobusNMMessageTypes::AddressClaimed_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 10: {
      RAW_Force_Omit field_force_omit(10, force_omit, IsobusNMMessageTypes::CommandedAddress_descr_.raw->forceomit);
      decoded_length = commandedAddress().RAW_decode(IsobusNMMessageTypes::CommandedAddress_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    default: break;
    }
    return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
  } else {
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_0_force_omit(0, force_omit, IsobusCMMessageTypes::ETP__DT_descr_.raw->forceomit);
      decoded_length = etp__dt().RAW_decode(IsobusCMMessageTypes::ETP__DT_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_0_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_1_force_omit(1, force_omit, IsobusCMMessageTypes::ETP__CM_descr_.raw->forceomit);
      decoded_length = etp__cm().RAW_decode(IsobusCMMessageTypes::ETP__CM_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_1_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_2_force_omit(2, force_omit, IsobusVTMessageTypes::VT2ECU_descr_.raw->forceomit);
      decoded_length = vt2ecu().RAW_decode(IsobusVTMessageTypes::VT2ECU_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_2_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_3_force_omit(3, force_omit, IsobusVTMessageTypes::ECU2VT_descr_.raw->forceomit);
      decoded_length = ecu2vt().RAW_decode(IsobusVTMessageTypes::ECU2VT_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_3_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_4_force_omit(4, force_omit, IsobusNMMessageTypes::RequestForAddressClaimed_descr_.raw->forceomit);
      decoded_length = requestForAddressClaimed().RAW_decode(IsobusNMMessageTypes::RequestForAddressClaimed_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_4_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_5_force_omit(5, force_omit, IsobusCMMessageTypes::TP__DT_descr_.raw->forceomit);
      decoded_length = tp__dt().RAW_decode(IsobusCMMessageTypes::TP__DT_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_5_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_6_force_omit(6, force_omit, IsobusCMMessageTypes::TP__CM_descr_.raw->forceomit);
      decoded_length = tp__cm().RAW_decode(IsobusCMMessageTypes::TP__CM_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_6_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_7_force_omit(7, force_omit, IsobusNMMessageTypes::NetworkMessage_descr_.raw->forceomit);
      decoded_length = networkMessage().RAW_decode(IsobusNMMessageTypes::NetworkMessage_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_7_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_8_force_omit(8, force_omit, IsobusNMMessageTypes::CannotClaimSourceAddress_descr_.raw->forceomit);
      decoded_length = cannotClaimSourceAddress().RAW_decode(IsobusNMMessageTypes::CannotClaimSourceAddress_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_8_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_9_force_omit(9, force_omit, IsobusNMMessageTypes::AddressClaimed_descr_.raw->forceomit);
      decoded_length = addressClaimed().RAW_decode(IsobusNMMessageTypes::AddressClaimed_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_9_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
      p_buf.set_pos_bit(starting_pos);
      RAW_Force_Omit field_10_force_omit(10, force_omit, IsobusNMMessageTypes::CommandedAddress_descr_.raw->forceomit);
      decoded_length = commandedAddress().RAW_decode(IsobusNMMessageTypes::CommandedAddress_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_10_force_omit);
      if (decoded_length >= 0) {
         return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
       }
 }
 clean_up();
 return -1;
}

int AnyIsoBusPdu::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const
{
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 11;  myleaf.body.node.nodes = init_nodes_of_enc_tree(11);
  memset(myleaf.body.node.nodes, 0, 11 * sizeof(RAW_enc_tree *));
  switch (union_selection) {
  case ALT_etp__dt:
    myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 0, IsobusCMMessageTypes::ETP__DT_descr_.raw);
    encoded_length = field_etp__dt->RAW_encode(IsobusCMMessageTypes::ETP__DT_descr_, *myleaf.body.node.nodes[0]);
    myleaf.body.node.nodes[0]->coding_descr = &IsobusCMMessageTypes::ETP__DT_descr_;
    break;
  case ALT_etp__cm:
    myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 1, IsobusCMMessageTypes::ETP__CM_descr_.raw);
    encoded_length = field_etp__cm->RAW_encode(IsobusCMMessageTypes::ETP__CM_descr_, *myleaf.body.node.nodes[1]);
    myleaf.body.node.nodes[1]->coding_descr = &IsobusCMMessageTypes::ETP__CM_descr_;
    break;
  case ALT_vt2ecu:
    myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 2, IsobusVTMessageTypes::VT2ECU_descr_.raw);
    encoded_length = field_vt2ecu->RAW_encode(IsobusVTMessageTypes::VT2ECU_descr_, *myleaf.body.node.nodes[2]);
    myleaf.body.node.nodes[2]->coding_descr = &IsobusVTMessageTypes::VT2ECU_descr_;
    break;
  case ALT_ecu2vt:
    myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 3, IsobusVTMessageTypes::ECU2VT_descr_.raw);
    encoded_length = field_ecu2vt->RAW_encode(IsobusVTMessageTypes::ECU2VT_descr_, *myleaf.body.node.nodes[3]);
    myleaf.body.node.nodes[3]->coding_descr = &IsobusVTMessageTypes::ECU2VT_descr_;
    break;
  case ALT_requestForAddressClaimed:
    myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 4, IsobusNMMessageTypes::RequestForAddressClaimed_descr_.raw);
    encoded_length = field_requestForAddressClaimed->RAW_encode(IsobusNMMessageTypes::RequestForAddressClaimed_descr_, *myleaf.body.node.nodes[4]);
    myleaf.body.node.nodes[4]->coding_descr = &IsobusNMMessageTypes::RequestForAddressClaimed_descr_;
    break;
  case ALT_tp__dt:
    myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 5, IsobusCMMessageTypes::TP__DT_descr_.raw);
    encoded_length = field_tp__dt->RAW_encode(IsobusCMMessageTypes::TP__DT_descr_, *myleaf.body.node.nodes[5]);
    myleaf.body.node.nodes[5]->coding_descr = &IsobusCMMessageTypes::TP__DT_descr_;
    break;
  case ALT_tp__cm:
    myleaf.body.node.nodes[6] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 6, IsobusCMMessageTypes::TP__CM_descr_.raw);
    encoded_length = field_tp__cm->RAW_encode(IsobusCMMessageTypes::TP__CM_descr_, *myleaf.body.node.nodes[6]);
    myleaf.body.node.nodes[6]->coding_descr = &IsobusCMMessageTypes::TP__CM_descr_;
    break;
  case ALT_networkMessage:
    myleaf.body.node.nodes[7] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 7, IsobusNMMessageTypes::NetworkMessage_descr_.raw);
    encoded_length = field_networkMessage->RAW_encode(IsobusNMMessageTypes::NetworkMessage_descr_, *myleaf.body.node.nodes[7]);
    myleaf.body.node.nodes[7]->coding_descr = &IsobusNMMessageTypes::NetworkMessage_descr_;
    break;
  case ALT_cannotClaimSourceAddress:
    myleaf.body.node.nodes[8] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 8, IsobusNMMessageTypes::CannotClaimSourceAddress_descr_.raw);
    encoded_length = field_cannotClaimSourceAddress->RAW_encode(IsobusNMMessageTypes::CannotClaimSourceAddress_descr_, *myleaf.body.node.nodes[8]);
    myleaf.body.node.nodes[8]->coding_descr = &IsobusNMMessageTypes::CannotClaimSourceAddress_descr_;
    break;
  case ALT_addressClaimed:
    myleaf.body.node.nodes[9] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 9, IsobusNMMessageTypes::AddressClaimed_descr_.raw);
    encoded_length = field_addressClaimed->RAW_encode(IsobusNMMessageTypes::AddressClaimed_descr_, *myleaf.body.node.nodes[9]);
    myleaf.body.node.nodes[9]->coding_descr = &IsobusNMMessageTypes::AddressClaimed_descr_;
    break;
  case ALT_commandedAddress:
    myleaf.body.node.nodes[10] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 10, IsobusNMMessageTypes::CommandedAddress_descr_.raw);
    encoded_length = field_commandedAddress->RAW_encode(IsobusNMMessageTypes::CommandedAddress_descr_, *myleaf.body.node.nodes[10]);
    myleaf.body.node.nodes[10]->coding_descr = &IsobusNMMessageTypes::CommandedAddress_descr_;
    break;
  default:
    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  }
  return encoded_length;
}

void AnyIsoBusPdu_template::copy_value(const AnyIsoBusPdu& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
single_value.field_etp__dt = new IsobusCMMessageTypes::ETP__DT_template(other_value.etp__dt());
break;
case AnyIsoBusPdu::ALT_etp__cm:
single_value.field_etp__cm = new IsobusCMMessageTypes::ETP__CM_template(other_value.etp__cm());
break;
case AnyIsoBusPdu::ALT_vt2ecu:
single_value.field_vt2ecu = new IsobusVTMessageTypes::VT2ECU_template(other_value.vt2ecu());
break;
case AnyIsoBusPdu::ALT_ecu2vt:
single_value.field_ecu2vt = new IsobusVTMessageTypes::ECU2VT_template(other_value.ecu2vt());
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
single_value.field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed_template(other_value.requestForAddressClaimed());
break;
case AnyIsoBusPdu::ALT_tp__dt:
single_value.field_tp__dt = new IsobusCMMessageTypes::TP__DT_template(other_value.tp__dt());
break;
case AnyIsoBusPdu::ALT_tp__cm:
single_value.field_tp__cm = new IsobusCMMessageTypes::TP__CM_template(other_value.tp__cm());
break;
case AnyIsoBusPdu::ALT_networkMessage:
single_value.field_networkMessage = new IsobusNMMessageTypes::NetworkMessage_template(other_value.networkMessage());
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
single_value.field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress_template(other_value.cannotClaimSourceAddress());
break;
case AnyIsoBusPdu::ALT_addressClaimed:
single_value.field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed_template(other_value.addressClaimed());
break;
case AnyIsoBusPdu::ALT_commandedAddress:
single_value.field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress_template(other_value.commandedAddress());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @Isobus.AnyIsoBusPdu.");
}
set_selection(SPECIFIC_VALUE);
}

void AnyIsoBusPdu_template::copy_template(const AnyIsoBusPdu_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 AnyIsoBusPdu::ALT_etp__dt:
single_value.field_etp__dt = new IsobusCMMessageTypes::ETP__DT_template(*other_value.single_value.field_etp__dt);
break;
case AnyIsoBusPdu::ALT_etp__cm:
single_value.field_etp__cm = new IsobusCMMessageTypes::ETP__CM_template(*other_value.single_value.field_etp__cm);
break;
case AnyIsoBusPdu::ALT_vt2ecu:
single_value.field_vt2ecu = new IsobusVTMessageTypes::VT2ECU_template(*other_value.single_value.field_vt2ecu);
break;
case AnyIsoBusPdu::ALT_ecu2vt:
single_value.field_ecu2vt = new IsobusVTMessageTypes::ECU2VT_template(*other_value.single_value.field_ecu2vt);
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
single_value.field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed_template(*other_value.single_value.field_requestForAddressClaimed);
break;
case AnyIsoBusPdu::ALT_tp__dt:
single_value.field_tp__dt = new IsobusCMMessageTypes::TP__DT_template(*other_value.single_value.field_tp__dt);
break;
case AnyIsoBusPdu::ALT_tp__cm:
single_value.field_tp__cm = new IsobusCMMessageTypes::TP__CM_template(*other_value.single_value.field_tp__cm);
break;
case AnyIsoBusPdu::ALT_networkMessage:
single_value.field_networkMessage = new IsobusNMMessageTypes::NetworkMessage_template(*other_value.single_value.field_networkMessage);
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
single_value.field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress_template(*other_value.single_value.field_cannotClaimSourceAddress);
break;
case AnyIsoBusPdu::ALT_addressClaimed:
single_value.field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed_template(*other_value.single_value.field_addressClaimed);
break;
case AnyIsoBusPdu::ALT_commandedAddress:
single_value.field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress_template(*other_value.single_value.field_commandedAddress);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @Isobus.AnyIsoBusPdu.");
}
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 AnyIsoBusPdu_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 @Isobus.AnyIsoBusPdu.");
}
set_selection(other_value);
}

AnyIsoBusPdu_template::AnyIsoBusPdu_template()
{
}

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

AnyIsoBusPdu_template::AnyIsoBusPdu_template(const AnyIsoBusPdu& other_value)
{
copy_value(other_value);
}

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

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

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

void AnyIsoBusPdu_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
delete single_value.field_etp__dt;
break;
case AnyIsoBusPdu::ALT_etp__cm:
delete single_value.field_etp__cm;
break;
case AnyIsoBusPdu::ALT_vt2ecu:
delete single_value.field_vt2ecu;
break;
case AnyIsoBusPdu::ALT_ecu2vt:
delete single_value.field_ecu2vt;
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
delete single_value.field_requestForAddressClaimed;
break;
case AnyIsoBusPdu::ALT_tp__dt:
delete single_value.field_tp__dt;
break;
case AnyIsoBusPdu::ALT_tp__cm:
delete single_value.field_tp__cm;
break;
case AnyIsoBusPdu::ALT_networkMessage:
delete single_value.field_networkMessage;
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
delete single_value.field_cannotClaimSourceAddress;
break;
case AnyIsoBusPdu::ALT_addressClaimed:
delete single_value.field_addressClaimed;
break;
case AnyIsoBusPdu::ALT_commandedAddress:
delete single_value.field_commandedAddress;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

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

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

boolean AnyIsoBusPdu_template::match(const AnyIsoBusPdu& 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:
{
AnyIsoBusPdu::union_selection_type value_selection = other_value.get_selection();
if (value_selection == AnyIsoBusPdu::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
return single_value.field_etp__dt->match(other_value.etp__dt(), legacy);
case AnyIsoBusPdu::ALT_etp__cm:
return single_value.field_etp__cm->match(other_value.etp__cm(), legacy);
case AnyIsoBusPdu::ALT_vt2ecu:
return single_value.field_vt2ecu->match(other_value.vt2ecu(), legacy);
case AnyIsoBusPdu::ALT_ecu2vt:
return single_value.field_ecu2vt->match(other_value.ecu2vt(), legacy);
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
return single_value.field_requestForAddressClaimed->match(other_value.requestForAddressClaimed(), legacy);
case AnyIsoBusPdu::ALT_tp__dt:
return single_value.field_tp__dt->match(other_value.tp__dt(), legacy);
case AnyIsoBusPdu::ALT_tp__cm:
return single_value.field_tp__cm->match(other_value.tp__cm(), legacy);
case AnyIsoBusPdu::ALT_networkMessage:
return single_value.field_networkMessage->match(other_value.networkMessage(), legacy);
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
return single_value.field_cannotClaimSourceAddress->match(other_value.cannotClaimSourceAddress(), legacy);
case AnyIsoBusPdu::ALT_addressClaimed:
return single_value.field_addressClaimed->match(other_value.addressClaimed(), legacy);
case AnyIsoBusPdu::ALT_commandedAddress:
return single_value.field_commandedAddress->match(other_value.commandedAddress(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @Isobus.AnyIsoBusPdu.");
}
}
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 @Isobus.AnyIsoBusPdu.");
}
return FALSE;
}

boolean AnyIsoBusPdu_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
return single_value.field_etp__dt->is_value();
case AnyIsoBusPdu::ALT_etp__cm:
return single_value.field_etp__cm->is_value();
case AnyIsoBusPdu::ALT_vt2ecu:
return single_value.field_vt2ecu->is_value();
case AnyIsoBusPdu::ALT_ecu2vt:
return single_value.field_ecu2vt->is_value();
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
return single_value.field_requestForAddressClaimed->is_value();
case AnyIsoBusPdu::ALT_tp__dt:
return single_value.field_tp__dt->is_value();
case AnyIsoBusPdu::ALT_tp__cm:
return single_value.field_tp__cm->is_value();
case AnyIsoBusPdu::ALT_networkMessage:
return single_value.field_networkMessage->is_value();
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
return single_value.field_cannotClaimSourceAddress->is_value();
case AnyIsoBusPdu::ALT_addressClaimed:
return single_value.field_addressClaimed->is_value();
case AnyIsoBusPdu::ALT_commandedAddress:
return single_value.field_commandedAddress->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @Isobus.AnyIsoBusPdu.");
}
}

AnyIsoBusPdu AnyIsoBusPdu_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 @Isobus.AnyIsoBusPdu.");
AnyIsoBusPdu ret_val;
switch (single_value.union_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
ret_val.etp__dt() = single_value.field_etp__dt->valueof();
break;
case AnyIsoBusPdu::ALT_etp__cm:
ret_val.etp__cm() = single_value.field_etp__cm->valueof();
break;
case AnyIsoBusPdu::ALT_vt2ecu:
ret_val.vt2ecu() = single_value.field_vt2ecu->valueof();
break;
case AnyIsoBusPdu::ALT_ecu2vt:
ret_val.ecu2vt() = single_value.field_ecu2vt->valueof();
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
ret_val.requestForAddressClaimed() = single_value.field_requestForAddressClaimed->valueof();
break;
case AnyIsoBusPdu::ALT_tp__dt:
ret_val.tp__dt() = single_value.field_tp__dt->valueof();
break;
case AnyIsoBusPdu::ALT_tp__cm:
ret_val.tp__cm() = single_value.field_tp__cm->valueof();
break;
case AnyIsoBusPdu::ALT_networkMessage:
ret_val.networkMessage() = single_value.field_networkMessage->valueof();
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
ret_val.cannotClaimSourceAddress() = single_value.field_cannotClaimSourceAddress->valueof();
break;
case AnyIsoBusPdu::ALT_addressClaimed:
ret_val.addressClaimed() = single_value.field_addressClaimed->valueof();
break;
case AnyIsoBusPdu::ALT_commandedAddress:
ret_val.commandedAddress() = single_value.field_commandedAddress->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @Isobus.AnyIsoBusPdu.");
}
return ret_val;
}

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

IsobusCMMessageTypes::ETP__DT_template& AnyIsoBusPdu_template::etp__dt()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_etp__dt) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_etp__dt = new IsobusCMMessageTypes::ETP__DT_template(ANY_VALUE);
else single_value.field_etp__dt = new IsobusCMMessageTypes::ETP__DT_template;
single_value.union_selection = AnyIsoBusPdu::ALT_etp__dt;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_etp__dt;
}

const IsobusCMMessageTypes::ETP__DT_template& AnyIsoBusPdu_template::etp__dt() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field etp_dt in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_etp__dt) TTCN_error("Accessing non-selected field etp_dt in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_etp__dt;
}

IsobusCMMessageTypes::ETP__CM_template& AnyIsoBusPdu_template::etp__cm()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_etp__cm) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_etp__cm = new IsobusCMMessageTypes::ETP__CM_template(ANY_VALUE);
else single_value.field_etp__cm = new IsobusCMMessageTypes::ETP__CM_template;
single_value.union_selection = AnyIsoBusPdu::ALT_etp__cm;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_etp__cm;
}

const IsobusCMMessageTypes::ETP__CM_template& AnyIsoBusPdu_template::etp__cm() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field etp_cm in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_etp__cm) TTCN_error("Accessing non-selected field etp_cm in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_etp__cm;
}

IsobusVTMessageTypes::VT2ECU_template& AnyIsoBusPdu_template::vt2ecu()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_vt2ecu) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_vt2ecu = new IsobusVTMessageTypes::VT2ECU_template(ANY_VALUE);
else single_value.field_vt2ecu = new IsobusVTMessageTypes::VT2ECU_template;
single_value.union_selection = AnyIsoBusPdu::ALT_vt2ecu;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_vt2ecu;
}

const IsobusVTMessageTypes::VT2ECU_template& AnyIsoBusPdu_template::vt2ecu() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field vt2ecu in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_vt2ecu) TTCN_error("Accessing non-selected field vt2ecu in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_vt2ecu;
}

IsobusVTMessageTypes::ECU2VT_template& AnyIsoBusPdu_template::ecu2vt()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_ecu2vt) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_ecu2vt = new IsobusVTMessageTypes::ECU2VT_template(ANY_VALUE);
else single_value.field_ecu2vt = new IsobusVTMessageTypes::ECU2VT_template;
single_value.union_selection = AnyIsoBusPdu::ALT_ecu2vt;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_ecu2vt;
}

const IsobusVTMessageTypes::ECU2VT_template& AnyIsoBusPdu_template::ecu2vt() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field ecu2vt in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_ecu2vt) TTCN_error("Accessing non-selected field ecu2vt in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_ecu2vt;
}

IsobusNMMessageTypes::RequestForAddressClaimed_template& AnyIsoBusPdu_template::requestForAddressClaimed()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_requestForAddressClaimed) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed_template(ANY_VALUE);
else single_value.field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed_template;
single_value.union_selection = AnyIsoBusPdu::ALT_requestForAddressClaimed;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_requestForAddressClaimed;
}

const IsobusNMMessageTypes::RequestForAddressClaimed_template& AnyIsoBusPdu_template::requestForAddressClaimed() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field requestForAddressClaimed in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_requestForAddressClaimed) TTCN_error("Accessing non-selected field requestForAddressClaimed in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_requestForAddressClaimed;
}

IsobusCMMessageTypes::TP__DT_template& AnyIsoBusPdu_template::tp__dt()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_tp__dt) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_tp__dt = new IsobusCMMessageTypes::TP__DT_template(ANY_VALUE);
else single_value.field_tp__dt = new IsobusCMMessageTypes::TP__DT_template;
single_value.union_selection = AnyIsoBusPdu::ALT_tp__dt;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_tp__dt;
}

const IsobusCMMessageTypes::TP__DT_template& AnyIsoBusPdu_template::tp__dt() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field tp_dt in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_tp__dt) TTCN_error("Accessing non-selected field tp_dt in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_tp__dt;
}

IsobusCMMessageTypes::TP__CM_template& AnyIsoBusPdu_template::tp__cm()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_tp__cm) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_tp__cm = new IsobusCMMessageTypes::TP__CM_template(ANY_VALUE);
else single_value.field_tp__cm = new IsobusCMMessageTypes::TP__CM_template;
single_value.union_selection = AnyIsoBusPdu::ALT_tp__cm;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_tp__cm;
}

const IsobusCMMessageTypes::TP__CM_template& AnyIsoBusPdu_template::tp__cm() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field tp_cm in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_tp__cm) TTCN_error("Accessing non-selected field tp_cm in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_tp__cm;
}

IsobusNMMessageTypes::NetworkMessage_template& AnyIsoBusPdu_template::networkMessage()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_networkMessage) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_networkMessage = new IsobusNMMessageTypes::NetworkMessage_template(ANY_VALUE);
else single_value.field_networkMessage = new IsobusNMMessageTypes::NetworkMessage_template;
single_value.union_selection = AnyIsoBusPdu::ALT_networkMessage;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_networkMessage;
}

const IsobusNMMessageTypes::NetworkMessage_template& AnyIsoBusPdu_template::networkMessage() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field networkMessage in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_networkMessage) TTCN_error("Accessing non-selected field networkMessage in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_networkMessage;
}

IsobusNMMessageTypes::CannotClaimSourceAddress_template& AnyIsoBusPdu_template::cannotClaimSourceAddress()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_cannotClaimSourceAddress) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress_template(ANY_VALUE);
else single_value.field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress_template;
single_value.union_selection = AnyIsoBusPdu::ALT_cannotClaimSourceAddress;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_cannotClaimSourceAddress;
}

const IsobusNMMessageTypes::CannotClaimSourceAddress_template& AnyIsoBusPdu_template::cannotClaimSourceAddress() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field cannotClaimSourceAddress in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_cannotClaimSourceAddress) TTCN_error("Accessing non-selected field cannotClaimSourceAddress in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_cannotClaimSourceAddress;
}

IsobusNMMessageTypes::AddressClaimed_template& AnyIsoBusPdu_template::addressClaimed()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_addressClaimed) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed_template(ANY_VALUE);
else single_value.field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed_template;
single_value.union_selection = AnyIsoBusPdu::ALT_addressClaimed;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_addressClaimed;
}

const IsobusNMMessageTypes::AddressClaimed_template& AnyIsoBusPdu_template::addressClaimed() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field addressClaimed in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_addressClaimed) TTCN_error("Accessing non-selected field addressClaimed in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_addressClaimed;
}

IsobusNMMessageTypes::CommandedAddress_template& AnyIsoBusPdu_template::commandedAddress()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != AnyIsoBusPdu::ALT_commandedAddress) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress_template(ANY_VALUE);
else single_value.field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress_template;
single_value.union_selection = AnyIsoBusPdu::ALT_commandedAddress;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_commandedAddress;
}

const IsobusNMMessageTypes::CommandedAddress_template& AnyIsoBusPdu_template::commandedAddress() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field commandedAddress in a non-specific template of union type @Isobus.AnyIsoBusPdu.");
if (single_value.union_selection != AnyIsoBusPdu::ALT_commandedAddress) TTCN_error("Accessing non-selected field commandedAddress in a template of union type @Isobus.AnyIsoBusPdu.");
return *single_value.field_commandedAddress;
}

boolean AnyIsoBusPdu_template::ischosen(AnyIsoBusPdu::union_selection_type checked_selection) const
{
if (checked_selection == AnyIsoBusPdu::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @Isobus.AnyIsoBusPdu.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == AnyIsoBusPdu::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @Isobus.AnyIsoBusPdu.");
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 @Isobus.AnyIsoBusPdu 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 AnyIsoBusPdu_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
TTCN_Logger::log_event_str("{ etp_dt := ");
single_value.field_etp__dt->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_etp__cm:
TTCN_Logger::log_event_str("{ etp_cm := ");
single_value.field_etp__cm->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_vt2ecu:
TTCN_Logger::log_event_str("{ vt2ecu := ");
single_value.field_vt2ecu->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_ecu2vt:
TTCN_Logger::log_event_str("{ ecu2vt := ");
single_value.field_ecu2vt->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
TTCN_Logger::log_event_str("{ requestForAddressClaimed := ");
single_value.field_requestForAddressClaimed->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_tp__dt:
TTCN_Logger::log_event_str("{ tp_dt := ");
single_value.field_tp__dt->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_tp__cm:
TTCN_Logger::log_event_str("{ tp_cm := ");
single_value.field_tp__cm->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_networkMessage:
TTCN_Logger::log_event_str("{ networkMessage := ");
single_value.field_networkMessage->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
TTCN_Logger::log_event_str("{ cannotClaimSourceAddress := ");
single_value.field_cannotClaimSourceAddress->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_addressClaimed:
TTCN_Logger::log_event_str("{ addressClaimed := ");
single_value.field_addressClaimed->log();
TTCN_Logger::log_event_str(" }");
break;
case AnyIsoBusPdu::ALT_commandedAddress:
TTCN_Logger::log_event_str("{ commandedAddress := ");
single_value.field_commandedAddress->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 AnyIsoBusPdu_template::log_match(const AnyIsoBusPdu& 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 AnyIsoBusPdu::ALT_etp__dt:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".etp_dt");
single_value.field_etp__dt->log_match(match_value.etp__dt(), legacy);
} else {
TTCN_Logger::log_event_str("{ etp_dt := ");
single_value.field_etp__dt->log_match(match_value.etp__dt(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_etp__cm:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".etp_cm");
single_value.field_etp__cm->log_match(match_value.etp__cm(), legacy);
} else {
TTCN_Logger::log_event_str("{ etp_cm := ");
single_value.field_etp__cm->log_match(match_value.etp__cm(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_vt2ecu:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".vt2ecu");
single_value.field_vt2ecu->log_match(match_value.vt2ecu(), legacy);
} else {
TTCN_Logger::log_event_str("{ vt2ecu := ");
single_value.field_vt2ecu->log_match(match_value.vt2ecu(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_ecu2vt:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".ecu2vt");
single_value.field_ecu2vt->log_match(match_value.ecu2vt(), legacy);
} else {
TTCN_Logger::log_event_str("{ ecu2vt := ");
single_value.field_ecu2vt->log_match(match_value.ecu2vt(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".requestForAddressClaimed");
single_value.field_requestForAddressClaimed->log_match(match_value.requestForAddressClaimed(), legacy);
} else {
TTCN_Logger::log_event_str("{ requestForAddressClaimed := ");
single_value.field_requestForAddressClaimed->log_match(match_value.requestForAddressClaimed(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_tp__dt:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".tp_dt");
single_value.field_tp__dt->log_match(match_value.tp__dt(), legacy);
} else {
TTCN_Logger::log_event_str("{ tp_dt := ");
single_value.field_tp__dt->log_match(match_value.tp__dt(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_tp__cm:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".tp_cm");
single_value.field_tp__cm->log_match(match_value.tp__cm(), legacy);
} else {
TTCN_Logger::log_event_str("{ tp_cm := ");
single_value.field_tp__cm->log_match(match_value.tp__cm(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_networkMessage:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".networkMessage");
single_value.field_networkMessage->log_match(match_value.networkMessage(), legacy);
} else {
TTCN_Logger::log_event_str("{ networkMessage := ");
single_value.field_networkMessage->log_match(match_value.networkMessage(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".cannotClaimSourceAddress");
single_value.field_cannotClaimSourceAddress->log_match(match_value.cannotClaimSourceAddress(), legacy);
} else {
TTCN_Logger::log_event_str("{ cannotClaimSourceAddress := ");
single_value.field_cannotClaimSourceAddress->log_match(match_value.cannotClaimSourceAddress(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_addressClaimed:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".addressClaimed");
single_value.field_addressClaimed->log_match(match_value.addressClaimed(), legacy);
} else {
TTCN_Logger::log_event_str("{ addressClaimed := ");
single_value.field_addressClaimed->log_match(match_value.addressClaimed(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case AnyIsoBusPdu::ALT_commandedAddress:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".commandedAddress");
single_value.field_commandedAddress->log_match(match_value.commandedAddress(), legacy);
} else {
TTCN_Logger::log_event_str("{ commandedAddress := ");
single_value.field_commandedAddress->log_match(match_value.commandedAddress(), 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 AnyIsoBusPdu_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 AnyIsoBusPdu::ALT_etp__dt:
single_value.field_etp__dt->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_etp__cm:
single_value.field_etp__cm->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_vt2ecu:
single_value.field_vt2ecu->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_ecu2vt:
single_value.field_ecu2vt->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
single_value.field_requestForAddressClaimed->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_tp__dt:
single_value.field_tp__dt->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_tp__cm:
single_value.field_tp__cm->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_networkMessage:
single_value.field_networkMessage->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
single_value.field_cannotClaimSourceAddress->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_addressClaimed:
single_value.field_addressClaimed->encode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_commandedAddress:
single_value.field_commandedAddress->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @Isobus.AnyIsoBusPdu.");
}
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 @Isobus.AnyIsoBusPdu.");
}
}

void AnyIsoBusPdu_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
{
single_value.union_selection = AnyIsoBusPdu::UNBOUND_VALUE;
AnyIsoBusPdu::union_selection_type new_selection = (AnyIsoBusPdu::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case AnyIsoBusPdu::ALT_etp__dt:
single_value.field_etp__dt = new IsobusCMMessageTypes::ETP__DT_template;
single_value.field_etp__dt->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_etp__cm:
single_value.field_etp__cm = new IsobusCMMessageTypes::ETP__CM_template;
single_value.field_etp__cm->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_vt2ecu:
single_value.field_vt2ecu = new IsobusVTMessageTypes::VT2ECU_template;
single_value.field_vt2ecu->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_ecu2vt:
single_value.field_ecu2vt = new IsobusVTMessageTypes::ECU2VT_template;
single_value.field_ecu2vt->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
single_value.field_requestForAddressClaimed = new IsobusNMMessageTypes::RequestForAddressClaimed_template;
single_value.field_requestForAddressClaimed->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_tp__dt:
single_value.field_tp__dt = new IsobusCMMessageTypes::TP__DT_template;
single_value.field_tp__dt->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_tp__cm:
single_value.field_tp__cm = new IsobusCMMessageTypes::TP__CM_template;
single_value.field_tp__cm->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_networkMessage:
single_value.field_networkMessage = new IsobusNMMessageTypes::NetworkMessage_template;
single_value.field_networkMessage->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
single_value.field_cannotClaimSourceAddress = new IsobusNMMessageTypes::CannotClaimSourceAddress_template;
single_value.field_cannotClaimSourceAddress->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_addressClaimed:
single_value.field_addressClaimed = new IsobusNMMessageTypes::AddressClaimed_template;
single_value.field_addressClaimed->decode_text(text_buf);
break;
case AnyIsoBusPdu::ALT_commandedAddress:
single_value.field_commandedAddress = new IsobusNMMessageTypes::CommandedAddress_template;
single_value.field_commandedAddress->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @Isobus.AnyIsoBusPdu.");
}
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 AnyIsoBusPdu_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 @Isobus.AnyIsoBusPdu.");
}
}

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

boolean AnyIsoBusPdu_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 AnyIsoBusPdu_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 `@Isobus.AnyIsoBusPdu'");
    }
    if (strcmp("etp_dt", param_field) == 0) {
      etp__dt().set_param(param);
      return;
    } else if (strcmp("etp_cm", param_field) == 0) {
      etp__cm().set_param(param);
      return;
    } else if (strcmp("vt2ecu", param_field) == 0) {
      vt2ecu().set_param(param);
      return;
    } else if (strcmp("ecu2vt", param_field) == 0) {
      ecu2vt().set_param(param);
      return;
    } else if (strcmp("requestForAddressClaimed", param_field) == 0) {
      requestForAddressClaimed().set_param(param);
      return;
    } else if (strcmp("tp_dt", param_field) == 0) {
      tp__dt().set_param(param);
      return;
    } else if (strcmp("tp_cm", param_field) == 0) {
      tp__cm().set_param(param);
      return;
    } else if (strcmp("networkMessage", param_field) == 0) {
      networkMessage().set_param(param);
      return;
    } else if (strcmp("cannotClaimSourceAddress", param_field) == 0) {
      cannotClaimSourceAddress().set_param(param);
      return;
    } else if (strcmp("addressClaimed", param_field) == 0) {
      addressClaimed().set_param(param);
      return;
    } else if (strcmp("commandedAddress", param_field) == 0) {
      commandedAddress().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@Isobus.AnyIsoBusPdu'", 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: {
    AnyIsoBusPdu_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", "@Isobus.AnyIsoBusPdu");
    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, "etp_dt")) {
      etp__dt().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "etp_cm")) {
      etp__cm().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "vt2ecu")) {
      vt2ecu().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "ecu2vt")) {
      ecu2vt().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "requestForAddressClaimed")) {
      requestForAddressClaimed().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "tp_dt")) {
      tp__dt().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "tp_cm")) {
      tp__cm().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "networkMessage")) {
      networkMessage().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "cannotClaimSourceAddress")) {
      cannotClaimSourceAddress().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "addressClaimed")) {
      addressClaimed().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "commandedAddress")) {
      commandedAddress().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @Isobus.AnyIsoBusPdu.", last_name);
  } break;
  default:
    param.type_error("union template", "@Isobus.AnyIsoBusPdu");
  }
  is_ifpresent = param.get_ifpresent();
}

void AnyIsoBusPdu_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 AnyIsoBusPdu::ALT_etp__dt:
single_value.field_etp__dt->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_etp__cm:
single_value.field_etp__cm->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_vt2ecu:
single_value.field_vt2ecu->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_ecu2vt:
single_value.field_ecu2vt->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_requestForAddressClaimed:
single_value.field_requestForAddressClaimed->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_tp__dt:
single_value.field_tp__dt->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_tp__cm:
single_value.field_tp__cm->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_networkMessage:
single_value.field_networkMessage->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
single_value.field_cannotClaimSourceAddress->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_addressClaimed:
single_value.field_addressClaimed->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
case AnyIsoBusPdu::ALT_commandedAddress:
single_value.field_commandedAddress->check_restriction(t_res, t_name ? t_name : "@Isobus.AnyIsoBusPdu");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @Isobus.AnyIsoBusPdu.");
}
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 : "@Isobus.AnyIsoBusPdu");
}

CAN__frame__j1939::CAN__frame__j1939()
{
}

CAN__frame__j1939::CAN__frame__j1939(const J1939& par_can__j1939,
    const AnyIsoBusPdu& par_can__pdu)
  :   field_can__j1939(par_can__j1939),
  field_can__pdu(par_can__pdu)
{
}

CAN__frame__j1939::CAN__frame__j1939(const CAN__frame__j1939& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Isobus.CAN_frame_j1939.");
if (other_value.can__j1939().is_bound()) field_can__j1939 = other_value.can__j1939();
else field_can__j1939.clean_up();
if (other_value.can__pdu().is_bound()) field_can__pdu = other_value.can__pdu();
else field_can__pdu.clean_up();
}

void CAN__frame__j1939::clean_up()
{
field_can__j1939.clean_up();
field_can__pdu.clean_up();
}

const TTCN_Typedescriptor_t* CAN__frame__j1939::get_descriptor() const { return &CAN__frame__j1939_descr_; }
CAN__frame__j1939& CAN__frame__j1939::operator=(const CAN__frame__j1939& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Isobus.CAN_frame_j1939.");
  if (other_value.can__j1939().is_bound()) field_can__j1939 = other_value.can__j1939();
  else field_can__j1939.clean_up();
  if (other_value.can__pdu().is_bound()) field_can__pdu = other_value.can__pdu();
  else field_can__pdu.clean_up();
}
return *this;
}

boolean CAN__frame__j1939::operator==(const CAN__frame__j1939& other_value) const
{
return field_can__j1939==other_value.field_can__j1939
  && field_can__pdu==other_value.field_can__pdu;
}

boolean CAN__frame__j1939::is_bound() const
{
return (field_can__j1939.is_bound())
  || (field_can__pdu.is_bound());
}
boolean CAN__frame__j1939::is_value() const
{
return field_can__j1939.is_value()
  && field_can__pdu.is_value();
}
void CAN__frame__j1939::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ can_j1939 := ");
field_can__j1939.log();
TTCN_Logger::log_event_str(", can_pdu := ");
field_can__pdu.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__frame__j1939::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 @Isobus.CAN_frame_j1939 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) can__j1939().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) can__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(), "can_j1939")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__j1939().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__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 @Isobus.CAN_frame_j1939: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Isobus.CAN_frame_j1939");
  }
}

void CAN__frame__j1939::set_implicit_omit()
{
if (can__j1939().is_bound()) can__j1939().set_implicit_omit();
if (can__pdu().is_bound()) can__pdu().set_implicit_omit();
}

void CAN__frame__j1939::encode_text(Text_Buf& text_buf) const
{
field_can__j1939.encode_text(text_buf);
field_can__pdu.encode_text(text_buf);
}

void CAN__frame__j1939::decode_text(Text_Buf& text_buf)
{
field_can__j1939.decode_text(text_buf);
field_can__pdu.decode_text(text_buf);
}

void CAN__frame__j1939::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void CAN__frame__j1939::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int CAN__frame__j1939::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, J1939_descr_.raw->forceomit);
  decoded_field_length = field_can__j1939.RAW_decode(J1939_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, AnyIsoBusPdu_descr_.raw->forceomit);
  decoded_field_length = field_can__pdu.RAW_decode(AnyIsoBusPdu_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int CAN__frame__j1939::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 2;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(2);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, J1939_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, AnyIsoBusPdu_descr_.raw);
  encoded_length += field_can__j1939.RAW_encode(J1939_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_can__pdu.RAW_encode(AnyIsoBusPdu_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__frame__j1939_template::single_value_struct {
J1939_template field_can__j1939;
AnyIsoBusPdu_template field_can__pdu;
};

void CAN__frame__j1939_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_can__j1939 = ANY_VALUE;
single_value->field_can__pdu = ANY_VALUE;
}
}
}

void CAN__frame__j1939_template::copy_value(const CAN__frame__j1939& other_value)
{
single_value = new single_value_struct;
if (other_value.can__j1939().is_bound()) {
  single_value->field_can__j1939 = other_value.can__j1939();
} else {
  single_value->field_can__j1939.clean_up();
}
if (other_value.can__pdu().is_bound()) {
  single_value->field_can__pdu = other_value.can__pdu();
} else {
  single_value->field_can__pdu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__frame__j1939_template::copy_template(const CAN__frame__j1939_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.can__j1939().get_selection()) {
single_value->field_can__j1939 = other_value.can__j1939();
} else {
single_value->field_can__j1939.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.can__pdu().get_selection()) {
single_value->field_can__pdu = other_value.can__pdu();
} else {
single_value->field_can__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 CAN__frame__j1939_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 @Isobus.CAN_frame_j1939.");
break;
}
set_selection(other_value);
}

CAN__frame__j1939_template::CAN__frame__j1939_template()
{
}

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

CAN__frame__j1939_template::CAN__frame__j1939_template(const CAN__frame__j1939& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__frame__j1939_template::match(const CAN__frame__j1939& 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.can__j1939().is_bound()) return FALSE;
if(!single_value->field_can__j1939.match(other_value.can__j1939(), legacy))return FALSE;
if(!other_value.can__pdu().is_bound()) return FALSE;
if(!single_value->field_can__pdu.match(other_value.can__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 @Isobus.CAN_frame_j1939.");
}
return FALSE;
}

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

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

boolean CAN__frame__j1939_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_can__j1939.is_value()
 &&single_value->field_can__pdu.is_value();
}

void CAN__frame__j1939_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;
}

CAN__frame__j1939 CAN__frame__j1939_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 @Isobus.CAN_frame_j1939.");
CAN__frame__j1939 ret_val;
if (single_value->field_can__j1939.is_bound()) {
ret_val.can__j1939() = single_value->field_can__j1939.valueof();
}
if (single_value->field_can__pdu.is_bound()) {
ret_val.can__pdu() = single_value->field_can__pdu.valueof();
}
return ret_val;
}

void CAN__frame__j1939_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 @Isobus.CAN_frame_j1939.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__frame__j1939_template[list_length];
}

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

J1939_template& CAN__frame__j1939_template::can__j1939()
{
set_specific();
return single_value->field_can__j1939;
}

const J1939_template& CAN__frame__j1939_template::can__j1939() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field can_j1939 of a non-specific template of type @Isobus.CAN_frame_j1939.");
return single_value->field_can__j1939;
}

AnyIsoBusPdu_template& CAN__frame__j1939_template::can__pdu()
{
set_specific();
return single_value->field_can__pdu;
}

const AnyIsoBusPdu_template& CAN__frame__j1939_template::can__pdu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field can_pdu of a non-specific template of type @Isobus.CAN_frame_j1939.");
return single_value->field_can__pdu;
}

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

void CAN__frame__j1939_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ can_j1939 := ");
single_value->field_can__j1939.log();
TTCN_Logger::log_event_str(", can_pdu := ");
single_value->field_can__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 CAN__frame__j1939_template::log_match(const CAN__frame__j1939& 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_can__j1939.match(match_value.can__j1939(), legacy)){
TTCN_Logger::log_logmatch_info(".can_j1939");
single_value->field_can__j1939.log_match(match_value.can__j1939(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_can__pdu.match(match_value.can__pdu(), legacy)){
TTCN_Logger::log_logmatch_info(".can_pdu");
single_value->field_can__pdu.log_match(match_value.can__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("{ can_j1939 := ");
single_value->field_can__j1939.log_match(match_value.can__j1939(), legacy);
TTCN_Logger::log_event_str(", can_pdu := ");
single_value->field_can__pdu.log_match(match_value.can__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 CAN__frame__j1939_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_can__j1939.encode_text(text_buf);
single_value->field_can__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 @Isobus.CAN_frame_j1939.");
}
}

void CAN__frame__j1939_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_can__j1939.decode_text(text_buf);
single_value->field_can__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 CAN__frame__j1939_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 @Isobus.CAN_frame_j1939.");
}
}

void CAN__frame__j1939_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: {
    CAN__frame__j1939_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 @Isobus.CAN_frame_j1939 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) can__j1939().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) can__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(), "can_j1939")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__j1939().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__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 @Isobus.CAN_frame_j1939: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Isobus.CAN_frame_j1939");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__frame__j1939_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_can__j1939.check_restriction(t_res, t_name ? t_name : "@Isobus.CAN_frame_j1939");
single_value->field_can__pdu.check_restriction(t_res, t_name ? t_name : "@Isobus.CAN_frame_j1939");
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 : "@Isobus.CAN_frame_j1939");
}

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

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

CAN__frame__j1939mod::CAN__frame__j1939mod()
{
}

CAN__frame__j1939mod::CAN__frame__j1939mod(const J1939mod& par_can__j1939,
    const AnyIsoBusPdu& par_can__pdu)
  :   field_can__j1939(par_can__j1939),
  field_can__pdu(par_can__pdu)
{
}

CAN__frame__j1939mod::CAN__frame__j1939mod(const CAN__frame__j1939mod& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @Isobus.CAN_frame_j1939mod.");
if (other_value.can__j1939().is_bound()) field_can__j1939 = other_value.can__j1939();
else field_can__j1939.clean_up();
if (other_value.can__pdu().is_bound()) field_can__pdu = other_value.can__pdu();
else field_can__pdu.clean_up();
}

void CAN__frame__j1939mod::clean_up()
{
field_can__j1939.clean_up();
field_can__pdu.clean_up();
}

const TTCN_Typedescriptor_t* CAN__frame__j1939mod::get_descriptor() const { return &CAN__frame__j1939mod_descr_; }
CAN__frame__j1939mod& CAN__frame__j1939mod::operator=(const CAN__frame__j1939mod& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @Isobus.CAN_frame_j1939mod.");
  if (other_value.can__j1939().is_bound()) field_can__j1939 = other_value.can__j1939();
  else field_can__j1939.clean_up();
  if (other_value.can__pdu().is_bound()) field_can__pdu = other_value.can__pdu();
  else field_can__pdu.clean_up();
}
return *this;
}

boolean CAN__frame__j1939mod::operator==(const CAN__frame__j1939mod& other_value) const
{
return field_can__j1939==other_value.field_can__j1939
  && field_can__pdu==other_value.field_can__pdu;
}

boolean CAN__frame__j1939mod::is_bound() const
{
return (field_can__j1939.is_bound())
  || (field_can__pdu.is_bound());
}
boolean CAN__frame__j1939mod::is_value() const
{
return field_can__j1939.is_value()
  && field_can__pdu.is_value();
}
void CAN__frame__j1939mod::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ can_j1939 := ");
field_can__j1939.log();
TTCN_Logger::log_event_str(", can_pdu := ");
field_can__pdu.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__frame__j1939mod::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 @Isobus.CAN_frame_j1939mod 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) can__j1939().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) can__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(), "can_j1939")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__j1939().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__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 @Isobus.CAN_frame_j1939mod: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@Isobus.CAN_frame_j1939mod");
  }
}

void CAN__frame__j1939mod::set_implicit_omit()
{
if (can__j1939().is_bound()) can__j1939().set_implicit_omit();
if (can__pdu().is_bound()) can__pdu().set_implicit_omit();
}

void CAN__frame__j1939mod::encode_text(Text_Buf& text_buf) const
{
field_can__j1939.encode_text(text_buf);
field_can__pdu.encode_text(text_buf);
}

void CAN__frame__j1939mod::decode_text(Text_Buf& text_buf)
{
field_can__j1939.decode_text(text_buf);
field_can__pdu.decode_text(text_buf);
}

void CAN__frame__j1939mod::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void CAN__frame__j1939mod::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int CAN__frame__j1939mod::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  int selected_field = -1;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, J1939mod_descr_.raw->forceomit);
  decoded_field_length = field_can__j1939.RAW_decode(J1939mod_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  if (field_can__j1939.comp() ==  os_0) selected_field = 0;
  else if (field_can__j1939.comp() ==  os_1) selected_field = 1;
  else if (field_can__j1939.comp() ==  os_2) selected_field = 2;
  else if (field_can__j1939.comp() ==  os_3) selected_field = 3;
  else if (field_can__j1939.comp() ==  os_4) selected_field = 4;
  else if (field_can__j1939.comp() ==  os_5) selected_field = 5;
  else if (field_can__j1939.comp() ==  os_6) selected_field = 6;
  else if (field_can__j1939.comp() ==  os_7) selected_field = 7;
  else if (field_can__j1939.comp() ==  os_8) selected_field = 8;
  else if (field_can__j1939.comp() ==  os_9) selected_field = 9;
  else if (field_can__j1939.comp() ==  os_10) selected_field = 10;
  else selected_field = -1;
  RAW_Force_Omit field_1_force_omit(1, force_omit, CAN__frame__j1939mod_can__pdu_descr_.raw->forceomit);
  decoded_field_length = field_can__pdu.RAW_decode(CAN__frame__j1939mod_can__pdu_descr_, p_buf, limit, local_top_order, no_err, selected_field, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int CAN__frame__j1939mod::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 2;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(2);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, J1939mod_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__frame__j1939mod_can__pdu_descr_.raw);
  encoded_length += field_can__j1939.RAW_encode(J1939mod_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_can__pdu.RAW_encode(CAN__frame__j1939mod_can__pdu_descr_, *myleaf.body.node.nodes[1]);
  switch (field_can__pdu.get_selection()) {
  case AnyIsoBusPdu::ALT_etp__dt:
  if (field_can__j1939.comp() !=  os_0) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_0.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_etp__cm:
  if (field_can__j1939.comp() !=  os_1) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_1.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_vt2ecu:
  if (field_can__j1939.comp() !=  os_2) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_2.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_ecu2vt:
  if (field_can__j1939.comp() !=  os_3) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_3.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_requestForAddressClaimed:
  if (field_can__j1939.comp() !=  os_4) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_4.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_tp__dt:
  if (field_can__j1939.comp() !=  os_5) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_5.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_tp__cm:
  if (field_can__j1939.comp() !=  os_6) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_6.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_networkMessage:
  if (field_can__j1939.comp() !=  os_7) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_7.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_cannotClaimSourceAddress:
  if (field_can__j1939.comp() !=  os_8) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_8.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_addressClaimed:
  if (field_can__j1939.comp() !=  os_9) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_9.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  case AnyIsoBusPdu::ALT_commandedAddress:
  if (field_can__j1939.comp() !=  os_10) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 2;
  int new_pos[] = { 0, 6 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 2, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_10.RAW_encode(J1939mod_comp_descr_,*temp_leaf);
  else
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  free_tree_pos(pr_pos.pos);
  }
  break;
  default:;
  }
  return myleaf.length = encoded_length;
}

struct CAN__frame__j1939mod_template::single_value_struct {
J1939mod_template field_can__j1939;
AnyIsoBusPdu_template field_can__pdu;
};

void CAN__frame__j1939mod_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_can__j1939 = ANY_VALUE;
single_value->field_can__pdu = ANY_VALUE;
}
}
}

void CAN__frame__j1939mod_template::copy_value(const CAN__frame__j1939mod& other_value)
{
single_value = new single_value_struct;
if (other_value.can__j1939().is_bound()) {
  single_value->field_can__j1939 = other_value.can__j1939();
} else {
  single_value->field_can__j1939.clean_up();
}
if (other_value.can__pdu().is_bound()) {
  single_value->field_can__pdu = other_value.can__pdu();
} else {
  single_value->field_can__pdu.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__frame__j1939mod_template::copy_template(const CAN__frame__j1939mod_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.can__j1939().get_selection()) {
single_value->field_can__j1939 = other_value.can__j1939();
} else {
single_value->field_can__j1939.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.can__pdu().get_selection()) {
single_value->field_can__pdu = other_value.can__pdu();
} else {
single_value->field_can__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 CAN__frame__j1939mod_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 @Isobus.CAN_frame_j1939mod.");
break;
}
set_selection(other_value);
}

CAN__frame__j1939mod_template::CAN__frame__j1939mod_template()
{
}

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

CAN__frame__j1939mod_template::CAN__frame__j1939mod_template(const CAN__frame__j1939mod& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__frame__j1939mod_template::match(const CAN__frame__j1939mod& 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.can__j1939().is_bound()) return FALSE;
if(!single_value->field_can__j1939.match(other_value.can__j1939(), legacy))return FALSE;
if(!other_value.can__pdu().is_bound()) return FALSE;
if(!single_value->field_can__pdu.match(other_value.can__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 @Isobus.CAN_frame_j1939mod.");
}
return FALSE;
}

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

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

boolean CAN__frame__j1939mod_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_can__j1939.is_value()
 &&single_value->field_can__pdu.is_value();
}

void CAN__frame__j1939mod_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;
}

CAN__frame__j1939mod CAN__frame__j1939mod_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 @Isobus.CAN_frame_j1939mod.");
CAN__frame__j1939mod ret_val;
if (single_value->field_can__j1939.is_bound()) {
ret_val.can__j1939() = single_value->field_can__j1939.valueof();
}
if (single_value->field_can__pdu.is_bound()) {
ret_val.can__pdu() = single_value->field_can__pdu.valueof();
}
return ret_val;
}

void CAN__frame__j1939mod_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 @Isobus.CAN_frame_j1939mod.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__frame__j1939mod_template[list_length];
}

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

J1939mod_template& CAN__frame__j1939mod_template::can__j1939()
{
set_specific();
return single_value->field_can__j1939;
}

const J1939mod_template& CAN__frame__j1939mod_template::can__j1939() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field can_j1939 of a non-specific template of type @Isobus.CAN_frame_j1939mod.");
return single_value->field_can__j1939;
}

AnyIsoBusPdu_template& CAN__frame__j1939mod_template::can__pdu()
{
set_specific();
return single_value->field_can__pdu;
}

const AnyIsoBusPdu_template& CAN__frame__j1939mod_template::can__pdu() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field can_pdu of a non-specific template of type @Isobus.CAN_frame_j1939mod.");
return single_value->field_can__pdu;
}

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

void CAN__frame__j1939mod_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ can_j1939 := ");
single_value->field_can__j1939.log();
TTCN_Logger::log_event_str(", can_pdu := ");
single_value->field_can__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 CAN__frame__j1939mod_template::log_match(const CAN__frame__j1939mod& 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_can__j1939.match(match_value.can__j1939(), legacy)){
TTCN_Logger::log_logmatch_info(".can_j1939");
single_value->field_can__j1939.log_match(match_value.can__j1939(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_can__pdu.match(match_value.can__pdu(), legacy)){
TTCN_Logger::log_logmatch_info(".can_pdu");
single_value->field_can__pdu.log_match(match_value.can__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("{ can_j1939 := ");
single_value->field_can__j1939.log_match(match_value.can__j1939(), legacy);
TTCN_Logger::log_event_str(", can_pdu := ");
single_value->field_can__pdu.log_match(match_value.can__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 CAN__frame__j1939mod_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_can__j1939.encode_text(text_buf);
single_value->field_can__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 @Isobus.CAN_frame_j1939mod.");
}
}

void CAN__frame__j1939mod_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_can__j1939.decode_text(text_buf);
single_value->field_can__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 CAN__frame__j1939mod_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 @Isobus.CAN_frame_j1939mod.");
}
}

void CAN__frame__j1939mod_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: {
    CAN__frame__j1939mod_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 @Isobus.CAN_frame_j1939mod 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) can__j1939().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) can__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(), "can_j1939")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__j1939().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "can_pdu")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__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 @Isobus.CAN_frame_j1939mod: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@Isobus.CAN_frame_j1939mod");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__frame__j1939mod_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_can__j1939.check_restriction(t_res, t_name ? t_name : "@Isobus.CAN_frame_j1939mod");
single_value->field_can__pdu.check_restriction(t_res, t_name ? t_name : "@Isobus.CAN_frame_j1939mod");
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 : "@Isobus.CAN_frame_j1939mod");
}

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

boolean CAN__frame__j1939mod_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 */

OCTETSTRING encode__CAN__frame__j1939mod(const CAN__frame__j1939mod& pdu)
{
if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {
TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
TTCN_Logger::log_event_str("encode_CAN_frame_j1939mod(): Encoding @Isobus.CAN_frame_j1939mod: ");
pdu.log();
TTCN_Logger::end_event();
}
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
TTCN_Buffer ttcn_buffer;
pdu.encode(CAN__frame__j1939mod_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW, 0);
OCTETSTRING ret_val;
ttcn_buffer.get_string(ret_val);
if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {
TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
TTCN_Logger::log_event_str("encode_CAN_frame_j1939mod(): Stream after encoding: ");
ret_val.log();
TTCN_Logger::end_event();
}
return ret_val;
}

CAN__frame__j1939mod decode__CAN__frame__j1939mod(const OCTETSTRING& data)
{
if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {
TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
TTCN_Logger::log_event_str("decode_CAN_frame_j1939mod(): Stream before decoding: ");
data.log();
TTCN_Logger::end_event();
}
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
TTCN_EncDec::clear_error();
TTCN_Buffer ttcn_buffer(data);
CAN__frame__j1939mod ret_val;
ret_val.decode(CAN__frame__j1939mod_descr_, ttcn_buffer, TTCN_EncDec::CT_RAW);
if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {
TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);
TTCN_Logger::log_event_str("decode_CAN_frame_j1939mod(): Decoded @Isobus.CAN_frame_j1939mod: ");
ret_val.log();
TTCN_Logger::end_event();
}
if (TTCN_EncDec::get_last_error_type() == TTCN_EncDec::ET_NONE) {
if (ttcn_buffer.get_pos() < ttcn_buffer.get_len()) {
ttcn_buffer.cut();
OCTETSTRING tmp_os;
ttcn_buffer.get_string(tmp_os);
TTCN_Logger::begin_event_log2str();
tmp_os.log();
CHARSTRING remaining_stream = TTCN_Logger::end_event_log2str();
TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_EXTRA_DATA, "decode_CAN_frame_j1939mod(): Data remained at the end of the stream after successful decoding: %s", (const char*) remaining_stream);
}
}
return ret_val;
}

Can::CAN__frame j1939frame2can(const CAN__frame__j1939& p__can__frame__j1939, const BITSTRING& p__priority, const OCTETSTRING& p__da, const OCTETSTRING& p__sa)
{
TTCN_Location current_location("Isobus.ttcn", 116, TTCN_Location::LOCATION_FUNCTION, "j1939frame2can");
current_location.update_lineno(117);
#line 117 "Isobus.ttcn"
Can::CAN__frame v__can__frame;
current_location.update_lineno(118);
#line 118 "Isobus.ttcn"
v__can__frame.can__id() = pdu1__j1939id2canid(const_cast< const CAN__frame__j1939&>(p__can__frame__j1939).can__j1939(), p__priority, p__da, p__sa);
current_location.update_lineno(120);
#line 120 "Isobus.ttcn"
v__can__frame.can__pdu() = substr(f__encode__CAN__frame__j1939(p__can__frame__j1939), 0, 3);
current_location.update_lineno(121);
#line 121 "Isobus.ttcn"
return v__can__frame;
}

OCTETSTRING pdu1__j1939id2canid(const J1939& p__j1939, const BITSTRING& p__priority, const OCTETSTRING& p__da, const OCTETSTRING& p__sa)
{
TTCN_Location current_location("Isobus.ttcn", 124, TTCN_Location::LOCATION_FUNCTION, "pdu1_j1939id2canid");
current_location.update_lineno(125);
#line 125 "Isobus.ttcn"
OCTETSTRING v__can__id;
current_location.update_lineno(126);
#line 126 "Isobus.ttcn"
v__can__id = bit2oct((((((oct2bit(p__sa) | (oct2bit(p__da) << 8)) | (oct2bit(const_cast< const J1939&>(p__j1939).pf()) << 16)) | (const_cast< const J1939&>(p__j1939).dp() << 24)) | (const_cast< const J1939&>(p__j1939).res() << 25)) | (int2bit(bit2int(p__priority), 32) << 26)));
current_location.update_lineno(128);
#line 128 "Isobus.ttcn"
return v__can__id;
}

OCTETSTRING j1939id2canid(const J1939& p__j1939)
{
TTCN_Location current_location("Isobus.ttcn", 140, TTCN_Location::LOCATION_FUNCTION, "j1939id2canid");
current_location.update_lineno(141);
#line 141 "Isobus.ttcn"
OCTETSTRING v__can__id;
current_location.update_lineno(142);
#line 142 "Isobus.ttcn"
v__can__id = int2oct((((((oct2int(const_cast< const J1939&>(p__j1939).sa()) + (oct2int(const_cast< const J1939&>(p__j1939).ps()) * 256)) + ((oct2int(const_cast< const J1939&>(p__j1939).pf()) * 256) * 256)) + (((bit2int(const_cast< const J1939&>(p__j1939).dp()) * 256) * 256) * 256)) + ((((bit2int(const_cast< const J1939&>(p__j1939).res()) * 256) * 256) * 256) * 2)) + (((((bit2int(const_cast< const J1939&>(p__j1939).prio()) * 256) * 256) * 256) * 2) * 2)), 4);
current_location.update_lineno(147);
#line 147 "Isobus.ttcn"
return v__can__id;
}

CAN__frame__j1939 can2j1939frame(const Can::CAN__frame& p__can__frame)
{
TTCN_Location current_location("Isobus.ttcn", 151, TTCN_Location::LOCATION_FUNCTION, "can2j1939frame");
current_location.update_lineno(153);
#line 153 "Isobus.ttcn"
CAN__frame__j1939 v__can__frame__j1939;
current_location.update_lineno(158);
#line 158 "Isobus.ttcn"
v__can__frame__j1939 = f__decode__CAN__frame__j1939((const_cast< const Can::CAN__frame&>(p__can__frame).can__id() + const_cast< const Can::CAN__frame&>(p__can__frame).can__pdu()));
current_location.update_lineno(161);
#line 161 "Isobus.ttcn"
return v__can__frame__j1939;
}

J1939 canid2j1939(const OCTETSTRING& p__can__id)
{
TTCN_Location current_location("Isobus.ttcn", 164, TTCN_Location::LOCATION_FUNCTION, "canid2j1939");
current_location.update_lineno(167);
#line 167 "Isobus.ttcn"
BITSTRING v__can__id__bitstring(oct2bit(p__can__id));
current_location.update_lineno(168);
#line 168 "Isobus.ttcn"
J1939 v__j1939;
current_location.update_lineno(170);
#line 170 "Isobus.ttcn"
v__j1939.prio() = substr(v__can__id__bitstring, 0, 6);
current_location.update_lineno(171);
#line 171 "Isobus.ttcn"
v__j1939.res() = const_cast< const BITSTRING&>(v__can__id__bitstring)[6];
current_location.update_lineno(172);
#line 172 "Isobus.ttcn"
v__j1939.dp() = const_cast< const BITSTRING&>(v__can__id__bitstring)[7];
current_location.update_lineno(173);
#line 173 "Isobus.ttcn"
v__j1939.pf() = const_cast< const OCTETSTRING&>(p__can__id)[1];
current_location.update_lineno(174);
#line 174 "Isobus.ttcn"
v__j1939.ps() = const_cast< const OCTETSTRING&>(p__can__id)[2];
current_location.update_lineno(175);
#line 175 "Isobus.ttcn"
v__j1939.sa() = const_cast< const OCTETSTRING&>(p__can__id)[3];
current_location.update_lineno(177);
#line 177 "Isobus.ttcn"
return v__j1939;
}

OCTETSTRING f__insert__aux__hdr(const OCTETSTRING& p__os)
{
TTCN_Location current_location("Isobus.ttcn", 185, TTCN_Location::LOCATION_FUNCTION, "f_insert_aux_hdr");
current_location.update_lineno(188);
#line 188 "Isobus.ttcn"
OCTETSTRING v__os;
current_location.update_lineno(191);
#line 191 "Isobus.ttcn"
v__os[0] = const_cast< const OCTETSTRING&>(p__os)[1];
current_location.update_lineno(192);
#line 192 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os)[1] == os_17)) {
current_location.update_lineno(194);
#line 194 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os)[2] == os_18)) {
current_location.update_lineno(194);
#line 194 "Isobus.ttcn"
v__os[1] = os_18;
current_location.update_lineno(194);
#line 194 "Isobus.ttcn"
v__os[2] = os_19;
}
}
else {
current_location.update_lineno(197);
#line 197 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os)[1] == os_20)) {
current_location.update_lineno(199);
#line 199 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os)[2] == os_21)) {
current_location.update_lineno(200);
#line 200 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os)[3] == os_17)) {
current_location.update_lineno(200);
#line 200 "Isobus.ttcn"
v__os[1] = os_21;
current_location.update_lineno(200);
#line 200 "Isobus.ttcn"
v__os[2] = os_17;
}
else {
current_location.update_lineno(201);
#line 201 "Isobus.ttcn"
v__os[1] = os_21;
current_location.update_lineno(201);
#line 201 "Isobus.ttcn"
v__os[2] = os_19;
}
}
}
else {
current_location.update_lineno(207);
#line 207 "Isobus.ttcn"
v__os[1] = os_19;
current_location.update_lineno(207);
#line 207 "Isobus.ttcn"
v__os[2] = os_19;
}
}
current_location.update_lineno(212);
#line 212 "Isobus.ttcn"
return replace(p__os, 4, 0, v__os);
}

OCTETSTRING f__remove__aux__hdr(const OCTETSTRING& p__os)
{
TTCN_Location current_location("Isobus.ttcn", 216, TTCN_Location::LOCATION_FUNCTION, "f_remove_aux_hdr");
OCTETSTRING p__os_shadow(p__os);
current_location.update_lineno(222);
#line 222 "Isobus.ttcn"
{
OCTETSTRING tmp_20;
tmp_20 = const_cast< const OCTETSTRING&>(p__os_shadow)[4];
p__os_shadow[1] = tmp_20;
}
current_location.update_lineno(223);
#line 223 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os_shadow)[4] == os_20)) {
current_location.update_lineno(225);
#line 225 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os_shadow)[6] == os_17)) {
current_location.update_lineno(226);
#line 226 "Isobus.ttcn"
{
OCTETSTRING tmp_21;
tmp_21 = const_cast< const OCTETSTRING&>(p__os_shadow)[5];
p__os_shadow[2] = tmp_21;
}
current_location.update_lineno(227);
#line 227 "Isobus.ttcn"
{
OCTETSTRING tmp_22;
tmp_22 = const_cast< const OCTETSTRING&>(p__os_shadow)[6];
p__os_shadow[3] = tmp_22;
}
}
else {
current_location.update_lineno(230);
#line 230 "Isobus.ttcn"
{
OCTETSTRING tmp_23;
tmp_23 = const_cast< const OCTETSTRING&>(p__os_shadow)[5];
p__os_shadow[2] = tmp_23;
}
}
}
else {
current_location.update_lineno(233);
#line 233 "Isobus.ttcn"
if ((const_cast< const OCTETSTRING&>(p__os_shadow)[4] == os_17)) {
current_location.update_lineno(235);
#line 235 "Isobus.ttcn"
{
OCTETSTRING tmp_24;
tmp_24 = const_cast< const OCTETSTRING&>(p__os_shadow)[5];
p__os_shadow[2] = tmp_24;
}
}
}
current_location.update_lineno(242);
#line 242 "Isobus.ttcn"
return replace(p__os_shadow, 4, 3, os_22);
}

CAN__frame__j1939 f__map__mod2frame(const CAN__frame__j1939mod& p__frame)
{
TTCN_Location current_location("Isobus.ttcn", 246, TTCN_Location::LOCATION_FUNCTION, "f_map_mod2frame");
current_location.update_lineno(249);
#line 249 "Isobus.ttcn"
CAN__frame__j1939 v__CAN__frame__j1939;
current_location.update_lineno(251);
#line 251 "Isobus.ttcn"
v__CAN__frame__j1939.can__pdu() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__pdu();
current_location.update_lineno(252);
#line 252 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().prio() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().prio();
current_location.update_lineno(253);
#line 253 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().res() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().res();
current_location.update_lineno(254);
#line 254 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().dp() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().dp();
current_location.update_lineno(255);
#line 255 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().pf() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().pf();
current_location.update_lineno(256);
#line 256 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().ps() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().ps();
current_location.update_lineno(257);
#line 257 "Isobus.ttcn"
v__CAN__frame__j1939.can__j1939().sa() = const_cast< const CAN__frame__j1939mod&>(p__frame).can__j1939().sa();
current_location.update_lineno(261);
#line 261 "Isobus.ttcn"
return v__CAN__frame__j1939;
}

CAN__frame__j1939mod f__map__frame2mod(const CAN__frame__j1939& p__frame)
{
TTCN_Location current_location("Isobus.ttcn", 267, TTCN_Location::LOCATION_FUNCTION, "f_map_frame2mod");
current_location.update_lineno(270);
#line 270 "Isobus.ttcn"
CAN__frame__j1939mod v__CAN__frame__j1939mod;
current_location.update_lineno(273);
#line 273 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__pdu() = const_cast< const CAN__frame__j1939&>(p__frame).can__pdu();
current_location.update_lineno(274);
#line 274 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().prio() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().prio();
current_location.update_lineno(275);
#line 275 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().res() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().res();
current_location.update_lineno(276);
#line 276 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().dp() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().dp();
current_location.update_lineno(277);
#line 277 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().pf() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf();
current_location.update_lineno(278);
#line 278 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().ps() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().ps();
current_location.update_lineno(279);
#line 279 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().sa() = const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().sa();
current_location.update_lineno(280);
#line 280 "Isobus.ttcn"
if ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() == os_20)) {
current_location.update_lineno(282);
#line 282 "Isobus.ttcn"
if ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().ps() == os_18)) {
current_location.update_lineno(283);
#line 283 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().comp() = ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() + const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().ps()) + os_19);
}
else {
current_location.update_lineno(284);
#line 284 "Isobus.ttcn"
if ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().ps() == os_21)) {
current_location.update_lineno(285);
#line 285 "Isobus.ttcn"
if ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().sa() == os_17)) {
current_location.update_lineno(286);
#line 286 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().comp() = ((const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() + const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().ps()) + const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().sa());
}
else {
current_location.update_lineno(288);
#line 288 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().comp() = (const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() + os_23);
}
}
else {
current_location.update_lineno(291);
#line 291 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().comp() = (const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() + os_23);
}
}
}
else {
current_location.update_lineno(294);
#line 294 "Isobus.ttcn"
v__CAN__frame__j1939mod.can__j1939().comp() = (const_cast< const CAN__frame__j1939&>(p__frame).can__j1939().pf() + os_23);
}
current_location.update_lineno(297);
#line 297 "Isobus.ttcn"
return v__CAN__frame__j1939mod;
}

OCTETSTRING f__encode__CAN__frame__j1939(const CAN__frame__j1939& pdu)
{
TTCN_Location current_location("Isobus.ttcn", 303, TTCN_Location::LOCATION_FUNCTION, "f_encode_CAN_frame_j1939");
current_location.update_lineno(307);
#line 307 "Isobus.ttcn"
return f__remove__aux__hdr(encode__CAN__frame__j1939mod(f__map__frame2mod(pdu)));
}

CAN__frame__j1939 f__decode__CAN__frame__j1939(const OCTETSTRING& data)
{
TTCN_Location current_location("Isobus.ttcn", 312, TTCN_Location::LOCATION_FUNCTION, "f_decode_CAN_frame_j1939");
current_location.update_lineno(315);
#line 315 "Isobus.ttcn"
try {
TTCN_Logger::begin_event(TTCN_USER);
TTCN_Logger::log_event_str("f_insert_aux_hdr(data)");
f__insert__aux__hdr(data).log();
TTCN_Logger::end_event();
} catch (...) {
TTCN_Logger::finish_event();
throw;
}
current_location.update_lineno(316);
#line 316 "Isobus.ttcn"
return f__map__mod2frame(decode__CAN__frame__j1939mod(f__insert__aux__hdr(data)));
}


/* Bodies of static functions */

static void pre_init_module()
{
TTCN_Location current_location("Isobus.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "Isobus");
Can::module_object.pre_init_module();
IsobusCMMessageTypes::module_object.pre_init_module();
IsobusNMMessageTypes::module_object.pre_init_module();
IsobusVTMessageTypes::module_object.pre_init_module();
module_object.add_function("encode_CAN_frame_j1939mod", (genericfunc_t)&encode__CAN__frame__j1939mod, NULL);
module_object.add_function("decode_CAN_frame_j1939mod", (genericfunc_t)&decode__CAN__frame__j1939mod, NULL);
current_location.update_lineno(33);
#line 33 "Isobus.ttcn"
const_ISOBUS__PRIORITY__MASK = os_11;
current_location.update_lineno(34);
#line 34 "Isobus.ttcn"
const_ISOBUS__RESERVED__MASK = os_12;
current_location.update_lineno(35);
#line 35 "Isobus.ttcn"
const_ISOBUS__DATAPAGE__MASK = os_13;
current_location.update_lineno(36);
#line 36 "Isobus.ttcn"
const_ISOBUS__PDUFORMAT__MASK = os_14;
current_location.update_lineno(37);
#line 37 "Isobus.ttcn"
const_ISOBUS__PDUSPECIFIC__MASK = os_15;
current_location.update_lineno(38);
#line 38 "Isobus.ttcn"
const_ISOBUS__SOURCEADDRESS__MASK = os_16;
module_object.add_function("j1939frame2can", (genericfunc_t)&j1939frame2can, NULL);
module_object.add_function("pdu1_j1939id2canid", (genericfunc_t)&pdu1__j1939id2canid, NULL);
module_object.add_function("j1939id2canid", (genericfunc_t)&j1939id2canid, NULL);
module_object.add_function("can2j1939frame", (genericfunc_t)&can2j1939frame, NULL);
module_object.add_function("canid2j1939", (genericfunc_t)&canid2j1939, NULL);
module_object.add_function("f_insert_aux_hdr", (genericfunc_t)&f__insert__aux__hdr, NULL);
module_object.add_function("f_remove_aux_hdr", (genericfunc_t)&f__remove__aux__hdr, NULL);
module_object.add_function("f_map_mod2frame", (genericfunc_t)&f__map__mod2frame, NULL);
module_object.add_function("f_map_frame2mod", (genericfunc_t)&f__map__frame2mod, NULL);
module_object.add_function("f_encode_CAN_frame_j1939", (genericfunc_t)&f__encode__CAN__frame__j1939, NULL);
module_object.add_function("f_decode_CAN_frame_j1939", (genericfunc_t)&f__decode__CAN__frame__j1939, NULL);
}

static void post_init_module()
{
TTCN_Location current_location("Isobus.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "Isobus");
Can::module_object.post_init_module();
IsobusCMMessageTypes::module_object.post_init_module();
IsobusNMMessageTypes::module_object.post_init_module();
IsobusVTMessageTypes::module_object.post_init_module();
}


} /* end of namespace */
