From 3b1429fabbaa6c2fc3d8c0f7c83b3810e530caf9 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Thu, 9 Apr 2015 17:25:47 +0800 Subject: [PATCH] option to force to encode empty table to "[]" Since lua-cjson use table index type to decide what type a lua table is encoded to, there is no way to encode empty lua type to list. This patch solves this problem by assigning a special meta-table to an empty table to force it to be encoded to "[]" instead of "{}": setmetatable({},cjson.as_array) --- lua_cjson.c | 23 +++++++++++++++++++++-- tests/test.lua | 7 +++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lua_cjson.c b/lua_cjson.c index c14a1c5..0452bcd 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -74,6 +74,8 @@ #define DEFAULT_DECODE_INVALID_NUMBERS 0 #endif +#define MT_AS_ARRAY "MT_AS_ARRAY" + typedef enum { T_OBJ_BEGIN, T_OBJ_END, @@ -687,8 +689,22 @@ static void json_append_data(lua_State *l, json_config_t *cfg, 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); + else { + int is_array = 0; + int got = lua_getmetatable(l, -1); + if (got > 0) { + luaL_getmetatable(l, MT_AS_ARRAY); + is_array = lua_rawequal(l, -1, -2); + lua_pop(l, 2); + } + + if (is_array) { + json_append_array(l, cfg, current_depth, json, 0); + } + else { + json_append_object(l, cfg, current_depth, json); + } + } break; case LUA_TNIL: strbuf_append_mem(json, "null", 4); @@ -1377,6 +1393,9 @@ static int lua_cjson_new(lua_State *l) lua_pushlightuserdata(l, NULL); lua_setfield(l, -2, "null"); + luaL_newmetatable(l, MT_AS_ARRAY); + lua_setfield(l, -2, "as_array"); + /* Set module name / version fields */ lua_pushliteral(l, CJSON_MODNAME); lua_setfield(l, -2, "_NAME"); diff --git a/tests/test.lua b/tests/test.lua index b8fce84..19f2f26 100755 --- a/tests/test.lua +++ b/tests/test.lua @@ -89,6 +89,9 @@ local NaN = math.huge * 0; local testdata = load_testdata() +local empty_array = {} +setmetatable(empty_array, json.as_array) + local cjson_tests = { -- Test API variables { "Check module name, version", @@ -212,6 +215,10 @@ local cjson_tests = { json.encode, { 10 }, true, { '10' } }, { "Encode string", json.encode, { "hello" }, true, { '"hello"' } }, + { "Encode empty table as array", + json.encode, { empty_array }, true, { '[]' } }, + { "Encode empty table as table", + json.encode, { {} }, true, { '{}' } }, { "Encode Lua function [throw error]", json.encode, { function () end }, false, { "Cannot serialise function: type not supported" } },