iliaa                                    Thu, 20 May 2010 19:37:52 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=299535

Log:
Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
numeric strings to integers.

Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/json/json.c
    U   php/php-src/branches/PHP_5_3/ext/json/php_json.h
    U   php/php-src/branches/PHP_5_3/ext/json/tests/json_encode_basic.phpt
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/ext/json/json.c
    U   php/php-src/trunk/ext/json/php_json.h
    U   php/php-src/trunk/ext/json/tests/json_encode_basic.phpt
    A   php/php-src/trunk/ext/json/tests/json_encode_numeric.phpt

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/branches/PHP_5_3/NEWS	2010-05-20 19:37:52 UTC (rev 299535)
@@ -4,6 +4,8 @@
 - Upgraded bundled sqlite to version 3.6.23.1. (Ilia)
 - Upgraded bundled PCRE to version 8.02. (Ilia)

+- Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
+  numeric strings to integers. (Ilia)
 - Added stream_set_read_buffer, allows to set the buffer for read operation.
   (Pierre).
 - Added stream filter support to mcrypt extension (ported from

Modified: php/php-src/branches/PHP_5_3/ext/json/json.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/json/json.c	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/branches/PHP_5_3/ext/json/json.c	2010-05-20 19:37:52 UTC (rev 299535)
@@ -37,15 +37,6 @@

 static const char digits[] = "0123456789abcdef";

-#define PHP_JSON_HEX_TAG	(1<<0)
-#define PHP_JSON_HEX_AMP	(1<<1)
-#define PHP_JSON_HEX_APOS	(1<<2)
-#define PHP_JSON_HEX_QUOT	(1<<3)
-#define PHP_JSON_FORCE_OBJECT	(1<<4)
-
-#define PHP_JSON_OUTPUT_ARRAY 0
-#define PHP_JSON_OUTPUT_OBJECT 1
-
 ZEND_DECLARE_MODULE_GLOBALS(json)

 /* {{{ arginfo */
@@ -81,6 +72,7 @@
 	REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT);
 	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_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
@@ -294,6 +286,30 @@
 		return;
 	}

+	if (options & PHP_JSON_NUMERIC_CHECK) {
+		double d;
+		int type;
+		long p;
+
+		if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
+			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 {
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
+					smart_str_appendc(buf, '0');
+				}
+			}
+			return;
+		}
+
+	}
+
 	utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);

 	len = utf8_to_utf16(utf16, s, len);
@@ -445,7 +461,7 @@
 					smart_str_appendl(buf, d, len);
 					efree(d);
 				} else {
-					zend_error(E_WARNING, "[json] (php_json_encode) double %.9g does not conform to the JSON spec, encoded as 0", dbl);
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
 					smart_str_appendc(buf, '0');
 				}
 			}
@@ -461,7 +477,7 @@
 			break;

 		default:
-			zend_error(E_WARNING, "[json] (php_json_encode) type is unsupported, encoded as null");
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
 			smart_str_appendl(buf, "null", 4);
 			break;
 	}

Modified: php/php-src/branches/PHP_5_3/ext/json/php_json.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/json/php_json.h	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/branches/PHP_5_3/ext/json/php_json.h	2010-05-20 19:37:52 UTC (rev 299535)
@@ -50,6 +50,16 @@
 PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC);
 PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC);

+#define PHP_JSON_HEX_TAG	(1<<0)
+#define PHP_JSON_HEX_AMP	(1<<1)
+#define PHP_JSON_HEX_APOS	(1<<2)
+#define PHP_JSON_HEX_QUOT	(1<<3)
+#define PHP_JSON_FORCE_OBJECT	(1<<4)
+#define PHP_JSON_NUMERIC_CHECK	(1<<5)
+
+#define PHP_JSON_OUTPUT_ARRAY 0
+#define PHP_JSON_OUTPUT_OBJECT 1
+
 #endif  /* PHP_JSON_H */

 /*

Modified: php/php-src/branches/PHP_5_3/ext/json/tests/json_encode_basic.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/json/tests/json_encode_basic.phpt	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/branches/PHP_5_3/ext/json/tests/json_encode_basic.phpt	2010-05-20 19:37:52 UTC (rev 299535)
@@ -151,8 +151,8 @@
 string(4) "null"
 -- Iteration 26 --

-Warning: [json] (php_json_encode) type is unsupported, encoded as null in %s on line %d
+Warning: json_encode(): type is unsupported, encoded as null in %s on line %d
 string(4) "null"
 -- Iteration 27 --
 string(82) "{"MyInt":99,"MyFloat":123.45,"MyBool":true,"MyNull":null,"MyString":"Hello World"}"
-===Done===
\ No newline at end of file
+===Done===

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/trunk/NEWS	2010-05-20 19:37:52 UTC (rev 299535)
@@ -37,6 +37,8 @@
 - Added iterator support in MySQLi. mysqli_result implements Traversable.
   (Andrey, Johannes)
 - Added scalar typehinting. (Ilia, Derick)
+- Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
+  numeric strings to integers. (Ilia)

 - default_charset if not specified is now UTF-8 instead of ISO-8859-1. (Rasmus)


Modified: php/php-src/trunk/ext/json/json.c
===================================================================
--- php/php-src/trunk/ext/json/json.c	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/trunk/ext/json/json.c	2010-05-20 19:37:52 UTC (rev 299535)
@@ -40,15 +40,6 @@

 zend_class_entry *php_json_serializable_ce;

-#define PHP_JSON_HEX_TAG	(1<<0)
-#define PHP_JSON_HEX_AMP	(1<<1)
-#define PHP_JSON_HEX_APOS	(1<<2)
-#define PHP_JSON_HEX_QUOT	(1<<3)
-#define PHP_JSON_FORCE_OBJECT	(1<<4)
-
-#define PHP_JSON_OUTPUT_ARRAY 0
-#define PHP_JSON_OUTPUT_OBJECT 1
-
 ZEND_DECLARE_MODULE_GLOBALS(json)

 /* {{{ arginfo */
