From de93a78d3002ee72bb1c7e3a629d67e19623a4ae Mon Sep 17 00:00:00 2001 From: lijunlong Date: Wed, 22 Feb 2023 11:28:15 +0800 Subject: feature: Add option to skip invalid value types. Co-authored-by: Jesper Lundgren --- lua_cjson.c | 59 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'lua_cjson.c') diff --git a/lua_cjson.c b/lua_cjson.c index 94b0b46..42672de 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -82,6 +82,7 @@ #define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 1 #define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 #define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 +#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0 #ifdef DISABLE_INVALID_NUMBERS #undef DEFAULT_DECODE_INVALID_NUMBERS @@ -165,6 +166,7 @@ typedef struct { int decode_invalid_numbers; int decode_max_depth; int decode_array_with_array_mt; + int encode_skip_unsupported_value_types; } json_config_t; typedef struct { @@ -356,6 +358,16 @@ static int json_cfg_decode_array_with_array_mt(lua_State *l) return 1; } +/* Configure how to treat invalid types */ +static int json_cfg_encode_skip_unsupported_value_types(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + + json_enum_option(l, 1, &cfg->encode_skip_unsupported_value_types, NULL, 1); + + return 1; +} + /* Configures JSON encoding buffer persistence */ static int json_cfg_encode_keep_buffer(lua_State *l) { @@ -463,6 +475,7 @@ static void json_create_config(lua_State *l) cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT; cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; + cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; #if DEFAULT_ENCODE_KEEP_BUFFER > 0 strbuf_init(&cfg->encode_buf, 0); @@ -627,7 +640,7 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg, current_depth); } -static void json_append_data(lua_State *l, json_config_t *cfg, +static int json_append_data(lua_State *l, json_config_t *cfg, int current_depth, strbuf_t *json); /* json_append_array args: @@ -637,19 +650,24 @@ static void json_append_data(lua_State *l, json_config_t *cfg, static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth, strbuf_t *json, int array_length) { - int comma, i; + int comma, i, json_pos, err; strbuf_append_char(json, '['); comma = 0; for (i = 1; i <= array_length; i++) { - if (comma) + json_pos = strbuf_length(json); + if (comma++ > 0) strbuf_append_char(json, ','); - else - comma = 1; lua_rawgeti(l, -1, i); - json_append_data(l, cfg, current_depth, json); + err = json_append_data(l, cfg, current_depth, json); + if (err) { + strbuf_set_length(json, json_pos); + if (comma == 1) { + comma = 0; + } + } lua_pop(l, 1); } @@ -697,7 +715,7 @@ static void json_append_number(lua_State *l, json_config_t *cfg, static void json_append_object(lua_State *l, json_config_t *cfg, int current_depth, strbuf_t *json) { - int comma, keytype; + int comma, keytype, json_pos, err; /* Object */ strbuf_append_char(json, '{'); @@ -706,10 +724,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg, /* table, startkey */ comma = 0; while (lua_next(l, -2) != 0) { - if (comma) + json_pos = strbuf_length(json); + if (comma++ > 0) strbuf_append_char(json, ','); - else - comma = 1; /* table, key, value */ keytype = lua_type(l, -2); @@ -727,7 +744,14 @@ static void json_append_object(lua_State *l, json_config_t *cfg, } /* table, key, value */ - json_append_data(l, cfg, current_depth, json); + err = json_append_data(l, cfg, current_depth, json); + if (err) { + strbuf_set_length(json, json_pos); + if (comma == 1) { + comma = 0; + } + } + lua_pop(l, 1); /* table, key */ } @@ -735,8 +759,8 @@ static void json_append_object(lua_State *l, json_config_t *cfg, strbuf_append_char(json, '}'); } -/* Serialise Lua data into JSON string. */ -static void json_append_data(lua_State *l, json_config_t *cfg, +/* Serialise Lua data into JSON string. Return 1 if error an error happened, else 0 */ +static int json_append_data(lua_State *l, json_config_t *cfg, int current_depth, strbuf_t *json) { int len; @@ -807,9 +831,15 @@ static void json_append_data(lua_State *l, json_config_t *cfg, default: /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, * and LUA_TLIGHTUSERDATA) cannot be serialised */ - json_encode_exception(l, cfg, json, -1, "type not supported"); + if (cfg->encode_skip_unsupported_value_types) { + return 1; + } else { + json_encode_exception(l, cfg, json, -1, "type not supported"); + } + /* never returns */ } + return 0; } static int json_encode(lua_State *l) @@ -1479,6 +1509,7 @@ static int lua_cjson_new(lua_State *l) { "encode_invalid_numbers", json_cfg_encode_invalid_numbers }, { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, + { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types }, { "new", lua_cjson_new }, { NULL, NULL } }; -- cgit v1.2.3-55-g6feb