aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorThibault Charbonnier <thibaultcha@me.com>2016-02-28 20:03:12 -0800
committerThibault Charbonnier <thibaultcha@me.com>2016-03-03 10:54:53 -0800
commit7a9c25ee69f38974e99322971eace37ba1753074 (patch)
tree8aded977eea3eca5f7c6ff2934615a602dacbc8f /lua_cjson.c
parent77b8669c95500629dff6e34b4b6b0df5d0041ddf (diff)
downloadlua-cjson-7a9c25ee69f38974e99322971eace37ba1753074.tar.gz
lua-cjson-7a9c25ee69f38974e99322971eace37ba1753074.tar.bz2
lua-cjson-7a9c25ee69f38974e99322971eace37ba1753074.zip
feat: cjson.as_array metamethod to enforce empty array encoding
A proposed improved patch of openresty/lua-cjson#1 (a patch commonly proposed to lua-cjson and its forks), taking into considerations comments from the original PR. - use a lightuserdata key to store the metatable in the Lua Registry (more efficient and avoiding conflicts) - provide a lightuserdata resulting in empty arrays as well - tests cases moved to t/agentzh.t, where cases for 'encode_empty_table_as_object' are already written. It seems like a better place for tests specific to the OpenResty fork's additions. - a more complex test case
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 5ff3bf7..5f4faf2 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -75,6 +75,8 @@
75#define DEFAULT_DECODE_INVALID_NUMBERS 0 75#define DEFAULT_DECODE_INVALID_NUMBERS 0
76#endif 76#endif
77 77
78static const char * const *json_empty_array;
79
78typedef enum { 80typedef enum {
79 T_OBJ_BEGIN, 81 T_OBJ_BEGIN,
80 T_OBJ_END, 82 T_OBJ_END,
@@ -698,8 +700,21 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
698 len = lua_array_length(l, cfg, json); 700 len = lua_array_length(l, cfg, json);
699 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) 701 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object))
700 json_append_array(l, cfg, current_depth, json, len); 702 json_append_array(l, cfg, current_depth, json, len);
701 else 703 else {
702 json_append_object(l, cfg, current_depth, json); 704 int as_array = 0;
705 if (lua_getmetatable(l, -1)) {
706 lua_pushlightuserdata(l, &json_empty_array);
707 lua_rawget(l, LUA_REGISTRYINDEX);
708 as_array = lua_rawequal(l, -1, -2);
709 lua_pop(l, 2);
710 }
711
712 if (as_array) {
713 json_append_array(l, cfg, current_depth, json, 0);
714 } else {
715 json_append_object(l, cfg, current_depth, json);
716 }
717 }
703 break; 718 break;
704 case LUA_TNIL: 719 case LUA_TNIL:
705 strbuf_append_mem(json, "null", 4); 720 strbuf_append_mem(json, "null", 4);
@@ -707,8 +722,10 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
707 case LUA_TLIGHTUSERDATA: 722 case LUA_TLIGHTUSERDATA:
708 if (lua_touserdata(l, -1) == NULL) { 723 if (lua_touserdata(l, -1) == NULL) {
709 strbuf_append_mem(json, "null", 4); 724 strbuf_append_mem(json, "null", 4);
710 break; 725 } else if (lua_touserdata(l, -1) == &json_empty_array) {
726 json_append_array(l, cfg, current_depth, json, 0);
711 } 727 }
728 break;
712 default: 729 default:
713 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, 730 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
714 * and LUA_TLIGHTUSERDATA) cannot be serialised */ 731 * and LUA_TLIGHTUSERDATA) cannot be serialised */
@@ -1378,6 +1395,11 @@ static int lua_cjson_new(lua_State *l)
1378 /* Initialise number conversions */ 1395 /* Initialise number conversions */
1379 fpconv_init(); 1396 fpconv_init();
1380 1397
1398 /* Create empty array metatable */
1399 lua_pushlightuserdata(l, &json_empty_array);
1400 lua_newtable(l);
1401 lua_rawset(l, LUA_REGISTRYINDEX);
1402
1381 /* cjson module table */ 1403 /* cjson module table */
1382 lua_newtable(l); 1404 lua_newtable(l);
1383 1405
@@ -1389,6 +1411,15 @@ static int lua_cjson_new(lua_State *l)
1389 lua_pushlightuserdata(l, NULL); 1411 lua_pushlightuserdata(l, NULL);
1390 lua_setfield(l, -2, "null"); 1412 lua_setfield(l, -2, "null");
1391 1413
1414 /* Set cjson.empty_array_mt */
1415 lua_pushlightuserdata(l, &json_empty_array);
1416 lua_rawget(l, LUA_REGISTRYINDEX);
1417 lua_setfield(l, -2, "empty_array_mt");
1418
1419 /* Set cjson.empty_array */
1420 lua_pushlightuserdata(l, &json_empty_array);
1421 lua_setfield(l, -2, "empty_array");
1422
1392 /* Set module name / version fields */ 1423 /* Set module name / version fields */
1393 lua_pushliteral(l, CJSON_MODNAME); 1424 lua_pushliteral(l, CJSON_MODNAME);
1394 lua_setfield(l, -2, "_NAME"); 1425 lua_setfield(l, -2, "_NAME");