diff options
author | Thibault Charbonnier <thibaultcha@me.com> | 2017-07-08 21:54:18 -0700 |
---|---|---|
committer | Yichun Zhang (agentzh) <agentzh@gmail.com> | 2017-11-15 20:41:57 -0800 |
commit | 5f9efa4829a72935ddcd40c7da6b1a9e10939b65 (patch) | |
tree | 319cdf13f99c753f85820c3fabb89bfa50496dae /lua_cjson.c | |
parent | a9af7965219710ac1ec1e2bbf1a63eb77be622b7 (diff) | |
download | lua-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 '')
-rw-r--r-- | lua_cjson.c | 63 |
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 | ||
94 | static const char * const *json_empty_array; | 94 | static const char * const *json_empty_array; |
95 | static const char * const *json_array; | ||
95 | 96 | ||
96 | typedef enum { | 97 | typedef 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 */ |