diff --git a/compiler2/Type.cc b/compiler2/Type.cc index 12033ba7312ce5f11193ddb5c643435c747ab280..05f0a578a3496b73616a53a74eab688c6a6bf713 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -3142,6 +3142,21 @@ namespace Common { err = true; } break; + case T_SEQ_T: + case T_SET_T: + if (last->get_nof_comps() != 0) { + error("JSON default values are not available for record/set types with " + "1 or more fields"); + break; + } + // else fall through + case T_SEQOF: + case T_SETOF: + if (dval_len != 2 || dval[0] != '{' || dval[1] != '}') { + error("Invalid JSON default value for type `%s'. Only the empty array " + "is allowed.", last->get_typename().c_str()); + } + break; default: error("JSON default values are not available for type `%s'", last->get_stringRepr().c_str()); diff --git a/compiler2/record.c b/compiler2/record.c index 38f8fcf3561ec59245c84224d77f12c030befad4..1218a72d2f0a75f20d18434143b994aa732b97e0 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -6539,8 +6539,13 @@ static void defEmptyRecordClass(const struct_def *sdef, // JSON decode, RT1 src = mputprintf(src, - "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n" + "int %s::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)\n" "{\n" + " if (NULL != p_td.json->default_value && 0 == p_tok.get_buffer_length()) {\n" + // use the default value + " bound_flag = TRUE;\n" + " return strlen(p_td.json->default_value);\n" + " }\n" " json_token_t token = JSON_TOKEN_NONE;\n" " size_t dec_len = p_tok.get_next_token(&token, NULL, NULL);\n" " if (JSON_TOKEN_ERROR == token) {\n" diff --git a/compiler2/record_of.c b/compiler2/record_of.c index 561784f0cea3319f09eecc2840f013bc5eb2211e..32b7333a7409ed95e8c46b5d3e8704babc8aac93 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -1569,6 +1569,12 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) src = mputprintf(src, "int %s::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)\n" "{\n" + " if (NULL != p_td.json->default_value && 0 == p_tok.get_buffer_length()) {\n" + // use the default value (currently only the empty array can be set as + // default value for this type) + " set_size(0);\n" + " return strlen(p_td.json->default_value);\n" + " }\n" " json_token_t token = JSON_TOKEN_NONE;\n" " size_t dec_len = p_tok.get_next_token(&token, NULL, NULL);\n" " if (JSON_TOKEN_ERROR == token) {\n" diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 89610e8115c9f7e90af2fe9344c8a2a1be6af5de..f9e669021916ffe16f8d4ac9a7349e55a038b279 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -1589,6 +1589,12 @@ int Record_Of_Type::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_desc int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent) { + if (NULL != p_td.json->default_value && 0 == p_tok.get_buffer_length()) { + // use the default value (currently only the empty array can be set as + // default value for this type) + set_size(0); + return strlen(p_td.json->default_value); + } json_token_t token = JSON_TOKEN_NONE; size_t dec_len = p_tok.get_next_token(&token, NULL, NULL); if (JSON_TOKEN_ERROR == token) { @@ -7306,8 +7312,13 @@ int Empty_Record_Type::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL); } -int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent) +int Empty_Record_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent) { + if (NULL != p_td.json->default_value && 0 == p_tok.get_buffer_length()) { + // use the default value + bound_flag = TRUE; + return strlen(p_td.json->default_value); + } json_token_t token = JSON_TOKEN_NONE; size_t dec_len = p_tok.get_next_token(&token, NULL, NULL); if (JSON_TOKEN_ERROR == token) { diff --git a/regression_test/json/AttributeTestcases.ttcn b/regression_test/json/AttributeTestcases.ttcn index a5d9ff7dc483b3c8ecc0695dc5ea9e6f6fd04e7b..b034d359806ec66439fbbee1f774557b1f4a7e20 100644 --- a/regression_test/json/AttributeTestcases.ttcn +++ b/regression_test/json/AttributeTestcases.ttcn @@ -504,6 +504,23 @@ testcase tc_attribute_as_number_negtest() runs on MTC { setverdict(pass); } +// Testing the attribute 'default' on structures +testcase tc_attribute_default_struct() runs on MTC { + var DefaultEmptyStructs val; + var DefaultEmptyStructs exp_val := { {}, {}, {}, {} }; + var universal charstring data := "{}"; + var integer res := decvalue_unichar(data, val); + if (res != 0 or lengthof(data) != 0) { + setverdict(fail, "Decoding failed. Result: ", res, ", remaining JSON data: ", data); + } + else if (val != exp_val) { + setverdict(fail, "Invalid decoded value. Expected: ", exp_val, ", got: ", val); + } + else { + setverdict(pass); + } +} + control { execute(tc_NoAttributeOnUpperLevel()) @@ -529,5 +546,6 @@ control { execute(tc_attribute_as_value_fields()); execute(tc_attribute_as_number()); execute(tc_attribute_as_number_negtest()); + execute(tc_attribute_default_struct()); } } diff --git a/regression_test/json/Types.ttcn b/regression_test/json/Types.ttcn index 18d89d7337302feea5ec9b8ad5ce53209d610550..c08d85680238c069e13461af087773a9e6f11746 100644 --- a/regression_test/json/Types.ttcn +++ b/regression_test/json/Types.ttcn @@ -305,6 +305,19 @@ type union Uni522660 { integer f1 } +type record DefaultEmptyStructs { + record { } r, + set { } s, + record of integer ro, + set of charstring so +} +with { + variant (r) "JSON: default({})"; + variant (s) "JSON: default({})"; + variant (ro) "JSON: default({})"; + variant (so) "JSON: default({})"; +} + } with { encode "JSON"; extension "anytype integer, charstring, R, RoI, Thing";