From f50a2225b137700b7454c7b8da1266bb2329ddf1 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 5 Mar 2015 17:42:42 +0800 Subject: [PATCH 1/4] Support lua 5.3 integer representation --- lua_cjson.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lua_cjson.c b/lua_cjson.c index c14a1c5c..40b4bdf4 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -81,6 +81,7 @@ typedef enum { T_ARR_END, T_STRING, T_NUMBER, + T_INTEGER, T_BOOLEAN, T_NULL, T_COLON, @@ -98,6 +99,7 @@ static const char *json_token_type_name[] = { "T_ARR_END", "T_STRING", "T_NUMBER", + "T_INTEGER", "T_BOOLEAN", "T_NULL", "T_COLON", @@ -143,6 +145,7 @@ typedef struct { union { const char *string; double number; + lua_Integer integer; int boolean; } value; int string_len; @@ -1002,13 +1005,18 @@ static int json_is_invalid_number(json_parse_t *json) static void json_next_number_token(json_parse_t *json, json_token_t *token) { char *endptr; - - token->type = T_NUMBER; - token->value.number = fpconv_strtod(json->ptr, &endptr); - if (json->ptr == endptr) + token->value.integer = strtoll(json->ptr, &endptr, 0); + if (json->ptr == endptr) { json_set_token_error(token, json, "invalid number"); - else - json->ptr = endptr; /* Skip the processed number */ + return; + } + if (*endptr == '.' || *endptr == 'e' || *endptr == 'E') { + token->type = T_NUMBER; + token->value.number = fpconv_strtod(json->ptr, &endptr); + } else { + token->type = T_INTEGER; + } + json->ptr = endptr; /* Skip the processed number */ return; } @@ -1237,6 +1245,9 @@ static void json_process_value(lua_State *l, json_parse_t *json, case T_NUMBER: lua_pushnumber(l, token->value.number); break;; + case T_INTEGER: + lua_pushinteger(l, token->value.integer); + break;; case T_BOOLEAN: lua_pushboolean(l, token->value.boolean); break;; From e02072ce28a5621725cbce23e32bbe3e38f0dcb3 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Tue, 1 Sep 2015 23:17:21 +0800 Subject: [PATCH 2/4] encode integer for lua 5.3 --- lua_cjson.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lua_cjson.c b/lua_cjson.c index 40b4bdf4..da80f0d4 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -589,8 +589,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept static void json_append_number(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex) { - double num = lua_tonumber(l, lindex); int len; +#if LUA_VERSION_NUM >= 503 + if (lua_isinteger(l, lindex)) { + lua_Integer num = lua_tointeger(l, lindex); + strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */ + len = lua_integer2str(strbuf_empty_ptr(json), num); + strbuf_extend_length(json, len); + return; + } +#endif + double num = lua_tonumber(l, lindex); if (cfg->encode_invalid_numbers == 0) { /* Prevent encoding invalid numbers */ From f5ee43d284d24c100bb11ecf286a04999bca6514 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Tue, 1 Dec 2015 22:21:19 +0800 Subject: [PATCH 3/4] Compatible with lua 5.3.2 --- lua_cjson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua_cjson.c b/lua_cjson.c index da80f0d4..2e918d77 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -594,7 +594,7 @@ static void json_append_number(lua_State *l, json_config_t *cfg, if (lua_isinteger(l, lindex)) { lua_Integer num = lua_tointeger(l, lindex); strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */ - len = lua_integer2str(strbuf_empty_ptr(json), num); + len = sprintf(strbuf_empty_ptr(json), LUA_INTEGER_FMT, num); strbuf_extend_length(json, len); return; } From 7cce6a1826a0cd997e962103a1842e1d17780a69 Mon Sep 17 00:00:00 2001 From: caijietao Date: Fri, 20 Jul 2018 13:27:43 +0800 Subject: [PATCH 4/4] support array hint --- lua_cjson.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lua_cjson.c b/lua_cjson.c index 2e918d77..8de6d49e 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -696,11 +696,22 @@ static void json_append_data(lua_State *l, json_config_t *cfg, case LUA_TTABLE: current_depth++; json_check_encode_depth(l, cfg, current_depth, json); - len = lua_array_length(l, cfg, json); - if (len > 0) + if (luaL_getmetafield(l, -1, "__len") != LUA_TNIL) { + lua_pushvalue(l, -2); + lua_call(l, 1, 1); + if (!lua_isinteger(l, -1)) { + luaL_error(l, "__len should return integer"); + } + len = lua_tointeger(l, -1); + lua_pop(l, 1); json_append_array(l, cfg, current_depth, json, len); - else - json_append_object(l, cfg, current_depth, json); + } else { + len = lua_array_length(l, cfg, json); + if (len > 0) + json_append_array(l, cfg, current_depth, json, len); + else + json_append_object(l, cfg, current_depth, json); + } break; case LUA_TNIL: strbuf_append_mem(json, "null", 4);