diff options
Diffstat (limited to '')
| -rw-r--r-- | lua_cjson.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index 93b81e6..789817d 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
| @@ -91,6 +91,7 @@ | |||
| 91 | #define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 | 91 | #define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 |
| 92 | #define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 | 92 | #define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 |
| 93 | #define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0 | 93 | #define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0 |
| 94 | #define DEFAULT_ENCODE_INDENT NULL | ||
| 94 | 95 | ||
| 95 | #ifdef DISABLE_INVALID_NUMBERS | 96 | #ifdef DISABLE_INVALID_NUMBERS |
| 96 | #undef DEFAULT_DECODE_INVALID_NUMBERS | 97 | #undef DEFAULT_DECODE_INVALID_NUMBERS |
| @@ -172,6 +173,7 @@ typedef struct { | |||
| 172 | int encode_keep_buffer; | 173 | int encode_keep_buffer; |
| 173 | int encode_empty_table_as_object; | 174 | int encode_empty_table_as_object; |
| 174 | int encode_escape_forward_slash; | 175 | int encode_escape_forward_slash; |
| 176 | const char *encode_indent; | ||
| 175 | 177 | ||
| 176 | int decode_invalid_numbers; | 178 | int decode_invalid_numbers; |
| 177 | int decode_max_depth; | 179 | int decode_max_depth; |
| @@ -310,6 +312,18 @@ static int json_enum_option(lua_State *l, int optindex, int *setting, | |||
| 310 | return 1; | 312 | return 1; |
| 311 | } | 313 | } |
| 312 | 314 | ||
| 315 | /* Process string option for a configuration function */ | ||
| 316 | static int json_string_option(lua_State *l, int optindex, const char **setting) | ||
| 317 | { | ||
| 318 | if (!lua_isnil(l, optindex)) { | ||
| 319 | const char *value = luaL_checkstring(l, optindex); | ||
| 320 | *setting = value; | ||
| 321 | } | ||
| 322 | |||
| 323 | lua_pushstring(l, *setting ? *setting : ""); | ||
| 324 | return 1; | ||
| 325 | } | ||
| 326 | |||
| 313 | /* Configures handling of extremely sparse arrays: | 327 | /* Configures handling of extremely sparse arrays: |
| 314 | * convert: Convert extremely sparse arrays into objects? Otherwise error. | 328 | * convert: Convert extremely sparse arrays into objects? Otherwise error. |
| 315 | * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio | 329 | * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio |
| @@ -400,6 +414,18 @@ static int json_cfg_encode_keep_buffer(lua_State *l) | |||
| 400 | return 1; | 414 | return 1; |
| 401 | } | 415 | } |
| 402 | 416 | ||
| 417 | /* Configure how to indent output */ | ||
| 418 | static int json_cfg_encode_indent(lua_State *l) | ||
| 419 | { | ||
| 420 | json_config_t *cfg = json_arg_init(l, 1); | ||
| 421 | |||
| 422 | json_string_option(l, 1, &cfg->encode_indent); | ||
| 423 | /* simplify further checking */ | ||
| 424 | if (cfg->encode_indent[0] == '\0') cfg->encode_indent = NULL; | ||
| 425 | |||
| 426 | return 1; | ||
| 427 | } | ||
| 428 | |||
| 403 | #if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) | 429 | #if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) |
| 404 | void json_verify_invalid_number_setting(lua_State *l, int *setting) | 430 | void json_verify_invalid_number_setting(lua_State *l, int *setting) |
| 405 | { | 431 | { |
| @@ -491,6 +517,7 @@ static void json_create_config(lua_State *l) | |||
| 491 | cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; | 517 | cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; |
| 492 | cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; | 518 | cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; |
| 493 | cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; | 519 | cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; |
| 520 | cfg->encode_indent = DEFAULT_ENCODE_INDENT; | ||
| 494 | 521 | ||
| 495 | #if DEFAULT_ENCODE_KEEP_BUFFER > 0 | 522 | #if DEFAULT_ENCODE_KEEP_BUFFER > 0 |
| 496 | strbuf_init(&cfg->encode_buf, 0); | 523 | strbuf_init(&cfg->encode_buf, 0); |
| @@ -660,6 +687,13 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg, | |||
| 660 | static int json_append_data(lua_State *l, json_config_t *cfg, | 687 | static int json_append_data(lua_State *l, json_config_t *cfg, |
| 661 | int current_depth, strbuf_t *json); | 688 | int current_depth, strbuf_t *json); |
| 662 | 689 | ||
| 690 | static void json_append_newline_and_indent(strbuf_t *json, json_config_t *cfg, int depth) | ||
| 691 | { | ||
| 692 | strbuf_append_char(json, '\n'); | ||
| 693 | for (int i = 0; i < depth; i++) | ||
| 694 | strbuf_append_string(json, cfg->encode_indent); | ||
| 695 | } | ||
| 696 | |||
| 663 | /* json_append_array args: | 697 | /* json_append_array args: |
| 664 | * - lua_State | 698 | * - lua_State |
| 665 | * - JSON strbuf | 699 | * - JSON strbuf |
| @@ -668,15 +702,21 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept | |||
| 668 | strbuf_t *json, int array_length, int raw) | 702 | strbuf_t *json, int array_length, int raw) |
| 669 | { | 703 | { |
| 670 | int comma, i, json_pos, err; | 704 | int comma, i, json_pos, err; |
| 705 | int has_items = 0; | ||
| 671 | 706 | ||
| 672 | strbuf_append_char(json, '['); | 707 | strbuf_append_char(json, '['); |
| 673 | 708 | ||
| 674 | comma = 0; | 709 | comma = 0; |
| 675 | for (i = 1; i <= array_length; i++) { | 710 | for (i = 1; i <= array_length; i++) { |
| 711 | has_items = 1; | ||
| 712 | |||
| 676 | json_pos = strbuf_length(json); | 713 | json_pos = strbuf_length(json); |
| 677 | if (comma++ > 0) | 714 | if (comma++ > 0) |
| 678 | strbuf_append_char(json, ','); | 715 | strbuf_append_char(json, ','); |
| 679 | 716 | ||
| 717 | if (cfg->encode_indent) | ||
| 718 | json_append_newline_and_indent(json, cfg, current_depth); | ||
| 719 | |||
| 680 | if (raw) { | 720 | if (raw) { |
| 681 | lua_rawgeti(l, -1, i); | 721 | lua_rawgeti(l, -1, i); |
| 682 | } else { | 722 | } else { |
| @@ -698,6 +738,9 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept | |||
| 698 | lua_pop(l, 1); | 738 | lua_pop(l, 1); |
| 699 | } | 739 | } |
| 700 | 740 | ||
| 741 | if (has_items && cfg->encode_indent) | ||
| 742 | json_append_newline_and_indent(json, cfg, current_depth-1); | ||
| 743 | |||
| 701 | strbuf_append_char(json, ']'); | 744 | strbuf_append_char(json, ']'); |
| 702 | } | 745 | } |
| 703 | 746 | ||
| @@ -752,6 +795,7 @@ static void json_append_object(lua_State *l, json_config_t *cfg, | |||
| 752 | int current_depth, strbuf_t *json) | 795 | int current_depth, strbuf_t *json) |
| 753 | { | 796 | { |
| 754 | int comma, keytype, json_pos, err; | 797 | int comma, keytype, json_pos, err; |
| 798 | int has_items = 0; | ||
| 755 | 799 | ||
| 756 | /* Object */ | 800 | /* Object */ |
| 757 | strbuf_append_char(json, '{'); | 801 | strbuf_append_char(json, '{'); |
| @@ -760,10 +804,15 @@ static void json_append_object(lua_State *l, json_config_t *cfg, | |||
| 760 | /* table, startkey */ | 804 | /* table, startkey */ |
| 761 | comma = 0; | 805 | comma = 0; |
| 762 | while (lua_next(l, -2) != 0) { | 806 | while (lua_next(l, -2) != 0) { |
| 807 | has_items = 1; | ||
| 808 | |||
| 763 | json_pos = strbuf_length(json); | 809 | json_pos = strbuf_length(json); |
| 764 | if (comma++ > 0) | 810 | if (comma++ > 0) |
| 765 | strbuf_append_char(json, ','); | 811 | strbuf_append_char(json, ','); |
| 766 | 812 | ||
| 813 | if (cfg->encode_indent) | ||
| 814 | json_append_newline_and_indent(json, cfg, current_depth); | ||
| 815 | |||
| 767 | /* table, key, value */ | 816 | /* table, key, value */ |
| 768 | keytype = lua_type(l, -2); | 817 | keytype = lua_type(l, -2); |
| 769 | if (keytype == LUA_TNUMBER) { | 818 | if (keytype == LUA_TNUMBER) { |
| @@ -778,6 +827,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg, | |||
| 778 | "table key must be a number or string"); | 827 | "table key must be a number or string"); |
| 779 | /* never returns */ | 828 | /* never returns */ |
| 780 | } | 829 | } |
| 830 | if (cfg->encode_indent) | ||
| 831 | strbuf_append_char(json, ' '); | ||
| 832 | |||
| 781 | 833 | ||
| 782 | /* table, key, value */ | 834 | /* table, key, value */ |
| 783 | err = json_append_data(l, cfg, current_depth, json); | 835 | err = json_append_data(l, cfg, current_depth, json); |
| @@ -792,6 +844,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg, | |||
| 792 | /* table, key */ | 844 | /* table, key */ |
| 793 | } | 845 | } |
| 794 | 846 | ||
| 847 | if (has_items && cfg->encode_indent) | ||
| 848 | json_append_newline_and_indent(json, cfg, current_depth-1); | ||
| 849 | |||
| 795 | strbuf_append_char(json, '}'); | 850 | strbuf_append_char(json, '}'); |
| 796 | } | 851 | } |
| 797 | 852 | ||
| @@ -1579,6 +1634,7 @@ static int lua_cjson_new(lua_State *l) | |||
| 1579 | { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, | 1634 | { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, |
| 1580 | { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, | 1635 | { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, |
| 1581 | { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types }, | 1636 | { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types }, |
| 1637 | { "encode_indent", json_cfg_encode_indent }, | ||
| 1582 | { "new", lua_cjson_new }, | 1638 | { "new", lua_cjson_new }, |
| 1583 | { NULL, NULL } | 1639 | { NULL, NULL } |
| 1584 | }; | 1640 | }; |
