Skip to content

Commit 0d4a3d6

Browse files
author
John J. Aylward
committed
fixes for Number output bug
1 parent 2e33310 commit 0d4a3d6

1 file changed

Lines changed: 36 additions & 14 deletions

File tree

JSONObject.java

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ of this software and associated documentation files (the "Software"), to deal
4141
import java.util.Map.Entry;
4242
import java.util.ResourceBundle;
4343
import 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

Comments
 (0)