aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorThibault Charbonnier <thibaultcha@me.com>2017-07-08 21:54:18 -0700
committerYichun Zhang (agentzh) <agentzh@gmail.com>2017-11-15 20:41:57 -0800
commit5f9efa4829a72935ddcd40c7da6b1a9e10939b65 (patch)
tree319cdf13f99c753f85820c3fabb89bfa50496dae /lua_cjson.c
parenta9af7965219710ac1ec1e2bbf1a63eb77be622b7 (diff)
downloadlua-cjson-5f9efa4829a72935ddcd40c7da6b1a9e10939b65.tar.gz
lua-cjson-5f9efa4829a72935ddcd40c7da6b1a9e10939b65.tar.bz2
lua-cjson-5f9efa4829a72935ddcd40c7da6b1a9e10939b65.zip
feature: added new cjson.array_mt metatable to allow enforcing JSON array encoding.
Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index d04f151..8d6e313 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -92,6 +92,7 @@
92#endif 92#endif
93 93
94static const char * const *json_empty_array; 94static const char * const *json_empty_array;
95static const char * const *json_array;
95 96
96typedef enum { 97typedef enum {
97 T_OBJ_BEGIN, 98 T_OBJ_BEGIN,
@@ -713,21 +714,37 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
713 case LUA_TTABLE: 714 case LUA_TTABLE:
714 current_depth++; 715 current_depth++;
715 json_check_encode_depth(l, cfg, current_depth, json); 716 json_check_encode_depth(l, cfg, current_depth, json);
716 len = lua_array_length(l, cfg, json); 717
717 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) 718 int as_array = 0;
719 int has_metatable = lua_getmetatable(l, -1);
720
721 if (has_metatable) {
722 lua_pushlightuserdata(l, &json_array);
723 lua_rawget(l, LUA_REGISTRYINDEX);
724 as_array = lua_rawequal(l, -1, -2);
725 lua_pop(l, 2);
726 }
727
728 if (as_array) {
729 len = lua_objlen(l, -1);
718 json_append_array(l, cfg, current_depth, json, len); 730 json_append_array(l, cfg, current_depth, json, len);
719 else { 731 } else {
720 int as_array = 0; 732 len = lua_array_length(l, cfg, json);
721 if (lua_getmetatable(l, -1)) {
722 lua_pushlightuserdata(l, &json_empty_array);
723 lua_rawget(l, LUA_REGISTRYINDEX);
724 as_array = lua_rawequal(l, -1, -2);
725 lua_pop(l, 2);
726 }
727 733
728 if (as_array) { 734 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) {
729 json_append_array(l, cfg, current_depth, json, 0); 735 json_append_array(l, cfg, current_depth, json, len);
730 } else { 736 } else {
737 if (has_metatable) {
738 lua_getmetatable(l, -1);
739 lua_pushlightuserdata(l, &json_empty_array);
740 lua_rawget(l, LUA_REGISTRYINDEX);
741 as_array = lua_rawequal(l, -1, -2);
742 lua_pop(l, 2); /* pop pointer + metatable */
743 if (as_array) {
744 json_append_array(l, cfg, current_depth, json, 0);
745 break;
746 }
747 }
731 json_append_object(l, cfg, current_depth, json); 748 json_append_object(l, cfg, current_depth, json);
732 } 749 }
733 } 750 }
@@ -738,7 +755,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
738 case LUA_TLIGHTUSERDATA: 755 case LUA_TLIGHTUSERDATA:
739 if (lua_touserdata(l, -1) == NULL) { 756 if (lua_touserdata(l, -1) == NULL) {
740 strbuf_append_mem(json, "null", 4); 757 strbuf_append_mem(json, "null", 4);
741 } else if (lua_touserdata(l, -1) == &json_empty_array) { 758 } else if (lua_touserdata(l, -1) == &json_array) {
742 json_append_array(l, cfg, current_depth, json, 0); 759 json_append_array(l, cfg, current_depth, json, 0);
743 } 760 }
744 break; 761 break;
@@ -1412,20 +1429,27 @@ static int lua_cjson_new(lua_State *l)
1412 /* Initialise number conversions */ 1429 /* Initialise number conversions */
1413 fpconv_init(); 1430 fpconv_init();
1414 1431
1415 /* Test if empty array metatable is in registry */ 1432 /* Test if array metatables are in registry */
1416 lua_pushlightuserdata(l, &json_empty_array); 1433 lua_pushlightuserdata(l, &json_empty_array);
1417 lua_rawget(l, LUA_REGISTRYINDEX); 1434 lua_rawget(l, LUA_REGISTRYINDEX);
1418 if (lua_isnil(l, -1)) { 1435 if (lua_isnil(l, -1)) {
1419 /* Create empty array metatable. 1436 /* Create array metatables.
1420 * 1437 *
1421 * If multiple calls to lua_cjson_new() are made, 1438 * If multiple calls to lua_cjson_new() are made,
1422 * this prevents overriding the table at the given 1439 * this prevents overriding the tables at the given
1423 * registry's index with a new one. 1440 * registry's index with a new one.
1424 */ 1441 */
1425 lua_pop(l, 1); 1442 lua_pop(l, 1);
1443
1444 /* empty_array_mt */
1426 lua_pushlightuserdata(l, &json_empty_array); 1445 lua_pushlightuserdata(l, &json_empty_array);
1427 lua_newtable(l); 1446 lua_newtable(l);
1428 lua_rawset(l, LUA_REGISTRYINDEX); 1447 lua_rawset(l, LUA_REGISTRYINDEX);
1448
1449 /* array_mt */
1450 lua_pushlightuserdata(l, &json_array);
1451 lua_newtable(l);
1452 lua_rawset(l, LUA_REGISTRYINDEX);
1429 } 1453 }
1430 1454
1431 /* cjson module table */ 1455 /* cjson module table */
@@ -1444,8 +1468,13 @@ static int lua_cjson_new(lua_State *l)
1444 lua_rawget(l, LUA_REGISTRYINDEX); 1468 lua_rawget(l, LUA_REGISTRYINDEX);
1445 lua_setfield(l, -2, "empty_array_mt"); 1469 lua_setfield(l, -2, "empty_array_mt");
1446 1470
1471 /* Set cjson.array_mt */
1472 lua_pushlightuserdata(l, &json_array);
1473 lua_rawget(l, LUA_REGISTRYINDEX);
1474 lua_setfield(l, -2, "array_mt");
1475
1447 /* Set cjson.empty_array */ 1476 /* Set cjson.empty_array */
1448 lua_pushlightuserdata(l, &json_empty_array); 1477 lua_pushlightuserdata(l, &json_array);
1449 lua_setfield(l, -2, "empty_array"); 1478 lua_setfield(l, -2, "empty_array");
1450 1479
1451 /* Set module name / version fields */ 1480 /* Set module name / version fields */