From 344d0e03e7ce4cbd7c4579b6c13226a48b8eeaf9 Mon Sep 17 00:00:00 2001 From: Botond Baranyi <botond.baranyi@ericsson.com> Date: Wed, 29 Aug 2018 16:08:27 +0200 Subject: [PATCH] Fixed OER encoding of empty records and record-ofs (github issues 133 and 134) Change-Id: Ibde4c1345b1644427678a9e488ec53b34568ed8f Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com> --- compiler2/record.c | 24 ++++++++++++++++----- core/OER.cc | 3 ++- core2/Basetype2.cc | 18 ++++++++++++++-- regression_test/OER/OER.ttcn | 40 +++++++++++++++++++++++++++++++++++ regression_test/OER/Types.asn | 6 ++++++ 5 files changed, 83 insertions(+), 8 deletions(-) diff --git a/compiler2/record.c b/compiler2/record.c index 076f6b766..53fc76430 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -6792,25 +6792,39 @@ static void defEmptyRecordClass(const struct_def *sdef, if (oer_needed) { // OER encode, RT1 src = mputprintf(src, - "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const\n" + "int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&%s) const\n" "{\n" " if (!is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n" " \"Encoding an unbound value of type %s.\");\n" " return -1;\n" " }\n\n" + "%s" " return 0;\n" "}\n\n" - , name, dispname); + , name, sdef->oerExtendable ? " p_buf" : "", dispname + , sdef->oerExtendable ? " p_buf.put_c(0);\n" : ""); // OER decode, RT1 src = mputprintf(src, - "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&)\n" + "int %s::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&%s, OER_struct&)\n" "{\n" " bound_flag = TRUE;\n" + , name, sdef->oerExtendable ? " p_buf" : ""); + if (sdef->oerExtendable) { + src = mputstr(src, + " const unsigned char* uc = p_buf.get_read_data();\n" + " boolean has_extension = (uc[0] & 0x80) != 0;\n" + " p_buf.increase_pos(1);\n" + " if (has_extension) {\n" + " size_t bytes = decode_oer_length(p_buf, FALSE);\n" + " p_buf.increase_pos(bytes);\n" + // TODO: handle extension fields + " }\n"); + } + src = mputstr(src, " return 0;\n" - "}\n\n" - , name); + "}\n\n"); } /* closing class definition */ diff --git a/core/OER.cc b/core/OER.cc index fd0e3b3fa..3a69e01a2 100644 --- a/core/OER.cc +++ b/core/OER.cc @@ -24,10 +24,11 @@ void encode_oer_length(size_t num_bytes, TTCN_Buffer& buf, boolean seof) { size_t bytes = num_bytes; // Encode length in maybe more than 1 byte size_t needed_bytes = 0; - while (bytes != 0) { + do { bytes >>= 8; needed_bytes++; } + while (bytes != 0); char c = 0; if (seof == FALSE) { c |= 1 << 7; diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 630628be8..eabf226dd 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -7011,6 +7011,7 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu act_pos = 0; } } + // TODO: handle extra extension fields } else if (p_td.oer->extendable) { // Set the optional fields after the extension to 'omit' @@ -7442,17 +7443,30 @@ int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Token return (int)dec_len; } -int Empty_Record_Type::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const { +int Empty_Record_Type::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const { if (!is_bound()) { TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound empty %s value.", is_set() ? "set" : "record"); return -1; } + if (p_td.oer->extendable) { + p_buf.put_c(0); + } return 0; } -int Empty_Record_Type::OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&) { +int Empty_Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, OER_struct&) { bound_flag = TRUE; + if (p_td.oer->extendable) { + const unsigned char* uc = p_buf.get_read_data(); + boolean has_extension = (uc[0] & 0x80) != 0; + p_buf.increase_pos(1); + if (has_extension) { + size_t bytes = decode_oer_length(p_buf, FALSE); + p_buf.increase_pos(bytes); + // TODO: handle extension fields + } + } return 0; } diff --git a/regression_test/OER/OER.ttcn b/regression_test/OER/OER.ttcn index 8ce3e6eb6..a455baa2b 100644 --- a/regression_test/OER/OER.ttcn +++ b/regression_test/OER/OER.ttcn @@ -3252,6 +3252,44 @@ setverdict(pass); } + + external function enc_EmptySeq(in EmptyExtendableSequence os) return octetstring + with { extension "prototype(convert) encode(OER)" } + + external function dec_EmptySeq(in octetstring os) return EmptyExtendableSequence + with { extension "prototype(convert) decode(OER)" } + + testcase tc_sequence_empty() runs on EmptyCT { + var EmptyExtendableSequence x := {}; + var octetstring os := enc_EmptySeq(x); + if (os != '00'O) { + setverdict(fail, "tc_sequence_empty: ", match('00'O, os)); + } + var EmptyExtendableSequence y := dec_EmptySeq(os); + if (y != x) { + setverdict(fail, "tc_sequence_empty: ", match(x, y)); + } + setverdict(pass); + } + + external function enc_SeqOfInt(in SequenceOfInteger os) return octetstring + with { extension "prototype(convert) encode(OER)" } + + external function dec_SeqOfInt(in octetstring os) return SequenceOfInteger + with { extension "prototype(convert) decode(OER)" } + + testcase tc_sequence_of_empty() runs on EmptyCT { + var SequenceOfInteger x := {}; + var octetstring os := enc_SeqOfInt(x); + if (os != '0100'O) { + setverdict(fail, "tc_sequence_of_empty: ", match('0100'O, os)); + } + var SequenceOfInteger y := dec_SeqOfInt(os); + if (y != x) { + setverdict(fail, "tc_sequence_of_empty: ", match(x, y)); + } + setverdict(pass); + } external function enc_MySet(in MySet pdu) return octetstring with { extension "prototype (convert) encode(OER)" } @@ -3685,6 +3723,8 @@ execute(tc_universal_charstring()); execute(tc_objid()); execute(tc_sequence()); + execute(tc_sequence_empty()); + execute(tc_sequence_of_empty()); execute(tc_pdv()); execute(tc_union()); execute(tc_set()); diff --git a/regression_test/OER/Types.asn b/regression_test/OER/Types.asn index c06a6c79d..7e8582f5a 100644 --- a/regression_test/OER/Types.asn +++ b/regression_test/OER/Types.asn @@ -549,5 +549,11 @@ RecWithDefault ::= SEQUENCE field2 INTEGER } +EmptyExtendableSequence ::= SEQUENCE { + ... +} + +SequenceOfInteger ::= SEQUENCE OF INTEGER + END -- GitLab