@@ -171,6 +171,16 @@ public String toString() {
171171 */
172172 public static final Object NULL = new Null ();
173173
174+ /**
175+ * Indicates if BigNumber is to be used
176+ */
177+ private boolean bigNumberEnabled = false ;
178+
179+ /**
180+ * Parses number token as BigNumber is token length exceeds this value
181+ */
182+ private int bigNumberLength ;
183+
174184 /**
175185 * Construct an empty JSONObject.
176186 */
@@ -209,12 +219,18 @@ public JSONObject(JSONObject jo, String[] names) {
209219 *
210220 * @param x
211221 * A JSONTokener object containing the source string.
222+ * @param bigNumberEnabled
223+ * If numbers should be attempted to be parsed as BigNumbers
224+ * @param bigNumberLength
225+ * Token length when it should be considered as BigNumber
212226 * @throws JSONException
213227 * If there is a syntax error in the source string or a
214228 * duplicated key.
215229 */
216- public JSONObject (JSONTokener x ) throws JSONException {
230+ public JSONObject (JSONTokener x , boolean bigNumberEnabled , int bigNumberLength ) throws JSONException {
217231 this ();
232+ this .bigNumberEnabled = bigNumberEnabled ;
233+ this .bigNumberLength = bigNumberLength ;
218234 char c ;
219235 String key ;
220236
@@ -224,13 +240,13 @@ public JSONObject(JSONTokener x) throws JSONException {
224240 for (;;) {
225241 c = x .nextClean ();
226242 switch (c ) {
227- case 0 :
228- throw x .syntaxError ("A JSONObject text must end with '}'" );
229- case '}' :
230- return ;
231- default :
232- x .back ();
233- key = x .nextValue ().toString ();
243+ case 0 :
244+ throw x .syntaxError ("A JSONObject text must end with '}'" );
245+ case '}' :
246+ return ;
247+ default :
248+ x .back ();
249+ key = x .nextValue ().toString ();
234250 }
235251
236252 // The key is followed by ':'.
@@ -239,9 +255,9 @@ public JSONObject(JSONTokener x) throws JSONException {
239255 if (c != ':' ) {
240256 throw x .syntaxError ("Expected a ':' after a key" );
241257 }
242-
258+
243259 // Use syntaxError(..) to include error location
244-
260+
245261 if (key != null ) {
246262 // Check if key exists
247263 if (this .opt (key ) != null ) {
@@ -258,21 +274,51 @@ public JSONObject(JSONTokener x) throws JSONException {
258274 // Pairs are separated by ','.
259275
260276 switch (x .nextClean ()) {
261- case ';' :
262- case ',' :
263- if (x .nextClean () == '}' ) {
277+ case ';' :
278+ case ',' :
279+ if (x .nextClean () == '}' ) {
280+ return ;
281+ }
282+ x .back ();
283+ break ;
284+ case '}' :
264285 return ;
265- }
266- x .back ();
267- break ;
268- case '}' :
269- return ;
270- default :
271- throw x .syntaxError ("Expected a ',' or '}'" );
286+ default :
287+ throw x .syntaxError ("Expected a ',' or '}'" );
272288 }
273289 }
274290 }
275291
292+ /**
293+ * Construct a JSONObject from a JSONTokener.
294+ *
295+ * @param x
296+ * A JSONTokener object containing the source string.
297+ * @param bigNumberEnabled
298+ * If numbers should be attempted to be parsed as BigNumbers.
299+ * If the, the default legnth of token to be considered as BigNumber is 14
300+ * @throws JSONException
301+ * If there is a syntax error in the source string or a
302+ * duplicated key.
303+ */
304+ public JSONObject (JSONTokener x , boolean bigNumberEnabled ) throws JSONException {
305+ this (x , bigNumberEnabled , 14 );
306+ }
307+ /**
308+ * Construct a JSONObject from a JSONTokener.
309+ *
310+ * Using this constructor does not enable BigNumber support.
311+ *
312+ * @param x
313+ * A JSONTokener object containing the source string.
314+ * @throws JSONException
315+ * If there is a syntax error in the source string or a
316+ * duplicated key.
317+ */
318+ public JSONObject (JSONTokener x ) throws JSONException {
319+ this (x , false , 14 );
320+ }
321+
276322 /**
277323 * Construct a JSONObject from a Map.
278324 *
@@ -398,12 +444,52 @@ public JSONObject(Object object, String names[]) {
398444 * A string beginning with <code>{</code> <small>(left
399445 * brace)</small> and ending with <code>}</code>
400446 * <small>(right brace)</small>.
447+ * @param bigNumberEnabled
448+ * If numbers should be attempted to be parsed as BigNumbers
449+ * @param bigNumberLength
450+ * Token length when it should be considered as BigNumber
401451 * @exception JSONException
402452 * If there is a syntax error in the source string or a
403453 * duplicated key.
404454 */
455+ public JSONObject (String source , boolean bigNumberEnabled , int bigNumberLength ) throws JSONException {
456+ this (new JSONTokener (source ), bigNumberEnabled , bigNumberLength );
457+ }
458+
459+ /**
460+ * Construct a JSONObject from a source JSON text string.
461+ *
462+ * @param source
463+ * A string beginning with <code>{</code> <small>(left
464+ * brace)</small> and ending with <code>}</code>
465+ * <small>(right brace)</small>.*
466+ * @param bigNumberEnabled
467+ * If numbers should be attempted to be parsed as BigNumbers.
468+ * If the, the default legnth of token to be considered as BigNumber is 14
469+ * @throws JSONException
470+ * If there is a syntax error in the source string or a
471+ * duplicated key.
472+ */
473+ public JSONObject (String source , boolean bigNumberEnabled ) throws JSONException {
474+ this (new JSONTokener (source ), bigNumberEnabled , 14 );
475+ }
476+ /**
477+ * Construct a JSONObject from a source JSON text string. This is the most
478+ * commonly used JSONObject constructor.
479+ *
480+ * Using this constructor does not enable BigNumber support.
481+ *
482+ * @param source
483+ * A string beginning with <code>{</code> <small>(left
484+ * brace)</small> and ending with <code>}</code>
485+ * <small>(right brace)</small>.*
486+ *
487+ * @throws JSONException
488+ * If there is a syntax error in the source string or a
489+ * duplicated key.
490+ */
405491 public JSONObject (String source ) throws JSONException {
406- this (new JSONTokener (source ));
492+ this (new JSONTokener (source ), false , 14 );
407493 }
408494
409495 /**
@@ -2085,7 +2171,7 @@ protected static Number stringToNumber(final String val) throws NumberFormatExce
20852171 if (isDecimalNotation (val )) {
20862172 // quick dirty way to see if we need a BigDecimal instead of a Double
20872173 // this only handles some cases of overflow or underflow
2088- if (val .length ()>14 ) {
2174+ if (val .length ()>bigNumberLength ) {
20892175 return new BigDecimal (val );
20902176 }
20912177 final Double d = Double .valueOf (val );
@@ -2168,21 +2254,22 @@ public static Object stringToValue(String string) {
21682254 char initial = string .charAt (0 );
21692255 if ((initial >= '0' && initial <= '9' ) || initial == '-' ) {
21702256 try {
2171- // if we want full Big Number support the contents of this
2172- // `try` block can be replaced with:
2173- // return stringToNumber(string);
2174- if (isDecimalNotation (string )) {
2175- Double d = Double .valueOf (string );
2176- if (!d .isInfinite () && !d .isNaN ()) {
2177- return d ;
2178- }
2257+ if (bigNumberEnabled ) {
2258+ return stringToNumber (string );
21792259 } else {
2180- Long myLong = Long .valueOf (string );
2181- if (string .equals (myLong .toString ())) {
2182- if (myLong .longValue () == myLong .intValue ()) {
2183- return Integer .valueOf (myLong .intValue ());
2260+ if (isDecimalNotation (string )) {
2261+ Double d = Double .valueOf (string );
2262+ if (!d .isInfinite () && !d .isNaN ()) {
2263+ return d ;
2264+ }
2265+ } else {
2266+ Long myLong = Long .valueOf (string );
2267+ if (string .equals (myLong .toString ())) {
2268+ if (myLong .longValue () == myLong .intValue ()) {
2269+ return Integer .valueOf (myLong .intValue ());
2270+ }
2271+ return myLong ;
21842272 }
2185- return myLong ;
21862273 }
21872274 }
21882275 } catch (Exception ignore ) {
0 commit comments