@@ -41,6 +41,7 @@ of this software and associated documentation files (the "Software"), to deal
4141import java .util .Map .Entry ;
4242import java .util .ResourceBundle ;
4343import java .util .Set ;
44+ import java .util .regex .Pattern ;
4445
4546/**
4647 * A JSONObject is an unordered collection of name/value pairs. Its external
@@ -137,6 +138,12 @@ public String toString() {
137138 return "null" ;
138139 }
139140 }
141+
142+ /**
143+ * Regex that expresses the allowable pattern of JSON numbers.
144+ * <a href="http://stackoverflow.com/a/13340826/6030888">http://stackoverflow.com/a/13340826/6030888</a>
145+ */
146+ private static final Pattern JSON_NUMBER_PATTERN = Pattern .compile ("-?(?:0|[1-9]\\ d*)(?:\\ .\\ d+)?(?:[eE][+-]?\\ d+)?" );
140147
141148 /**
142149 * The map where the JSONObject's properties are kept.
@@ -838,7 +845,7 @@ public static String numberToString(Number number) throws JSONException {
838845 }
839846 testValidity (number );
840847
841- // Shave off trailing zeros and decimal point, if possible.
848+ // Shave off trailing zeros and decimal point, if possible.
842849
843850 String string = number .toString ();
844851 if (string .indexOf ('.' ) > 0 && string .indexOf ('e' ) < 0
@@ -1693,7 +1700,14 @@ public static String valueToString(Object value) throws JSONException {
16931700 throw new JSONException ("Bad value from toJSONString: " + object );
16941701 }
16951702 if (value instanceof Number ) {
1696- return numberToString ((Number ) value );
1703+ // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
1704+ final String numberAsString = numberToString ((Number ) value );
1705+ // Do we really want to take a REGEX hit for every number encountered?
1706+ // Is there a faster check?
1707+ if (JSON_NUMBER_PATTERN .matcher (numberAsString ).matches ()) {
1708+ return numberAsString ;
1709+ }
1710+ return quote (numberAsString );
16971711 }
16981712 if (value instanceof Boolean || value instanceof JSONObject
16991713 || value instanceof JSONArray ) {
@@ -1779,6 +1793,26 @@ static final Writer writeValue(Writer writer, Object value,
17791793 int indentFactor , int indent ) throws JSONException , IOException {
17801794 if (value == null || value .equals (null )) {
17811795 writer .write ("null" );
1796+ } else if (value instanceof JSONString ) {
1797+ Object o ;
1798+ try {
1799+ o = ((JSONString ) value ).toJSONString ();
1800+ } catch (Exception e ) {
1801+ throw new JSONException (e );
1802+ }
1803+ writer .write (o != null ? o .toString () : quote (value .toString ()));
1804+ } else if (value instanceof Number ) {
1805+ // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
1806+ final String numberAsString = numberToString ((Number ) value );
1807+ // Do we really want to take a REGEX hit for every number encountered?
1808+ // Is there a faster check?
1809+ if (JSON_NUMBER_PATTERN .matcher (numberAsString ).matches ()) {
1810+ writer .write (numberAsString );
1811+ } else {
1812+ quote (numberAsString ,writer );
1813+ }
1814+ } else if (value instanceof Boolean ) {
1815+ writer .write (value .toString ());
17821816 } else if (value instanceof JSONObject ) {
17831817 ((JSONObject ) value ).write (writer , indentFactor , indent );
17841818 } else if (value instanceof JSONArray ) {
@@ -1791,18 +1825,6 @@ static final Writer writeValue(Writer writer, Object value,
17911825 new JSONArray (coll ).write (writer , indentFactor , indent );
17921826 } else if (value .getClass ().isArray ()) {
17931827 new JSONArray (value ).write (writer , indentFactor , indent );
1794- } else if (value instanceof Number ) {
1795- writer .write (numberToString ((Number ) value ));
1796- } else if (value instanceof Boolean ) {
1797- writer .write (value .toString ());
1798- } else if (value instanceof JSONString ) {
1799- Object o ;
1800- try {
1801- o = ((JSONString ) value ).toJSONString ();
1802- } catch (Exception e ) {
1803- throw new JSONException (e );
1804- }
1805- writer .write (o != null ? o .toString () : quote (value .toString ()));
18061828 } else {
18071829 quote (value .toString (), writer );
18081830 }
0 commit comments