From aa4cd2a7ebb6ee645210820504cee2ae7f27a0e1 Mon Sep 17 00:00:00 2001 From: Botond Baranyi <botond.baranyi@ericsson.com> Date: Thu, 13 Jul 2017 17:25:07 +0200 Subject: [PATCH] Fixed C++ warning in JSON coders generated for unions with no fields (bug 519642) Change-Id: I21b1d3684a9dc754cee100b0af4370247a8dadc2 Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com> --- compiler2/union.c | 565 ++++++++++++++++++++++++---------------------- 1 file changed, 298 insertions(+), 267 deletions(-) diff --git a/compiler2/union.c b/compiler2/union.c index 05e835e15..ce599013f 100644 --- a/compiler2/union.c +++ b/compiler2/union.c @@ -589,10 +589,13 @@ void defUnionClass(struct_def const *sdef, output_struct *output) " BER_chk_descr(p_td);\n" " ASN_BER_TLV_t *new_tlv = NULL;\n" " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n" - " TTCN_EncDec_ErrorContext ec_1;\n" - " const Erroneous_values_t* err_vals = NULL;\n" - " const Erroneous_descriptor_t* emb_descr = NULL;\n" - " switch (union_selection) {\n", name); + " TTCN_EncDec_ErrorContext ec_1;\n", name); + if (sdef->nElements > 0) { + src = mputstr(src, + " const Erroneous_values_t* err_vals = NULL;\n" + " const Erroneous_descriptor_t* emb_descr = NULL;\n"); + } + src = mputstr(src, " switch (union_selection) {\n"); for (i = 0; i < sdef->nElements; i++) { src = mputprintf(src, " case %s_%s:\n" " err_vals = p_err_descr->get_field_err_values(%d);\n" @@ -2017,62 +2020,11 @@ void defUnionClass(struct_def const *sdef, output_struct *output) // JSON encode src = mputprintf(src, "int %s::JSON_encode(const TTCN_Typedescriptor_t&%s, JSON_Tokenizer& p_tok) const\n" - "{\n", name, (use_runtime_2 || !sdef->jsonAsValue) ? " p_td" : ""); - if (use_runtime_2) { - src = mputstr(src, " if (err_descr) return JSON_encode_negtest(err_descr, p_td, p_tok);\n"); - } - if (!sdef->jsonAsValue) { - // 'as value' is not set for the base type, but it might still be set in - // the type descriptor - src = mputstr(src, - " boolean as_value = NULL != p_td.json && p_td.json->as_value;\n" - " int enc_len = as_value ? 0 : " - "p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n"); - } else { - src = mputstr(src, " int enc_len = 0;\n"); - } - src = mputstr(src, " switch(union_selection) {\n"); - - for (i = 0; i < sdef->nElements; ++i) { - src = mputprintf(src, " case %s_%s:\n", selection_prefix, sdef->elements[i].name); - if (!sdef->jsonAsValue) { - src = mputprintf(src, - " if (!as_value) {\n" - " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" - " }\n" - , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); + "{\n", name, (sdef->nElements > 0) && (use_runtime_2 || !sdef->jsonAsValue) ? " p_td" : ""); + if (sdef->nElements > 0) { + if (use_runtime_2) { + src = mputstr(src, " if (err_descr) return JSON_encode_negtest(err_descr, p_td, p_tok);\n"); } - src = mputprintf(src, - " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n" - " break;\n" - , sdef->elements[i].name, sdef->elements[i].typedescrname); - } - src = mputprintf(src, - " default:\n" - " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n" - " \"Encoding an unbound value of type %s.\");\n" - " return -1;\n" - " }\n\n" - , dispname); - if (!sdef->jsonAsValue) { - src = mputstr(src, - " if (!as_value) {\n" - " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n" - " }\n"); - } - src = mputstr(src, - " return enc_len;\n" - "}\n\n"); - - if (use_runtime_2) { - // JSON encode for negative testing - def = mputstr(def, - "int JSON_encode_negtest(const Erroneous_descriptor_t*, " - "const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"); - src = mputprintf(src, - "int %s::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr, " - "const TTCN_Typedescriptor_t&%s, JSON_Tokenizer& p_tok) const\n" - "{\n", name, !sdef->jsonAsValue ? " p_td" : ""); if (!sdef->jsonAsValue) { // 'as value' is not set for the base type, but it might still be set in // the type descriptor @@ -2081,55 +2033,22 @@ void defUnionClass(struct_def const *sdef, output_struct *output) " int enc_len = as_value ? 0 : " "p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n"); } else { - src = mputstr(src, " int enc_len = 0;\n\n"); + src = mputstr(src, " int enc_len = 0;\n"); } - src = mputstr(src, - " const Erroneous_values_t* err_vals = NULL;\n" - " const Erroneous_descriptor_t* emb_descr = NULL;\n" - " switch(union_selection) {\n"); - + src = mputstr(src, " switch(union_selection) {\n"); + for (i = 0; i < sdef->nElements; ++i) { - src = mputprintf(src, - " case %s_%s:\n" - " err_vals = p_err_descr->get_field_err_values(%d);\n" - " emb_descr = p_err_descr->get_field_emb_descr(%d);\n" - " if (NULL != err_vals && NULL != err_vals->value) {\n" - " if (NULL != err_vals->value->errval) {\n" - " if(err_vals->value->raw){\n" - " enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);\n" - " } else {\n" - " if (NULL == err_vals->value->type_descr) {\n" - " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n" - " }\n" - , selection_prefix, sdef->elements[i].name, (int)i, (int)i); + src = mputprintf(src, " case %s_%s:\n", selection_prefix, sdef->elements[i].name); if (!sdef->jsonAsValue) { src = mputprintf(src, - " if (!as_value) {\n" - " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" - " }\n" - , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); - } - src = mputstr(src, - " enc_len += err_vals->value->errval->JSON_encode(*err_vals->value->type_descr, p_tok);\n" - " }\n" - " }\n" - " } else {\n"); - if (!sdef->jsonAsValue) { - src = mputprintf(src, - " if (!as_value) {\n" - " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" - " }\n" + " if (!as_value) {\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" + " }\n" , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); } - src = mputprintf(src, - " if (NULL != emb_descr) {\n" - " enc_len += field_%s->JSON_encode_negtest(emb_descr, %s_descr_, p_tok);\n" - " } else {\n" - " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n" - " }\n" - " }\n" + src = mputprintf(src, + " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n" " break;\n" - , sdef->elements[i].name, sdef->elements[i].typedescrname , sdef->elements[i].name, sdef->elements[i].typedescrname); } src = mputprintf(src, @@ -2143,195 +2062,307 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputstr(src, " if (!as_value) {\n" " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n" - "}\n"); + " }\n"); } src = mputstr(src, " return enc_len;\n" "}\n\n"); } + else { + src = mputprintf(src, + " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n" + " \"Cannot encode union of type %s, because it has zero alternatives.\");\n" + " return -1;\n" + "}\n\n", dispname); + } + + if (use_runtime_2) { + // JSON encode for negative testing + def = mputstr(def, + "int JSON_encode_negtest(const Erroneous_descriptor_t*, " + "const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"); + src = mputprintf(src, + "int %s::JSON_encode_negtest(const Erroneous_descriptor_t*%s, " + "const TTCN_Typedescriptor_t&%s, JSON_Tokenizer& p_tok) const\n" + "{\n", name, sdef->nElements > 0 ? " p_err_descr" : "", + (sdef->nElements > 0 && !sdef->jsonAsValue) ? " p_td" : ""); + if (sdef->nElements > 0) { + if (!sdef->jsonAsValue) { + // 'as value' is not set for the base type, but it might still be set in + // the type descriptor + src = mputstr(src, + " boolean as_value = NULL != p_td.json && p_td.json->as_value;\n" + " int enc_len = as_value ? 0 : " + "p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n"); + } else { + src = mputstr(src, " int enc_len = 0;\n\n"); + } + src = mputstr(src, + " const Erroneous_values_t* err_vals = NULL;\n" + " const Erroneous_descriptor_t* emb_descr = NULL;\n" + " switch(union_selection) {\n"); + + for (i = 0; i < sdef->nElements; ++i) { + src = mputprintf(src, + " case %s_%s:\n" + " err_vals = p_err_descr->get_field_err_values(%d);\n" + " emb_descr = p_err_descr->get_field_emb_descr(%d);\n" + " if (NULL != err_vals && NULL != err_vals->value) {\n" + " if (NULL != err_vals->value->errval) {\n" + " if(err_vals->value->raw){\n" + " enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);\n" + " } else {\n" + " if (NULL == err_vals->value->type_descr) {\n" + " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n" + " }\n" + , selection_prefix, sdef->elements[i].name, (int)i, (int)i); + if (!sdef->jsonAsValue) { + src = mputprintf(src, + " if (!as_value) {\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" + " }\n" + , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); + } + src = mputstr(src, + " enc_len += err_vals->value->errval->JSON_encode(*err_vals->value->type_descr, p_tok);\n" + " }\n" + " }\n" + " } else {\n"); + if (!sdef->jsonAsValue) { + src = mputprintf(src, + " if (!as_value) {\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n" + " }\n" + , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname); + } + src = mputprintf(src, + " if (NULL != emb_descr) {\n" + " enc_len += field_%s->JSON_encode_negtest(emb_descr, %s_descr_, p_tok);\n" + " } else {\n" + " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n" + " }\n" + " }\n" + " break;\n" + , sdef->elements[i].name, sdef->elements[i].typedescrname + , sdef->elements[i].name, sdef->elements[i].typedescrname); + } + src = mputprintf(src, + " default:\n" + " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n" + " \"Encoding an unbound value of type %s.\");\n" + " return -1;\n" + " }\n\n" + , dispname); + if (!sdef->jsonAsValue) { + src = mputstr(src, + " if (!as_value) {\n" + " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n" + "}\n"); + } + src = mputstr(src, + " return enc_len;\n" + "}\n\n"); + } + else { + src = mputprintf(src, + " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n" + " \"Cannot encode union of type %s, because it has zero alternatives.\");\n" + " return -1;\n" + "}\n\n", dispname); + } + } // JSON decode src = mputprintf(src, "int %s::JSON_decode(const TTCN_Typedescriptor_t&%s, JSON_Tokenizer& p_tok, boolean p_silent)\n" "{\n" - " json_token_t j_token = JSON_TOKEN_NONE;\n" - , name, !sdef->jsonAsValue ? " p_td" : ""); - if (!sdef->jsonAsValue) { - src = mputstr(src, - " if (NULL != p_td.json && p_td.json->as_value) {\n"); - } - src = mputstr(src, - " size_t buf_pos = p_tok.get_buf_pos();\n" - " p_tok.get_next_token(&j_token, NULL, NULL);\n" - " int ret_val = 0;\n" - " switch(j_token) {\n" - " case JSON_TOKEN_NUMBER: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_NUMBER & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); - } - } - src = mputstr(src, - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"number\");\n" - " clean_up();\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " case JSON_TOKEN_STRING: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_STRING & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + , name, sdef->nElements > 0 && !sdef->jsonAsValue ? " p_td" : ""); + if (sdef->nElements > 0) { + src = mputstr(src, " json_token_t j_token = JSON_TOKEN_NONE;\n"); + if (!sdef->jsonAsValue) { + src = mputstr(src, + " if (NULL != p_td.json && p_td.json->as_value) {\n"); } - } - src = mputstr(src, - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"string\");\n" - " clean_up();\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " case JSON_TOKEN_LITERAL_TRUE:\n" - " case JSON_TOKEN_LITERAL_FALSE: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_BOOLEAN & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + src = mputstr(src, + " size_t buf_pos = p_tok.get_buf_pos();\n" + " p_tok.get_next_token(&j_token, NULL, NULL);\n" + " int ret_val = 0;\n" + " switch(j_token) {\n" + " case JSON_TOKEN_NUMBER: {\n"); + for (i = 0; i < sdef->nElements; ++i) { + if (JSON_NUMBER & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } } - } - src = mputstr(src, - " char* literal_str = mprintf(\"literal (%s)\",\n" - " (JSON_TOKEN_LITERAL_TRUE == j_token) ? \"true\" : \"false\");\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, literal_str);\n" - " Free(literal_str);\n" - " clean_up();\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " case JSON_TOKEN_ARRAY_START: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_ARRAY & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + src = mputstr(src, + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"number\");\n" + " clean_up();\n" + " return JSON_ERROR_FATAL;\n" + " }\n" + " case JSON_TOKEN_STRING: {\n"); + for (i = 0; i < sdef->nElements; ++i) { + if (JSON_STRING & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } } - } - src = mputstr(src, - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"array\");\n" - " clean_up();\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " case JSON_TOKEN_OBJECT_START: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_OBJECT & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + src = mputstr(src, + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"string\");\n" + " clean_up();\n" + " return JSON_ERROR_FATAL;\n" + " }\n" + " case JSON_TOKEN_LITERAL_TRUE:\n" + " case JSON_TOKEN_LITERAL_FALSE: {\n"); + for (i = 0; i < sdef->nElements; ++i) { + if (JSON_BOOLEAN & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } } - } - src = mputstr(src, - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"object\");\n" - " clean_up();\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " case JSON_TOKEN_LITERAL_NULL: {\n"); - for (i = 0; i < sdef->nElements; ++i) { - if (JSON_NULL & sdef->elements[i].jsonValueType) { - src = mputprintf(src, - " p_tok.set_buf_pos(buf_pos);\n" - " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" - " if (0 <= ret_val) {\n" - " return ret_val;\n" - " }\n" - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + src = mputstr(src, + " char* literal_str = mprintf(\"literal (%s)\",\n" + " (JSON_TOKEN_LITERAL_TRUE == j_token) ? \"true\" : \"false\");\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, literal_str);\n" + " Free(literal_str);\n" + " clean_up();\n" + " return JSON_ERROR_FATAL;\n" + " }\n" + " case JSON_TOKEN_ARRAY_START: {\n"); + for (i = 0; i < sdef->nElements; ++i) { + if (JSON_ARRAY & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } } - } - src = mputstr(src, - " clean_up();\n" - // the caller might be able to decode the null value if it's an optional field - // only return an invalid token error, not a fatal error - " return JSON_ERROR_INVALID_TOKEN;\n" - " }\n" - " case JSON_TOKEN_ERROR:\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n" - " return JSON_ERROR_FATAL;\n" - " default:\n" - " return JSON_ERROR_INVALID_TOKEN;\n" - " }\n" - " return ret_val;\n"); - if (!sdef->jsonAsValue) { - src = mputprintf(src, - " }\n" - " else {\n" // if there is no 'as value' set in the type descriptor - " size_t dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n" - " if (JSON_TOKEN_ERROR == j_token) {\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n" + src = mputstr(src, + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"array\");\n" + " clean_up();\n" " return JSON_ERROR_FATAL;\n" " }\n" - " else if (JSON_TOKEN_OBJECT_START != j_token) {\n" - " return JSON_ERROR_INVALID_TOKEN;\n" - " }\n\n" - " char* fld_name = 0;\n" - " size_t name_len = 0;\n" - " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n" - " if (JSON_TOKEN_NAME != j_token) {\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n" + " case JSON_TOKEN_OBJECT_START: {\n"); + for (i = 0; i < sdef->nElements; ++i) { + if (JSON_OBJECT & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } + } + src = mputstr(src, + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"object\");\n" + " clean_up();\n" " return JSON_ERROR_FATAL;\n" - " } else {\n" - " union_selection = %s;\n " - , unbound_value); + " }\n" + " case JSON_TOKEN_LITERAL_NULL: {\n"); for (i = 0; i < sdef->nElements; ++i) { - src = mputprintf(src, - "if (0 == strncmp(fld_name, \"%s\", name_len)) {\n" - " int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n" - " if (0 > ret_val) {\n" - " if (JSON_ERROR_INVALID_TOKEN) {\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, %lu, \"%s\");\n" - " }\n" - " return JSON_ERROR_FATAL;\n" - " } else {\n" - " dec_len += (size_t)ret_val;\n" - " }\n" - " } else " - , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname - , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname - , (unsigned long) strlen(sdef->elements[i].dispname), sdef->elements[i].dispname); + if (JSON_NULL & sdef->elements[i].jsonValueType) { + src = mputprintf(src, + " p_tok.set_buf_pos(buf_pos);\n" + " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, TRUE);\n" + " if (0 <= ret_val) {\n" + " return ret_val;\n" + " }\n" + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname); + } } src = mputstr(src, - "{\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, (int)name_len, fld_name);\n" - " return JSON_ERROR_FATAL;\n" - " }\n" - " }\n\n" - " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n" - " if (JSON_TOKEN_OBJECT_END != j_token) {\n" - " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n" + " clean_up();\n" + // the caller might be able to decode the null value if it's an optional field + // only return an invalid token error, not a fatal error + " return JSON_ERROR_INVALID_TOKEN;\n" + " }\n" + " case JSON_TOKEN_ERROR:\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n" " return JSON_ERROR_FATAL;\n" - " }\n\n" - " return (int)dec_len;\n" - " }\n"); + " default:\n" + " return JSON_ERROR_INVALID_TOKEN;\n" + " }\n" + " return ret_val;\n"); + if (!sdef->jsonAsValue) { + src = mputprintf(src, + " }\n" + " else {\n" // if there is no 'as value' set in the type descriptor + " size_t dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n" + " if (JSON_TOKEN_ERROR == j_token) {\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n" + " return JSON_ERROR_FATAL;\n" + " }\n" + " else if (JSON_TOKEN_OBJECT_START != j_token) {\n" + " return JSON_ERROR_INVALID_TOKEN;\n" + " }\n\n" + " char* fld_name = 0;\n" + " size_t name_len = 0;\n" + " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n" + " if (JSON_TOKEN_NAME != j_token) {\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n" + " return JSON_ERROR_FATAL;\n" + " } else {\n" + " union_selection = %s;\n " + , unbound_value); + for (i = 0; i < sdef->nElements; ++i) { + src = mputprintf(src, + "if (0 == strncmp(fld_name, \"%s\", name_len)) {\n" + " int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n" + " if (0 > ret_val) {\n" + " if (JSON_ERROR_INVALID_TOKEN) {\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, %lu, \"%s\");\n" + " }\n" + " return JSON_ERROR_FATAL;\n" + " } else {\n" + " dec_len += (size_t)ret_val;\n" + " }\n" + " } else " + , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname + , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname + , (unsigned long) strlen(sdef->elements[i].dispname), sdef->elements[i].dispname); + } + src = mputstr(src, + "{\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, (int)name_len, fld_name);\n" + " return JSON_ERROR_FATAL;\n" + " }\n" + " }\n\n" + " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n" + " if (JSON_TOKEN_OBJECT_END != j_token) {\n" + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n" + " return JSON_ERROR_FATAL;\n" + " }\n\n" + " return (int)dec_len;\n" + " }\n"); + } + src = mputstr(src, "}\n\n"); + } + else { // no fields + src = mputprintf(src, + " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, \n" + " \"Cannot decode union of type %s, because it has zero alternatives.\");\n" + " return JSON_ERROR_FATAL;\n" + "}\n\n", dispname); } - src = mputstr(src, "}\n\n"); } /* end of class definition */ -- GitLab