diff --git a/compiler2/Type.cc b/compiler2/Type.cc index 3f59a33bcf340e1c253779fd2bcd387d7485e1d7..2a02327609d93e9f577363f213406282d11fe261 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -2611,14 +2611,42 @@ namespace Common { case T_INT: case T_INT_A: break; + case T_BSTR: + case T_BSTR_A: + case T_OSTR: + if ((rawpar->fieldlength < 1 && ft->get_sub_type() == NULL) || + (rawpar->fieldlength < 1 && ft->get_sub_type()->get_length_restriction() < 1)) { + error("The length of `%s' field must be specified either with `length()` " + "subtyping or with the `FIELDLENGTH` attribute", + field_id.get_dispname().c_str()); + } + break; case T_CHOICE_T: case T_CHOICE_A: for (size_t fi = 0; fi < ft->get_nof_comps(); fi++) { - typetype_t uftt = ft->get_comp_byIndex(fi)->get_type() - ->get_typetype(); - if (uftt != T_INT && uftt != T_INT_A) - error("The union type LENGTHTO field must contain only " - "integer fields"); + Type *uft = ft->get_comp_byIndex(fi)->get_type(); + typetype_t uftt = uft->get_typetype(); + switch (uftt) { + case T_INT: + case T_INT_A: + break; + case T_BSTR: + case T_BSTR_A: + case T_OSTR: + if ((uft->rawattrib == NULL && ft->get_sub_type() == NULL) || + (uft->rawattrib == NULL && ft->get_sub_type()->get_length_restriction() < 1) || + (uft->rawattrib->fieldlength < 1 && ft->get_sub_type() == NULL) || + (uft->rawattrib->fieldlength < 1 && ft->get_sub_type()->get_length_restriction() < 1)) { + error("The length of `%s' field must be specified either with `length()` " + "subtyping or with the `FIELDLENGTH` attribute", + ft->get_comp_byIndex(fi)->get_name().get_dispname().c_str()); + } + break; + default: + error("The union type LENGTHTO field must contain only " + "integer, bitstring or octetstring fields"); + break; + } } break; case T_ANYTYPE: @@ -2630,7 +2658,7 @@ namespace Common { if (rawpar->lengthindex) break; // Will be checked in the next step. // Else continue with default. default: - error("The LENGTHTO field must be an integer or union type " + error("The LENGTHTO field must be an integer, bitstring, octetstring or union type " "instead of `%s'", ft->get_typename().c_str()); break; } diff --git a/compiler2/record.c b/compiler2/record.c index 9565222957b2450f28ca0c51f03752d82031ed68..6237c8a81fee64bc63a0abe3653777d0daa09635 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -751,6 +751,9 @@ char* generate_raw_coding(char* src, } src = mputprintf(src, " if (myleaf.body.node.nodes[%lu]->body.node.nodes[%d]) {\n" + " myleaf.body.node.nodes[%lu]->body.node.nodes[%d] = " + "new RAW_enc_tree(TRUE, myleaf.body.node.nodes[%lu], " + "&(myleaf.body.node.nodes[%lu]->curr_pos), %d, %s_descr_.raw);\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->" "calc = CALC_LENGTH;\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->" @@ -766,6 +769,9 @@ char* generate_raw_coding(char* src, "init_lengthto_fields_list(%d);\n", (unsigned long)i, sdef->elements[i].raw.lengthindex->nthfield, (unsigned long)i, sdef->elements[i].raw.lengthindex->nthfield, + (unsigned long)i, (unsigned long)i, + sdef->elements[i].raw.lengthindex->nthfield, sdef->elements[i].raw.lengthindex->typedescr, + (unsigned long)i, sdef->elements[i].raw.lengthindex->nthfield, (unsigned long)i, sdef->elements[i].raw.lengthindex->nthfield, sdef->elements[i].raw.lengthindex->typedescr, (unsigned long)i, sdef->elements[i].raw.lengthindex->nthfield, @@ -823,9 +829,16 @@ char* generate_raw_coding(char* src, " int sel_field = 0;\n" " while (myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field] == NULL) " "{ sel_field++; }\n" + " const TTCN_Typedescriptor_t* tmpTypeDesc = myleaf.body.node.nodes[%lu]->" + "body.node.nodes[sel_field]->coding_descr;\n" + " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field] = " + "new RAW_enc_tree(TRUE, myleaf.body.node.nodes[%lu], " + "&(myleaf.body.node.nodes[%lu]->curr_pos), sel_field, tmpTypeDesc->raw);\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->" "calc = CALC_LENGTH;\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->" + "coding_descr = tmpTypeDesc;\n" + " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->" "calcof.lengthto.num_of_fields = %d;\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->" "calcof.lengthto.unit = %d;\n" @@ -833,7 +846,8 @@ char* generate_raw_coding(char* src, "calcof.lengthto.offset = %d;\n" " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->" "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n", - (unsigned long)i,(unsigned long)i, + (unsigned long)i,(unsigned long)i,(unsigned long)i,(unsigned long)i, + (unsigned long)i,(unsigned long)i,(unsigned long)i, (unsigned long)i,sdef->elements[i].raw.lengthto_num, (unsigned long)i,sdef->elements[i].raw.unit, (unsigned long)i,sdef->elements[i].raw.lengthto_offset, @@ -5636,23 +5650,20 @@ static char *genRawDecodeRecordField(char *src, const struct_def *sdef, ,sdef->elements[i].raw.lengthindex->nthfieldname ); } + src = mputprintf(src, " INTEGER tmp = field_%s%s.%s%s().convert_to_Integer(%s_descr_);\n", + sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", + sdef->elements[i].raw.lengthindex->nthfieldname, + sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD ? "()" : "", + sdef->elements[i].raw.lengthindex->typedescr); if (sdef->elements[i].raw.lengthto_offset != 0) { - src = mputprintf(src, " field_%s%s.%s%s() = field_%s%s.%s%s() - %d;\n", - sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.lengthindex->nthfieldname, - sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD ? "()" : "", - sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.lengthindex->nthfieldname, - sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD ? "()" : "", - sdef->elements[i].raw.lengthto_offset); + src = mputprintf(src, " tmp = tmp - %d;\n", sdef->elements[i].raw.lengthto_offset); } - src=mputprintf(src, - " value_of_length_field%d+=field_%s%s.%s%s().get_long_long_val()*%d;\n" - ,i,sdef->elements[i].name,sdef->elements[i].isOptional?"()":"" - ,sdef->elements[i].raw.lengthindex->nthfieldname - ,sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD?"()":"" - ,sdef->elements[i].raw.unit==-1?1:sdef->elements[i].raw.unit - ); + src = mputprintf(src, " field_%s%s.%s%s() = tmp;\n", + sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", + sdef->elements[i].raw.lengthindex->nthfieldname, + sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD ? "()" : ""); + src = mputprintf(src, " value_of_length_field%d += tmp.get_long_long_val() * %d;\n", + i, sdef->elements[i].raw.unit == -1 ? 1 : sdef->elements[i].raw.unit); if(sdef->elements[i].raw.lengthindex->fieldtype == OPTIONAL_FIELD){ src=mputstr(src, " }\n" @@ -5662,41 +5673,43 @@ static char *genRawDecodeRecordField(char *src, const struct_def *sdef, else if(sdef->elements[i].raw.union_member_num){ int m; src = mputprintf(src, " switch (field_%s%s.get_selection()) {\n", - sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : ""); + sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : ""); for (m = 1; m < sdef->elements[i].raw.union_member_num + 1; m++) { - src = mputprintf(src, " case %s%s%s:\n", sdef->elements[i].raw.member_name[0], - "::ALT_", sdef->elements[i].raw.member_name[m]); - if (sdef->elements[i].raw.lengthto_offset != 0) { - src = mputprintf(src, " field_%s%s.%s() = field_%s%s.%s() - %d;\n", - sdef->elements[i].name, - sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.member_name[m], sdef->elements[i].name, - sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.member_name[m], sdef->elements[i].raw.lengthto_offset); - } - src = mputprintf(src, - " value_of_length_field%d += field_%s%s.%s().get_long_long_val() * %d;\n" - " break;\n", i, sdef->elements[i].name, - sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.member_name[m], - sdef->elements[i].raw.unit == -1 ? 1 : sdef->elements[i].raw.unit); + src = mputprintf(src, " case %s%s%s: {\n", sdef->elements[i].raw.member_name[0], + "::ALT_", sdef->elements[i].raw.member_name[m]); + src = mputprintf(src, " INTEGER tmp%d = field_%s%s.%s().convert_to_Integer(%s_%s_descr_);\n", + m, sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", + sdef->elements[i].raw.member_name[m], sdef->elements[i].type, + sdef->elements[i].raw.member_name[m]); + if (sdef->elements[i].raw.lengthto_offset != 0) { + src = mputprintf(src, " tmp%d = tmp%d - %d;\n", + m, m, sdef->elements[i].raw.lengthto_offset); + } + src = mputprintf(src, " field_%s%s.%s() = tmp%d;\n", + sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", + sdef->elements[i].raw.member_name[m], m); + src = mputprintf(src, + " value_of_length_field%d += tmp%d.get_long_long_val() * %d;\n" + " break; }\n", + i, m, sdef->elements[i].raw.unit == -1 ? 1 : sdef->elements[i].raw.unit); } src = mputprintf(src, " default:\n" - " value_of_length_field%d = 0;\n" - " }\n", i); + " value_of_length_field%d = 0;\n" + " }\n", i); } else{ + src = mputprintf(src, " INTEGER tmp%d = field_%s%s.convert_to_Integer(%s_descr_);\n", + i, sdef->elements[i].name, + sdef->elements[i].isOptional ? "()" : "", sdef->elements[i].typedescrname); if (sdef->elements[i].raw.lengthto_offset != 0) { - src = mputprintf(src, " field_%s%s = field_%s%s - %d;\n", - sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", - sdef->elements[i].raw.lengthto_offset); + src = mputprintf(src, " tmp%d = tmp%d - %d;\n", + i, i, sdef->elements[i].raw.lengthto_offset); } - src=mputprintf(src, - " value_of_length_field%d+=field_%s%s.get_long_long_val()*%d;\n" - ,i,sdef->elements[i].name,sdef->elements[i].isOptional?"()":"" - ,sdef->elements[i].raw.unit==-1?1:sdef->elements[i].raw.unit - ); + src = mputprintf(src, " field_%s%s = tmp%d;\n", + sdef->elements[i].name, sdef->elements[i].isOptional ? "()" : "", i); + src = mputprintf(src, + " value_of_length_field%d += tmp%d.get_long_long_val() * %d;\n", + i, i, sdef->elements[i].raw.unit == -1 ? 1 : sdef->elements[i].raw.unit); } } if(raw_options[i].pointerto){ /* store the start of pointed field*/ diff --git a/core/Bitstring.cc b/core/Bitstring.cc index 70a2b39ea0758ac18a7adbf7adb1b5bd57bce861..5bc0e6618067d20867de8fc34ac0f22b43f83331 100644 --- a/core/Bitstring.cc +++ b/core/Bitstring.cc @@ -164,6 +164,11 @@ BITSTRING& BITSTRING::operator=(const BITSTRING_ELEMENT& other_value) return *this; } +BITSTRING& BITSTRING::operator=(const INTEGER& other_value) +{ + return this->operator=(int2bit(other_value, val_ptr->n_bits)); +} + boolean BITSTRING::operator==(const BITSTRING& other_value) const { must_bound("Unbound left operand of bitstring comparison."); @@ -559,6 +564,17 @@ void BITSTRING::log() const } else TTCN_Logger::log_event_unbound(); } +INTEGER BITSTRING::convert_to_Integer(const TTCN_Typedescriptor_t& p_td) +{ + TTCN_EncDec_ErrorContext ec("While converting to integer type '%s': ", p_td.name); + TTCN_Buffer ttcn_buf; + encode(p_td, ttcn_buf, TTCN_EncDec::CT_RAW, 0); + raw_order_t order = p_td.raw->top_bit_order == TOP_BIT_LEFT ? ORDER_LSB : ORDER_MSB; + INTEGER integer; + integer.RAW_decode(p_td, ttcn_buf, ttcn_buf.get_len() * 8, order); + return integer; +} + void BITSTRING::set_param(Module_Param& param) { param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "bitstring value"); Module_Param_Ptr mp = ¶m; diff --git a/core/Bitstring.hh b/core/Bitstring.hh index b6301a292c405a69023259b97a9f20ae8d84863f..8677626f5da0f735fab86dd4f75e948a69ecd026 100644 --- a/core/Bitstring.hh +++ b/core/Bitstring.hh @@ -101,6 +101,7 @@ public: BITSTRING& operator=(const BITSTRING& other_value); BITSTRING& operator=(const BITSTRING_ELEMENT& other_value); + BITSTRING& operator=(const INTEGER& other_value); boolean operator==(const BITSTRING& other_value) const; boolean operator==(const BITSTRING_ELEMENT& other_value) const; @@ -146,6 +147,8 @@ public: void log() const; + INTEGER convert_to_Integer(const TTCN_Typedescriptor_t&); + #ifdef TITAN_RUNTIME_2 boolean is_equal(const Base_Type* other_value) const { return *this == *(static_cast(other_value)); } void set_value(const Base_Type* other_value) { *this = *(static_cast(other_value)); } diff --git a/core/Integer.hh b/core/Integer.hh index 25d0f9aa07c53936c11d98fe2424a1c39aab71db..1ffe2aadf34280c3b03cd340cb54d69ff9b2acbc 100644 --- a/core/Integer.hh +++ b/core/Integer.hh @@ -137,6 +137,8 @@ public: void log() const; + inline INTEGER convert_to_Integer(const TTCN_Typedescriptor_t&) { return *this; } + #ifdef TITAN_RUNTIME_2 boolean is_equal(const Base_Type* other_value) const { return *this == *(static_cast(other_value)); } void set_value(const Base_Type* other_value) { *this = *(static_cast(other_value)); } diff --git a/core/Octetstring.cc b/core/Octetstring.cc index 49d67a2af6123a05e4da0fc745c4b6fd34e1eaaa..3bbef5e25d67054d6186a8a05db6de805dac25e6 100644 --- a/core/Octetstring.cc +++ b/core/Octetstring.cc @@ -142,6 +142,11 @@ OCTETSTRING& OCTETSTRING::operator=(const OCTETSTRING_ELEMENT& other_value) return *this; } +OCTETSTRING& OCTETSTRING::operator=(const INTEGER& other_value) +{ + return this->operator=(int2oct(other_value, val_ptr->n_octets)); +} + boolean OCTETSTRING::operator==(const OCTETSTRING& other_value) const { must_bound("Unbound left operand of octetstring comparison."); @@ -517,6 +522,16 @@ void OCTETSTRING::log() const } else TTCN_Logger::log_event_unbound(); } +INTEGER OCTETSTRING::convert_to_Integer(const TTCN_Typedescriptor_t& p_td) +{ + TTCN_EncDec_ErrorContext ec("While converting to integer type '%s': ", p_td.name); + TTCN_Buffer ttcn_buf(*this); + raw_order_t order = p_td.raw->top_bit_order == TOP_BIT_LEFT ? ORDER_LSB : ORDER_MSB; + INTEGER integer; + integer.RAW_decode(p_td, ttcn_buf, ttcn_buf.get_len() * 8, order); + return integer; +} + void OCTETSTRING::set_param(Module_Param& param) { param.basic_check(Module_Param::BC_VALUE|Module_Param::BC_LIST, "octetstring value"); Module_Param_Ptr mp = ¶m; diff --git a/core/Octetstring.hh b/core/Octetstring.hh index 99390f2dd5eb0994b7ff3f2be95b80b98fcdb256..7b349549633b0bf363efcbf5fb81281b5fff95e7 100644 --- a/core/Octetstring.hh +++ b/core/Octetstring.hh @@ -80,6 +80,7 @@ public: OCTETSTRING& operator=(const OCTETSTRING& other_value); OCTETSTRING& operator=(const OCTETSTRING_ELEMENT& other_value); + OCTETSTRING& operator=(const INTEGER& other_value); boolean operator==(const OCTETSTRING& other_value) const; boolean operator==(const OCTETSTRING_ELEMENT& other_value) const; @@ -127,6 +128,8 @@ public: operator const unsigned char*() const; void dump () const; + INTEGER convert_to_Integer(const TTCN_Typedescriptor_t&); + #ifdef TITAN_RUNTIME_2 boolean is_equal(const Base_Type* other_value) const { return *this == *(static_cast(other_value)); } void set_value(const Base_Type* other_value) { *this = *(static_cast(other_value)); } diff --git a/core/Template.cc b/core/Template.cc index 53a9f3f05a4970320477cf5e44dd5486a771be42..eaaf18cb7468901f3e33794c3b68958b38813c86 100644 --- a/core/Template.cc +++ b/core/Template.cc @@ -2181,6 +2181,9 @@ int Set_Of_Template::n_elem() const case VALUE_RANGE: case STRING_PATTERN: case DECODE_MATCH: + case CONJUNCTION_MATCH: + case IMPLICATION_MATCH: + case DYNAMIC_MATCH: break; } TTCN_error("Performing n_elem() operation on an uninitialized/unsupported " diff --git a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script index d2731de4a1db4e6eadfac862e23b3c7f83985346..4e2073434e31d8d1cb6961293b102e322e3eab7a 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script @@ -7756,10 +7756,10 @@ type record myr5 { (?is)\berror: The union type LENGTHTO field must contain only integer fields -(?is)\berror: The LENGTHTO field must be an integer or union type instead of `\@Temp.mylist' +(?is)\berror: The LENGTHTO field must be an integer, bitstring, octetstring or union type instead of `\@Temp.mylist' -(?is)\berror: The LENGTHTO field must be an integer or union type instead of `charstring' +(?is)\berror: The LENGTHTO field must be an integer, bitstring, octetstring or union type instead of `charstring' (?is)\berror: diff --git a/regression_test/EncodeDecode/RAW/Bug546231/Bug546231.ttcn b/regression_test/EncodeDecode/RAW/Bug546231/Bug546231.ttcn index 39577bf50ab19ff79280661c4da0af31300845a3..130c46e5ffa33bd87b133466c4ab1a7cb80cc6b7 100644 --- a/regression_test/EncodeDecode/RAW/Bug546231/Bug546231.ttcn +++ b/regression_test/EncodeDecode/RAW/Bug546231/Bug546231.ttcn @@ -16,6 +16,12 @@ module Bug546231 { external function dec_R2(in octetstring stream) return R2 with { extension "prototype(convert)" extension "decode(RAW)" } +external function dec_R2_Octet(in octetstring stream) return R2_Octet +with { extension "prototype(convert)" extension "decode(RAW)" } + +external function dec_R2_Bit(in octetstring stream) return R2_Bit +with { extension "prototype(convert)" extension "decode(RAW)" } + type record R2 { integer lengthfield, record of integer listfield, @@ -25,6 +31,24 @@ type record R2 { variant (lengthfield) "UNIT(elements)" } +type record R2_Octet { + octetstring lengthfield length(1), + record of integer listfield, + integer last_field +} with { + variant (lengthfield) "LENGTHTO(listfield)" + variant (lengthfield) "UNIT(elements)" +} + +type record R2_Bit { + bitstring lengthfield length(8), + record of integer listfield, + integer last_field +} with { + variant (lengthfield) "LENGTHTO(listfield)" + variant (lengthfield) "UNIT(elements)" +} + type component CT {}; testcase tc1() runs on CT { @@ -49,9 +73,57 @@ testcase tc2() runs on CT { } } +testcase tc1_Octet() runs on CT { + var R2_Octet res := dec_R2_Octet('0000'O); + var R2_Octet exp := { lengthfield := '00'O, listfield := { }, last_field := 0 }; + if (res == exp) { + setverdict(pass); + } + else { + setverdict(fail, "Got: ", res, ", expected: ", exp); + } +} + +testcase tc2_Octet() runs on CT { + var R2_Octet res := dec_R2_Octet('010102'O); + var R2_Octet exp := { lengthfield := '01'O, listfield := { 1 }, last_field := 2 }; + if (res == exp) { + setverdict(pass); + } + else { + setverdict(fail, "Got: ", res, ", expected: ", exp); + } +} + +testcase tc1_Bit() runs on CT { + var R2_Bit res := dec_R2_Bit('0000'O); + var R2_Bit exp := { lengthfield := '00000000'B, listfield := { }, last_field := 0 }; + if (res == exp) { + setverdict(pass); + } + else { + setverdict(fail, "Got: ", res, ", expected: ", exp); + } +} + +testcase tc2_Bit() runs on CT { + var R2_Bit res := dec_R2_Bit('010102'O); + var R2_Bit exp := { lengthfield := '00000001'B, listfield := { 1 }, last_field := 2 }; + if (res == exp) { + setverdict(pass); + } + else { + setverdict(fail, "Got: ", res, ", expected: ", exp); + } +} + control { execute(tc1()); execute(tc2()); + execute(tc1_Octet()); + execute(tc2_Octet()); + execute(tc1_Bit()); + execute(tc2_Bit()); } } with { diff --git a/regression_test/EncodeDecode/RAW/Bug572603/Bug572603.ttcn b/regression_test/EncodeDecode/RAW/Bug572603/Bug572603.ttcn index fbfc349472a9721685c92cd974e308b72be3ba77..7338b44007b925cccadf9563de4974eb3c6c59aa 100644 --- a/regression_test/EncodeDecode/RAW/Bug572603/Bug572603.ttcn +++ b/regression_test/EncodeDecode/RAW/Bug572603/Bug572603.ttcn @@ -14,7 +14,7 @@ module Bug572603 { type record UnknownIE { integer ie_code, - integer ie_length, + octetstring ie_length length(1), octetstring ie_data } with { variant (ie_length) "LENGTHTO(ie_data)" @@ -46,7 +46,7 @@ type record of IE2 IE2_list type record IE3 { integer ie_code, - integer ie_length, + bitstring ie_length length(8), octetstring ie_data } with { variant "PRESENCE(ie_code = 3)" @@ -75,7 +75,7 @@ with { extension "prototype(convert)" extension "decode(RAW)" } type component CT {} testcase tc_bug572603() runs on CT { - var PDU v_pdu1 := { f_ie1 := { 1, 1, 'AA'O }, f_ie2_list := { { 2, 1, 'BB'O }, { 2, 1, 'BB'O } }, f_ie3 := { 3, 1, 'CC'O }, f_other := { { 4, 1, 'DD'O } } } + var PDU v_pdu1 := { f_ie1 := { 1, 1, 'AA'O }, f_ie2_list := { { 2, 1, 'BB'O }, { 2, 1, 'BB'O } }, f_ie3 := { 3, '00000001'B, 'CC'O }, f_other := { { 4, '01'O, 'DD'O } } } var PDU v_pdu2 var octetstring v_oct := '0101AA0201BB0401DD0201BB0301CC'O; v_pdu2 := dec_PDU(v_oct); diff --git a/regression_test/EncodeDecode/RAW/Lengthto_Offset/Lengthto_Offset.ttcn b/regression_test/EncodeDecode/RAW/Lengthto_Offset/Lengthto_Offset.ttcn index 90c27c07c8b4e72a9e64aa17b4fd7b4d08df045f..aca0e983e109ee512ebd83e00171e20f024287c2 100644 --- a/regression_test/EncodeDecode/RAW/Lengthto_Offset/Lengthto_Offset.ttcn +++ b/regression_test/EncodeDecode/RAW/Lengthto_Offset/Lengthto_Offset.ttcn @@ -42,6 +42,64 @@ testcase tc1() runs on CT { setverdict(pass); } +type record Rec1_Octet { + octetstring len, + octetstring data +} +with { + variant (len) "LENGTHTO(data) + 1"; + variant (len) "FIELDLENGTH(1)" +} + +testcase tc1_Octet() runs on CT { + var Rec1_Octet val := { '00'O, '12345678'O }; + var bitstring enc_exp := oct2bit('0512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec1_Octet dec_exp := { int2oct(lengthof(val.data), 1), val.data }; + var Rec1_Octet dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +type record Rec1_Bit { + bitstring len, + octetstring data +} +with { + variant (len) "LENGTHTO(data) + 1"; + variant (len) "FIELDLENGTH(8)" +} + +testcase tc1_Bit() runs on CT { + var Rec1_Bit val := { '00000000'B, '12345678'O }; + var bitstring enc_exp := oct2bit('0512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec1_Bit dec_exp := { int2bit(lengthof(val.data), 8), val.data }; + var Rec1_Bit dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + type record Rec2 { integer len, bitstring data1, @@ -72,6 +130,69 @@ testcase tc2() runs on CT { setverdict(pass); } +type record Rec2_Octet { + octetstring len, + bitstring data1, + octetstring data2 +} +with { + variant (len) "LENGTHTO(data1, data2) - 2"; + variant (len) "FIELDLENGTH(1)"; + variant (data1) "FIELDLENGTH(8)"; +} + + +testcase tc2_Octet() runs on CT { + var Rec2_Octet val := { '00'O, '10010101'B, '12345678'O }; + var bitstring enc_exp := oct2bit('039512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec2_Octet dec_exp := { int2oct(lengthof(val.data1) / 8 + lengthof(val.data2), 1), val.data1, val.data2 }; + var Rec2_Octet dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +type record Rec2_Bit { + bitstring len, + bitstring data1, + octetstring data2 +} +with { + variant (len) "LENGTHTO(data1, data2) - 2"; + variant (len) "FIELDLENGTH(8)"; + variant (data1) "FIELDLENGTH(8)"; +} + +testcase tc2_Bit() runs on CT { + var Rec2_Bit val := { '00000000'B, '10010101'B, '12345678'O }; + var bitstring enc_exp := oct2bit('039512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec2_Bit dec_exp := { int2bit(lengthof(val.data1) / 8 + lengthof(val.data2), 8), val.data1, val.data2 }; + var Rec2_Bit dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + type record Rec3 { union { integer i1, integer i2 } len, bitstring data1, @@ -102,10 +223,86 @@ testcase tc3() runs on CT { setverdict(pass); } +type union length_octet { octetstring i1, octetstring i2 } with { + variant (i1) "FIELDLENGTH(1)"; + variant (i2) "FIELDLENGTH(2)"; +} + +type record Rec3_Octet { + length_octet len, + bitstring data1, + octetstring data2 +} +with { + variant (len) "LENGTHTO(data1, data2) + 10"; + variant (data1) "FIELDLENGTH(8)"; +} + +testcase tc3_Octet() runs on CT { + var Rec3_Octet val := { { i1 := '00'O }, '10010101'B, '12345678'O }; + var bitstring enc_exp := oct2bit('0F9512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec3_Octet dec_exp := { { i1 := int2oct(lengthof(val.data1) / 8 + lengthof(val.data2), 1) }, val.data1, val.data2 }; + var Rec3_Octet dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +type union length_bit { bitstring i1, bitstring i2 } with { + variant (i1) "FIELDLENGTH(8)"; + variant (i2) "FIELDLENGTH(12)"; +} + +type record Rec3_Bit { + length_bit len, + bitstring data1, + octetstring data2 +} +with { + variant (len) "LENGTHTO(data1, data2) + 10"; + variant (data1) "FIELDLENGTH(8)"; +} + +testcase tc3_Bit() runs on CT { + var Rec3_Bit val := { { i1 := '00000000'B }, '10010101'B, '12345678'O }; + var bitstring enc_exp := oct2bit('0F9512345678'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var Rec3_Bit dec_exp := { { i1 := int2bit(lengthof(val.data1) / 8 + lengthof(val.data2), 8) }, val.data1, val.data2 }; + var Rec3_Bit dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + control { execute(tc1()); execute(tc2()); execute(tc3()); + execute(tc1_Octet()); + execute(tc2_Octet()); + execute(tc3_Octet()); + execute(tc1_Bit()); + execute(tc2_Bit()); + execute(tc3_Bit()); } } diff --git a/regression_test/EncodeDecode/RAW/RAW_EncDec/Makefile b/regression_test/EncodeDecode/RAW/RAW_EncDec/Makefile index 3a947d229c2ce39b2a513be619edab00ed7b94cb..0fa79a65b44595bba7249f99a62b16f40c73d81c 100644 --- a/regression_test/EncodeDecode/RAW/RAW_EncDec/Makefile +++ b/regression_test/EncodeDecode/RAW/RAW_EncDec/Makefile @@ -24,7 +24,7 @@ include $(TOPDIR)/Makefile.regression TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) -TTCN3_MODULES = RAW_EncDec_1.ttcn RAW_EncDec_2.ttcn RAW_EncDec_3.ttcn RAW_EncDec_4.ttcn RAW_EncDec_5.ttcn RAW_EncDec_6.ttcn RAW_EncDec_7.ttcn RAW_EncDec_8.ttcn +TTCN3_MODULES = RAW_EncDec_1.ttcn RAW_EncDec_2.ttcn RAW_EncDec_3.ttcn RAW_EncDec_4.ttcn RAW_EncDec_5.ttcn RAW_EncDec_6.ttcn RAW_EncDec_7.ttcn RAW_EncDec_8.ttcn RAW_EncDec_Lengthto.ttcn ASN1_MODULES = diff --git a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec.cfg b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec.cfg index 11b98d3fd9e04c05e093a36549e0bdef6de6bf9a..9ca99bb876686e93d3e51b84e3f285225f91cd1e 100644 --- a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec.cfg +++ b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec.cfg @@ -24,4 +24,5 @@ RAW_EncDec_4 RAW_EncDec_5 RAW_EncDec_6 RAW_EncDec_7 -RAW_EncDec_8 \ No newline at end of file +RAW_EncDec_8 +RAW_EncDec_Lengthto \ No newline at end of file diff --git a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_1.ttcn b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_1.ttcn index 771d5bbb762055c7b7bfb1908147661e6d3c6dae..8dae2a5a82ba7f071dc716f7544558dea1d8002b 100644 --- a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_1.ttcn +++ b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_1.ttcn @@ -4819,7 +4819,7 @@ with {variant (paramLength) "LENGTHTO(octstr , bit7 , bit1 , hexstr , int )" } type record Param2 { ParamName paramName , - integer paramLength , + octetstring paramLength length(1), OCT3_ octstr , BIT7_ bit7 , BIT1_ bit1 , @@ -4829,7 +4829,7 @@ with {variant (paramLength) "LENGTHTO(octstr , bit7 , bit1 , hexstr , int )" } type record Param3 { ParamName paramName , - integer paramLength , + bitstring paramLength length(8), OCT3_ octstr , BIT7_ bit7 , BIT1_ bit1 , @@ -5017,7 +5017,7 @@ testcase TC_structured_types_10() runs on TempComp{ int := 1 } , param3 := { paramName := name3 , - paramLength := 6 , + paramLength := '00000110'B , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , @@ -5025,7 +5025,7 @@ testcase TC_structured_types_10() runs on TempComp{ int := 1 } , param2 := { paramName := name2 , - paramLength := 6 , + paramLength := '06'O , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , @@ -5105,7 +5105,7 @@ testcase TC_structured_types_12() runs on TempComp{ int := 1 } , param3 := { paramName := name3 , - paramLength := 6 , + paramLength := '00000110'B , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , @@ -5151,7 +5151,7 @@ testcase TC_structured_types_13() runs on TempComp{ param4 := omit , param3 := { paramName := name3 , - paramLength := 6 , + paramLength := '00000110'B , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , @@ -5432,7 +5432,7 @@ testcase TC_structured_types_14() runs on TempComp{ int := 1 } , param3 := { paramName := name3 , - paramLength := 6 , + paramLength := '00000110'B , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , @@ -5482,7 +5482,7 @@ testcase TC_structured_types_15() runs on TempComp{ int := 1 } , param3 := { paramName := name3 , - paramLength := 6 , + paramLength := '00000110'B , octstr := '123456'O , bit7 := '0000000'B , bit1 := '1'B , diff --git a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_8.ttcn b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_8.ttcn index 0655421599a24debd5cf97ba51e8dcd9bb8e585b..087556a985886777c79ecc05d0e41db5434fbb07 100644 --- a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_8.ttcn +++ b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_8.ttcn @@ -23,8 +23,29 @@ module RAW_EncDec_8 { extension "prototype(convert)" extension "decode(RAW)" } - - type octetstring OCT2 length(2); + + external function enc_U_Octet(in U_Octet pl_pdu) return octetstring + with { + extension "prototype(convert)" + extension "encode(RAW)" + }; + external function dec_U_Octet(in octetstring pl_octetstring) return U_Octet + with { + extension "prototype(convert)" + extension "decode(RAW)" + } + + external function enc_U_Bit(in U_Bit pl_pdu) return octetstring + with { + extension "prototype(convert)" + extension "encode(RAW)" + }; + external function dec_U_Bit(in octetstring pl_octetstring) return U_Bit + with { + extension "prototype(convert)" + extension "decode(RAW)" + } + type record R1 { integer f1, @@ -44,6 +65,43 @@ module RAW_EncDec_8 { variant "" } + type record R1_Octet { + octetstring f1, + octetstring f2, + integer f3 + } with { + encode "RAW" + variant (f1) "FIELDLENGTH(8)" + variant (f1) "LENGTHTO(f2)" + } + + type union U_Octet { + R1_Octet u1, + octetstring u2 length(8) + } with { + encode "RAW" + variant "" + } + + type record R1_Bit { + bitstring f1, + octetstring f2, + integer f3 + } with { + encode "RAW" + variant (f1) "FIELDLENGTH(64)" + variant (f1) "LENGTHTO(f2)" + } + + type union U_Bit { + R1_Bit u1, + octetstring u2 length(8) + } with { + encode "RAW" + variant "" + } + + testcase TC_01() runs on Test_CT{ var U pl_u, pl_u_result; pl_u.u2 := 'FFFFFFFFFFFFFFFF'O; @@ -55,8 +113,32 @@ testcase TC_01() runs on Test_CT{ setverdict(pass); } +testcase TC_01_Octet() runs on Test_CT{ + var U_Octet pl_u, pl_u_result; + pl_u.u2 := 'FFFFFFFFFFFFFFFF'O; + var octetstring os := enc_U_Octet(pl_u); + pl_u_result := dec_U_Octet(os); + if (pl_u != pl_u_result) { + setverdict(fail); + } + setverdict(pass); +} + +testcase TC_01_Bit() runs on Test_CT{ + var U_Bit pl_u, pl_u_result; + pl_u.u2 := 'FFFFFFFFFFFFFFFF'O; + var octetstring os := enc_U_Bit(pl_u); + pl_u_result := dec_U_Bit(os); + if (pl_u != pl_u_result) { + setverdict(fail); + } + setverdict(pass); +} + control{ execute(TC_01()); + execute(TC_01_Octet()); + execute(TC_01_Bit()); } } diff --git a/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_Lengthto.ttcn b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_Lengthto.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..08ca515645deea8332dfbea366e9666ecea23009 --- /dev/null +++ b/regression_test/EncodeDecode/RAW/RAW_EncDec/RAW_EncDec_Lengthto.ttcn @@ -0,0 +1,812 @@ +module RAW_EncDec_Lengthto { + +type component TempComp {} + +type bitstring BIT1_ +with { variant "FIELDLENGTH(1)" } ; + +type bitstring BIT7_ +with { variant "FIELDLENGTH(7)" } ; + +type octetstring OCT3_ +with { variant "FIELDLENGTH(3)" } ; + + +type record Rec1 +{ BIT7_ data , + BIT1_ extensionbit } + with { variant "EXTENSION_BIT (yes)"}; + + +type record Rec2 +{ BIT7_ data , + BIT1_ extensionbit } + with { variant "EXTENSION_BIT (yes)"}; + + +type record Rec3 +{ BIT7_ data , + BIT1_ extensionbit } + with { variant "EXTENSION_BIT (yes)"}; + + +type record Octet1 +{ BIT7_ data , + BIT1_ extensionbit , + Rec1 rec1 , + octetstring more_extension optional } + with { variant "EXTENSION_BIT (yes)"; + variant (more_extension) "EXTENSION_BIT (yes)"}; + + +type record Octet2 +{ BIT7_ data , + BIT1_ extensionbit , + Rec2 rec2 , + octetstring more_extension optional } + with { variant "EXTENSION_BIT (yes)"; + variant (more_extension) "EXTENSION_BIT (yes)"}; + + +type record Octet3 +{ BIT7_ data , + BIT1_ extensionbit , + Rec3 rec3 , + octetstring more_extension optional } + with { variant "EXTENSION_BIT (yes)"; + variant (more_extension) "EXTENSION_BIT (yes)"}; + + +type record RAW_PDU_127_Octet +{ OCT3_ octstr , + octetstring length1 , + Octet1 oct1 , + Octet2 oct2 optional , + Octet3 oct3 optional } +with { variant (length1) "LENGTHTO(oct1, oct2, oct3)"; + variant (length1) "FIELDLENGTH(1)" } + +external function enc_RAW_PDU_127_Octet(in RAW_PDU_127_Octet pdu) return octetstring with { extension "prototype(convert) encode(RAW)" } +external function dec_RAW_PDU_127_Octet(in octetstring stream) return RAW_PDU_127_Octet with { extension "prototype(convert) decode(RAW)" } + +type record RAW_PDU_127_Bit +{ OCT3_ octstr , + bitstring length1 , + Octet1 oct1 , + Octet2 oct2 optional , + Octet3 oct3 optional } +with { variant (length1) "LENGTHTO(oct1, oct2, oct3)"; + variant (length1) "FIELDLENGTH(8)" } + +external function enc_RAW_PDU_127_Bit(in RAW_PDU_127_Bit pdu) return octetstring with { extension "prototype(convert) encode(RAW)" } +external function dec_RAW_PDU_127_Bit(in octetstring stream) return RAW_PDU_127_Bit with { extension "prototype(convert) decode(RAW)" } + +testcase TC_record_with_EXTENSION_BIT_1_Octet() runs on TempComp { + + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '0F'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + const octetstring o :='1234560F010100008002020000800303000080'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_1_Bit() runs on TempComp { + + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00001111'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + const octetstring o :='1234560F010100008002020000800303000080'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 2 +testcase TC_record_with_EXTENSION_BIT_2_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '0C'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + + const octetstring o :='1234560C010100008002820303000080'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_2_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00001100'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + + const octetstring o :='1234560C010100008002820303000080'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 3 +testcase TC_record_with_EXTENSION_BIT_3_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '09'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '1'B } , + more_extension := omit } } + + const octetstring o :='12345609010100008002820383'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_3_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00001001'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '1'B } , + more_extension := omit } } + + const octetstring o :='12345609010100008002820383'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 4 +testcase TC_record_with_EXTENSION_BIT_4_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '06'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '1'B } , + more_extension := omit } } + + const octetstring o :='12345606018102820383'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_4_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00000110'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '1'B } , + more_extension := omit } } + + const octetstring o :='12345606018102820383'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 5 +testcase TC_record_with_EXTENSION_BIT_5_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '04'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := omit } + + const octetstring o :='1234560401810282'O + + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_5_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00000100'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '1'B } , + more_extension := omit } , + oct3 := omit } + + const octetstring o :='1234560401810282'O + + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 6 +testcase TC_record_with_EXTENSION_BIT_6_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '02'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := omit , + oct3 := omit } + + const octetstring o :='123456020181'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_6_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00000010'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '1'B } , + more_extension := omit } , + oct2 := omit , + oct3 := omit } + + const octetstring o :='123456020181'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 7 +testcase TC_record_with_EXTENSION_BIT_7_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '0F'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + const octetstring o :='1234560F010100008002020000800303000080'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_7_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00001111'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := + { data := '0000011'B , + extensionbit := '0'B , + rec3 := + { data := '0000011'B , + extensionbit := '0'B } , + more_extension := '000080'O } } + + const octetstring o :='1234560F010100008002020000800303000080'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 8 +testcase TC_record_with_EXTENSION_BIT_8_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '05'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := omit , + oct3 := omit } + + const octetstring o :='123456050101000080'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_8_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00000101'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := omit , + oct3 := omit } + + const octetstring o :='123456050101000080'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + +// Test of record with EXTENSION_BIT 9 +testcase TC_record_with_EXTENSION_BIT_9_Octet() runs on TempComp { + const RAW_PDU_127_Octet + i := { octstr := '123456'O , + length1 := '0A'O , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := omit } + + const octetstring o :='1234560A01010000800202000080'O + + if ((enc_RAW_PDU_127_Octet(i) == o)and(dec_RAW_PDU_127_Octet(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Octet(i)= ", enc_RAW_PDU_127_Octet(i), "; dec_RAW_PDU_127_Octet(o)= ", dec_RAW_PDU_127_Octet(o));} +} + +testcase TC_record_with_EXTENSION_BIT_9_Bit() runs on TempComp { + const RAW_PDU_127_Bit + i := { octstr := '123456'O , + length1 := '00001010'B , + oct1 := + { data := '0000001'B , + extensionbit := '0'B , + rec1 := + { data := '0000001'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct2 := + { data := '0000010'B , + extensionbit := '0'B , + rec2 := + { data := '0000010'B , + extensionbit := '0'B } , + more_extension := '000080'O } , + oct3 := omit } + + const octetstring o :='1234560A01010000800202000080'O + + if ((enc_RAW_PDU_127_Bit(i) == o)and(dec_RAW_PDU_127_Bit(o) == i )) {setverdict(pass);} + else {setverdict(fail,"enc_RAW_PDU_127_Bit(i)= ", enc_RAW_PDU_127_Bit(i), "; dec_RAW_PDU_127_Bit(o)= ", dec_RAW_PDU_127_Bit(o));} +} + + +// Tests with units +type record Rec1_Bit { + bitstring len length(64), + octetstring data +} +with { + variant (len) "LENGTHTO(data)"; + variant (len) "UNIT(bits)" +} + +type record Rec1_Octet { + octetstring len length(8), + octetstring data +} +with { + variant (len) "LENGTHTO(data)"; + variant (len) "UNIT(bits)" +} + +testcase TC_with_units_1() runs on TempComp { + var Rec1_Bit val := { int2bit(0, 64), '01FF'O }; + var bitstring enc_exp := oct2bit('100000000000000001FF'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + var Rec1_Bit dec_exp := { int2bit(lengthof(val.data) * 8, 64), val.data }; + var Rec1_Bit dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +testcase TC_with_units_2() runs on TempComp { + var Rec1_Octet val := { int2oct(0, 8), '01FF'O }; + var bitstring enc_exp := oct2bit('100000000000000001FF'O); + var bitstring enc := encvalue(val); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + var Rec1_Octet dec_exp := { int2oct(lengthof(val.data) * 8, 8), val.data }; + var Rec1_Octet dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + + +// Tests with LENGTHINDEX +type integer INT1 +with { + variant "FIELDLENGTH(8)" +} + +type record InnerRec { + INT1 len +} +with { variant "" } + +type record OuterRec { + InnerRec lengthRec, + octetstring field +} +with { + variant (lengthRec) "LENGTHTO(field)"; + variant (lengthRec) "LENGTHINDEX(len)" +} + +testcase TC_with_lengthindex_1() runs on TempComp { + var OuterRec val := { { 0 }, '01FF'O }; + var bitstring enc_exp := oct2bit('0201FF'O); + var bitstring enc := encvalue(val); + log(bit2oct(enc_exp)); + log(bit2oct(enc)); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var OuterRec dec_exp := { { 2 }, val.field }; + var OuterRec dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +type octetstring OCT1 +with { + variant "FIELDLENGTH(1)" +} + +type record InnerRecOct { + OCT1 len +} +with { variant "" } + +type record OuterRecOct { + InnerRecOct lengthRec, + octetstring field +} +with { + variant (lengthRec) "LENGTHTO(field)"; + variant (lengthRec) "LENGTHINDEX(len)" +} + +testcase TC_with_lengthindex_2() runs on TempComp { + var OuterRecOct val := { { '00'O }, '01FF'O }; + var bitstring enc_exp := oct2bit('0201FF'O); + var bitstring enc := encvalue(val); + log(bit2oct(enc_exp)); + log(bit2oct(enc)); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var OuterRecOct dec_exp := { { '02'O }, val.field }; + var OuterRecOct dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +type bitstring BIT8 +with { + variant "FIELDLENGTH(8)" +} + +type record InnerRecBit { + BIT8 len +} +with { variant "" } + +type record OuterRecBit { + InnerRecBit lengthRec, + octetstring field +} +with { + variant (lengthRec) "LENGTHTO(field)"; + variant (lengthRec) "LENGTHINDEX(len)" +} + +testcase TC_with_lengthindex_3() runs on TempComp { + var OuterRecBit val := { { '00000000'B }, '01FF'O }; + var bitstring enc_exp := oct2bit('0201FF'O); + var bitstring enc := encvalue(val); + log(bit2oct(enc_exp)); + log(bit2oct(enc)); + if (enc_exp != enc) { + setverdict(fail, "Encoding failed. Expected: ", bit2oct(enc_exp), ", got: ", bit2oct(enc)); + } + + var OuterRecBit dec_exp := { { '00000010'B }, val.field }; + var OuterRecBit dec; + var integer res := decvalue(enc_exp, dec); + if (res != 0) { + setverdict(fail, "Invalid decoding result: ", res); + } + else if (dec_exp != dec) { + setverdict(fail, "Decoding failed. Expected: ", dec_exp, ", got: ", dec); + } + setverdict(pass); +} + +//=========================================== +// CONTROL PART +//=========================================== +control { + execute(TC_record_with_EXTENSION_BIT_1_Octet()); + execute(TC_record_with_EXTENSION_BIT_2_Octet()); + execute(TC_record_with_EXTENSION_BIT_3_Octet()); + execute(TC_record_with_EXTENSION_BIT_4_Octet()); + execute(TC_record_with_EXTENSION_BIT_5_Octet()); + execute(TC_record_with_EXTENSION_BIT_6_Octet()); + execute(TC_record_with_EXTENSION_BIT_7_Octet()); + execute(TC_record_with_EXTENSION_BIT_8_Octet()); + execute(TC_record_with_EXTENSION_BIT_9_Octet()); + execute(TC_record_with_EXTENSION_BIT_1_Bit()); + execute(TC_record_with_EXTENSION_BIT_2_Bit()); + execute(TC_record_with_EXTENSION_BIT_3_Bit()); + execute(TC_record_with_EXTENSION_BIT_4_Bit()); + execute(TC_record_with_EXTENSION_BIT_5_Bit()); + execute(TC_record_with_EXTENSION_BIT_6_Bit()); + execute(TC_record_with_EXTENSION_BIT_7_Bit()); + execute(TC_record_with_EXTENSION_BIT_8_Bit()); + execute(TC_record_with_EXTENSION_BIT_9_Bit()); + execute(TC_with_units_1()); + execute(TC_with_units_2()); + execute(TC_with_lengthindex_1()); + execute(TC_with_lengthindex_2()); + execute(TC_with_lengthindex_3()); +} + +} with { encode "RAW" } diff --git a/regression_test/EncodeDecode/RAW/RAW_repeat/RAW_repeat_test.ttcn b/regression_test/EncodeDecode/RAW/RAW_repeat/RAW_repeat_test.ttcn index df8af22b1fe2b967cf22a1d2de97bb61d00a9ce7..b4cd626746e3a967f00dc0567a948797e1ff3c56 100644 --- a/regression_test/EncodeDecode/RAW/RAW_repeat/RAW_repeat_test.ttcn +++ b/regression_test/EncodeDecode/RAW/RAW_repeat/RAW_repeat_test.ttcn @@ -29,13 +29,22 @@ type record IE1{ type record IE2{ OCT1 ie_type, - integer len, + octetstring len length(1), octetstring data } with { variant "PRESENCE(ie_type = '02'O)" variant (len) "LENGTHTO(data)" } +type record IE3{ + OCT1 ie_type, + bitstring len length(8), + octetstring data +} with { + variant "PRESENCE(ie_type = '03'O)" + variant (len) "LENGTHTO(data)" +} + type record unknown_IE{ OCT1 ie_type, integer len, @@ -49,6 +58,7 @@ type record of unknown_IE unknown_IE_list type set PDU{ IE1 ie1_field, IE2 ie2_field optional, + IE3 ie3_field optional, unknown_IE_list unknown_ies optional } with { variant (unknown_ies) "REPEATABLE(yes)" @@ -59,24 +69,20 @@ with { extension "prototype(backtrack) decode(RAW)" } // no spread record of testcase tc_1() runs on CT { - var octetstring stream; + var octetstring stream := '010100020100030100040100050100'O ; // IE1, IE2, IE3, unknown IE var PDU pdu_decoded; var PDU pdu_expected := { ie1_field := { ie_type := '01'O, len:=1, data := '00'O }, - ie2_field := { ie_type := '02'O, len:=1, data := '00'O }, + ie2_field := { ie_type := '02'O, len:='01'O, data := '00'O }, + ie3_field := { ie_type := '03'O, len:='00000001'B, data := '00'O }, unknown_ies := { - { ie_type := '03'O, len:=1, data := '00'O}, - { ie_type := '04'O, len:=1, data := '00'O} + { ie_type := '04'O, len:=1, data := '00'O}, + { ie_type := '05'O, len:=1, data := '00'O} } } - var integer result; - stream := '010100020100030100040100'O // IE1, IE2, unknown IE + var integer result; result:=dec_PDU_backtrack(stream,pdu_decoded); - log(stream); - log(result) // { ie1_field := { ie_type := '01'O, len := 1, data := '00'O }, ie2_field := { ie_type := '02'O, len := 1, data := '00'O }, unknown_ies := { { ie_type := '03'O, len := 1, data := '00'O }, { ie_type := '04'O, len := 1, data := '00'O } } } - log(pdu_decoded); - if (result != 0) { setverdict(fail, "decoding failed"); } else if ( pdu_decoded != pdu_expected) { @@ -90,22 +96,19 @@ testcase tc_1() runs on CT { // spread record of testcase tc_2() runs on CT { - var octetstring stream := '010100030100020100040100'O // IE1, unknown IE, IE2 -> IE2 added to the unknown_ies + var octetstring stream := '010100030100040100020100050100'O // IE1, IE3, unknown IE, IE2 -> IE2 added to the unknown_ies var PDU pdu_decoded; var PDU pdu_expected := { ie1_field := { ie_type := '01'O, len:=1, data := '00'O }, - ie2_field := { ie_type := '02'O, len:=1, data := '00'O }, + ie2_field := { ie_type := '02'O, len:='01'O, data := '00'O }, + ie3_field := { ie_type := '03'O, len:='00000001'B, data := '00'O }, unknown_ies := { - { ie_type := '03'O, len:=1, data := '00'O}, - { ie_type := '04'O, len:=1, data := '00'O} + { ie_type := '04'O, len:=1, data := '00'O}, + { ie_type := '05'O, len:=1, data := '00'O} } } var integer result; - // stream := '010100030100020100040100'O // IE1, unknown IE, IE2 -> IE2 added to the unknown_ies result:=dec_PDU_backtrack(stream,pdu_decoded); - log(stream) - log(result) // { ie1_field := { ie_type := '01'O, len := 1, data := '00'O }, ie2_field := omit, unknown_ies := { { ie_type := '03'O, len := 1, data := '00'O }, { ie_type := '02'O, len := 1, data := '00'O }, { ie_type := '04'O, len := 1, data := '00'O } } } - log(pdu_decoded) if (result != 0) { setverdict(fail, "decoding failed"); } else if ( pdu_decoded != pdu_expected) { @@ -119,24 +122,22 @@ testcase tc_2() runs on CT { // spread record of testcase tc_3() runs on CT { - var octetstring stream := '010100030100020100020100040100020100'O; // IE1, unknown IE, IE2 , IE2, unknown IE, IE2 which should be at the unknown_ies list. The ie2_field is not repeatable + var octetstring stream := '010100030100040100020100020100050100020100'O; // IE1, IE3, unknown IE, IE2 , IE2, unknown IE, IE2 which should be at the unknown_ies list. The ie2_field is not repeatable var PDU pdu_decoded; var PDU pdu_expected := { ie1_field := { ie_type := '01'O, len:=1, data := '00'O }, - ie2_field := { ie_type := '02'O, len:=1, data := '00'O }, + ie2_field := { ie_type := '02'O, len:='01'O, data := '00'O }, + ie3_field := { ie_type := '03'O, len:='00000001'B, data := '00'O }, unknown_ies := { - { ie_type := '03'O, len:=1, data := '00'O}, - { ie_type := '02'O, len:=1, data := '00'O}, { ie_type := '04'O, len:=1, data := '00'O}, + { ie_type := '02'O, len:=1, data := '00'O}, + { ie_type := '05'O, len:=1, data := '00'O}, { ie_type := '02'O, len:=1, data := '00'O} } } var integer result; result:=dec_PDU_backtrack(stream,pdu_decoded); - log(stream) - log(result) // { ie1_field := { ie_type := '01'O, len := 1, data := '00'O }, ie2_field := omit, unknown_ies := { { ie_type := '03'O, len := 1, data := '00'O }, { ie_type := '02'O, len := 1, data := '00'O }, { ie_type := '04'O, len := 1, data := '00'O } } } - log(pdu_decoded) if (result != 0) { setverdict(fail, "decoding failed"); } else if ( pdu_decoded != pdu_expected) { diff --git a/usrguide/referenceguide/4-ttcn3_language_extensions.adoc b/usrguide/referenceguide/4-ttcn3_language_extensions.adoc index 104f27c516885a5d0fe6d4eecdf7aa2a5da3b138..48a7a48460f3b350e252521bf2020d6928ec1722 100644 --- a/usrguide/referenceguide/4-ttcn3_language_extensions.adoc +++ b/usrguide/referenceguide/4-ttcn3_language_extensions.adoc @@ -1381,8 +1381,9 @@ Differences from the legacy method: * `encode` and `variant` attributes can be defined for types as described in the TTCN-3 standard (although the type restrictions for built-in codecs still apply); * a type can have multiple `encode` attributes (this provides the option to choose from multiple codecs, even user-defined ones, when encoding values of that type); * ASN.1 types automatically have `BER`, `JSON`, `PER` (see section <>), and XML (if the compiler option `-a` is set) encoding (they are treated as if they had the corresponding `encode` attributes); -* encoding-specific `variant` attributes are supported(e.g.: `variant "XML"."untagged"`); -* the parameters `encoding_info/decoding_info` and `dynamic_encoding` of predefined functions `encvalue`, `decvalue`, `encvalue_unichar` and `decvalue_unichar` are supported (the `dynamic_encoding` parameter can be used for choosing the codec to use for values of types with multiple encodings; the `encoding_info`/`decoding_info` parameters are currently ignored); +* encoding-specific `variant` attributes are supported (e.g.: `variant "XML"."untagged"`); +* the parameters `encoding_info/decoding_info` and `dynamic_encoding` of predefined functions `encvalue`, `decvalue`, `encvalue_unichar` and `decvalue_unichar` are supported (the `encoding_info`/`decoding_info` parameters are currently ignored, see also the next point) +* the `dynamic_encoding` parameter can be used for choosing the codec to use for values of types with multiple encodings, the following values are available: `BER:2002`, `CER:2002`, `DER:2002`, `JSON`, `OER`, `RAW`, `TEXT`, `XER`, `XML`; * the `self.setencode` version of the `setencode` operation is supported (it can be used for choosing the codec to use for types with multiple encodings within the scope of the current component); * the `@local` modifier is supported for `encode` attributes; * a type's the default codec (used by `decmatch` templates, the @decoded modifier, and the predefined functions `encvalue`, `decvalue`, `encvalue_unichar` and `decvalue_unichar` when no dynamic encoding parameter is given) is: @@ -1794,7 +1795,7 @@ The TTCN-3 standard defines a mechanism using `attributes` to define, among othe ==== General Rules -If an `attribute` can be assigned to a given type, it can also almost always be assigned to the same type of fields in a `record`, set or `union`. Attributes belonging to a `record` or `set` field overwrites the effect of the same attributes specified for the type of the field. +If an `attribute` can be assigned to a given type, it can also almost always be assigned to the same type of fields in a `record`, `set` or `union`. Attributes belonging to a `record` or `set` field overwrites the effect of the same attributes specified for the type of the field. The location of an attribute is evaluated before the attribute itself. This means that if an attribute is overwritten thanks to its qualification or the overwriting rules, or both, its validity at the given location will not be checked. @@ -2982,7 +2983,7 @@ Description: The encoder is able to calculate the encoded length of one or sever If the offset is present, it is added to or subtracted from (the operation specified in the attribute is performed) the calculated length during encoding. During decoding, the offset is subtracted from or added to (the opposite operation to the one specified in the attribute is performed) the decoded value of the length field. -NOTE: The length is expressed in units defined by the attribute UNIT The default unit is octet. The length field should be a TTCN-3 `integer` or `union` type. Special union containing only integer fields can be used for variable length field. It must not be used with `LENGTHINDEX`. The length field can be included in to the sum of the lengths of multiple fields (e.g. `lengthField` + `field2` + `field3`). The `union` field is NOT selected by the encoder. So the suitable field must be selected before encoding! The fields included in the length computing need not be continuous. +NOTE: The length is expressed in units defined by the attribute UNIT The default unit is octet. The length field should be a TTCN-3 `integer`, `bitstring`, `octetstring` or `union` type. Special union containing only `integer`, `bitstring` or `octetstring` fields can be used for variable length field. It must not be used with `LENGTHINDEX`. The length field can be included in to the sum of the lengths of multiple fields (e.g. `lengthField` + `field2` + `field3`). The `union` field is NOT selected by the encoder. So the suitable field must be selected before encoding! The fields included in the length computing need not be continuous. If `bitstring` or `octetstring` type is used, the length of the field must be specified either with `length()` subtyping or with the `FIELDLENGTH` variant. Examples: [source] @@ -2995,7 +2996,7 @@ octetstring field2 } with { -variant (len) "LENGTHTO(field1); +variant (len) "LENGTHTO(field1)"; variant (len) "UNIT(bits)" } @@ -3008,7 +3009,7 @@ octetstring field2 } with { -variant (len) "LENGTHTO(len, field1, field2) +variant (len) "LENGTHTO(len, field1, field2)" } //Example number 3) @@ -3016,12 +3017,12 @@ variant (len) "LENGTHTO(len, field1, field2) type record Rec3 { INT1 len, OCT3 field1, -OCT1 field2 +OCT1 field2, octetstring field3 } with { -variant (len) "LENGTHTO(field1, field3) +variant (len) "LENGTHTO(field1, field3)" // field2 is excluded! } @@ -3040,7 +3041,7 @@ length_union length_field, octetstring data } with { variant (length_field) -"CROSSTAG(short_length_field, flag = '0'B +"CROSSTAG(short_length_field, flag = '0'B; long_length_field, flag = '1'B)"; variant (length_field) "LENGTHTO(data)" } @@ -3091,6 +3092,31 @@ variant (len) "LENGTHTO(field) - 2" // (1 is added to the length of `field') // and '0212345678'O would be decoded into { len := 4, field := '12345678'O } // (1 is subtracted from the decoded value of `len') + +//Example number 7): octetstring +type record Rec7 { +octetstring len length(1), // length of this field in octet +OCT3 field1, +octetstring field2 +} + +with { +variant (len) "LENGTHTO(field1)"; +variant (len) "UNIT(bits)" +} + +//Example number 8): bitstring +type record Rec8 { +btstring len, +OCT3 field1, +octetstring field2 +} + +with { +variant (len) "FIELDLENGTH(8)"; // length of this field in bits +variant (len) "LENGTHTO(field1)"; +variant (len) "UNIT(bits)" +} ---- *LENGTHINDEX* @@ -3108,7 +3134,8 @@ Can be used with: fields of a `record`. Description: This attribute extends the `LENGTHTO` attribute with the identification of the nested field containing the length value within the field of the corresponding `LENGTHTO` attribute. Comment: See also the description of the `LENGTHTO` attribute. -NOTE: The field named by `LENGTHINDEX` attribute should be a TTCN-3 integer type. + +NOTE: The field named by `LENGTHINDEX` attribute should be a TTCN-3 `integer`, `bitstring` or `octetstring` type. Example (see also example of `LENGTHTO` attribute). [source] @@ -3147,6 +3174,7 @@ Can be used with: fields of a `record`. Description: Some record fields contain the distance to another encoded field. Records can be encoded in the form of: `ptr1`, `ptr2`, `ptr3`, `field1`, `field2`, `field3`, where the position of fieldN within the encoded stream can be determined from the value and position of field ptrN. The distance of the pointed field from the base field will be `ptrN` * `UNIT` + `PTROFFSET`. The default base field is the pointer itself. The base field can be set by the PTROFFSET attribute. When the pointed field is optional, the pointer value 0 indicates the absence of the pointed field. Comment: See also the description of `UNIT` (0) and `PTROFFSET` (0) attributes. + NOTE: Pointer fields should be TTCN-3 `integer` type. Examples: