Skip to content

Commit e6fb493

Browse files
committed
Refactore json double encoding to use php_gcvt
1 parent 8304e46 commit e6fb493

File tree

1 file changed

+25
-23
lines changed

1 file changed

+25
-23
lines changed

ext/json/json_encoder.c

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
#include "php_json.h"
3131
#include <zend_exceptions.h>
3232

33+
/* double limits */
34+
#include <float.h>
35+
#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP)
36+
#define PHP_JSON_DOUBLE_MAX_LENGTH (1 + DBL_MANT_DIG - DBL_MIN_EXP)
37+
#else
38+
#define PHP_JSON_DOUBLE_MAX_LENGTH 1078
39+
#endif
40+
3341
ZEND_DECLARE_MODULE_GLOBALS(json)
3442

3543
static const char digits[] = "0123456789abcdef";
@@ -87,6 +95,21 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options) /*
8795

8896
/* }}} */
8997

98+
static inline void php_json_encode_double(smart_str *buf, double d) /* {{{ */
99+
{
100+
if (!zend_isinf(d) && !zend_isnan(d)) {
101+
size_t len;
102+
char num[PHP_JSON_DOUBLE_MAX_LENGTH];
103+
php_gcvt(d, EG(precision), '.', 'e', &num[0]);
104+
len = strlen(num);
105+
smart_str_appendl(buf, num, len);
106+
} else {
107+
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
108+
smart_str_appendc(buf, '0');
109+
}
110+
}
111+
/* }}} */
112+
90113
static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */
91114
{
92115
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
267290
if (type == IS_LONG) {
268291
smart_str_append_long(buf, p);
269292
} else if (type == IS_DOUBLE) {
270-
if (!zend_isinf(d) && !zend_isnan(d)) {
271-
char *tmp;
272-
int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
273-
smart_str_appendl(buf, tmp, l);
274-
efree(tmp);
275-
} else {
276-
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
277-
smart_str_appendc(buf, '0');
278-
}
293+
php_json_encode_double(buf, d);
279294
}
280295
return;
281296
}
@@ -487,20 +502,7 @@ void php_json_encode_zval(smart_str *buf, zval *val, int options) /* {{{ */
487502
break;
488503

489504
case IS_DOUBLE:
490-
{
491-
char *d = NULL;
492-
int len;
493-
double dbl = Z_DVAL_P(val);
494-
495-
if (!zend_isinf(dbl) && !zend_isnan(dbl)) {
496-
len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl);
497-
smart_str_appendl(buf, d, len);
498-
efree(d);
499-
} else {
500-
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
501-
smart_str_appendc(buf, '0');
502-
}
503-
}
505+
php_json_encode_double(buf, Z_DVAL_P(val));
504506
break;
505507

506508
case IS_STRING:

0 commit comments

Comments
 (0)