diff options
author | Jakub Zelenka <bukka@php.net> | 2015-01-10 19:42:28 +0000 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2015-01-11 13:30:21 +0000 |
commit | e6fb493e5dbafdad37ba5334c986636342b5d9aa (patch) | |
tree | abb9f23161039856d15fbd09c6c7c816eac599a6 /ext/json/json_encoder.c | |
parent | 8304e468cdd9de651407935c8630884896233228 (diff) | |
download | php-git-e6fb493e5dbafdad37ba5334c986636342b5d9aa.tar.gz |
Refactore json double encoding to use php_gcvt
Diffstat (limited to 'ext/json/json_encoder.c')
-rw-r--r-- | ext/json/json_encoder.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 20e6dbd7c4..8657fd2cdb 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -30,6 +30,14 @@ #include "php_json.h" #include <zend_exceptions.h> +/* double limits */ +#include <float.h> +#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) +#define PHP_JSON_DOUBLE_MAX_LENGTH (1 + DBL_MANT_DIG - DBL_MIN_EXP) +#else +#define PHP_JSON_DOUBLE_MAX_LENGTH 1078 +#endif + ZEND_DECLARE_MODULE_GLOBALS(json) static const char digits[] = "0123456789abcdef"; @@ -87,6 +95,21 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options) /* /* }}} */ +static inline void php_json_encode_double(smart_str *buf, double d) /* {{{ */ +{ + if (!zend_isinf(d) && !zend_isnan(d)) { + size_t len; + char num[PHP_JSON_DOUBLE_MAX_LENGTH]; + php_gcvt(d, EG(precision), '.', 'e', &num[0]); + len = strlen(num); + smart_str_appendl(buf, num, len); + } else { + JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; + smart_str_appendc(buf, '0'); + } +} +/* }}} */ + static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */ { int i, r, need_comma = 0; @@ -267,15 +290,7 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti if (type == IS_LONG) { smart_str_append_long(buf, p); } else if (type == IS_DOUBLE) { - if (!zend_isinf(d) && !zend_isnan(d)) { - char *tmp; - int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d); - smart_str_appendl(buf, tmp, l); - efree(tmp); - } else { - JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; - smart_str_appendc(buf, '0'); - } + php_json_encode_double(buf, d); } return; } @@ -487,20 +502,7 @@ again: break; case IS_DOUBLE: - { - char *d = NULL; - int len; - double dbl = Z_DVAL_P(val); - - if (!zend_isinf(dbl) && !zend_isnan(dbl)) { - len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl); - smart_str_appendl(buf, d, len); - efree(d); - } else { - JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; - smart_str_appendc(buf, '0'); - } - } + php_json_encode_double(buf, Z_DVAL_P(val)); break; case IS_STRING: |