diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/json/json.c | 47 | ||||
| -rw-r--r-- | ext/json/php_json.h | 2 | ||||
| -rw-r--r-- | ext/json/tests/json_encode_pretty_print.phpt | 40 |
3 files changed, 88 insertions, 1 deletions
diff --git a/ext/json/json.c b/ext/json/json.c index 1836c7f7e2..95766106df 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -94,6 +94,7 @@ static PHP_MINIT_FUNCTION(json) REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT); @@ -113,6 +114,7 @@ static PHP_MINIT_FUNCTION(json) */ static PHP_GINIT_FUNCTION(json) { + json_globals->encoder_depth = 0; json_globals->error_code = 0; } /* }}} */ @@ -189,6 +191,30 @@ static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ } /* }}} */ +/* {{{ Pretty printing support functions */ + +static inline void json_pretty_print_char(smart_str *buf, int options, char c TSRMLS_DC) /* {{{ */ +{ + if (options & PHP_JSON_PRETTY_PRINT) { + smart_str_appendc(buf, c); + } +} +/* }}} */ + +static inline void json_pretty_print_indent(smart_str *buf, int options TSRMLS_DC) /* {{{ */ +{ + int i; + + if (options & PHP_JSON_PRETTY_PRINT) { + for (i = 0; i < JSON_G(encoder_depth); ++i) { + smart_str_appendl(buf, " ", 4); + } + } +} +/* }}} */ + +/* }}} */ + static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */ { int i, r; @@ -214,6 +240,9 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) smart_str_appendc(buf, '{'); } + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + ++JSON_G(encoder_depth); + i = myht ? zend_hash_num_elements(myht) : 0; if (i > 0) @@ -241,10 +270,12 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) if (r == PHP_JSON_OUTPUT_ARRAY) { if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } - + + json_pretty_print_indent(buf, options TSRMLS_CC); php_json_encode(buf, *data, options TSRMLS_CC); } else if (r == PHP_JSON_OUTPUT_OBJECT) { if (i == HASH_KEY_IS_STRING) { @@ -258,26 +289,36 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } + json_pretty_print_indent(buf, options TSRMLS_CC); + json_escape_string(buf, key, key_len - 1, options TSRMLS_CC); smart_str_appendc(buf, ':'); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); + php_json_encode(buf, *data, options TSRMLS_CC); } else { if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } + json_pretty_print_indent(buf, options TSRMLS_CC); + smart_str_appendc(buf, '"'); smart_str_append_long(buf, (long) index); smart_str_appendc(buf, '"'); smart_str_appendc(buf, ':'); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); + php_json_encode(buf, *data, options TSRMLS_CC); } } @@ -288,6 +329,10 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) } } } + + --JSON_G(encoder_depth); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + json_pretty_print_indent(buf, options TSRMLS_CC); if (r == PHP_JSON_OUTPUT_ARRAY) { smart_str_appendc(buf, ']'); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index c321ad292a..7b1c7b72ff 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -38,6 +38,7 @@ extern zend_module_entry json_module_entry; #endif ZEND_BEGIN_MODULE_GLOBALS(json) + int encoder_depth; int error_code; ZEND_END_MODULE_GLOBALS(json) @@ -60,6 +61,7 @@ extern zend_class_entry *php_json_serializable_ce; #define PHP_JSON_FORCE_OBJECT (1<<4) #define PHP_JSON_NUMERIC_CHECK (1<<5) #define PHP_JSON_UNESCAPED_SLASHES (1<<6) +#define PHP_JSON_PRETTY_PRINT (1<<7) /* Internal flags */ #define PHP_JSON_OUTPUT_ARRAY 0 diff --git a/ext/json/tests/json_encode_pretty_print.phpt b/ext/json/tests/json_encode_pretty_print.phpt new file mode 100644 index 0000000000..43b93aafe6 --- /dev/null +++ b/ext/json/tests/json_encode_pretty_print.phpt @@ -0,0 +1,40 @@ +--TEST-- +json_encode() with JSON_PRETTY_PRINT +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php +function encode_decode($json) { + $struct = json_decode($json); + $pretty = json_encode($struct, JSON_PRETTY_PRINT); + echo "$pretty\n"; + $pretty = json_decode($pretty); + printf("Match: %d\n", $pretty == $struct); +} + +encode_decode('[1,2,3,[1,2,3]]'); +encode_decode('{"a":1,"b":[1,2],"c":{"d":42}}'); +?> +--EXPECT-- +[ + 1, + 2, + 3, + [ + 1, + 2, + 3 + ] +] +Match: 1 +{ + "a": 1, + "b": [ + 1, + 2 + ], + "c": { + "d": 42 + } +} +Match: 1 |
