9191#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
9292#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
9393#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
94+ #define DEFAULT_ENCODE_INDENT NULL
9495
9596#ifdef DISABLE_INVALID_NUMBERS
9697#undef DEFAULT_DECODE_INVALID_NUMBERS
@@ -172,6 +173,7 @@ typedef struct {
172173 int encode_keep_buffer ;
173174 int encode_empty_table_as_object ;
174175 int encode_escape_forward_slash ;
176+ const char * encode_indent ;
175177
176178 int decode_invalid_numbers ;
177179 int decode_max_depth ;
@@ -310,6 +312,18 @@ static int json_enum_option(lua_State *l, int optindex, int *setting,
310312 return 1 ;
311313}
312314
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+
313327/* Configures handling of extremely sparse arrays:
314328 * convert: Convert extremely sparse arrays into objects? Otherwise error.
315329 * 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)
400414 return 1 ;
401415}
402416
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+
403429#if defined(DISABLE_INVALID_NUMBERS ) && !defined(USE_INTERNAL_FPCONV )
404430void json_verify_invalid_number_setting (lua_State * l , int * setting )
405431{
@@ -491,6 +517,7 @@ static void json_create_config(lua_State *l)
491517 cfg -> decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT ;
492518 cfg -> encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH ;
493519 cfg -> encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES ;
520+ cfg -> encode_indent = DEFAULT_ENCODE_INDENT ;
494521
495522#if DEFAULT_ENCODE_KEEP_BUFFER > 0
496523 strbuf_init (& cfg -> encode_buf , 0 );
@@ -660,6 +687,13 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
660687static int json_append_data (lua_State * l , json_config_t * cfg ,
661688 int current_depth , strbuf_t * json );
662689
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+
663697/* json_append_array args:
664698 * - lua_State
665699 * - JSON strbuf
@@ -668,15 +702,21 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
668702 strbuf_t * json , int array_length , int raw )
669703{
670704 int comma , i , json_pos , err ;
705+ int has_items = 0 ;
671706
672707 strbuf_append_char (json , '[' );
673708
674709 comma = 0 ;
675710 for (i = 1 ; i <= array_length ; i ++ ) {
711+ has_items = 1 ;
712+
676713 json_pos = strbuf_length (json );
677714 if (comma ++ > 0 )
678715 strbuf_append_char (json , ',' );
679716
717+ if (cfg -> encode_indent )
718+ json_append_newline_and_indent (json , cfg , current_depth );
719+
680720 if (raw ) {
681721 lua_rawgeti (l , -1 , i );
682722 } else {
@@ -698,6 +738,9 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
698738 lua_pop (l , 1 );
699739 }
700740
741+ if (has_items && cfg -> encode_indent )
742+ json_append_newline_and_indent (json , cfg , current_depth - 1 );
743+
701744 strbuf_append_char (json , ']' );
702745}
703746
@@ -752,6 +795,7 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
752795 int current_depth , strbuf_t * json )
753796{
754797 int comma , keytype , json_pos , err ;
798+ int has_items = 0 ;
755799
756800 /* Object */
757801 strbuf_append_char (json , '{' );
@@ -760,10 +804,15 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
760804 /* table, startkey */
761805 comma = 0 ;
762806 while (lua_next (l , -2 ) != 0 ) {
807+ has_items = 1 ;
808+
763809 json_pos = strbuf_length (json );
764810 if (comma ++ > 0 )
765811 strbuf_append_char (json , ',' );
766812
813+ if (cfg -> encode_indent )
814+ json_append_newline_and_indent (json , cfg , current_depth );
815+
767816 /* table, key, value */
768817 keytype = lua_type (l , -2 );
769818 if (keytype == LUA_TNUMBER ) {
@@ -778,6 +827,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
778827 "table key must be a number or string" );
779828 /* never returns */
780829 }
830+ if (cfg -> encode_indent )
831+ strbuf_append_char (json , ' ' );
832+
781833
782834 /* table, key, value */
783835 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,
792844 /* table, key */
793845 }
794846
847+ if (has_items && cfg -> encode_indent )
848+ json_append_newline_and_indent (json , cfg , current_depth - 1 );
849+
795850 strbuf_append_char (json , '}' );
796851}
797852
@@ -1571,6 +1626,7 @@ static int lua_cjson_new(lua_State *l)
15711626 { "decode_invalid_numbers" , json_cfg_decode_invalid_numbers },
15721627 { "encode_escape_forward_slash" , json_cfg_encode_escape_forward_slash },
15731628 { "encode_skip_unsupported_value_types" , json_cfg_encode_skip_unsupported_value_types },
1629+ { "encode_indent" , json_cfg_encode_indent },
15741630 { "new" , lua_cjson_new },
15751631 { NULL , NULL }
15761632 };
0 commit comments