@@ -99,6 +90,7 @@
 	REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT);
 	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_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
@@ -312,6 +304,30 @@
 		return;
 	}

+	if (options & PHP_JSON_NUMERIC_CHECK) {
+		double d;
+		int type;
+		long p;
+
+		if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
+			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 {
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
+					smart_str_appendc(buf, '0');
+				}
+			}
+			return;
+		}
+
+	}
+
 	utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);

 	len = utf8_to_utf16(utf16, s, len);
@@ -496,7 +512,7 @@
 					smart_str_appendl(buf, d, len);
 					efree(d);
 				} else {
-					zend_error(E_WARNING, "[json] (php_json_encode) double %.9g does not conform to the JSON spec, encoded as 0", dbl);
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
 					smart_str_appendc(buf, '0');
 				}
 			}
@@ -517,7 +533,7 @@
 			break;

 		default:
-			zend_error(E_WARNING, "[json] (php_json_encode) type is unsupported, encoded as null");
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
 			smart_str_appendl(buf, "null", 4);
 			break;
 	}

Modified: php/php-src/trunk/ext/json/php_json.h
===================================================================
--- php/php-src/trunk/ext/json/php_json.h	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/trunk/ext/json/php_json.h	2010-05-20 19:37:52 UTC (rev 299535)
@@ -51,6 +51,16 @@
 PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC);
 extern zend_class_entry *php_json_serializable_ce;

+#define PHP_JSON_HEX_TAG	(1<<0)
+#define PHP_JSON_HEX_AMP	(1<<1)
+#define PHP_JSON_HEX_APOS	(1<<2)
+#define PHP_JSON_HEX_QUOT	(1<<3)
+#define PHP_JSON_FORCE_OBJECT	(1<<4)
+#define PHP_JSON_NUMERIC_CHECK	(1<<5)
+
+#define PHP_JSON_OUTPUT_ARRAY 0
+#define PHP_JSON_OUTPUT_OBJECT 1
+
 #endif  /* PHP_JSON_H */

 /*

Modified: php/php-src/trunk/ext/json/tests/json_encode_basic.phpt
===================================================================
--- php/php-src/trunk/ext/json/tests/json_encode_basic.phpt	2010-05-20 19:18:35 UTC (rev 299534)
+++ php/php-src/trunk/ext/json/tests/json_encode_basic.phpt	2010-05-20 19:37:52 UTC (rev 299535)
@@ -151,7 +151,7 @@
 string(4) "null"
 -- Iteration 26 --

-Warning: [json] (php_json_encode) type is unsupported, encoded as null in %s on line %d
+Warning: json_encode(): type is unsupported, encoded as null in %s on line %d
 string(4) "null"
 -- Iteration 27 --
 string(82) "{"MyInt":99,"MyFloat":123.45,"MyBool":true,"MyNull":null,"MyString":"Hello World"}"

Added: php/php-src/trunk/ext/json/tests/json_encode_numeric.phpt
===================================================================
--- php/php-src/trunk/ext/json/tests/json_encode_numeric.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/json/tests/json_encode_numeric.phpt	2010-05-20 19:37:52 UTC (rev 299535)
@@ -0,0 +1,26 @@
+--TEST--
+Test json_encode() function with numeric flag
+--SKIPIF--
+<?php
+if (!extension_loaded("json")) {
+	die('skip JSON extension not available in this build');
+}
+?>
+--FILE--
+<?php
+var_dump(
+	json_encode("1", JSON_NUMERIC_CHECK),
+	json_encode("9.4324", JSON_NUMERIC_CHECK),
+	json_encode(array("122321", "3232595.33423"), JSON_NUMERIC_CHECK),
+	json_encode("1"),
+	json_encode("9.4324"),
+	json_encode(array("122321", "3232595.33423"))
+);
+?>
+--EXPECT--
+string(1) "1"
+string(6) "9.4324"
+string(22) "[122321,3232595.33423]"
+string(3) ""1""
+string(8) ""9.4324""
+string(26) "["122321","3232595.33423"]"
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to