Commit 344d0e03 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Fixed OER encoding of empty records and record-ofs (github issues 133 and 134)



Change-Id: Ibde4c1345b1644427678a9e488ec53b34568ed8f
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent e2d3eb2b
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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());
......
......@@ -549,5 +549,11 @@ RecWithDefault ::= SEQUENCE
field2 INTEGER
}
EmptyExtendableSequence ::= SEQUENCE {
...
}
SequenceOfInteger ::= SEQUENCE OF INTEGER
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment