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

namespace CAN__matrix__messages {

/* Prototypes of static functions */

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

/* Literal string constants */

static const unsigned char os_0_octets[] = { 0, 0, 1, 34 },
os_1_octets[] = { 0, 0, 1, 35 },
os_2_octets[] = { 0, 0, 1, 36 },
os_3_octets[] = { 0, 0, 1, 37 },
os_4_octets[] = { 0, 0, 1, 38 },
os_5_octets[] = { 0, 0, 1, 39 },
os_6_octets[] = { 128, 0, 0, 1 };
static const OCTETSTRING os_0(4, os_0_octets),
os_1(4, os_1_octets),
os_2(4, os_2_octets),
os_3(4, os_3_octets),
os_4(4, os_4_octets),
os_5(4, os_5_octets),
os_6(4, os_6_octets);
static const unsigned char module_checksum[] = { 0x8d, 0x75, 0x4a, 0x7d, 0x73, 0xfb, 0x93, 0xd7, 0x5b, 0xbe, 0x7e, 0xb1, 0x6e, 0xe5, 0xfa, 0x1a };

/* Global variable definitions */

const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_raw_ = {11,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,11,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_xer_ = { {"test_sig_11_bit_bitstring_little_endian_coded>\n", "test_sig_11_bit_bitstring_little_endian_coded>\n"}, {47, 47}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.test_sig_11_bit_bitstring_little_endian_coded", &BITSTRING_ber_, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_raw_, NULL, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_xer_, &BITSTRING_json_, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_raw_ = {5,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,5,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_xer_ = { {"test_sig_5_bit_bitstring_little_endian_coded>\n", "test_sig_5_bit_bitstring_little_endian_coded>\n"}, {46, 46}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.test_sig_5_bit_bitstring_little_endian_coded", &BITSTRING_ber_, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_raw_, NULL, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_xer_, &BITSTRING_json_, &CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_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 CAN__MESSAGE__TESTFRAME0__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME0__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type", NULL, &CAN__MESSAGE__TESTFRAME0__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_raw_ = {11,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,11,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_xer_ = { {"test_sig_11_bit_bitstring_big_endian_coded>\n", "test_sig_11_bit_bitstring_big_endian_coded>\n"}, {44, 44}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.test_sig_11_bit_bitstring_big_endian_coded", &BITSTRING_ber_, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_raw_, NULL, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_xer_, &BITSTRING_json_, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_raw_ = {5,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,5,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_xer_ = { {"test_sig_5_bit_bitstring_big_endian_coded>\n", "test_sig_5_bit_bitstring_big_endian_coded>\n"}, {43, 43}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.test_sig_5_bit_bitstring_big_endian_coded", &BITSTRING_ber_, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_raw_, NULL, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_xer_, &BITSTRING_json_, &CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_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 CAN__MESSAGE__TESTFRAME1__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME1__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type", NULL, &CAN__MESSAGE__TESTFRAME1__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_raw_ = {11,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_xer_ = { {"test_sig_11_bit_integer_big_endian_coded>\n", "test_sig_11_bit_integer_big_endian_coded>\n"}, {42, 42}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.test_sig_11_bit_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_ = {5,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_ = { {"test_sig_5_bit_integer_big_endian_coded>\n", "test_sig_5_bit_integer_big_endian_coded>\n"}, {41, 41}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.test_sig_5_bit_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_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 CAN__MESSAGE__TESTFRAME2__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME2__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type", NULL, &CAN__MESSAGE__TESTFRAME2__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_xer_ = { {"test_sig_1_byte_octetstring_big_endian_coded>\n", "test_sig_1_byte_octetstring_big_endian_coded>\n"}, {46, 46}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_ext_arr_[0] = {};
const int CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_p_[0] = {};
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_ = { -1, TRUE, 1, FALSE, 0, 0, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_ext_arr_, 0, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_p_};
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.test_sig_1_byte_octetstring_big_endian_coded", &OCTETSTRING_ber_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_raw_, &OCTETSTRING_text_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_xer_, &OCTETSTRING_json_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_raw_ = {16,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,2,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_xer_ = { {"test_sig_2_byte_octetstring_big_endian_coded>\n", "test_sig_2_byte_octetstring_big_endian_coded>\n"}, {46, 46}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_ext_arr_[0] = {};
const int CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_p_[0] = {};
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_ = { -1, TRUE, 2, FALSE, 0, 0, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_ext_arr_, 0, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_p_};
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.test_sig_2_byte_octetstring_big_endian_coded", &OCTETSTRING_ber_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_raw_, &OCTETSTRING_text_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_xer_, &OCTETSTRING_json_, &CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_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 CAN__MESSAGE__TESTFRAME3__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME3__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type", NULL, &CAN__MESSAGE__TESTFRAME3__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_raw_ = {11,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_xer_ = { {"test_unsig_9_bit_2_padded_integer_big_endian_coded>\n", "test_unsig_9_bit_2_padded_integer_big_endian_coded>\n"}, {52, 52}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.test_unsig_9_bit_2_padded_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_ = {5,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_MSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_ = { {"test_sig_5_bit_integer_big_endian_coded>\n", "test_sig_5_bit_integer_big_endian_coded>\n"}, {41, 41}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.test_sig_5_bit_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_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 CAN__MESSAGE__TESTFRAME4__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME4__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type", NULL, &CAN__MESSAGE__TESTFRAME4__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_raw_ = {11,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_xer_ = { {"test_unsig_9_bit_2_padded_integer_big_endian_coded>\n", "test_unsig_9_bit_2_padded_integer_big_endian_coded>\n"}, {52, 52}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.test_unsig_9_bit_2_padded_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_ = {5,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_ = { {"test_sig_5_bit_integer_big_endian_coded>\n", "test_sig_5_bit_integer_big_endian_coded>\n"}, {41, 41}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.test_sig_5_bit_integer_big_endian_coded", &INTEGER_ber_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_raw_, &INTEGER_text_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_xer_, &INTEGER_json_, &CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_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 CAN__MESSAGE__TESTFRAME5__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__TESTFRAME5__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type", NULL, &CAN__MESSAGE__TESTFRAME5__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_raw_ = {16,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_MSB,EXT_BIT_NO,ORDER_LSB,ORDER_MSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,2,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_xer_ = { {"test_sig_2_byte_octetstring_msb_coded>\n", "test_sig_2_byte_octetstring_msb_coded>\n"}, {39, 39}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_ext_arr_[0] = {};
const int CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_p_[0] = {};
const TTCN_OERdescriptor_t CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_ = { -1, TRUE, 2, FALSE, 0, 0, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_ext_arr_, 0, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_p_};
const TTCN_Typedescriptor_t CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.test_sig_2_byte_octetstring_msb_coded", &OCTETSTRING_ber_, &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_raw_, &OCTETSTRING_text_, &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_xer_, &OCTETSTRING_json_, &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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 CAN__MESSAGE__EXTENDEDFRAME1__msg__type
const TTCN_Typedescriptor_t CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_ = { "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type", NULL, &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MatrixPayloadUnion_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__MatrixPayloadUnion
const TTCN_Typedescriptor_t CAN__MatrixPayloadUnion_descr_ = { "@CAN_matrix_messages.CAN_MatrixPayloadUnion", NULL, &CAN__MatrixPayloadUnion_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       CAN__MatrixUnion_can__id_xer_ = { {"can_id>\n", "can_id>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int CAN__MatrixUnion_can__id_oer_ext_arr_[0] = {};
const int CAN__MatrixUnion_can__id_oer_p_[0] = {};
const TTCN_OERdescriptor_t CAN__MatrixUnion_can__id_oer_ = { -1, TRUE, 4, FALSE, 0, 0, CAN__MatrixUnion_can__id_oer_ext_arr_, 0, CAN__MatrixUnion_can__id_oer_p_};
const TTCN_Typedescriptor_t CAN__MatrixUnion_can__id_descr_ = { "@CAN_matrix_messages.CAN_MatrixUnion.can_id", &OCTETSTRING_ber_, &Can::CAN__id_raw_, &OCTETSTRING_text_, &CAN__MatrixUnion_can__id_xer_, &OCTETSTRING_json_, &CAN__MatrixUnion_can__id_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MatrixUnion_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__MatrixUnion_can__pdu
const TTCN_Typedescriptor_t CAN__MatrixUnion_can__pdu_descr_ = { "@CAN_matrix_messages.CAN_MatrixUnion.can_pdu", NULL, &CAN__MatrixUnion_can__pdu_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t CAN__MatrixUnion_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__MatrixUnion
const TTCN_Typedescriptor_t CAN__MatrixUnion_descr_ = { "@CAN_matrix_messages.CAN_MatrixUnion", NULL, &CAN__MatrixUnion_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
TTCN_Module module_object("CAN_matrix_messages", __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 */

CAN__MESSAGE__TESTFRAME0__msg__type::CAN__MESSAGE__TESTFRAME0__msg__type()
{
}

CAN__MESSAGE__TESTFRAME0__msg__type::CAN__MESSAGE__TESTFRAME0__msg__type(const BITSTRING& par_test__sig__11__bit__bitstring__little__endian__coded,
    const BITSTRING& par_test__sig__5__bit__bitstring__little__endian__coded)
  :   field_test__sig__11__bit__bitstring__little__endian__coded(par_test__sig__11__bit__bitstring__little__endian__coded),
  field_test__sig__5__bit__bitstring__little__endian__coded(par_test__sig__5__bit__bitstring__little__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME0__msg__type::CAN__MESSAGE__TESTFRAME0__msg__type(const CAN__MESSAGE__TESTFRAME0__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
if (other_value.test__sig__11__bit__bitstring__little__endian__coded().is_bound()) field_test__sig__11__bit__bitstring__little__endian__coded = other_value.test__sig__11__bit__bitstring__little__endian__coded();
else field_test__sig__11__bit__bitstring__little__endian__coded.clean_up();
if (other_value.test__sig__5__bit__bitstring__little__endian__coded().is_bound()) field_test__sig__5__bit__bitstring__little__endian__coded = other_value.test__sig__5__bit__bitstring__little__endian__coded();
else field_test__sig__5__bit__bitstring__little__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME0__msg__type::clean_up()
{
field_test__sig__11__bit__bitstring__little__endian__coded.clean_up();
field_test__sig__5__bit__bitstring__little__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME0__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME0__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME0__msg__type& CAN__MESSAGE__TESTFRAME0__msg__type::operator=(const CAN__MESSAGE__TESTFRAME0__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
  if (other_value.test__sig__11__bit__bitstring__little__endian__coded().is_bound()) field_test__sig__11__bit__bitstring__little__endian__coded = other_value.test__sig__11__bit__bitstring__little__endian__coded();
  else field_test__sig__11__bit__bitstring__little__endian__coded.clean_up();
  if (other_value.test__sig__5__bit__bitstring__little__endian__coded().is_bound()) field_test__sig__5__bit__bitstring__little__endian__coded = other_value.test__sig__5__bit__bitstring__little__endian__coded();
  else field_test__sig__5__bit__bitstring__little__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME0__msg__type::operator==(const CAN__MESSAGE__TESTFRAME0__msg__type& other_value) const
{
return field_test__sig__11__bit__bitstring__little__endian__coded==other_value.field_test__sig__11__bit__bitstring__little__endian__coded
  && field_test__sig__5__bit__bitstring__little__endian__coded==other_value.field_test__sig__5__bit__bitstring__little__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME0__msg__type::is_bound() const
{
return (field_test__sig__11__bit__bitstring__little__endian__coded.is_bound())
  || (field_test__sig__5__bit__bitstring__little__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME0__msg__type::is_value() const
{
return field_test__sig__11__bit__bitstring__little__endian__coded.is_value()
  && field_test__sig__5__bit__bitstring__little__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME0__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_sig_11_bit_bitstring_little_endian_coded := ");
field_test__sig__11__bit__bitstring__little__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_little_endian_coded := ");
field_test__sig__5__bit__bitstring__little__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME0__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type 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) test__sig__11__bit__bitstring__little__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__bitstring__little__endian__coded().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(), "test_sig_11_bit_bitstring_little_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__bitstring__little__endian__coded().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(), "test_sig_5_bit_bitstring_little_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__bitstring__little__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME0__msg__type::set_implicit_omit()
{
if (test__sig__11__bit__bitstring__little__endian__coded().is_bound()) test__sig__11__bit__bitstring__little__endian__coded().set_implicit_omit();
if (test__sig__5__bit__bitstring__little__endian__coded().is_bound()) test__sig__5__bit__bitstring__little__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME0__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__sig__11__bit__bitstring__little__endian__coded.encode_text(text_buf);
field_test__sig__5__bit__bitstring__little__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME0__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__sig__11__bit__bitstring__little__endian__coded.decode_text(text_buf);
field_test__sig__5__bit__bitstring__little__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME0__msg__type::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__MESSAGE__TESTFRAME0__msg__type::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__MESSAGE__TESTFRAME0__msg__type::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, CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__11__bit__bitstring__little__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_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, CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__5__bit__bitstring__little__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_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__MESSAGE__TESTFRAME0__msg__type::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, CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_descr_.raw);
  encoded_length += field_test__sig__11__bit__bitstring__little__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__11__bit__bitstring__little__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__5__bit__bitstring__little__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME0__msg__type_test__sig__5__bit__bitstring__little__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME0__msg__type_template::single_value_struct {
BITSTRING_template field_test__sig__11__bit__bitstring__little__endian__coded;
BITSTRING_template field_test__sig__5__bit__bitstring__little__endian__coded;
};

void CAN__MESSAGE__TESTFRAME0__msg__type_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_test__sig__11__bit__bitstring__little__endian__coded = ANY_VALUE;
single_value->field_test__sig__5__bit__bitstring__little__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME0__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME0__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__sig__11__bit__bitstring__little__endian__coded().is_bound()) {
  single_value->field_test__sig__11__bit__bitstring__little__endian__coded = other_value.test__sig__11__bit__bitstring__little__endian__coded();
} else {
  single_value->field_test__sig__11__bit__bitstring__little__endian__coded.clean_up();
}
if (other_value.test__sig__5__bit__bitstring__little__endian__coded().is_bound()) {
  single_value->field_test__sig__5__bit__bitstring__little__endian__coded = other_value.test__sig__5__bit__bitstring__little__endian__coded();
} else {
  single_value->field_test__sig__5__bit__bitstring__little__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME0__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME0__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__11__bit__bitstring__little__endian__coded().get_selection()) {
single_value->field_test__sig__11__bit__bitstring__little__endian__coded = other_value.test__sig__11__bit__bitstring__little__endian__coded();
} else {
single_value->field_test__sig__11__bit__bitstring__little__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__5__bit__bitstring__little__endian__coded().get_selection()) {
single_value->field_test__sig__5__bit__bitstring__little__endian__coded = other_value.test__sig__5__bit__bitstring__little__endian__coded();
} else {
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.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__MESSAGE__TESTFRAME0__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME0__msg__type_template::CAN__MESSAGE__TESTFRAME0__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME0__msg__type_template::CAN__MESSAGE__TESTFRAME0__msg__type_template(const CAN__MESSAGE__TESTFRAME0__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME0__msg__type_template::match(const CAN__MESSAGE__TESTFRAME0__msg__type& 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.test__sig__11__bit__bitstring__little__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__11__bit__bitstring__little__endian__coded.match(other_value.test__sig__11__bit__bitstring__little__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__5__bit__bitstring__little__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__5__bit__bitstring__little__endian__coded.match(other_value.test__sig__5__bit__bitstring__little__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME0__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__sig__11__bit__bitstring__little__endian__coded.is_value()
 &&single_value->field_test__sig__5__bit__bitstring__little__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME0__msg__type_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__MESSAGE__TESTFRAME0__msg__type CAN__MESSAGE__TESTFRAME0__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
CAN__MESSAGE__TESTFRAME0__msg__type ret_val;
if (single_value->field_test__sig__11__bit__bitstring__little__endian__coded.is_bound()) {
ret_val.test__sig__11__bit__bitstring__little__endian__coded() = single_value->field_test__sig__11__bit__bitstring__little__endian__coded.valueof();
}
if (single_value->field_test__sig__5__bit__bitstring__little__endian__coded.is_bound()) {
ret_val.test__sig__5__bit__bitstring__little__endian__coded() = single_value->field_test__sig__5__bit__bitstring__little__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME0__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME0__msg__type_template[list_length];
}

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

BITSTRING_template& CAN__MESSAGE__TESTFRAME0__msg__type_template::test__sig__11__bit__bitstring__little__endian__coded()
{
set_specific();
return single_value->field_test__sig__11__bit__bitstring__little__endian__coded;
}

const BITSTRING_template& CAN__MESSAGE__TESTFRAME0__msg__type_template::test__sig__11__bit__bitstring__little__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_11_bit_bitstring_little_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
return single_value->field_test__sig__11__bit__bitstring__little__endian__coded;
}

BITSTRING_template& CAN__MESSAGE__TESTFRAME0__msg__type_template::test__sig__5__bit__bitstring__little__endian__coded()
{
set_specific();
return single_value->field_test__sig__5__bit__bitstring__little__endian__coded;
}

const BITSTRING_template& CAN__MESSAGE__TESTFRAME0__msg__type_template::test__sig__5__bit__bitstring__little__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_5_bit_bitstring_little_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
return single_value->field_test__sig__5__bit__bitstring__little__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME0__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_sig_11_bit_bitstring_little_endian_coded := ");
single_value->field_test__sig__11__bit__bitstring__little__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_little_endian_coded := ");
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.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__MESSAGE__TESTFRAME0__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME0__msg__type& 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_test__sig__11__bit__bitstring__little__endian__coded.match(match_value.test__sig__11__bit__bitstring__little__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_11_bit_bitstring_little_endian_coded");
single_value->field_test__sig__11__bit__bitstring__little__endian__coded.log_match(match_value.test__sig__11__bit__bitstring__little__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__5__bit__bitstring__little__endian__coded.match(match_value.test__sig__5__bit__bitstring__little__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_5_bit_bitstring_little_endian_coded");
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.log_match(match_value.test__sig__5__bit__bitstring__little__endian__coded(), 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("{ test_sig_11_bit_bitstring_little_endian_coded := ");
single_value->field_test__sig__11__bit__bitstring__little__endian__coded.log_match(match_value.test__sig__11__bit__bitstring__little__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_little_endian_coded := ");
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.log_match(match_value.test__sig__5__bit__bitstring__little__endian__coded(), 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__MESSAGE__TESTFRAME0__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__sig__11__bit__bitstring__little__endian__coded.encode_text(text_buf);
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME0__msg__type_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_test__sig__11__bit__bitstring__little__endian__coded.decode_text(text_buf);
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.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__MESSAGE__TESTFRAME0__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME0__msg__type_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__MESSAGE__TESTFRAME0__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type 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) test__sig__11__bit__bitstring__little__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__bitstring__little__endian__coded().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(), "test_sig_11_bit_bitstring_little_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__bitstring__little__endian__coded().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(), "test_sig_5_bit_bitstring_little_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__bitstring__little__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME0__msg__type_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_test__sig__11__bit__bitstring__little__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type");
single_value->field_test__sig__5__bit__bitstring__little__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME0_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME0__msg__type_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__MESSAGE__TESTFRAME1__msg__type::CAN__MESSAGE__TESTFRAME1__msg__type()
{
}

CAN__MESSAGE__TESTFRAME1__msg__type::CAN__MESSAGE__TESTFRAME1__msg__type(const BITSTRING& par_test__sig__11__bit__bitstring__big__endian__coded,
    const BITSTRING& par_test__sig__5__bit__bitstring__big__endian__coded)
  :   field_test__sig__11__bit__bitstring__big__endian__coded(par_test__sig__11__bit__bitstring__big__endian__coded),
  field_test__sig__5__bit__bitstring__big__endian__coded(par_test__sig__5__bit__bitstring__big__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME1__msg__type::CAN__MESSAGE__TESTFRAME1__msg__type(const CAN__MESSAGE__TESTFRAME1__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
if (other_value.test__sig__11__bit__bitstring__big__endian__coded().is_bound()) field_test__sig__11__bit__bitstring__big__endian__coded = other_value.test__sig__11__bit__bitstring__big__endian__coded();
else field_test__sig__11__bit__bitstring__big__endian__coded.clean_up();
if (other_value.test__sig__5__bit__bitstring__big__endian__coded().is_bound()) field_test__sig__5__bit__bitstring__big__endian__coded = other_value.test__sig__5__bit__bitstring__big__endian__coded();
else field_test__sig__5__bit__bitstring__big__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME1__msg__type::clean_up()
{
field_test__sig__11__bit__bitstring__big__endian__coded.clean_up();
field_test__sig__5__bit__bitstring__big__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME1__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME1__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME1__msg__type& CAN__MESSAGE__TESTFRAME1__msg__type::operator=(const CAN__MESSAGE__TESTFRAME1__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
  if (other_value.test__sig__11__bit__bitstring__big__endian__coded().is_bound()) field_test__sig__11__bit__bitstring__big__endian__coded = other_value.test__sig__11__bit__bitstring__big__endian__coded();
  else field_test__sig__11__bit__bitstring__big__endian__coded.clean_up();
  if (other_value.test__sig__5__bit__bitstring__big__endian__coded().is_bound()) field_test__sig__5__bit__bitstring__big__endian__coded = other_value.test__sig__5__bit__bitstring__big__endian__coded();
  else field_test__sig__5__bit__bitstring__big__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME1__msg__type::operator==(const CAN__MESSAGE__TESTFRAME1__msg__type& other_value) const
{
return field_test__sig__11__bit__bitstring__big__endian__coded==other_value.field_test__sig__11__bit__bitstring__big__endian__coded
  && field_test__sig__5__bit__bitstring__big__endian__coded==other_value.field_test__sig__5__bit__bitstring__big__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME1__msg__type::is_bound() const
{
return (field_test__sig__11__bit__bitstring__big__endian__coded.is_bound())
  || (field_test__sig__5__bit__bitstring__big__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME1__msg__type::is_value() const
{
return field_test__sig__11__bit__bitstring__big__endian__coded.is_value()
  && field_test__sig__5__bit__bitstring__big__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME1__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_sig_11_bit_bitstring_big_endian_coded := ");
field_test__sig__11__bit__bitstring__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_big_endian_coded := ");
field_test__sig__5__bit__bitstring__big__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME1__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type 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) test__sig__11__bit__bitstring__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__bitstring__big__endian__coded().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(), "test_sig_11_bit_bitstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__bitstring__big__endian__coded().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(), "test_sig_5_bit_bitstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__bitstring__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME1__msg__type::set_implicit_omit()
{
if (test__sig__11__bit__bitstring__big__endian__coded().is_bound()) test__sig__11__bit__bitstring__big__endian__coded().set_implicit_omit();
if (test__sig__5__bit__bitstring__big__endian__coded().is_bound()) test__sig__5__bit__bitstring__big__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME1__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__sig__11__bit__bitstring__big__endian__coded.encode_text(text_buf);
field_test__sig__5__bit__bitstring__big__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME1__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__sig__11__bit__bitstring__big__endian__coded.decode_text(text_buf);
field_test__sig__5__bit__bitstring__big__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME1__msg__type::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__MESSAGE__TESTFRAME1__msg__type::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__MESSAGE__TESTFRAME1__msg__type::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, CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__11__bit__bitstring__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_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, CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__5__bit__bitstring__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_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__MESSAGE__TESTFRAME1__msg__type::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, CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_descr_.raw);
  encoded_length += field_test__sig__11__bit__bitstring__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__11__bit__bitstring__big__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__5__bit__bitstring__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME1__msg__type_test__sig__5__bit__bitstring__big__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME1__msg__type_template::single_value_struct {
BITSTRING_template field_test__sig__11__bit__bitstring__big__endian__coded;
BITSTRING_template field_test__sig__5__bit__bitstring__big__endian__coded;
};

void CAN__MESSAGE__TESTFRAME1__msg__type_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_test__sig__11__bit__bitstring__big__endian__coded = ANY_VALUE;
single_value->field_test__sig__5__bit__bitstring__big__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME1__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME1__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__sig__11__bit__bitstring__big__endian__coded().is_bound()) {
  single_value->field_test__sig__11__bit__bitstring__big__endian__coded = other_value.test__sig__11__bit__bitstring__big__endian__coded();
} else {
  single_value->field_test__sig__11__bit__bitstring__big__endian__coded.clean_up();
}
if (other_value.test__sig__5__bit__bitstring__big__endian__coded().is_bound()) {
  single_value->field_test__sig__5__bit__bitstring__big__endian__coded = other_value.test__sig__5__bit__bitstring__big__endian__coded();
} else {
  single_value->field_test__sig__5__bit__bitstring__big__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME1__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME1__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__11__bit__bitstring__big__endian__coded().get_selection()) {
single_value->field_test__sig__11__bit__bitstring__big__endian__coded = other_value.test__sig__11__bit__bitstring__big__endian__coded();
} else {
single_value->field_test__sig__11__bit__bitstring__big__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__5__bit__bitstring__big__endian__coded().get_selection()) {
single_value->field_test__sig__5__bit__bitstring__big__endian__coded = other_value.test__sig__5__bit__bitstring__big__endian__coded();
} else {
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.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__MESSAGE__TESTFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME1__msg__type_template::CAN__MESSAGE__TESTFRAME1__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME1__msg__type_template::CAN__MESSAGE__TESTFRAME1__msg__type_template(const CAN__MESSAGE__TESTFRAME1__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME1__msg__type_template::match(const CAN__MESSAGE__TESTFRAME1__msg__type& 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.test__sig__11__bit__bitstring__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__11__bit__bitstring__big__endian__coded.match(other_value.test__sig__11__bit__bitstring__big__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__5__bit__bitstring__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__5__bit__bitstring__big__endian__coded.match(other_value.test__sig__5__bit__bitstring__big__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME1__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__sig__11__bit__bitstring__big__endian__coded.is_value()
 &&single_value->field_test__sig__5__bit__bitstring__big__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME1__msg__type_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__MESSAGE__TESTFRAME1__msg__type CAN__MESSAGE__TESTFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
CAN__MESSAGE__TESTFRAME1__msg__type ret_val;
if (single_value->field_test__sig__11__bit__bitstring__big__endian__coded.is_bound()) {
ret_val.test__sig__11__bit__bitstring__big__endian__coded() = single_value->field_test__sig__11__bit__bitstring__big__endian__coded.valueof();
}
if (single_value->field_test__sig__5__bit__bitstring__big__endian__coded.is_bound()) {
ret_val.test__sig__5__bit__bitstring__big__endian__coded() = single_value->field_test__sig__5__bit__bitstring__big__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME1__msg__type_template[list_length];
}

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

BITSTRING_template& CAN__MESSAGE__TESTFRAME1__msg__type_template::test__sig__11__bit__bitstring__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__11__bit__bitstring__big__endian__coded;
}

const BITSTRING_template& CAN__MESSAGE__TESTFRAME1__msg__type_template::test__sig__11__bit__bitstring__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_11_bit_bitstring_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
return single_value->field_test__sig__11__bit__bitstring__big__endian__coded;
}

BITSTRING_template& CAN__MESSAGE__TESTFRAME1__msg__type_template::test__sig__5__bit__bitstring__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__5__bit__bitstring__big__endian__coded;
}

const BITSTRING_template& CAN__MESSAGE__TESTFRAME1__msg__type_template::test__sig__5__bit__bitstring__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_5_bit_bitstring_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
return single_value->field_test__sig__5__bit__bitstring__big__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME1__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_sig_11_bit_bitstring_big_endian_coded := ");
single_value->field_test__sig__11__bit__bitstring__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_big_endian_coded := ");
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.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__MESSAGE__TESTFRAME1__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME1__msg__type& 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_test__sig__11__bit__bitstring__big__endian__coded.match(match_value.test__sig__11__bit__bitstring__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_11_bit_bitstring_big_endian_coded");
single_value->field_test__sig__11__bit__bitstring__big__endian__coded.log_match(match_value.test__sig__11__bit__bitstring__big__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__5__bit__bitstring__big__endian__coded.match(match_value.test__sig__5__bit__bitstring__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_5_bit_bitstring_big_endian_coded");
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.log_match(match_value.test__sig__5__bit__bitstring__big__endian__coded(), 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("{ test_sig_11_bit_bitstring_big_endian_coded := ");
single_value->field_test__sig__11__bit__bitstring__big__endian__coded.log_match(match_value.test__sig__11__bit__bitstring__big__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_5_bit_bitstring_big_endian_coded := ");
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.log_match(match_value.test__sig__5__bit__bitstring__big__endian__coded(), 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__MESSAGE__TESTFRAME1__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__sig__11__bit__bitstring__big__endian__coded.encode_text(text_buf);
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME1__msg__type_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_test__sig__11__bit__bitstring__big__endian__coded.decode_text(text_buf);
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.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__MESSAGE__TESTFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME1__msg__type_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__MESSAGE__TESTFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type 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) test__sig__11__bit__bitstring__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__bitstring__big__endian__coded().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(), "test_sig_11_bit_bitstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__bitstring__big__endian__coded().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(), "test_sig_5_bit_bitstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__bitstring__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME1__msg__type_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_test__sig__11__bit__bitstring__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type");
single_value->field_test__sig__5__bit__bitstring__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME1_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME1__msg__type_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__MESSAGE__TESTFRAME2__msg__type::CAN__MESSAGE__TESTFRAME2__msg__type()
{
}

CAN__MESSAGE__TESTFRAME2__msg__type::CAN__MESSAGE__TESTFRAME2__msg__type(const INTEGER& par_test__sig__11__bit__integer__big__endian__coded,
    const INTEGER& par_test__sig__5__bit__integer__big__endian__coded)
  :   field_test__sig__11__bit__integer__big__endian__coded(par_test__sig__11__bit__integer__big__endian__coded),
  field_test__sig__5__bit__integer__big__endian__coded(par_test__sig__5__bit__integer__big__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME2__msg__type::CAN__MESSAGE__TESTFRAME2__msg__type(const CAN__MESSAGE__TESTFRAME2__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
if (other_value.test__sig__11__bit__integer__big__endian__coded().is_bound()) field_test__sig__11__bit__integer__big__endian__coded = other_value.test__sig__11__bit__integer__big__endian__coded();
else field_test__sig__11__bit__integer__big__endian__coded.clean_up();
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME2__msg__type::clean_up()
{
field_test__sig__11__bit__integer__big__endian__coded.clean_up();
field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME2__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME2__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME2__msg__type& CAN__MESSAGE__TESTFRAME2__msg__type::operator=(const CAN__MESSAGE__TESTFRAME2__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
  if (other_value.test__sig__11__bit__integer__big__endian__coded().is_bound()) field_test__sig__11__bit__integer__big__endian__coded = other_value.test__sig__11__bit__integer__big__endian__coded();
  else field_test__sig__11__bit__integer__big__endian__coded.clean_up();
  if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
  else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME2__msg__type::operator==(const CAN__MESSAGE__TESTFRAME2__msg__type& other_value) const
{
return field_test__sig__11__bit__integer__big__endian__coded==other_value.field_test__sig__11__bit__integer__big__endian__coded
  && field_test__sig__5__bit__integer__big__endian__coded==other_value.field_test__sig__5__bit__integer__big__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME2__msg__type::is_bound() const
{
return (field_test__sig__11__bit__integer__big__endian__coded.is_bound())
  || (field_test__sig__5__bit__integer__big__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME2__msg__type::is_value() const
{
return field_test__sig__11__bit__integer__big__endian__coded.is_value()
  && field_test__sig__5__bit__integer__big__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME2__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_sig_11_bit_integer_big_endian_coded := ");
field_test__sig__11__bit__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
field_test__sig__5__bit__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME2__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type 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) test__sig__11__bit__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_sig_11_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME2__msg__type::set_implicit_omit()
{
if (test__sig__11__bit__integer__big__endian__coded().is_bound()) test__sig__11__bit__integer__big__endian__coded().set_implicit_omit();
if (test__sig__5__bit__integer__big__endian__coded().is_bound()) test__sig__5__bit__integer__big__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME2__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__sig__11__bit__integer__big__endian__coded.encode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME2__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__sig__11__bit__integer__big__endian__coded.decode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME2__msg__type::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__MESSAGE__TESTFRAME2__msg__type::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__MESSAGE__TESTFRAME2__msg__type::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, CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__11__bit__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_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, CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__5__bit__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_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__MESSAGE__TESTFRAME2__msg__type::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, CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw);
  encoded_length += field_test__sig__11__bit__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__11__bit__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__5__bit__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME2__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME2__msg__type_template::single_value_struct {
INTEGER_template field_test__sig__11__bit__integer__big__endian__coded;
INTEGER_template field_test__sig__5__bit__integer__big__endian__coded;
};

void CAN__MESSAGE__TESTFRAME2__msg__type_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_test__sig__11__bit__integer__big__endian__coded = ANY_VALUE;
single_value->field_test__sig__5__bit__integer__big__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME2__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME2__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__sig__11__bit__integer__big__endian__coded().is_bound()) {
  single_value->field_test__sig__11__bit__integer__big__endian__coded = other_value.test__sig__11__bit__integer__big__endian__coded();
} else {
  single_value->field_test__sig__11__bit__integer__big__endian__coded.clean_up();
}
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) {
  single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
  single_value->field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME2__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME2__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__11__bit__integer__big__endian__coded().get_selection()) {
single_value->field_test__sig__11__bit__integer__big__endian__coded = other_value.test__sig__11__bit__integer__big__endian__coded();
} else {
single_value->field_test__sig__11__bit__integer__big__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__5__bit__integer__big__endian__coded().get_selection()) {
single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME2__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME2__msg__type_template::CAN__MESSAGE__TESTFRAME2__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME2__msg__type_template::CAN__MESSAGE__TESTFRAME2__msg__type_template(const CAN__MESSAGE__TESTFRAME2__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME2__msg__type_template::match(const CAN__MESSAGE__TESTFRAME2__msg__type& 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.test__sig__11__bit__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__11__bit__integer__big__endian__coded.match(other_value.test__sig__11__bit__integer__big__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(other_value.test__sig__5__bit__integer__big__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME2__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__sig__11__bit__integer__big__endian__coded.is_value()
 &&single_value->field_test__sig__5__bit__integer__big__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME2__msg__type_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__MESSAGE__TESTFRAME2__msg__type CAN__MESSAGE__TESTFRAME2__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
CAN__MESSAGE__TESTFRAME2__msg__type ret_val;
if (single_value->field_test__sig__11__bit__integer__big__endian__coded.is_bound()) {
ret_val.test__sig__11__bit__integer__big__endian__coded() = single_value->field_test__sig__11__bit__integer__big__endian__coded.valueof();
}
if (single_value->field_test__sig__5__bit__integer__big__endian__coded.is_bound()) {
ret_val.test__sig__5__bit__integer__big__endian__coded() = single_value->field_test__sig__5__bit__integer__big__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME2__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME2__msg__type_template[list_length];
}

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

INTEGER_template& CAN__MESSAGE__TESTFRAME2__msg__type_template::test__sig__11__bit__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__11__bit__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME2__msg__type_template::test__sig__11__bit__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_11_bit_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
return single_value->field_test__sig__11__bit__integer__big__endian__coded;
}

INTEGER_template& CAN__MESSAGE__TESTFRAME2__msg__type_template::test__sig__5__bit__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME2__msg__type_template::test__sig__5__bit__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_5_bit_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME2__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_sig_11_bit_integer_big_endian_coded := ");
single_value->field_test__sig__11__bit__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME2__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME2__msg__type& 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_test__sig__11__bit__integer__big__endian__coded.match(match_value.test__sig__11__bit__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_11_bit_integer_big_endian_coded");
single_value->field_test__sig__11__bit__integer__big__endian__coded.log_match(match_value.test__sig__11__bit__integer__big__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(match_value.test__sig__5__bit__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_5_bit_integer_big_endian_coded");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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("{ test_sig_11_bit_integer_big_endian_coded := ");
single_value->field_test__sig__11__bit__integer__big__endian__coded.log_match(match_value.test__sig__11__bit__integer__big__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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__MESSAGE__TESTFRAME2__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__sig__11__bit__integer__big__endian__coded.encode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME2__msg__type_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_test__sig__11__bit__integer__big__endian__coded.decode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME2__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME2__msg__type_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__MESSAGE__TESTFRAME2__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type 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) test__sig__11__bit__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_sig_11_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__11__bit__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME2__msg__type_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_test__sig__11__bit__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type");
single_value->field_test__sig__5__bit__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME2_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME2__msg__type_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__MESSAGE__TESTFRAME3__msg__type::CAN__MESSAGE__TESTFRAME3__msg__type()
{
}

CAN__MESSAGE__TESTFRAME3__msg__type::CAN__MESSAGE__TESTFRAME3__msg__type(const OCTETSTRING& par_test__sig__1__byte__octetstring__big__endian__coded,
    const OCTETSTRING& par_test__sig__2__byte__octetstring__big__endian__coded)
  :   field_test__sig__1__byte__octetstring__big__endian__coded(par_test__sig__1__byte__octetstring__big__endian__coded),
  field_test__sig__2__byte__octetstring__big__endian__coded(par_test__sig__2__byte__octetstring__big__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME3__msg__type::CAN__MESSAGE__TESTFRAME3__msg__type(const CAN__MESSAGE__TESTFRAME3__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
if (other_value.test__sig__1__byte__octetstring__big__endian__coded().is_bound()) field_test__sig__1__byte__octetstring__big__endian__coded = other_value.test__sig__1__byte__octetstring__big__endian__coded();
else field_test__sig__1__byte__octetstring__big__endian__coded.clean_up();
if (other_value.test__sig__2__byte__octetstring__big__endian__coded().is_bound()) field_test__sig__2__byte__octetstring__big__endian__coded = other_value.test__sig__2__byte__octetstring__big__endian__coded();
else field_test__sig__2__byte__octetstring__big__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME3__msg__type::clean_up()
{
field_test__sig__1__byte__octetstring__big__endian__coded.clean_up();
field_test__sig__2__byte__octetstring__big__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME3__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME3__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME3__msg__type& CAN__MESSAGE__TESTFRAME3__msg__type::operator=(const CAN__MESSAGE__TESTFRAME3__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
  if (other_value.test__sig__1__byte__octetstring__big__endian__coded().is_bound()) field_test__sig__1__byte__octetstring__big__endian__coded = other_value.test__sig__1__byte__octetstring__big__endian__coded();
  else field_test__sig__1__byte__octetstring__big__endian__coded.clean_up();
  if (other_value.test__sig__2__byte__octetstring__big__endian__coded().is_bound()) field_test__sig__2__byte__octetstring__big__endian__coded = other_value.test__sig__2__byte__octetstring__big__endian__coded();
  else field_test__sig__2__byte__octetstring__big__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME3__msg__type::operator==(const CAN__MESSAGE__TESTFRAME3__msg__type& other_value) const
{
return field_test__sig__1__byte__octetstring__big__endian__coded==other_value.field_test__sig__1__byte__octetstring__big__endian__coded
  && field_test__sig__2__byte__octetstring__big__endian__coded==other_value.field_test__sig__2__byte__octetstring__big__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME3__msg__type::is_bound() const
{
return (field_test__sig__1__byte__octetstring__big__endian__coded.is_bound())
  || (field_test__sig__2__byte__octetstring__big__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME3__msg__type::is_value() const
{
return field_test__sig__1__byte__octetstring__big__endian__coded.is_value()
  && field_test__sig__2__byte__octetstring__big__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME3__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_sig_1_byte_octetstring_big_endian_coded := ");
field_test__sig__1__byte__octetstring__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_2_byte_octetstring_big_endian_coded := ");
field_test__sig__2__byte__octetstring__big__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME3__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type 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) test__sig__1__byte__octetstring__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__2__byte__octetstring__big__endian__coded().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(), "test_sig_1_byte_octetstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__1__byte__octetstring__big__endian__coded().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(), "test_sig_2_byte_octetstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__2__byte__octetstring__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME3__msg__type::set_implicit_omit()
{
if (test__sig__1__byte__octetstring__big__endian__coded().is_bound()) test__sig__1__byte__octetstring__big__endian__coded().set_implicit_omit();
if (test__sig__2__byte__octetstring__big__endian__coded().is_bound()) test__sig__2__byte__octetstring__big__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME3__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__sig__1__byte__octetstring__big__endian__coded.encode_text(text_buf);
field_test__sig__2__byte__octetstring__big__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME3__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__sig__1__byte__octetstring__big__endian__coded.decode_text(text_buf);
field_test__sig__2__byte__octetstring__big__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME3__msg__type::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__MESSAGE__TESTFRAME3__msg__type::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__MESSAGE__TESTFRAME3__msg__type::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, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__1__byte__octetstring__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_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, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__2__byte__octetstring__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_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__MESSAGE__TESTFRAME3__msg__type::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, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_descr_.raw);
  encoded_length += field_test__sig__1__byte__octetstring__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__1__byte__octetstring__big__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__2__byte__octetstring__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME3__msg__type_test__sig__2__byte__octetstring__big__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME3__msg__type_template::single_value_struct {
OCTETSTRING_template field_test__sig__1__byte__octetstring__big__endian__coded;
OCTETSTRING_template field_test__sig__2__byte__octetstring__big__endian__coded;
};

void CAN__MESSAGE__TESTFRAME3__msg__type_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_test__sig__1__byte__octetstring__big__endian__coded = ANY_VALUE;
single_value->field_test__sig__2__byte__octetstring__big__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME3__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME3__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__sig__1__byte__octetstring__big__endian__coded().is_bound()) {
  single_value->field_test__sig__1__byte__octetstring__big__endian__coded = other_value.test__sig__1__byte__octetstring__big__endian__coded();
} else {
  single_value->field_test__sig__1__byte__octetstring__big__endian__coded.clean_up();
}
if (other_value.test__sig__2__byte__octetstring__big__endian__coded().is_bound()) {
  single_value->field_test__sig__2__byte__octetstring__big__endian__coded = other_value.test__sig__2__byte__octetstring__big__endian__coded();
} else {
  single_value->field_test__sig__2__byte__octetstring__big__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME3__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME3__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__1__byte__octetstring__big__endian__coded().get_selection()) {
single_value->field_test__sig__1__byte__octetstring__big__endian__coded = other_value.test__sig__1__byte__octetstring__big__endian__coded();
} else {
single_value->field_test__sig__1__byte__octetstring__big__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__2__byte__octetstring__big__endian__coded().get_selection()) {
single_value->field_test__sig__2__byte__octetstring__big__endian__coded = other_value.test__sig__2__byte__octetstring__big__endian__coded();
} else {
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.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__MESSAGE__TESTFRAME3__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME3__msg__type_template::CAN__MESSAGE__TESTFRAME3__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME3__msg__type_template::CAN__MESSAGE__TESTFRAME3__msg__type_template(const CAN__MESSAGE__TESTFRAME3__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME3__msg__type_template::match(const CAN__MESSAGE__TESTFRAME3__msg__type& 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.test__sig__1__byte__octetstring__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__1__byte__octetstring__big__endian__coded.match(other_value.test__sig__1__byte__octetstring__big__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__2__byte__octetstring__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__2__byte__octetstring__big__endian__coded.match(other_value.test__sig__2__byte__octetstring__big__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME3__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__sig__1__byte__octetstring__big__endian__coded.is_value()
 &&single_value->field_test__sig__2__byte__octetstring__big__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME3__msg__type_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__MESSAGE__TESTFRAME3__msg__type CAN__MESSAGE__TESTFRAME3__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
CAN__MESSAGE__TESTFRAME3__msg__type ret_val;
if (single_value->field_test__sig__1__byte__octetstring__big__endian__coded.is_bound()) {
ret_val.test__sig__1__byte__octetstring__big__endian__coded() = single_value->field_test__sig__1__byte__octetstring__big__endian__coded.valueof();
}
if (single_value->field_test__sig__2__byte__octetstring__big__endian__coded.is_bound()) {
ret_val.test__sig__2__byte__octetstring__big__endian__coded() = single_value->field_test__sig__2__byte__octetstring__big__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME3__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME3__msg__type_template[list_length];
}

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

OCTETSTRING_template& CAN__MESSAGE__TESTFRAME3__msg__type_template::test__sig__1__byte__octetstring__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__1__byte__octetstring__big__endian__coded;
}

const OCTETSTRING_template& CAN__MESSAGE__TESTFRAME3__msg__type_template::test__sig__1__byte__octetstring__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_1_byte_octetstring_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
return single_value->field_test__sig__1__byte__octetstring__big__endian__coded;
}

OCTETSTRING_template& CAN__MESSAGE__TESTFRAME3__msg__type_template::test__sig__2__byte__octetstring__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__2__byte__octetstring__big__endian__coded;
}

const OCTETSTRING_template& CAN__MESSAGE__TESTFRAME3__msg__type_template::test__sig__2__byte__octetstring__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_2_byte_octetstring_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
return single_value->field_test__sig__2__byte__octetstring__big__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME3__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_sig_1_byte_octetstring_big_endian_coded := ");
single_value->field_test__sig__1__byte__octetstring__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_2_byte_octetstring_big_endian_coded := ");
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.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__MESSAGE__TESTFRAME3__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME3__msg__type& 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_test__sig__1__byte__octetstring__big__endian__coded.match(match_value.test__sig__1__byte__octetstring__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_1_byte_octetstring_big_endian_coded");
single_value->field_test__sig__1__byte__octetstring__big__endian__coded.log_match(match_value.test__sig__1__byte__octetstring__big__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__2__byte__octetstring__big__endian__coded.match(match_value.test__sig__2__byte__octetstring__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_2_byte_octetstring_big_endian_coded");
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.log_match(match_value.test__sig__2__byte__octetstring__big__endian__coded(), 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("{ test_sig_1_byte_octetstring_big_endian_coded := ");
single_value->field_test__sig__1__byte__octetstring__big__endian__coded.log_match(match_value.test__sig__1__byte__octetstring__big__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_2_byte_octetstring_big_endian_coded := ");
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.log_match(match_value.test__sig__2__byte__octetstring__big__endian__coded(), 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__MESSAGE__TESTFRAME3__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__sig__1__byte__octetstring__big__endian__coded.encode_text(text_buf);
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME3__msg__type_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_test__sig__1__byte__octetstring__big__endian__coded.decode_text(text_buf);
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.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__MESSAGE__TESTFRAME3__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME3__msg__type_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__MESSAGE__TESTFRAME3__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type 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) test__sig__1__byte__octetstring__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__2__byte__octetstring__big__endian__coded().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(), "test_sig_1_byte_octetstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__1__byte__octetstring__big__endian__coded().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(), "test_sig_2_byte_octetstring_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__2__byte__octetstring__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME3__msg__type_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_test__sig__1__byte__octetstring__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type");
single_value->field_test__sig__2__byte__octetstring__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME3_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME3__msg__type_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__MESSAGE__TESTFRAME4__msg__type::CAN__MESSAGE__TESTFRAME4__msg__type()
{
}

CAN__MESSAGE__TESTFRAME4__msg__type::CAN__MESSAGE__TESTFRAME4__msg__type(const INTEGER& par_test__unsig__9__bit__2__padded__integer__big__endian__coded,
    const INTEGER& par_test__sig__5__bit__integer__big__endian__coded)
  :   field_test__unsig__9__bit__2__padded__integer__big__endian__coded(par_test__unsig__9__bit__2__padded__integer__big__endian__coded),
  field_test__sig__5__bit__integer__big__endian__coded(par_test__sig__5__bit__integer__big__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME4__msg__type::CAN__MESSAGE__TESTFRAME4__msg__type(const CAN__MESSAGE__TESTFRAME4__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
else field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME4__msg__type::clean_up()
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME4__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME4__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME4__msg__type& CAN__MESSAGE__TESTFRAME4__msg__type::operator=(const CAN__MESSAGE__TESTFRAME4__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
  if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
  else field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
  if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
  else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME4__msg__type::operator==(const CAN__MESSAGE__TESTFRAME4__msg__type& other_value) const
{
return field_test__unsig__9__bit__2__padded__integer__big__endian__coded==other_value.field_test__unsig__9__bit__2__padded__integer__big__endian__coded
  && field_test__sig__5__bit__integer__big__endian__coded==other_value.field_test__sig__5__bit__integer__big__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME4__msg__type::is_bound() const
{
return (field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_bound())
  || (field_test__sig__5__bit__integer__big__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME4__msg__type::is_value() const
{
return field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_value()
  && field_test__sig__5__bit__integer__big__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME4__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
field_test__sig__5__bit__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME4__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type 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) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_unsig_9_bit_2_padded_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__unsig__9__bit__2__padded__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME4__msg__type::set_implicit_omit()
{
if (test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_implicit_omit();
if (test__sig__5__bit__integer__big__endian__coded().is_bound()) test__sig__5__bit__integer__big__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME4__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.encode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME4__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.decode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME4__msg__type::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__MESSAGE__TESTFRAME4__msg__type::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__MESSAGE__TESTFRAME4__msg__type::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, CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__unsig__9__bit__2__padded__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_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, CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__5__bit__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_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__MESSAGE__TESTFRAME4__msg__type::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, CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw);
  encoded_length += field_test__unsig__9__bit__2__padded__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME4__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__5__bit__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME4__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME4__msg__type_template::single_value_struct {
INTEGER_template field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
INTEGER_template field_test__sig__5__bit__integer__big__endian__coded;
};

void CAN__MESSAGE__TESTFRAME4__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded = ANY_VALUE;
single_value->field_test__sig__5__bit__integer__big__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME4__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME4__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) {
  single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
} else {
  single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
}
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) {
  single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
  single_value->field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME4__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME4__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().get_selection()) {
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
} else {
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__5__bit__integer__big__endian__coded().get_selection()) {
single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME4__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME4__msg__type_template::CAN__MESSAGE__TESTFRAME4__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME4__msg__type_template::CAN__MESSAGE__TESTFRAME4__msg__type_template(const CAN__MESSAGE__TESTFRAME4__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME4__msg__type_template::match(const CAN__MESSAGE__TESTFRAME4__msg__type& 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.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.match(other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(other_value.test__sig__5__bit__integer__big__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME4__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_value()
 &&single_value->field_test__sig__5__bit__integer__big__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME4__msg__type_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__MESSAGE__TESTFRAME4__msg__type CAN__MESSAGE__TESTFRAME4__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
CAN__MESSAGE__TESTFRAME4__msg__type ret_val;
if (single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_bound()) {
ret_val.test__unsig__9__bit__2__padded__integer__big__endian__coded() = single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.valueof();
}
if (single_value->field_test__sig__5__bit__integer__big__endian__coded.is_bound()) {
ret_val.test__sig__5__bit__integer__big__endian__coded() = single_value->field_test__sig__5__bit__integer__big__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME4__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME4__msg__type_template[list_length];
}

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

INTEGER_template& CAN__MESSAGE__TESTFRAME4__msg__type_template::test__unsig__9__bit__2__padded__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME4__msg__type_template::test__unsig__9__bit__2__padded__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_unsig_9_bit_2_padded_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
}

INTEGER_template& CAN__MESSAGE__TESTFRAME4__msg__type_template::test__sig__5__bit__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME4__msg__type_template::test__sig__5__bit__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_5_bit_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME4__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME4__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME4__msg__type& 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_test__unsig__9__bit__2__padded__integer__big__endian__coded.match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_unsig_9_bit_2_padded_integer_big_endian_coded");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log_match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(match_value.test__sig__5__bit__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_5_bit_integer_big_endian_coded");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log_match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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__MESSAGE__TESTFRAME4__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.encode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME4__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded.decode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME4__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME4__msg__type_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__MESSAGE__TESTFRAME4__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type 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) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_unsig_9_bit_2_padded_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__unsig__9__bit__2__padded__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME4__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type");
single_value->field_test__sig__5__bit__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME4_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME4__msg__type_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__MESSAGE__TESTFRAME5__msg__type::CAN__MESSAGE__TESTFRAME5__msg__type()
{
}

CAN__MESSAGE__TESTFRAME5__msg__type::CAN__MESSAGE__TESTFRAME5__msg__type(const INTEGER& par_test__unsig__9__bit__2__padded__integer__big__endian__coded,
    const INTEGER& par_test__sig__5__bit__integer__big__endian__coded)
  :   field_test__unsig__9__bit__2__padded__integer__big__endian__coded(par_test__unsig__9__bit__2__padded__integer__big__endian__coded),
  field_test__sig__5__bit__integer__big__endian__coded(par_test__sig__5__bit__integer__big__endian__coded)
{
}

CAN__MESSAGE__TESTFRAME5__msg__type::CAN__MESSAGE__TESTFRAME5__msg__type(const CAN__MESSAGE__TESTFRAME5__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
else field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

void CAN__MESSAGE__TESTFRAME5__msg__type::clean_up()
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__TESTFRAME5__msg__type::get_descriptor() const { return &CAN__MESSAGE__TESTFRAME5__msg__type_descr_; }
CAN__MESSAGE__TESTFRAME5__msg__type& CAN__MESSAGE__TESTFRAME5__msg__type::operator=(const CAN__MESSAGE__TESTFRAME5__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
  if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
  else field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
  if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
  else field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__TESTFRAME5__msg__type::operator==(const CAN__MESSAGE__TESTFRAME5__msg__type& other_value) const
{
return field_test__unsig__9__bit__2__padded__integer__big__endian__coded==other_value.field_test__unsig__9__bit__2__padded__integer__big__endian__coded
  && field_test__sig__5__bit__integer__big__endian__coded==other_value.field_test__sig__5__bit__integer__big__endian__coded;
}

boolean CAN__MESSAGE__TESTFRAME5__msg__type::is_bound() const
{
return (field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_bound())
  || (field_test__sig__5__bit__integer__big__endian__coded.is_bound());
}
boolean CAN__MESSAGE__TESTFRAME5__msg__type::is_value() const
{
return field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_value()
  && field_test__sig__5__bit__integer__big__endian__coded.is_value();
}
void CAN__MESSAGE__TESTFRAME5__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
field_test__sig__5__bit__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__TESTFRAME5__msg__type::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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type 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) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_unsig_9_bit_2_padded_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__unsig__9__bit__2__padded__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type");
  }
}

void CAN__MESSAGE__TESTFRAME5__msg__type::set_implicit_omit()
{
if (test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_implicit_omit();
if (test__sig__5__bit__integer__big__endian__coded().is_bound()) test__sig__5__bit__integer__big__endian__coded().set_implicit_omit();
}

void CAN__MESSAGE__TESTFRAME5__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.encode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.encode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME5__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__unsig__9__bit__2__padded__integer__big__endian__coded.decode_text(text_buf);
field_test__sig__5__bit__integer__big__endian__coded.decode_text(text_buf);
}

void CAN__MESSAGE__TESTFRAME5__msg__type::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__MESSAGE__TESTFRAME5__msg__type::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__MESSAGE__TESTFRAME5__msg__type::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, CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__unsig__9__bit__2__padded__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_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, CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__5__bit__integer__big__endian__coded.RAW_decode(CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_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__MESSAGE__TESTFRAME5__msg__type::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, CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_.raw);
  encoded_length += field_test__unsig__9__bit__2__padded__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME5__msg__type_test__unsig__9__bit__2__padded__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_test__sig__5__bit__integer__big__endian__coded.RAW_encode(CAN__MESSAGE__TESTFRAME5__msg__type_test__sig__5__bit__integer__big__endian__coded_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__TESTFRAME5__msg__type_template::single_value_struct {
INTEGER_template field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
INTEGER_template field_test__sig__5__bit__integer__big__endian__coded;
};

void CAN__MESSAGE__TESTFRAME5__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded = ANY_VALUE;
single_value->field_test__sig__5__bit__integer__big__endian__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__TESTFRAME5__msg__type_template::copy_value(const CAN__MESSAGE__TESTFRAME5__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) {
  single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
} else {
  single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
}
if (other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) {
  single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
  single_value->field_test__sig__5__bit__integer__big__endian__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__TESTFRAME5__msg__type_template::copy_template(const CAN__MESSAGE__TESTFRAME5__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded().get_selection()) {
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded = other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded();
} else {
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__5__bit__integer__big__endian__coded().get_selection()) {
single_value->field_test__sig__5__bit__integer__big__endian__coded = other_value.test__sig__5__bit__integer__big__endian__coded();
} else {
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME5__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__TESTFRAME5__msg__type_template::CAN__MESSAGE__TESTFRAME5__msg__type_template()
{
}

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

CAN__MESSAGE__TESTFRAME5__msg__type_template::CAN__MESSAGE__TESTFRAME5__msg__type_template(const CAN__MESSAGE__TESTFRAME5__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__TESTFRAME5__msg__type_template::match(const CAN__MESSAGE__TESTFRAME5__msg__type& 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.test__unsig__9__bit__2__padded__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.match(other_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy))return FALSE;
if(!other_value.test__sig__5__bit__integer__big__endian__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(other_value.test__sig__5__bit__integer__big__endian__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
}
return FALSE;
}

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

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

boolean CAN__MESSAGE__TESTFRAME5__msg__type_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_value()
 &&single_value->field_test__sig__5__bit__integer__big__endian__coded.is_value();
}

void CAN__MESSAGE__TESTFRAME5__msg__type_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__MESSAGE__TESTFRAME5__msg__type CAN__MESSAGE__TESTFRAME5__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
CAN__MESSAGE__TESTFRAME5__msg__type ret_val;
if (single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.is_bound()) {
ret_val.test__unsig__9__bit__2__padded__integer__big__endian__coded() = single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.valueof();
}
if (single_value->field_test__sig__5__bit__integer__big__endian__coded.is_bound()) {
ret_val.test__sig__5__bit__integer__big__endian__coded() = single_value->field_test__sig__5__bit__integer__big__endian__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__TESTFRAME5__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__TESTFRAME5__msg__type_template[list_length];
}

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

INTEGER_template& CAN__MESSAGE__TESTFRAME5__msg__type_template::test__unsig__9__bit__2__padded__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME5__msg__type_template::test__unsig__9__bit__2__padded__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_unsig_9_bit_2_padded_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
return single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded;
}

INTEGER_template& CAN__MESSAGE__TESTFRAME5__msg__type_template::test__sig__5__bit__integer__big__endian__coded()
{
set_specific();
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

const INTEGER_template& CAN__MESSAGE__TESTFRAME5__msg__type_template::test__sig__5__bit__integer__big__endian__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_5_bit_integer_big_endian_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
return single_value->field_test__sig__5__bit__integer__big__endian__coded;
}

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

void CAN__MESSAGE__TESTFRAME5__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log();
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME5__msg__type_template::log_match(const CAN__MESSAGE__TESTFRAME5__msg__type& 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_test__unsig__9__bit__2__padded__integer__big__endian__coded.match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_unsig_9_bit_2_padded_integer_big_endian_coded");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log_match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_test__sig__5__bit__integer__big__endian__coded.match(match_value.test__sig__5__bit__integer__big__endian__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_5_bit_integer_big_endian_coded");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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("{ test_unsig_9_bit_2_padded_integer_big_endian_coded := ");
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.log_match(match_value.test__unsig__9__bit__2__padded__integer__big__endian__coded(), legacy);
TTCN_Logger::log_event_str(", test_sig_5_bit_integer_big_endian_coded := ");
single_value->field_test__sig__5__bit__integer__big__endian__coded.log_match(match_value.test__sig__5__bit__integer__big__endian__coded(), 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__MESSAGE__TESTFRAME5__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__unsig__9__bit__2__padded__integer__big__endian__coded.encode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME5__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded.decode_text(text_buf);
single_value->field_test__sig__5__bit__integer__big__endian__coded.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__MESSAGE__TESTFRAME5__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type.");
}
}

void CAN__MESSAGE__TESTFRAME5__msg__type_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__MESSAGE__TESTFRAME5__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type 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) test__unsig__9__bit__2__padded__integer__big__endian__coded().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) test__sig__5__bit__integer__big__endian__coded().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(), "test_unsig_9_bit_2_padded_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__unsig__9__bit__2__padded__integer__big__endian__coded().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(), "test_sig_5_bit_integer_big_endian_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__5__bit__integer__big__endian__coded().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 @CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__TESTFRAME5__msg__type_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_test__unsig__9__bit__2__padded__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type");
single_value->field_test__sig__5__bit__integer__big__endian__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_TESTFRAME5_msg_type");
}

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

boolean CAN__MESSAGE__TESTFRAME5__msg__type_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__MESSAGE__EXTENDEDFRAME1__msg__type::CAN__MESSAGE__EXTENDEDFRAME1__msg__type()
{
}

CAN__MESSAGE__EXTENDEDFRAME1__msg__type::CAN__MESSAGE__EXTENDEDFRAME1__msg__type(const OCTETSTRING& par_test__sig__2__byte__octetstring__msb__coded)
  :   field_test__sig__2__byte__octetstring__msb__coded(par_test__sig__2__byte__octetstring__msb__coded)
{
}

CAN__MESSAGE__EXTENDEDFRAME1__msg__type::CAN__MESSAGE__EXTENDEDFRAME1__msg__type(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
if (other_value.test__sig__2__byte__octetstring__msb__coded().is_bound()) field_test__sig__2__byte__octetstring__msb__coded = other_value.test__sig__2__byte__octetstring__msb__coded();
else field_test__sig__2__byte__octetstring__msb__coded.clean_up();
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::clean_up()
{
field_test__sig__2__byte__octetstring__msb__coded.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MESSAGE__EXTENDEDFRAME1__msg__type::get_descriptor() const { return &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_; }
CAN__MESSAGE__EXTENDEDFRAME1__msg__type& CAN__MESSAGE__EXTENDEDFRAME1__msg__type::operator=(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
  if (other_value.test__sig__2__byte__octetstring__msb__coded().is_bound()) field_test__sig__2__byte__octetstring__msb__coded = other_value.test__sig__2__byte__octetstring__msb__coded();
  else field_test__sig__2__byte__octetstring__msb__coded.clean_up();
}
return *this;
}

boolean CAN__MESSAGE__EXTENDEDFRAME1__msg__type::operator==(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& other_value) const
{
return field_test__sig__2__byte__octetstring__msb__coded==other_value.field_test__sig__2__byte__octetstring__msb__coded;
}

boolean CAN__MESSAGE__EXTENDEDFRAME1__msg__type::is_bound() const
{
return (field_test__sig__2__byte__octetstring__msb__coded.is_bound());
}
boolean CAN__MESSAGE__EXTENDEDFRAME1__msg__type::is_value() const
{
return field_test__sig__2__byte__octetstring__msb__coded.is_value();
}
void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ test_sig_2_byte_octetstring_msb_coded := ");
field_test__sig__2__byte__octetstring__msb__coded.log();
TTCN_Logger::log_event_str(" }");
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (1<param.get_size()) {
      param.error("record value of type @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type has 1 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) test__sig__2__byte__octetstring__msb__coded().set_param(*param.get_elem(0));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "test_sig_2_byte_octetstring_msb_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__2__byte__octetstring__msb__coded().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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type");
  }
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::set_implicit_omit()
{
if (test__sig__2__byte__octetstring__msb__coded().is_bound()) test__sig__2__byte__octetstring__msb__coded().set_implicit_omit();
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::encode_text(Text_Buf& text_buf) const
{
field_test__sig__2__byte__octetstring__msb__coded.encode_text(text_buf);
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::decode_text(Text_Buf& text_buf)
{
field_test__sig__2__byte__octetstring__msb__coded.decode_text(text_buf);
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type::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__MESSAGE__EXTENDEDFRAME1__msg__type::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__MESSAGE__EXTENDEDFRAME1__msg__type::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, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_descr_.raw->forceomit);
  decoded_field_length = field_test__sig__2__byte__octetstring__msb__coded.RAW_decode(CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_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());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int CAN__MESSAGE__EXTENDEDFRAME1__msg__type::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 = 1;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(1);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_descr_.raw);
  encoded_length += field_test__sig__2__byte__octetstring__msb__coded.RAW_encode(CAN__MESSAGE__EXTENDEDFRAME1__msg__type_test__sig__2__byte__octetstring__msb__coded_descr_, *myleaf.body.node.nodes[0]);
  return myleaf.length = encoded_length;
}

struct CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::single_value_struct {
OCTETSTRING_template field_test__sig__2__byte__octetstring__msb__coded;
};

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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_test__sig__2__byte__octetstring__msb__coded = ANY_VALUE;
}
}
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::copy_value(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& other_value)
{
single_value = new single_value_struct;
if (other_value.test__sig__2__byte__octetstring__msb__coded().is_bound()) {
  single_value->field_test__sig__2__byte__octetstring__msb__coded = other_value.test__sig__2__byte__octetstring__msb__coded();
} else {
  single_value->field_test__sig__2__byte__octetstring__msb__coded.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::copy_template(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.test__sig__2__byte__octetstring__msb__coded().get_selection()) {
single_value->field_test__sig__2__byte__octetstring__msb__coded = other_value.test__sig__2__byte__octetstring__msb__coded();
} else {
single_value->field_test__sig__2__byte__octetstring__msb__coded.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__MESSAGE__EXTENDEDFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
break;
}
set_selection(other_value);
}

CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template()
{
}

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

CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::match(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& 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.test__sig__2__byte__octetstring__msb__coded().is_bound()) return FALSE;
if(!single_value->field_test__sig__2__byte__octetstring__msb__coded.match(other_value.test__sig__2__byte__octetstring__msb__coded(), 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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
}
return FALSE;
}

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

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

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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__MESSAGE__EXTENDEDFRAME1__msg__type CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
CAN__MESSAGE__EXTENDEDFRAME1__msg__type ret_val;
if (single_value->field_test__sig__2__byte__octetstring__msb__coded.is_bound()) {
ret_val.test__sig__2__byte__octetstring__msb__coded() = single_value->field_test__sig__2__byte__octetstring__msb__coded.valueof();
}
return ret_val;
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template[list_length];
}

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

OCTETSTRING_template& CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::test__sig__2__byte__octetstring__msb__coded()
{
set_specific();
return single_value->field_test__sig__2__byte__octetstring__msb__coded;
}

const OCTETSTRING_template& CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::test__sig__2__byte__octetstring__msb__coded() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field test_sig_2_byte_octetstring_msb_coded of a non-specific template of type @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
return single_value->field_test__sig__2__byte__octetstring__msb__coded;
}

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

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ test_sig_2_byte_octetstring_msb_coded := ");
single_value->field_test__sig__2__byte__octetstring__msb__coded.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__MESSAGE__EXTENDEDFRAME1__msg__type_template::log_match(const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& 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_test__sig__2__byte__octetstring__msb__coded.match(match_value.test__sig__2__byte__octetstring__msb__coded(), legacy)){
TTCN_Logger::log_logmatch_info(".test_sig_2_byte_octetstring_msb_coded");
single_value->field_test__sig__2__byte__octetstring__msb__coded.log_match(match_value.test__sig__2__byte__octetstring__msb__coded(), 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("{ test_sig_2_byte_octetstring_msb_coded := ");
single_value->field_test__sig__2__byte__octetstring__msb__coded.log_match(match_value.test__sig__2__byte__octetstring__msb__coded(), 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__MESSAGE__EXTENDEDFRAME1__msg__type_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_test__sig__2__byte__octetstring__msb__coded.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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
}
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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_test__sig__2__byte__octetstring__msb__coded.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__MESSAGE__EXTENDEDFRAME1__msg__type_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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type.");
}
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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__MESSAGE__EXTENDEDFRAME1__msg__type_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (1<param.get_size()) {
      param.error("record template of type @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type has 1 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) test__sig__2__byte__octetstring__msb__coded().set_param(*param.get_elem(0));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "test_sig_2_byte_octetstring_msb_coded")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          test__sig__2__byte__octetstring__msb__coded().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 @CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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_test__sig__2__byte__octetstring__msb__coded.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type");
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 : "@CAN_matrix_messages.CAN_MESSAGE_EXTENDEDFRAME1_msg_type");
}

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

boolean CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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 CAN__MatrixPayloadUnion::copy_value(const CAN__MatrixPayloadUnion& other_value)
{
switch (other_value.union_selection) {
case ALT_message__MyTestframe0:
field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type(*other_value.field_message__MyTestframe0);
break;
case ALT_message__MyTestframe1:
field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type(*other_value.field_message__MyTestframe1);
break;
case ALT_message__MyTestframe2:
field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type(*other_value.field_message__MyTestframe2);
break;
case ALT_message__MyTestframe3:
field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type(*other_value.field_message__MyTestframe3);
break;
case ALT_message__MyTestframe4:
field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type(*other_value.field_message__MyTestframe4);
break;
case ALT_message__MyTestframe5:
field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type(*other_value.field_message__MyTestframe5);
break;
case ALT_message__extendedFrame1:
field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type(*other_value.field_message__extendedFrame1);
break;
default:
TTCN_error("Assignment of an unbound union value of type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
union_selection = other_value.union_selection;
}

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

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

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

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

boolean CAN__MatrixPayloadUnion::operator==(const CAN__MatrixPayloadUnion& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_message__MyTestframe0:
return *field_message__MyTestframe0 == *other_value.field_message__MyTestframe0;
case ALT_message__MyTestframe1:
return *field_message__MyTestframe1 == *other_value.field_message__MyTestframe1;
case ALT_message__MyTestframe2:
return *field_message__MyTestframe2 == *other_value.field_message__MyTestframe2;
case ALT_message__MyTestframe3:
return *field_message__MyTestframe3 == *other_value.field_message__MyTestframe3;
case ALT_message__MyTestframe4:
return *field_message__MyTestframe4 == *other_value.field_message__MyTestframe4;
case ALT_message__MyTestframe5:
return *field_message__MyTestframe5 == *other_value.field_message__MyTestframe5;
case ALT_message__extendedFrame1:
return *field_message__extendedFrame1 == *other_value.field_message__extendedFrame1;
default:
return FALSE;
}
}

CAN__MESSAGE__TESTFRAME0__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe0()
{
if (union_selection != ALT_message__MyTestframe0) {
clean_up();
field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type;
union_selection = ALT_message__MyTestframe0;
}
return *field_message__MyTestframe0;
}

const CAN__MESSAGE__TESTFRAME0__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe0() const
{
if (union_selection != ALT_message__MyTestframe0) TTCN_error("Using non-selected field message_MyTestframe0 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe0;
}

CAN__MESSAGE__TESTFRAME1__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe1()
{
if (union_selection != ALT_message__MyTestframe1) {
clean_up();
field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type;
union_selection = ALT_message__MyTestframe1;
}
return *field_message__MyTestframe1;
}

const CAN__MESSAGE__TESTFRAME1__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe1() const
{
if (union_selection != ALT_message__MyTestframe1) TTCN_error("Using non-selected field message_MyTestframe1 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe1;
}

CAN__MESSAGE__TESTFRAME2__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe2()
{
if (union_selection != ALT_message__MyTestframe2) {
clean_up();
field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type;
union_selection = ALT_message__MyTestframe2;
}
return *field_message__MyTestframe2;
}

const CAN__MESSAGE__TESTFRAME2__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe2() const
{
if (union_selection != ALT_message__MyTestframe2) TTCN_error("Using non-selected field message_MyTestframe2 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe2;
}

CAN__MESSAGE__TESTFRAME3__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe3()
{
if (union_selection != ALT_message__MyTestframe3) {
clean_up();
field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type;
union_selection = ALT_message__MyTestframe3;
}
return *field_message__MyTestframe3;
}

const CAN__MESSAGE__TESTFRAME3__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe3() const
{
if (union_selection != ALT_message__MyTestframe3) TTCN_error("Using non-selected field message_MyTestframe3 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe3;
}

CAN__MESSAGE__TESTFRAME4__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe4()
{
if (union_selection != ALT_message__MyTestframe4) {
clean_up();
field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type;
union_selection = ALT_message__MyTestframe4;
}
return *field_message__MyTestframe4;
}

const CAN__MESSAGE__TESTFRAME4__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe4() const
{
if (union_selection != ALT_message__MyTestframe4) TTCN_error("Using non-selected field message_MyTestframe4 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe4;
}

CAN__MESSAGE__TESTFRAME5__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe5()
{
if (union_selection != ALT_message__MyTestframe5) {
clean_up();
field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type;
union_selection = ALT_message__MyTestframe5;
}
return *field_message__MyTestframe5;
}

const CAN__MESSAGE__TESTFRAME5__msg__type& CAN__MatrixPayloadUnion::message__MyTestframe5() const
{
if (union_selection != ALT_message__MyTestframe5) TTCN_error("Using non-selected field message_MyTestframe5 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__MyTestframe5;
}

CAN__MESSAGE__EXTENDEDFRAME1__msg__type& CAN__MatrixPayloadUnion::message__extendedFrame1()
{
if (union_selection != ALT_message__extendedFrame1) {
clean_up();
field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type;
union_selection = ALT_message__extendedFrame1;
}
return *field_message__extendedFrame1;
}

const CAN__MESSAGE__EXTENDEDFRAME1__msg__type& CAN__MatrixPayloadUnion::message__extendedFrame1() const
{
if (union_selection != ALT_message__extendedFrame1) TTCN_error("Using non-selected field message_extendedFrame1 in a value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *field_message__extendedFrame1;
}

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

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

boolean CAN__MatrixPayloadUnion::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_message__MyTestframe0: return field_message__MyTestframe0->is_value();
case ALT_message__MyTestframe1: return field_message__MyTestframe1->is_value();
case ALT_message__MyTestframe2: return field_message__MyTestframe2->is_value();
case ALT_message__MyTestframe3: return field_message__MyTestframe3->is_value();
case ALT_message__MyTestframe4: return field_message__MyTestframe4->is_value();
case ALT_message__MyTestframe5: return field_message__MyTestframe5->is_value();
case ALT_message__extendedFrame1: return field_message__extendedFrame1->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void CAN__MatrixPayloadUnion::clean_up()
{
switch (union_selection) {
case ALT_message__MyTestframe0:
  delete field_message__MyTestframe0;
  break;
case ALT_message__MyTestframe1:
  delete field_message__MyTestframe1;
  break;
case ALT_message__MyTestframe2:
  delete field_message__MyTestframe2;
  break;
case ALT_message__MyTestframe3:
  delete field_message__MyTestframe3;
  break;
case ALT_message__MyTestframe4:
  delete field_message__MyTestframe4;
  break;
case ALT_message__MyTestframe5:
  delete field_message__MyTestframe5;
  break;
case ALT_message__extendedFrame1:
  delete field_message__extendedFrame1;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void CAN__MatrixPayloadUnion::log() const
{
switch (union_selection) {
case ALT_message__MyTestframe0:
TTCN_Logger::log_event_str("{ message_MyTestframe0 := ");
field_message__MyTestframe0->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__MyTestframe1:
TTCN_Logger::log_event_str("{ message_MyTestframe1 := ");
field_message__MyTestframe1->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__MyTestframe2:
TTCN_Logger::log_event_str("{ message_MyTestframe2 := ");
field_message__MyTestframe2->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__MyTestframe3:
TTCN_Logger::log_event_str("{ message_MyTestframe3 := ");
field_message__MyTestframe3->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__MyTestframe4:
TTCN_Logger::log_event_str("{ message_MyTestframe4 := ");
field_message__MyTestframe4->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__MyTestframe5:
TTCN_Logger::log_event_str("{ message_MyTestframe5 := ");
field_message__MyTestframe5->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_message__extendedFrame1:
TTCN_Logger::log_event_str("{ message_extendedFrame1 := ");
field_message__extendedFrame1->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void CAN__MatrixPayloadUnion::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, "message_MyTestframe0")) {
    message__MyTestframe0().set_param(*mp_last);
    if (!message__MyTestframe0().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_MyTestframe1")) {
    message__MyTestframe1().set_param(*mp_last);
    if (!message__MyTestframe1().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_MyTestframe2")) {
    message__MyTestframe2().set_param(*mp_last);
    if (!message__MyTestframe2().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_MyTestframe3")) {
    message__MyTestframe3().set_param(*mp_last);
    if (!message__MyTestframe3().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_MyTestframe4")) {
    message__MyTestframe4().set_param(*mp_last);
    if (!message__MyTestframe4().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_MyTestframe5")) {
    message__MyTestframe5().set_param(*mp_last);
    if (!message__MyTestframe5().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "message_extendedFrame1")) {
    message__extendedFrame1().set_param(*mp_last);
    if (!message__extendedFrame1().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @CAN_matrix_messages.CAN_MatrixPayloadUnion.", last_name);
}

void CAN__MatrixPayloadUnion::set_implicit_omit()
{
switch (union_selection) {
case ALT_message__MyTestframe0:
field_message__MyTestframe0->set_implicit_omit(); break;
case ALT_message__MyTestframe1:
field_message__MyTestframe1->set_implicit_omit(); break;
case ALT_message__MyTestframe2:
field_message__MyTestframe2->set_implicit_omit(); break;
case ALT_message__MyTestframe3:
field_message__MyTestframe3->set_implicit_omit(); break;
case ALT_message__MyTestframe4:
field_message__MyTestframe4->set_implicit_omit(); break;
case ALT_message__MyTestframe5:
field_message__MyTestframe5->set_implicit_omit(); break;
case ALT_message__extendedFrame1:
field_message__extendedFrame1->set_implicit_omit(); break;
default: break;
}
}

void CAN__MatrixPayloadUnion::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_message__MyTestframe0:
field_message__MyTestframe0->encode_text(text_buf);
break;
case ALT_message__MyTestframe1:
field_message__MyTestframe1->encode_text(text_buf);
break;
case ALT_message__MyTestframe2:
field_message__MyTestframe2->encode_text(text_buf);
break;
case ALT_message__MyTestframe3:
field_message__MyTestframe3->encode_text(text_buf);
break;
case ALT_message__MyTestframe4:
field_message__MyTestframe4->encode_text(text_buf);
break;
case ALT_message__MyTestframe5:
field_message__MyTestframe5->encode_text(text_buf);
break;
case ALT_message__extendedFrame1:
field_message__extendedFrame1->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}

void CAN__MatrixPayloadUnion::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_message__MyTestframe0:
message__MyTestframe0().decode_text(text_buf);
break;
case ALT_message__MyTestframe1:
message__MyTestframe1().decode_text(text_buf);
break;
case ALT_message__MyTestframe2:
message__MyTestframe2().decode_text(text_buf);
break;
case ALT_message__MyTestframe3:
message__MyTestframe3().decode_text(text_buf);
break;
case ALT_message__MyTestframe4:
message__MyTestframe4().decode_text(text_buf);
break;
case ALT_message__MyTestframe5:
message__MyTestframe5().decode_text(text_buf);
break;
case ALT_message__extendedFrame1:
message__extendedFrame1().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}

void CAN__MatrixPayloadUnion::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 CAN__MatrixPayloadUnion::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__MatrixPayloadUnion::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, CAN__MESSAGE__TESTFRAME0__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe0().RAW_decode(CAN__MESSAGE__TESTFRAME0__msg__type_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, CAN__MESSAGE__TESTFRAME1__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe1().RAW_decode(CAN__MESSAGE__TESTFRAME1__msg__type_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, CAN__MESSAGE__TESTFRAME2__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe2().RAW_decode(CAN__MESSAGE__TESTFRAME2__msg__type_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, CAN__MESSAGE__TESTFRAME3__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe3().RAW_decode(CAN__MESSAGE__TESTFRAME3__msg__type_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, CAN__MESSAGE__TESTFRAME4__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe4().RAW_decode(CAN__MESSAGE__TESTFRAME4__msg__type_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, CAN__MESSAGE__TESTFRAME5__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe5().RAW_decode(CAN__MESSAGE__TESTFRAME5__msg__type_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, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_.raw->forceomit);
      decoded_length = message__extendedFrame1().RAW_decode(CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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, CAN__MESSAGE__TESTFRAME0__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe0().RAW_decode(CAN__MESSAGE__TESTFRAME0__msg__type_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, CAN__MESSAGE__TESTFRAME1__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe1().RAW_decode(CAN__MESSAGE__TESTFRAME1__msg__type_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, CAN__MESSAGE__TESTFRAME2__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe2().RAW_decode(CAN__MESSAGE__TESTFRAME2__msg__type_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, CAN__MESSAGE__TESTFRAME3__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe3().RAW_decode(CAN__MESSAGE__TESTFRAME3__msg__type_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, CAN__MESSAGE__TESTFRAME4__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe4().RAW_decode(CAN__MESSAGE__TESTFRAME4__msg__type_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, CAN__MESSAGE__TESTFRAME5__msg__type_descr_.raw->forceomit);
      decoded_length = message__MyTestframe5().RAW_decode(CAN__MESSAGE__TESTFRAME5__msg__type_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, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_.raw->forceomit);
      decoded_length = message__extendedFrame1().RAW_decode(CAN__MESSAGE__EXTENDEDFRAME1__msg__type_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;
       }
 }
 clean_up();
 return -1;
}

int CAN__MatrixPayloadUnion::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const
{
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 7;  myleaf.body.node.nodes = init_nodes_of_enc_tree(7);
  memset(myleaf.body.node.nodes, 0, 7 * sizeof(RAW_enc_tree *));
  switch (union_selection) {
  case ALT_message__MyTestframe0:
    myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 0, CAN__MESSAGE__TESTFRAME0__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe0->RAW_encode(CAN__MESSAGE__TESTFRAME0__msg__type_descr_, *myleaf.body.node.nodes[0]);
    myleaf.body.node.nodes[0]->coding_descr = &CAN__MESSAGE__TESTFRAME0__msg__type_descr_;
    break;
  case ALT_message__MyTestframe1:
    myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 1, CAN__MESSAGE__TESTFRAME1__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe1->RAW_encode(CAN__MESSAGE__TESTFRAME1__msg__type_descr_, *myleaf.body.node.nodes[1]);
    myleaf.body.node.nodes[1]->coding_descr = &CAN__MESSAGE__TESTFRAME1__msg__type_descr_;
    break;
  case ALT_message__MyTestframe2:
    myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 2, CAN__MESSAGE__TESTFRAME2__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe2->RAW_encode(CAN__MESSAGE__TESTFRAME2__msg__type_descr_, *myleaf.body.node.nodes[2]);
    myleaf.body.node.nodes[2]->coding_descr = &CAN__MESSAGE__TESTFRAME2__msg__type_descr_;
    break;
  case ALT_message__MyTestframe3:
    myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 3, CAN__MESSAGE__TESTFRAME3__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe3->RAW_encode(CAN__MESSAGE__TESTFRAME3__msg__type_descr_, *myleaf.body.node.nodes[3]);
    myleaf.body.node.nodes[3]->coding_descr = &CAN__MESSAGE__TESTFRAME3__msg__type_descr_;
    break;
  case ALT_message__MyTestframe4:
    myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 4, CAN__MESSAGE__TESTFRAME4__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe4->RAW_encode(CAN__MESSAGE__TESTFRAME4__msg__type_descr_, *myleaf.body.node.nodes[4]);
    myleaf.body.node.nodes[4]->coding_descr = &CAN__MESSAGE__TESTFRAME4__msg__type_descr_;
    break;
  case ALT_message__MyTestframe5:
    myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 5, CAN__MESSAGE__TESTFRAME5__msg__type_descr_.raw);
    encoded_length = field_message__MyTestframe5->RAW_encode(CAN__MESSAGE__TESTFRAME5__msg__type_descr_, *myleaf.body.node.nodes[5]);
    myleaf.body.node.nodes[5]->coding_descr = &CAN__MESSAGE__TESTFRAME5__msg__type_descr_;
    break;
  case ALT_message__extendedFrame1:
    myleaf.body.node.nodes[6] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 6, CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_.raw);
    encoded_length = field_message__extendedFrame1->RAW_encode(CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_, *myleaf.body.node.nodes[6]);
    myleaf.body.node.nodes[6]->coding_descr = &CAN__MESSAGE__EXTENDEDFRAME1__msg__type_descr_;
    break;
  default:
    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  }
  return encoded_length;
}

void CAN__MatrixPayloadUnion_template::copy_value(const CAN__MatrixPayloadUnion& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
single_value.field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type_template(other_value.message__MyTestframe0());
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
single_value.field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type_template(other_value.message__MyTestframe1());
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
single_value.field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type_template(other_value.message__MyTestframe2());
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
single_value.field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type_template(other_value.message__MyTestframe3());
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
single_value.field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type_template(other_value.message__MyTestframe4());
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
single_value.field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type_template(other_value.message__MyTestframe5());
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
single_value.field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template(other_value.message__extendedFrame1());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
set_selection(SPECIFIC_VALUE);
}

void CAN__MatrixPayloadUnion_template::copy_template(const CAN__MatrixPayloadUnion_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
single_value.field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type_template(*other_value.single_value.field_message__MyTestframe0);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
single_value.field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type_template(*other_value.single_value.field_message__MyTestframe1);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
single_value.field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type_template(*other_value.single_value.field_message__MyTestframe2);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
single_value.field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type_template(*other_value.single_value.field_message__MyTestframe3);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
single_value.field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type_template(*other_value.single_value.field_message__MyTestframe4);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
single_value.field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type_template(*other_value.single_value.field_message__MyTestframe5);
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
single_value.field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template(*other_value.single_value.field_message__extendedFrame1);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
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__MatrixPayloadUnion_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 @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
set_selection(other_value);
}

CAN__MatrixPayloadUnion_template::CAN__MatrixPayloadUnion_template()
{
}

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

CAN__MatrixPayloadUnion_template::CAN__MatrixPayloadUnion_template(const CAN__MatrixPayloadUnion& other_value)
{
copy_value(other_value);
}

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

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

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

void CAN__MatrixPayloadUnion_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
delete single_value.field_message__MyTestframe0;
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
delete single_value.field_message__MyTestframe1;
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
delete single_value.field_message__MyTestframe2;
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
delete single_value.field_message__MyTestframe3;
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
delete single_value.field_message__MyTestframe4;
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
delete single_value.field_message__MyTestframe5;
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
delete single_value.field_message__extendedFrame1;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

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

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

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

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

boolean CAN__MatrixPayloadUnion_template::match(const CAN__MatrixPayloadUnion& 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:
{
CAN__MatrixPayloadUnion::union_selection_type value_selection = other_value.get_selection();
if (value_selection == CAN__MatrixPayloadUnion::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
return single_value.field_message__MyTestframe0->match(other_value.message__MyTestframe0(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
return single_value.field_message__MyTestframe1->match(other_value.message__MyTestframe1(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
return single_value.field_message__MyTestframe2->match(other_value.message__MyTestframe2(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
return single_value.field_message__MyTestframe3->match(other_value.message__MyTestframe3(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
return single_value.field_message__MyTestframe4->match(other_value.message__MyTestframe4(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
return single_value.field_message__MyTestframe5->match(other_value.message__MyTestframe5(), legacy);
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
return single_value.field_message__extendedFrame1->match(other_value.message__extendedFrame1(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}
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 @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
return FALSE;
}

boolean CAN__MatrixPayloadUnion_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
return single_value.field_message__MyTestframe0->is_value();
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
return single_value.field_message__MyTestframe1->is_value();
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
return single_value.field_message__MyTestframe2->is_value();
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
return single_value.field_message__MyTestframe3->is_value();
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
return single_value.field_message__MyTestframe4->is_value();
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
return single_value.field_message__MyTestframe5->is_value();
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
return single_value.field_message__extendedFrame1->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}

CAN__MatrixPayloadUnion CAN__MatrixPayloadUnion_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 @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
CAN__MatrixPayloadUnion ret_val;
switch (single_value.union_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
ret_val.message__MyTestframe0() = single_value.field_message__MyTestframe0->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
ret_val.message__MyTestframe1() = single_value.field_message__MyTestframe1->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
ret_val.message__MyTestframe2() = single_value.field_message__MyTestframe2->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
ret_val.message__MyTestframe3() = single_value.field_message__MyTestframe3->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
ret_val.message__MyTestframe4() = single_value.field_message__MyTestframe4->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
ret_val.message__MyTestframe5() = single_value.field_message__MyTestframe5->valueof();
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
ret_val.message__extendedFrame1() = single_value.field_message__extendedFrame1->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
return ret_val;
}

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

CAN__MESSAGE__TESTFRAME0__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe0()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe0) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe0;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe0;
}

const CAN__MESSAGE__TESTFRAME0__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe0() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe0 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe0) TTCN_error("Accessing non-selected field message_MyTestframe0 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe0;
}

CAN__MESSAGE__TESTFRAME1__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe1()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe1) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe1;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe1;
}

const CAN__MESSAGE__TESTFRAME1__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe1() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe1 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe1) TTCN_error("Accessing non-selected field message_MyTestframe1 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe1;
}

CAN__MESSAGE__TESTFRAME2__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe2()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe2) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe2;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe2;
}

const CAN__MESSAGE__TESTFRAME2__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe2() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe2 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe2) TTCN_error("Accessing non-selected field message_MyTestframe2 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe2;
}

CAN__MESSAGE__TESTFRAME3__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe3()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe3) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe3;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe3;
}

const CAN__MESSAGE__TESTFRAME3__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe3() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe3 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe3) TTCN_error("Accessing non-selected field message_MyTestframe3 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe3;
}

CAN__MESSAGE__TESTFRAME4__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe4()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe4) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe4;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe4;
}

const CAN__MESSAGE__TESTFRAME4__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe4() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe4 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe4) TTCN_error("Accessing non-selected field message_MyTestframe4 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe4;
}

CAN__MESSAGE__TESTFRAME5__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe5()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe5) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type_template(ANY_VALUE);
else single_value.field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__MyTestframe5;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__MyTestframe5;
}

const CAN__MESSAGE__TESTFRAME5__msg__type_template& CAN__MatrixPayloadUnion_template::message__MyTestframe5() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_MyTestframe5 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__MyTestframe5) TTCN_error("Accessing non-selected field message_MyTestframe5 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__MyTestframe5;
}

CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template& CAN__MatrixPayloadUnion_template::message__extendedFrame1()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__extendedFrame1) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template(ANY_VALUE);
else single_value.field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template;
single_value.union_selection = CAN__MatrixPayloadUnion::ALT_message__extendedFrame1;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_message__extendedFrame1;
}

const CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template& CAN__MatrixPayloadUnion_template::message__extendedFrame1() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field message_extendedFrame1 in a non-specific template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
if (single_value.union_selection != CAN__MatrixPayloadUnion::ALT_message__extendedFrame1) TTCN_error("Accessing non-selected field message_extendedFrame1 in a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
return *single_value.field_message__extendedFrame1;
}

boolean CAN__MatrixPayloadUnion_template::ischosen(CAN__MatrixPayloadUnion::union_selection_type checked_selection) const
{
if (checked_selection == CAN__MatrixPayloadUnion::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == CAN__MatrixPayloadUnion::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
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 @CAN_matrix_messages.CAN_MatrixPayloadUnion 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 CAN__MatrixPayloadUnion_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
TTCN_Logger::log_event_str("{ message_MyTestframe0 := ");
single_value.field_message__MyTestframe0->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
TTCN_Logger::log_event_str("{ message_MyTestframe1 := ");
single_value.field_message__MyTestframe1->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
TTCN_Logger::log_event_str("{ message_MyTestframe2 := ");
single_value.field_message__MyTestframe2->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
TTCN_Logger::log_event_str("{ message_MyTestframe3 := ");
single_value.field_message__MyTestframe3->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
TTCN_Logger::log_event_str("{ message_MyTestframe4 := ");
single_value.field_message__MyTestframe4->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
TTCN_Logger::log_event_str("{ message_MyTestframe5 := ");
single_value.field_message__MyTestframe5->log();
TTCN_Logger::log_event_str(" }");
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
TTCN_Logger::log_event_str("{ message_extendedFrame1 := ");
single_value.field_message__extendedFrame1->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 CAN__MatrixPayloadUnion_template::log_match(const CAN__MatrixPayloadUnion& 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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe0");
single_value.field_message__MyTestframe0->log_match(match_value.message__MyTestframe0(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe0 := ");
single_value.field_message__MyTestframe0->log_match(match_value.message__MyTestframe0(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe1");
single_value.field_message__MyTestframe1->log_match(match_value.message__MyTestframe1(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe1 := ");
single_value.field_message__MyTestframe1->log_match(match_value.message__MyTestframe1(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe2");
single_value.field_message__MyTestframe2->log_match(match_value.message__MyTestframe2(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe2 := ");
single_value.field_message__MyTestframe2->log_match(match_value.message__MyTestframe2(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe3");
single_value.field_message__MyTestframe3->log_match(match_value.message__MyTestframe3(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe3 := ");
single_value.field_message__MyTestframe3->log_match(match_value.message__MyTestframe3(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe4");
single_value.field_message__MyTestframe4->log_match(match_value.message__MyTestframe4(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe4 := ");
single_value.field_message__MyTestframe4->log_match(match_value.message__MyTestframe4(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_MyTestframe5");
single_value.field_message__MyTestframe5->log_match(match_value.message__MyTestframe5(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_MyTestframe5 := ");
single_value.field_message__MyTestframe5->log_match(match_value.message__MyTestframe5(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".message_extendedFrame1");
single_value.field_message__extendedFrame1->log_match(match_value.message__extendedFrame1(), legacy);
} else {
TTCN_Logger::log_event_str("{ message_extendedFrame1 := ");
single_value.field_message__extendedFrame1->log_match(match_value.message__extendedFrame1(), 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 CAN__MatrixPayloadUnion_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
single_value.field_message__MyTestframe0->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
single_value.field_message__MyTestframe1->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
single_value.field_message__MyTestframe2->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
single_value.field_message__MyTestframe3->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
single_value.field_message__MyTestframe4->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
single_value.field_message__MyTestframe5->encode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
single_value.field_message__extendedFrame1->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
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 @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}

void CAN__MatrixPayloadUnion_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
{
single_value.union_selection = CAN__MatrixPayloadUnion::UNBOUND_VALUE;
CAN__MatrixPayloadUnion::union_selection_type new_selection = (CAN__MatrixPayloadUnion::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
single_value.field_message__MyTestframe0 = new CAN__MESSAGE__TESTFRAME0__msg__type_template;
single_value.field_message__MyTestframe0->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
single_value.field_message__MyTestframe1 = new CAN__MESSAGE__TESTFRAME1__msg__type_template;
single_value.field_message__MyTestframe1->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
single_value.field_message__MyTestframe2 = new CAN__MESSAGE__TESTFRAME2__msg__type_template;
single_value.field_message__MyTestframe2->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
single_value.field_message__MyTestframe3 = new CAN__MESSAGE__TESTFRAME3__msg__type_template;
single_value.field_message__MyTestframe3->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
single_value.field_message__MyTestframe4 = new CAN__MESSAGE__TESTFRAME4__msg__type_template;
single_value.field_message__MyTestframe4->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
single_value.field_message__MyTestframe5 = new CAN__MESSAGE__TESTFRAME5__msg__type_template;
single_value.field_message__MyTestframe5->decode_text(text_buf);
break;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
single_value.field_message__extendedFrame1 = new CAN__MESSAGE__EXTENDEDFRAME1__msg__type_template;
single_value.field_message__extendedFrame1->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
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 CAN__MatrixPayloadUnion_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 @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
}

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

boolean CAN__MatrixPayloadUnion_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 CAN__MatrixPayloadUnion_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 `@CAN_matrix_messages.CAN_MatrixPayloadUnion'");
    }
    if (strcmp("message_MyTestframe0", param_field) == 0) {
      message__MyTestframe0().set_param(param);
      return;
    } else if (strcmp("message_MyTestframe1", param_field) == 0) {
      message__MyTestframe1().set_param(param);
      return;
    } else if (strcmp("message_MyTestframe2", param_field) == 0) {
      message__MyTestframe2().set_param(param);
      return;
    } else if (strcmp("message_MyTestframe3", param_field) == 0) {
      message__MyTestframe3().set_param(param);
      return;
    } else if (strcmp("message_MyTestframe4", param_field) == 0) {
      message__MyTestframe4().set_param(param);
      return;
    } else if (strcmp("message_MyTestframe5", param_field) == 0) {
      message__MyTestframe5().set_param(param);
      return;
    } else if (strcmp("message_extendedFrame1", param_field) == 0) {
      message__extendedFrame1().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@CAN_matrix_messages.CAN_MatrixPayloadUnion'", 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: {
    CAN__MatrixPayloadUnion_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", "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
    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, "message_MyTestframe0")) {
      message__MyTestframe0().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_MyTestframe1")) {
      message__MyTestframe1().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_MyTestframe2")) {
      message__MyTestframe2().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_MyTestframe3")) {
      message__MyTestframe3().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_MyTestframe4")) {
      message__MyTestframe4().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_MyTestframe5")) {
      message__MyTestframe5().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "message_extendedFrame1")) {
      message__extendedFrame1().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @CAN_matrix_messages.CAN_MatrixPayloadUnion.", last_name);
  } break;
  default:
    param.type_error("union template", "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MatrixPayloadUnion_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
single_value.field_message__MyTestframe0->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
single_value.field_message__MyTestframe1->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
single_value.field_message__MyTestframe2->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
single_value.field_message__MyTestframe3->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
single_value.field_message__MyTestframe4->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
single_value.field_message__MyTestframe5->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
case CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
single_value.field_message__extendedFrame1->check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @CAN_matrix_messages.CAN_MatrixPayloadUnion.");
}
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 : "@CAN_matrix_messages.CAN_MatrixPayloadUnion");
}

CAN__MatrixUnion::CAN__MatrixUnion()
{
}

CAN__MatrixUnion::CAN__MatrixUnion(const OCTETSTRING& par_can__id,
    const CAN__MatrixPayloadUnion& par_can__pdu)
  :   field_can__id(par_can__id),
  field_can__pdu(par_can__pdu)
{
}

CAN__MatrixUnion::CAN__MatrixUnion(const CAN__MatrixUnion& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @CAN_matrix_messages.CAN_MatrixUnion.");
if (other_value.can__id().is_bound()) field_can__id = other_value.can__id();
else field_can__id.clean_up();
if (other_value.can__pdu().is_bound()) field_can__pdu = other_value.can__pdu();
else field_can__pdu.clean_up();
}

void CAN__MatrixUnion::clean_up()
{
field_can__id.clean_up();
field_can__pdu.clean_up();
}

const TTCN_Typedescriptor_t* CAN__MatrixUnion::get_descriptor() const { return &CAN__MatrixUnion_descr_; }
CAN__MatrixUnion& CAN__MatrixUnion::operator=(const CAN__MatrixUnion& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @CAN_matrix_messages.CAN_MatrixUnion.");
  if (other_value.can__id().is_bound()) field_can__id = other_value.can__id();
  else field_can__id.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__MatrixUnion::operator==(const CAN__MatrixUnion& other_value) const
{
return field_can__id==other_value.field_can__id
  && field_can__pdu==other_value.field_can__pdu;
}

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

void CAN__MatrixUnion::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 @CAN_matrix_messages.CAN_MatrixUnion 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__id().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_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__id().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "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 @CAN_matrix_messages.CAN_MatrixUnion: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@CAN_matrix_messages.CAN_MatrixUnion");
  }
}

void CAN__MatrixUnion::set_implicit_omit()
{
if (can__id().is_bound()) can__id().set_implicit_omit();
if (can__pdu().is_bound()) can__pdu().set_implicit_omit();
}

void CAN__MatrixUnion::encode_text(Text_Buf& text_buf) const
{
field_can__id.encode_text(text_buf);
field_can__pdu.encode_text(text_buf);
}

void CAN__MatrixUnion::decode_text(Text_Buf& text_buf)
{
field_can__id.decode_text(text_buf);
field_can__pdu.decode_text(text_buf);
}

void CAN__MatrixUnion::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__MatrixUnion::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__MatrixUnion::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, Can::CAN__id_descr_.raw->forceomit);
  decoded_field_length = field_can__id.RAW_decode(Can::CAN__id_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__id ==  os_0) selected_field = 0;
  else if (field_can__id ==  os_1) selected_field = 1;
  else if (field_can__id ==  os_2) selected_field = 2;
  else if (field_can__id ==  os_3) selected_field = 3;
  else if (field_can__id ==  os_4) selected_field = 4;
  else if (field_can__id ==  os_5) selected_field = 5;
  else if (field_can__id ==  os_6) selected_field = 6;
  else selected_field = -1;
  RAW_Force_Omit field_1_force_omit(1, force_omit, CAN__MatrixUnion_can__pdu_descr_.raw->forceomit);
  decoded_field_length = field_can__pdu.RAW_decode(CAN__MatrixUnion_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__MatrixUnion::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, Can::CAN__id_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, CAN__MatrixUnion_can__pdu_descr_.raw);
  encoded_length += field_can__id.RAW_encode(Can::CAN__id_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_can__pdu.RAW_encode(CAN__MatrixUnion_can__pdu_descr_, *myleaf.body.node.nodes[1]);
  switch (field_can__pdu.get_selection()) {
  case CAN__MatrixPayloadUnion::ALT_message__MyTestframe0:
  if (field_can__id !=  os_0) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_0.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe1:
  if (field_can__id !=  os_1) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_1.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe2:
  if (field_can__id !=  os_2) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_2.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe3:
  if (field_can__id !=  os_3) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_3.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe4:
  if (field_can__id !=  os_4) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_4.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__MyTestframe5:
  if (field_can__id !=  os_5) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_5.RAW_encode(Can::CAN__id_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 CAN__MatrixPayloadUnion::ALT_message__extendedFrame1:
  if (field_can__id !=  os_6) {
  RAW_enc_tr_pos pr_pos;
  pr_pos.level = myleaf.curr_pos.level + 1;
  int new_pos[] = { 0 };
  pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, 1, new_pos);
  RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);
  if (temp_leaf != NULL)
     os_6.RAW_encode(Can::CAN__id_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__MatrixUnion_template::single_value_struct {
OCTETSTRING_template field_can__id;
CAN__MatrixPayloadUnion_template field_can__pdu;
};

void CAN__MatrixUnion_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__id = ANY_VALUE;
single_value->field_can__pdu = ANY_VALUE;
}
}
}

void CAN__MatrixUnion_template::copy_value(const CAN__MatrixUnion& other_value)
{
single_value = new single_value_struct;
if (other_value.can__id().is_bound()) {
  single_value->field_can__id = other_value.can__id();
} else {
  single_value->field_can__id.clean_up();
}
if (other_value.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__MatrixUnion_template::copy_template(const CAN__MatrixUnion_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.can__id().get_selection()) {
single_value->field_can__id = other_value.can__id();
} else {
single_value->field_can__id.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.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__MatrixUnion_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 @CAN_matrix_messages.CAN_MatrixUnion.");
break;
}
set_selection(other_value);
}

CAN__MatrixUnion_template::CAN__MatrixUnion_template()
{
}

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

CAN__MatrixUnion_template::CAN__MatrixUnion_template(const CAN__MatrixUnion& other_value)
{
copy_value(other_value);
}

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

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

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

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

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

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

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

boolean CAN__MatrixUnion_template::match(const CAN__MatrixUnion& 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__id().is_bound()) return FALSE;
if(!single_value->field_can__id.match(other_value.can__id(), 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 @CAN_matrix_messages.CAN_MatrixUnion.");
}
return FALSE;
}

boolean CAN__MatrixUnion_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__id.is_bound()

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

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

void CAN__MatrixUnion_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__MatrixUnion CAN__MatrixUnion_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 @CAN_matrix_messages.CAN_MatrixUnion.");
CAN__MatrixUnion ret_val;
if (single_value->field_can__id.is_bound()) {
ret_val.can__id() = single_value->field_can__id.valueof();
}
if (single_value->field_can__pdu.is_bound()) {
ret_val.can__pdu() = single_value->field_can__pdu.valueof();
}
return ret_val;
}

void CAN__MatrixUnion_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 @CAN_matrix_messages.CAN_MatrixUnion.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new CAN__MatrixUnion_template[list_length];
}

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

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

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

CAN__MatrixPayloadUnion_template& CAN__MatrixUnion_template::can__pdu()
{
set_specific();
return single_value->field_can__pdu;
}

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

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

void CAN__MatrixUnion_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ can_id := ");
single_value->field_can__id.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__MatrixUnion_template::log_match(const CAN__MatrixUnion& 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__id.match(match_value.can__id(), legacy)){
TTCN_Logger::log_logmatch_info(".can_id");
single_value->field_can__id.log_match(match_value.can__id(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_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_id := ");
single_value->field_can__id.log_match(match_value.can__id(), 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__MatrixUnion_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_can__id.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 @CAN_matrix_messages.CAN_MatrixUnion.");
}
}

void CAN__MatrixUnion_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__id.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__MatrixUnion_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 @CAN_matrix_messages.CAN_MatrixUnion.");
}
}

void CAN__MatrixUnion_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__MatrixUnion_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 @CAN_matrix_messages.CAN_MatrixUnion 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__id().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_id")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          can__id().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "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 @CAN_matrix_messages.CAN_MatrixUnion: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@CAN_matrix_messages.CAN_MatrixUnion");
  }
  is_ifpresent = param.get_ifpresent();
}

void CAN__MatrixUnion_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__id.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixUnion");
single_value->field_can__pdu.check_restriction(t_res, t_name ? t_name : "@CAN_matrix_messages.CAN_MatrixUnion");
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 : "@CAN_matrix_messages.CAN_MatrixUnion");
}

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

boolean CAN__MatrixUnion_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 static functions */

static void pre_init_module()
{
TTCN_Location current_location("CAN_matrix_messages.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "CAN_matrix_messages");
Can::module_object.pre_init_module();
CAN__matrix__signals::module_object.pre_init_module();
}

static void post_init_module()
{
TTCN_Location current_location("CAN_matrix_messages.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "CAN_matrix_messages");
Can::module_object.post_init_module();
CAN__matrix__signals::module_object.post_init_module();
}


} /* end of namespace */
