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 | |
| 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 */ |
