diff --git a/compiler2/record.c b/compiler2/record.c index 8b6bf98449d6c84a34c35d51cafc656bcea7e46b..e0b83b966a21e25073cacd09c9f6d55b5212db72 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -4977,10 +4977,13 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n" , ind, pos, sdef->elements[i].name , sdef->elements[sdef->oerP[i]].typedescrname); - if (sdef->elements[sdef->oerP[i]].isOptional) { + if (sdef->elements[sdef->oerP[i]].isOptional || + sdef->elements[sdef->oerP[i]].isDefault) { src = mputprintf(src, " else\n" - " field_%s = OMIT_VALUE;\n" - , sdef->elements[sdef->oerP[i]].name); + " field_%s = %s;\n" + , sdef->elements[sdef->oerP[i]].name + , sdef->elements[sdef->oerP[i]].isOptional ? "OMIT_VALUE" + : sdef->elements[sdef->oerP[i]].defvalname); } if (pos == 0) { ind++; @@ -5013,20 +5016,26 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) { eag_pos++; for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) { - if (sdef->elements[sdef->oerP[j]].isOptional) { + if (sdef->elements[sdef->oerP[j]].isOptional || + sdef->elements[sdef->oerP[j]].isDefault) { has_optional_in_extension = TRUE; src = mputprintf(src, - " field_%s = OMIT_VALUE;\n" - , sdef->elements[sdef->oerP[j]].name); + " field_%s = %s;\n" + , sdef->elements[sdef->oerP[j]].name + , sdef->elements[sdef->oerP[j]].isOptional ? "OMIT_VALUE" + : sdef->elements[sdef->oerP[j]].defvalname); } } eag_pos--; } else { - if (sdef->elements[sdef->oerP[i]].isOptional) { + if (sdef->elements[sdef->oerP[i]].isOptional || + sdef->elements[sdef->oerP[i]].isDefault) { has_optional_in_extension = TRUE; src = mputprintf(src, - " field_%s = OMIT_VALUE;\n" - , sdef->elements[i].name); + " field_%s = %s;\n" + , sdef->elements[sdef->oerP[i]].name + , sdef->elements[sdef->oerP[i]].isOptional ? "OMIT_VALUE" + : sdef->elements[sdef->oerP[i]].defvalname); } } src = mputstr(src, @@ -5056,12 +5065,15 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " field_%s.OER_decode(%s_descr_, p_buf, p_oer);\n" " }\n" , ind2, 1 << pos2, sdef->elements[sdef->oerP[j]].name, sdef->elements[sdef->oerP[j]].typedescrname); - if (sdef->elements[sdef->oerP[j]].isOptional) { + if (sdef->elements[sdef->oerP[j]].isOptional || + sdef->elements[sdef->oerP[j]].isDefault) { src = mputprintf(src, " else {\n" - " field_%s = OMIT_VALUE;\n" + " field_%s = %s;\n" " }\n" - , sdef->elements[sdef->oerP[j]].name); + , sdef->elements[sdef->oerP[j]].name + , sdef->elements[sdef->oerP[j]].isOptional ? "OMIT_VALUE" + : sdef->elements[sdef->oerP[j]].defvalname); } if (pos2 == 0) { pos2 = 8; @@ -5091,10 +5103,13 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) " }\n" " else {\n"); for (i = limit; i < sdef->nElements; i++) { - if (sdef->elements[sdef->oerP[i]].isOptional) { + if (sdef->elements[sdef->oerP[i]].isOptional || + sdef->elements[sdef->oerP[i]].isDefault) { src = mputprintf(src, - " field_%s = OMIT_VALUE;\n" - , sdef->elements[i].name); + " field_%s = %s;\n" + , sdef->elements[sdef->oerP[i]].name + , sdef->elements[sdef->oerP[i]].isOptional ? "OMIT_VALUE" + : sdef->elements[sdef->oerP[i]].defvalname); } } } diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 231fbee13cc60018a2ccee4da189db6f12beadfb..ca5ef47d337f372f47901e04ab6ff6c761c3f098 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -6809,6 +6809,7 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu next_default_idx = 0; for (int i = 0; i < limit; ++i) { boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]); + const Base_Type* default_value = is_default_field ? default_indexes[next_default_idx].value : NULL; if (is_default_field) { next_default_idx++; } @@ -6817,6 +6818,9 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu if (get_at(p_td.oer->p[i])->is_optional()) { get_at(p_td.oer->p[i])->set_to_omit(); } + else if (is_default_field) { + get_at(p_td.oer->p[i])->set_value(default_value); + } } else { get_at(p_td.oer->p[i])->OER_decode(*fld_descr(p_td.oer->p[i]), p_buf, p_oer); } @@ -6843,6 +6847,7 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu // Decode fields for (int i = limit; i < field_count; ++i) { boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]); + const Base_Type* default_value = is_default_field ? default_indexes[next_default_idx].value : NULL; if (is_default_field) { next_default_idx++; } @@ -6852,9 +6857,14 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu if (eag_pos != -1 && p_td.oer->eag[eag_pos] == i - limit) { eag_pos++; for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) { + is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]); + default_value = is_default_field ? default_indexes[next_default_idx].value : NULL; if (get_at(p_td.oer->p[j])->is_optional()) { get_at(p_td.oer->p[j])->set_to_omit(); } + else if (is_default_field) { + get_at(p_td.oer->p[j])->set_value(default_value); + } } i += p_td.oer->eag[eag_pos] - p_td.oer->eag[eag_pos-1] - 1; eag_pos++; @@ -6862,6 +6872,9 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu if (get_at(p_td.oer->p[i])->is_optional()) { get_at(p_td.oer->p[i])->set_to_omit(); } + else if (is_default_field) { + get_at(p_td.oer->p[i])->set_value(default_value); + } } } else { // Extension field or group is present @@ -6892,6 +6905,7 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu next_default_idx = old_next_default_idx; for (int j = i; j < limit + p_td.oer->eag[eag_pos]; j++) { is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[j]); + default_value = is_default_field ? default_indexes[next_default_idx].value : NULL; if (is_default_field) { next_default_idx++; } @@ -6901,6 +6915,9 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu if (get_at(p_td.oer->p[j])->is_optional()) { get_at(p_td.oer->p[j])->set_to_omit(); } + else if (is_default_field) { + get_at(p_td.oer->p[j])->set_value(default_value); + } } else { // Field is present get_at(p_td.oer->p[j])->OER_decode(*fld_descr(p_td.oer->p[j]), p_buf, p_oer); @@ -6932,9 +6949,17 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu else if (p_td.oer->extendable) { // Set the optional fields after the extension to 'omit' for (int i = limit; i < field_count; ++i) { + boolean is_default_field = default_indexes && (default_indexes[next_default_idx].index==p_td.oer->p[i]); + const Base_Type* default_value = is_default_field ? default_indexes[next_default_idx].value : NULL; + if (is_default_field) { + next_default_idx++; + } if (get_at(p_td.oer->p[i])->is_optional()) { get_at(p_td.oer->p[i])->set_to_omit(); } + else if (is_default_field) { + get_at(p_td.oer->p[i])->set_value(default_value); + } } } diff --git a/regression_test/OER/OER.ttcn b/regression_test/OER/OER.ttcn index 531ca79c3fa7efc2b2e2b079032ad4ce4bc8bc00..f7b7af89668489d3ada94d171382313df85539f7 100644 --- a/regression_test/OER/OER.ttcn +++ b/regression_test/OER/OER.ttcn @@ -2301,6 +2301,7 @@ if (os != '40010101020104'O) { setverdict(fail, "tc_sequence: ", match('40010101020104'O, os)); } + er2 := { f0 := 5, f9 := 2 }; // default values erres2 := dec_ExtensionRecord2(os); if (not(match(log2str(er2), log2str(erres2)))) { setverdict(fail, "tc_sequence: ", match(log2str(er2), log2str(erres2))); @@ -2392,7 +2393,7 @@ f6 := 6, f7 := omit, f8 := 8, - f9 := -, + f9 := 2, // default value f_nul := NULL } erres2 := dec_ExtensionRecord2(os); @@ -2432,7 +2433,7 @@ f6 := 6, f7 := omit, f8 := 8, - f9 := -, + f9 := 2, // default value f_nul := - } erres2 := dec_ExtensionRecord2(os); @@ -2683,11 +2684,15 @@ } erres71 := { me := 1, + f0 := 5, // default value + f1 := 5, // default value f2 := omit, + f3 := 5, // default value f4 := omit, f5 := omit, f6 := omit, f7 := omit, + f8 := 4, // default value f9 := omit, f_nul := omit } @@ -3575,11 +3580,11 @@ external function dec_RecWithDefault(in octetstring stream) return RecWithDefault with { extension "prototype (convert) decode(OER)" } - // Testing the decoding of a field with a default value (bug 534769) + // Testing the decoding of a field with a default value (bug 534769, bug 534943) testcase tc_default() runs on EmptyCT { var octetstring enc := '000104'O; var RecWithDefault dec := dec_RecWithDefault(enc); - var RecWithDefault dec_exp := { field2 := 4 }; // the default value is currently not set, the field remains unbound, but there should be no DTE + var RecWithDefault dec_exp := { field1 := 1, field2 := 4 }; if (log2str(dec) != log2str(dec_exp)) { setverdict(fail, "Decoding failed. Got: ", dec, ", expected: ", dec_exp); }