mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #37 - Touch support without userscript, many other feats
This commit is contained in:
@ -149,11 +149,40 @@ public class JSONArray implements Iterable<Object> {
|
||||
* A Collection.
|
||||
*/
|
||||
public JSONArray(Collection<?> collection) {
|
||||
this(collection, 0, new JSONParserConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a JSONArray from a Collection.
|
||||
*
|
||||
* @param collection
|
||||
* A Collection.
|
||||
* @param jsonParserConfiguration
|
||||
* Configuration object for the JSON parser
|
||||
*/
|
||||
public JSONArray(Collection<?> collection, JSONParserConfiguration jsonParserConfiguration) {
|
||||
this(collection, 0, jsonParserConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a JSONArray from a collection with recursion depth.
|
||||
*
|
||||
* @param collection
|
||||
* A Collection.
|
||||
* @param recursionDepth
|
||||
* Variable for tracking the count of nested object creations.
|
||||
* @param jsonParserConfiguration
|
||||
* Configuration object for the JSON parser
|
||||
*/
|
||||
JSONArray(Collection<?> collection, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) {
|
||||
if (recursionDepth > jsonParserConfiguration.getMaxNestingDepth()) {
|
||||
throw new JSONException("JSONArray has reached recursion depth limit of " + jsonParserConfiguration.getMaxNestingDepth());
|
||||
}
|
||||
if (collection == null) {
|
||||
this.myArrayList = new ArrayList<Object>();
|
||||
} else {
|
||||
this.myArrayList = new ArrayList<Object>(collection.size());
|
||||
this.addAll(collection, true);
|
||||
this.addAll(collection, true, recursionDepth, jsonParserConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,7 +234,7 @@ public class JSONArray implements Iterable<Object> {
|
||||
throw new JSONException(
|
||||
"JSONArray initial value should be a string or collection or array.");
|
||||
}
|
||||
this.addAll(array, true);
|
||||
this.addAll(array, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -599,6 +628,38 @@ public class JSONArray implements Iterable<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Boolean object associated with an index. It returns false
|
||||
* if there is no value at that index, or if the value is not Boolean.TRUE
|
||||
* or the String "true".
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return The truth.
|
||||
*/
|
||||
public Boolean optBooleanObject(int index) {
|
||||
return this.optBooleanObject(index, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Boolean object associated with an index. It returns the
|
||||
* defaultValue if there is no value at that index or if it is not a Boolean
|
||||
* or the String "true" or "false" (case insensitive).
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @param defaultValue
|
||||
* A boolean default.
|
||||
* @return The truth.
|
||||
*/
|
||||
public Boolean optBooleanObject(int index, Boolean defaultValue) {
|
||||
try {
|
||||
return this.getBoolean(index);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional double value associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
@ -635,6 +696,42 @@ public class JSONArray implements Iterable<Object> {
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Double object associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return The object.
|
||||
*/
|
||||
public Double optDoubleObject(int index) {
|
||||
return this.optDoubleObject(index, Double.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional double value associated with an index. The defaultValue
|
||||
* is returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* subscript
|
||||
* @param defaultValue
|
||||
* The default object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Double optDoubleObject(int index, Double defaultValue) {
|
||||
final Number val = this.optNumber(index, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
final Double doubleValue = val.doubleValue();
|
||||
// if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
|
||||
// return defaultValue;
|
||||
// }
|
||||
return doubleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional float value associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
@ -671,6 +768,42 @@ public class JSONArray implements Iterable<Object> {
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Float object associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return The object.
|
||||
*/
|
||||
public Float optFloatObject(int index) {
|
||||
return this.optFloatObject(index, Float.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Float object associated with an index. The defaultValue
|
||||
* is returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* subscript
|
||||
* @param defaultValue
|
||||
* The default object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Float optFloatObject(int index, Float defaultValue) {
|
||||
final Number val = this.optNumber(index, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
final Float floatValue = val.floatValue();
|
||||
// if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) {
|
||||
// return floatValue;
|
||||
// }
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional int value associated with an index. Zero is returned if
|
||||
* there is no value for the index, or if the value is not a number and
|
||||
@ -703,6 +836,38 @@ public class JSONArray implements Iterable<Object> {
|
||||
return val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Integer object associated with an index. Zero is returned if
|
||||
* there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return The object.
|
||||
*/
|
||||
public Integer optIntegerObject(int index) {
|
||||
return this.optIntegerObject(index, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Integer object associated with an index. The defaultValue is
|
||||
* returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @param defaultValue
|
||||
* The default object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Integer optIntegerObject(int index, Integer defaultValue) {
|
||||
final Number val = this.optNumber(index, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum value associated with a key.
|
||||
*
|
||||
@ -788,30 +953,57 @@ public class JSONArray implements Iterable<Object> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional JSONArray associated with an index.
|
||||
* Get the optional JSONArray associated with an index. Null is returned if
|
||||
* there is no value at that index or if the value is not a JSONArray.
|
||||
*
|
||||
* @param index
|
||||
* subscript
|
||||
* @return A JSONArray value, or null if the index has no value, or if the
|
||||
* value is not a JSONArray.
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return A JSONArray value.
|
||||
*/
|
||||
public JSONArray optJSONArray(int index) {
|
||||
Object o = this.opt(index);
|
||||
return o instanceof JSONArray ? (JSONArray) o : null;
|
||||
return this.optJSONArray(index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional JSONArray associated with an index. The defaultValue is returned if
|
||||
* there is no value at that index or if the value is not a JSONArray.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return A JSONArray value.
|
||||
*/
|
||||
public JSONArray optJSONArray(int index, JSONArray defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
return object instanceof JSONArray ? (JSONArray) object : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional JSONObject associated with an index. Null is returned if
|
||||
* the key is not found, or null if the index has no value, or if the value
|
||||
* is not a JSONObject.
|
||||
* there is no value at that index or if the value is not a JSONObject.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return A JSONObject value.
|
||||
*/
|
||||
public JSONObject optJSONObject(int index) {
|
||||
Object o = this.opt(index);
|
||||
return o instanceof JSONObject ? (JSONObject) o : null;
|
||||
return this.optJSONObject(index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional JSONObject associated with an index. The defaultValue is returned if
|
||||
* there is no value at that index or if the value is not a JSONObject.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return A JSONObject value.
|
||||
*/
|
||||
public JSONObject optJSONObject(int index, JSONObject defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
return object instanceof JSONObject ? (JSONObject) object : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -846,6 +1038,38 @@ public class JSONArray implements Iterable<Object> {
|
||||
return val.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Long object associated with an index. Zero is returned if
|
||||
* there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @return The object.
|
||||
*/
|
||||
public Long optLongObject(int index) {
|
||||
return this.optLongObject(index, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Long object associated with an index. The defaultValue is
|
||||
* returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
* @param index
|
||||
* The index must be between 0 and length() - 1.
|
||||
* @param defaultValue
|
||||
* The default object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Long optLongObject(int index, Long defaultValue) {
|
||||
final Number val = this.optNumber(index, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return val.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional {@link Number} value associated with a key, or <code>null</code>
|
||||
* if there is no such key or if the value is not a number. If the value is a string,
|
||||
@ -1135,7 +1359,8 @@ public class JSONArray implements Iterable<Object> {
|
||||
* The subscript.
|
||||
* @param value
|
||||
* The Map value.
|
||||
* @return this.
|
||||
* @return
|
||||
* reference to self
|
||||
* @throws JSONException
|
||||
* If the index is negative or if the value is an invalid
|
||||
* number.
|
||||
@ -1143,7 +1368,27 @@ public class JSONArray implements Iterable<Object> {
|
||||
* If a key in the map is <code>null</code>
|
||||
*/
|
||||
public JSONArray put(int index, Map<?, ?> value) throws JSONException {
|
||||
this.put(index, new JSONObject(value));
|
||||
this.put(index, new JSONObject(value, new JSONParserConfiguration()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a value in the JSONArray, where the value will be a JSONObject that
|
||||
* is produced from a Map.
|
||||
*
|
||||
* @param index
|
||||
* The subscript
|
||||
* @param value
|
||||
* The Map value.
|
||||
* @param jsonParserConfiguration
|
||||
* Configuration object for the JSON parser
|
||||
* @return reference to self
|
||||
* @throws JSONException
|
||||
* If the index is negative or if the value is an invalid
|
||||
* number.
|
||||
*/
|
||||
public JSONArray put(int index, Map<?, ?> value, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
|
||||
this.put(index, new JSONObject(value, jsonParserConfiguration));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1451,9 +1696,7 @@ public class JSONArray implements Iterable<Object> {
|
||||
@SuppressWarnings("resource")
|
||||
public String toString(int indentFactor) throws JSONException {
|
||||
StringWriter sw = new StringWriter();
|
||||
synchronized (sw.getBuffer()) {
|
||||
return this.write(sw, indentFactor, 0).toString();
|
||||
}
|
||||
return this.write(sw, indentFactor, 0).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1586,13 +1829,14 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @param wrap
|
||||
* {@code true} to call {@link JSONObject#wrap(Object)} for each item,
|
||||
* {@code false} to add the items directly
|
||||
*
|
||||
* @param recursionDepth
|
||||
* Variable for tracking the count of nested object creations.
|
||||
*/
|
||||
private void addAll(Collection<?> collection, boolean wrap) {
|
||||
private void addAll(Collection<?> collection, boolean wrap, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) {
|
||||
this.myArrayList.ensureCapacity(this.myArrayList.size() + collection.size());
|
||||
if (wrap) {
|
||||
for (Object o: collection){
|
||||
this.put(JSONObject.wrap(o));
|
||||
this.put(JSONObject.wrap(o, recursionDepth + 1, jsonParserConfiguration));
|
||||
}
|
||||
} else {
|
||||
for (Object o: collection){
|
||||
@ -1621,7 +1865,24 @@ public class JSONArray implements Iterable<Object> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an array's elements to the JSONArray.
|
||||
*
|
||||
* @param array
|
||||
* Array. If the parameter passed is null, or not an array,
|
||||
* JSONArray, Collection, or Iterable, an exception will be
|
||||
* thrown.
|
||||
* @param wrap
|
||||
* {@code true} to call {@link JSONObject#wrap(Object)} for each item,
|
||||
* {@code false} to add the items directly
|
||||
* @throws JSONException
|
||||
* If not an array or if an array value is non-finite number.
|
||||
*/
|
||||
private void addAll(Object array, boolean wrap) throws JSONException {
|
||||
this.addAll(array, wrap, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an array's elements to the JSONArray.
|
||||
*
|
||||
@ -1630,21 +1891,40 @@ public class JSONArray implements Iterable<Object> {
|
||||
* JSONArray, Collection, or Iterable, an exception will be
|
||||
* thrown.
|
||||
* @param wrap
|
||||
* {@code true} to call {@link JSONObject#wrap(Object)} for each item,
|
||||
* {@code false} to add the items directly
|
||||
* @param recursionDepth
|
||||
* Variable for tracking the count of nested object creations.
|
||||
*/
|
||||
private void addAll(Object array, boolean wrap, int recursionDepth) {
|
||||
addAll(array, wrap, recursionDepth, new JSONParserConfiguration());
|
||||
}
|
||||
/**
|
||||
* Add an array's elements to the JSONArray.
|
||||
*`
|
||||
* @param array
|
||||
* Array. If the parameter passed is null, or not an array,
|
||||
* JSONArray, Collection, or Iterable, an exception will be
|
||||
* thrown.
|
||||
* @param wrap
|
||||
* {@code true} to call {@link JSONObject#wrap(Object)} for each item,
|
||||
* {@code false} to add the items directly
|
||||
*
|
||||
* @param recursionDepth
|
||||
* Variable for tracking the count of nested object creations.
|
||||
* @param jsonParserConfiguration
|
||||
* Variable to pass parser custom configuration for json parsing.
|
||||
* @throws JSONException
|
||||
* If not an array or if an array value is non-finite number.
|
||||
* @throws NullPointerException
|
||||
* Thrown if the array parameter is null.
|
||||
*/
|
||||
private void addAll(Object array, boolean wrap) throws JSONException {
|
||||
private void addAll(Object array, boolean wrap, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
|
||||
if (array.getClass().isArray()) {
|
||||
int length = Array.getLength(array);
|
||||
this.myArrayList.ensureCapacity(this.myArrayList.size() + length);
|
||||
if (wrap) {
|
||||
for (int i = 0; i < length; i += 1) {
|
||||
this.put(JSONObject.wrap(Array.get(array, i)));
|
||||
this.put(JSONObject.wrap(Array.get(array, i), recursionDepth + 1, jsonParserConfiguration));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; i += 1) {
|
||||
@ -1657,7 +1937,7 @@ public class JSONArray implements Iterable<Object> {
|
||||
// JSONArray
|
||||
this.myArrayList.addAll(((JSONArray)array).myArrayList);
|
||||
} else if (array instanceof Collection) {
|
||||
this.addAll((Collection<?>)array, wrap);
|
||||
this.addAll((Collection<?>)array, wrap, recursionDepth);
|
||||
} else if (array instanceof Iterable) {
|
||||
this.addAll((Iterable<?>)array, wrap);
|
||||
} else {
|
||||
|
@ -145,6 +145,11 @@ public class JSONObject {
|
||||
*/
|
||||
private final Map<String, Object> map;
|
||||
|
||||
/**
|
||||
* Retrieves the type of the underlying Map in this class.
|
||||
*
|
||||
* @return The class object representing the type of the underlying Map.
|
||||
*/
|
||||
public Class<? extends Map> getMapType() {
|
||||
return map.getClass();
|
||||
}
|
||||
@ -208,22 +213,14 @@ public class JSONObject {
|
||||
throw x.syntaxError("A JSONObject text must begin with '{'");
|
||||
}
|
||||
for (;;) {
|
||||
char prev = x.getPrevious();
|
||||
c = x.nextClean();
|
||||
switch (c) {
|
||||
case 0:
|
||||
throw x.syntaxError("A JSONObject text must end with '}'");
|
||||
case '}':
|
||||
return;
|
||||
case '{':
|
||||
case '[':
|
||||
if(prev=='{') {
|
||||
throw x.syntaxError("A JSON Object can not directly nest another JSON Object or JSON Array.");
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
x.back();
|
||||
key = x.nextValue().toString();
|
||||
key = x.nextSimpleValue(c).toString();
|
||||
}
|
||||
|
||||
// The key is followed by ':'.
|
||||
@ -237,12 +234,10 @@ public class JSONObject {
|
||||
|
||||
if (key != null) {
|
||||
// Check if key exists
|
||||
/*
|
||||
if (this.opt(key) != null) {
|
||||
// key already exists
|
||||
throw x.syntaxError("Duplicate key \"" + key + "\"");
|
||||
}
|
||||
*/
|
||||
// Only add value if non-null
|
||||
Object value = x.nextValue();
|
||||
if (value!=null) {
|
||||
@ -258,6 +253,9 @@ public class JSONObject {
|
||||
if (x.nextClean() == '}') {
|
||||
return;
|
||||
}
|
||||
if (x.end()) {
|
||||
throw x.syntaxError("A JSONObject text must end with '}'");
|
||||
}
|
||||
x.back();
|
||||
break;
|
||||
case '}':
|
||||
@ -280,6 +278,30 @@ public class JSONObject {
|
||||
* If a key in the map is <code>null</code>
|
||||
*/
|
||||
public JSONObject(Map<?, ?> m) {
|
||||
this(m, 0, new JSONParserConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a JSONObject from a Map with custom json parse configurations.
|
||||
*
|
||||
* @param m
|
||||
* A map object that can be used to initialize the contents of
|
||||
* the JSONObject.
|
||||
* @param jsonParserConfiguration
|
||||
* Variable to pass parser custom configuration for json parsing.
|
||||
*/
|
||||
public JSONObject(Map<?, ?> m, JSONParserConfiguration jsonParserConfiguration) {
|
||||
this(m, 0, jsonParserConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a JSONObject from a map with recursion depth.
|
||||
*
|
||||
*/
|
||||
private JSONObject(Map<?, ?> m, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) {
|
||||
if (recursionDepth > jsonParserConfiguration.getMaxNestingDepth()) {
|
||||
throw new JSONException("JSONObject has reached recursion depth limit of " + jsonParserConfiguration.getMaxNestingDepth());
|
||||
}
|
||||
if (m == null) {
|
||||
this.map = new HashMap<String, Object>();
|
||||
} else {
|
||||
@ -290,7 +312,8 @@ public class JSONObject {
|
||||
}
|
||||
final Object value = e.getValue();
|
||||
if (value != null) {
|
||||
this.map.put(String.valueOf(e.getKey()), wrap(value));
|
||||
testValidity(value);
|
||||
this.map.put(String.valueOf(e.getKey()), wrap(value, recursionDepth + 1, jsonParserConfiguration));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,11 +371,12 @@ public class JSONObject {
|
||||
* @JSONPropertyIgnore
|
||||
* public String getName() { return this.name; }
|
||||
* </pre>
|
||||
* <p>
|
||||
*
|
||||
* @param bean
|
||||
* An object that has getter methods that should be used to make
|
||||
* a JSONObject.
|
||||
* @throws JSONException
|
||||
* If a getter returned a non-finite number.
|
||||
*/
|
||||
public JSONObject(Object bean) {
|
||||
this();
|
||||
@ -1133,6 +1157,45 @@ public class JSONObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional boolean object associated with a key. It returns false if there
|
||||
* is no such key, or if the value is not Boolean.TRUE or the String "true".
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @return The truth.
|
||||
*/
|
||||
public Boolean optBooleanObject(String key) {
|
||||
return this.optBooleanObject(key, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional boolean object associated with a key. It returns the
|
||||
* defaultValue if there is no such key, or if it is not a Boolean or the
|
||||
* String "true" or "false" (case insensitive).
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return The truth.
|
||||
*/
|
||||
public Boolean optBooleanObject(String key, Boolean defaultValue) {
|
||||
Object val = this.opt(key);
|
||||
if (NULL.equals(val)) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (val instanceof Boolean){
|
||||
return ((Boolean) val).booleanValue();
|
||||
}
|
||||
try {
|
||||
// we'll use the get anyway because it does string conversion.
|
||||
return this.getBoolean(key);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional BigDecimal associated with a key, or the defaultValue if
|
||||
* there is no such key or if its value is not a number. If the value is a
|
||||
@ -1292,15 +1355,43 @@ public class JSONObject {
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
final double doubleValue = val.doubleValue();
|
||||
// if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
|
||||
// return defaultValue;
|
||||
// }
|
||||
return doubleValue;
|
||||
return val.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional double value associated with an index. NaN is returned
|
||||
* Get an optional Double object associated with a key, or NaN if there is no such
|
||||
* key or if its value is not a number. If the value is a string, an attempt
|
||||
* will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A string which is the key.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Double optDoubleObject(String key) {
|
||||
return this.optDoubleObject(key, Double.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional Double object associated with a key, or the defaultValue if
|
||||
* there is no such key or if its value is not a number. If the value is a
|
||||
* string, an attempt will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Double optDoubleObject(String key, Double defaultValue) {
|
||||
Number val = this.optNumber(key);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return val.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional float value associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
@ -1313,7 +1404,7 @@ public class JSONObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional double value associated with an index. The defaultValue
|
||||
* Get the optional float value associated with an index. The defaultValue
|
||||
* is returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
@ -1335,6 +1426,42 @@ public class JSONObject {
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Float object associated with an index. NaN is returned
|
||||
* if there is no value for the index, or if the value is not a number and
|
||||
* cannot be converted to a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @return The object.
|
||||
*/
|
||||
public Float optFloatObject(String key) {
|
||||
return this.optFloatObject(key, Float.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional Float object associated with an index. The defaultValue
|
||||
* is returned if there is no value for the index, or if the value is not a
|
||||
* number and cannot be converted to a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Float optFloatObject(String key, Float defaultValue) {
|
||||
Number val = this.optNumber(key);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
final Float floatValue = val.floatValue();
|
||||
// if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) {
|
||||
// return defaultValue;
|
||||
// }
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional int value associated with a key, or zero if there is no
|
||||
* such key or if the value is not a number. If the value is a string, an
|
||||
@ -1367,6 +1494,38 @@ public class JSONObject {
|
||||
return val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional Integer object associated with a key, or zero if there is no
|
||||
* such key or if the value is not a number. If the value is a string, an
|
||||
* attempt will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Integer optIntegerObject(String key) {
|
||||
return this.optIntegerObject(key, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional Integer object associated with a key, or the default if there
|
||||
* is no such key or if the value is not a number. If the value is a string,
|
||||
* an attempt will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Integer optIntegerObject(String key, Integer defaultValue) {
|
||||
final Number val = this.optNumber(key, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional JSONArray associated with a key. It returns null if there
|
||||
* is no such key, or if its value is not a JSONArray.
|
||||
@ -1376,8 +1535,22 @@ public class JSONObject {
|
||||
* @return A JSONArray which is the value.
|
||||
*/
|
||||
public JSONArray optJSONArray(String key) {
|
||||
Object o = this.opt(key);
|
||||
return o instanceof JSONArray ? (JSONArray) o : null;
|
||||
return this.optJSONArray(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional JSONArray associated with a key, or the default if there
|
||||
* is no such key, or if its value is not a JSONArray.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return A JSONArray which is the value.
|
||||
*/
|
||||
public JSONArray optJSONArray(String key, JSONArray defaultValue) {
|
||||
Object object = this.opt(key);
|
||||
return object instanceof JSONArray ? (JSONArray) object : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1438,6 +1611,39 @@ public class JSONObject {
|
||||
return val.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional Long object associated with a key, or zero if there is no
|
||||
* such key or if the value is not a number. If the value is a string, an
|
||||
* attempt will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Long optLongObject(String key) {
|
||||
return this.optLongObject(key, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional Long object associated with a key, or the default if there
|
||||
* is no such key or if the value is not a number. If the value is a string,
|
||||
* an attempt will be made to evaluate it as a number.
|
||||
*
|
||||
* @param key
|
||||
* A key string.
|
||||
* @param defaultValue
|
||||
* The default.
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public Long optLongObject(String key, Long defaultValue) {
|
||||
final Number val = this.optNumber(key, null);
|
||||
if (val == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return val.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional {@link Number} value associated with a key, or <code>null</code>
|
||||
* if there is no such key or if the value is not a number. If the value is a string,
|
||||
@ -1516,6 +1722,8 @@ public class JSONObject {
|
||||
*
|
||||
* @param bean
|
||||
* the bean
|
||||
* @throws JSONException
|
||||
* If a getter returned a non-finite number.
|
||||
*/
|
||||
private void populateMap(Object bean) {
|
||||
populateMap(bean, Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>()));
|
||||
@ -1543,21 +1751,22 @@ public class JSONObject {
|
||||
final Object result = method.invoke(bean);
|
||||
if (result != null) {
|
||||
// check cyclic dependency and throw error if needed
|
||||
// the wrap and populateMap combination method is
|
||||
// the wrap and populateMap combination method is
|
||||
// itself DFS recursive
|
||||
if (objectsRecord.contains(result)) {
|
||||
throw recursivelyDefinedObjectException(key);
|
||||
}
|
||||
|
||||
|
||||
objectsRecord.add(result);
|
||||
|
||||
testValidity(result);
|
||||
this.map.put(key, wrap(result, objectsRecord));
|
||||
|
||||
objectsRecord.remove(result);
|
||||
|
||||
// we don't use the result anywhere outside of wrap
|
||||
// if it's a resource we should be sure to close it
|
||||
// after calling toString
|
||||
// after calling toString
|
||||
if (result instanceof Closeable) {
|
||||
try {
|
||||
((Closeable) result).close();
|
||||
@ -1657,6 +1866,10 @@ public class JSONObject {
|
||||
}
|
||||
}
|
||||
|
||||
//If the superclass is Object, no annotations will be found any more
|
||||
if (c.getSuperclass().equals(Object.class))
|
||||
return null;
|
||||
|
||||
try {
|
||||
return getAnnotation(
|
||||
c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
|
||||
@ -1711,6 +1924,10 @@ public class JSONObject {
|
||||
}
|
||||
}
|
||||
|
||||
//If the superclass is Object, no annotations will be found any more
|
||||
if (c.getSuperclass().equals(Object.class))
|
||||
return -1;
|
||||
|
||||
try {
|
||||
int d = getAnnotationDepth(
|
||||
c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
|
||||
@ -2008,16 +2225,22 @@ public class JSONObject {
|
||||
@SuppressWarnings("resource")
|
||||
public static String quote(String string) {
|
||||
StringWriter sw = new StringWriter();
|
||||
synchronized (sw.getBuffer()) {
|
||||
try {
|
||||
return quote(string, sw).toString();
|
||||
} catch (IOException ignored) {
|
||||
// will never happen - we are writing to a string writer
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return quote(string, sw).toString();
|
||||
} catch (IOException ignored) {
|
||||
// will never happen - we are writing to a string writer
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a string and appends the result to a given Writer.
|
||||
*
|
||||
* @param string The input string to be quoted.
|
||||
* @param w The Writer to which the quoted string will be appended.
|
||||
* @return The same Writer instance after appending the quoted string.
|
||||
* @throws IOException If an I/O error occurs while writing to the Writer.
|
||||
*/
|
||||
public static Writer quote(String string, Writer w) throws IOException {
|
||||
if (string == null || string.isEmpty()) {
|
||||
w.write("\"\"");
|
||||
@ -2201,6 +2424,49 @@ public class JSONObject {
|
||||
|| val.indexOf('E') > -1 || "-0".equals(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert a string into a number, boolean, or null. If the string
|
||||
* can't be converted, return the string.
|
||||
*
|
||||
* @param string
|
||||
* A String. can not be null.
|
||||
* @return A simple JSON value.
|
||||
* @throws NullPointerException
|
||||
* Thrown if the string is null.
|
||||
*/
|
||||
// Changes to this method must be copied to the corresponding method in
|
||||
// the XML class to keep full support for Android
|
||||
public static Object stringToValue(String string) {
|
||||
if ("".equals(string)) {
|
||||
return string;
|
||||
}
|
||||
|
||||
// check JSON key words true/false/null
|
||||
if ("true".equalsIgnoreCase(string)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if ("false".equalsIgnoreCase(string)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
if ("null".equalsIgnoreCase(string)) {
|
||||
return JSONObject.NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it might be a number, try converting it. If a number cannot be
|
||||
* produced, then the value will just be a string.
|
||||
*/
|
||||
|
||||
char initial = string.charAt(0);
|
||||
if ((initial >= '0' && initial <= '9') || initial == '-') {
|
||||
try {
|
||||
return stringToNumber(string);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to a number using the narrowest possible type. Possible
|
||||
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
|
||||
@ -2271,49 +2537,6 @@ public class JSONObject {
|
||||
throw new NumberFormatException("val ["+val+"] is not a valid number.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert a string into a number, boolean, or null. If the string
|
||||
* can't be converted, return the string.
|
||||
*
|
||||
* @param string
|
||||
* A String. can not be null.
|
||||
* @return A simple JSON value.
|
||||
* @throws NullPointerException
|
||||
* Thrown if the string is null.
|
||||
*/
|
||||
// Changes to this method must be copied to the corresponding method in
|
||||
// the XML class to keep full support for Android
|
||||
public static Object stringToValue(String string) {
|
||||
if ("".equals(string)) {
|
||||
return string;
|
||||
}
|
||||
|
||||
// check JSON key words true/false/null
|
||||
if ("true".equalsIgnoreCase(string)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
if ("false".equalsIgnoreCase(string)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
if ("null".equalsIgnoreCase(string)) {
|
||||
return JSONObject.NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it might be a number, try converting it. If a number cannot be
|
||||
* produced, then the value will just be a string.
|
||||
*/
|
||||
|
||||
char initial = string.charAt(0);
|
||||
if ((initial >= '0' && initial <= '9') || initial == '-') {
|
||||
try {
|
||||
return stringToNumber(string);
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception if the object is a NaN or infinite number.
|
||||
*
|
||||
@ -2401,9 +2624,7 @@ public class JSONObject {
|
||||
@SuppressWarnings("resource")
|
||||
public String toString(int indentFactor) throws JSONException {
|
||||
StringWriter w = new StringWriter();
|
||||
synchronized (w.getBuffer()) {
|
||||
return this.write(w, indentFactor, 0).toString();
|
||||
}
|
||||
return this.write(w, indentFactor, 0).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2454,7 +2675,31 @@ public class JSONObject {
|
||||
return wrap(object, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an object, if necessary. If the object is <code>null</code>, return the NULL
|
||||
* object. If it is an array or collection, wrap it in a JSONArray. If it is
|
||||
* a map, wrap it in a JSONObject. If it is a standard property (Double,
|
||||
* String, et al) then it is already wrapped. Otherwise, if it comes from
|
||||
* one of the java packages, turn it into a string. And if it doesn't, try
|
||||
* to wrap it in a JSONObject. If the wrapping fails, then null is returned.
|
||||
*
|
||||
* @param object
|
||||
* The object to wrap
|
||||
* @param recursionDepth
|
||||
* Variable for tracking the count of nested object creations.
|
||||
* @param jsonParserConfiguration
|
||||
* Variable to pass parser custom configuration for json parsing.
|
||||
* @return The wrapped value
|
||||
*/
|
||||
static Object wrap(Object object, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) {
|
||||
return wrap(object, null, recursionDepth, jsonParserConfiguration);
|
||||
}
|
||||
|
||||
private static Object wrap(Object object, Set<Object> objectsRecord) {
|
||||
return wrap(object, objectsRecord, 0, new JSONParserConfiguration());
|
||||
}
|
||||
|
||||
private static Object wrap(Object object, Set<Object> objectsRecord, int recursionDepth, JSONParserConfiguration jsonParserConfiguration) {
|
||||
try {
|
||||
if (NULL.equals(object)) {
|
||||
return NULL;
|
||||
@ -2472,14 +2717,14 @@ public class JSONObject {
|
||||
|
||||
if (object instanceof Collection) {
|
||||
Collection<?> coll = (Collection<?>) object;
|
||||
return new JSONArray(coll);
|
||||
return new JSONArray(coll, recursionDepth, jsonParserConfiguration);
|
||||
}
|
||||
if (object.getClass().isArray()) {
|
||||
return new JSONArray(object);
|
||||
}
|
||||
if (object instanceof Map) {
|
||||
Map<?, ?> map = (Map<?, ?>) object;
|
||||
return new JSONObject(map);
|
||||
return new JSONObject(map, recursionDepth, jsonParserConfiguration);
|
||||
}
|
||||
Package objectPackage = object.getClass().getPackage();
|
||||
String objectPackageName = objectPackage != null ? objectPackage
|
||||
@ -2715,4 +2960,24 @@ public class JSONObject {
|
||||
"JavaBean object contains recursively defined member variable of key " + quote(key)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a prospective number, remove the leading zeros
|
||||
* @param value prospective number
|
||||
* @return number without leading zeros
|
||||
*/
|
||||
private static String removeLeadingZerosOfNumber(String value){
|
||||
if (value.equals("-")){return value;}
|
||||
boolean negativeFirstChar = (value.charAt(0) == '-');
|
||||
int counter = negativeFirstChar ? 1:0;
|
||||
while (counter < value.length()){
|
||||
if (value.charAt(counter) != '0'){
|
||||
if (negativeFirstChar) {return "-".concat(value.substring(counter));}
|
||||
return value.substring(counter);
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
if (negativeFirstChar) {return "-0";}
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
26
sources/main/java/org/json/JSONParserConfiguration.java
Normal file
26
sources/main/java/org/json/JSONParserConfiguration.java
Normal file
@ -0,0 +1,26 @@
|
||||
package org.json;
|
||||
|
||||
/**
|
||||
* Configuration object for the JSON parser. The configuration is immutable.
|
||||
*/
|
||||
public class JSONParserConfiguration extends ParserConfiguration {
|
||||
|
||||
/**
|
||||
* Configuration with the default values.
|
||||
*/
|
||||
public JSONParserConfiguration() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONParserConfiguration clone() {
|
||||
return new JSONParserConfiguration();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public JSONParserConfiguration withMaxNestingDepth(final int maxNestingDepth) {
|
||||
return super.withMaxNestingDepth(maxNestingDepth);
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,12 @@ public class JSONPointer {
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* Constructs a new Builder object.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
// Segments for the eventual JSONPointer string
|
||||
private final List<String> refTokens = new ArrayList<String>();
|
||||
|
||||
@ -163,6 +169,12 @@ public class JSONPointer {
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new JSONPointer instance with the provided list of reference tokens.
|
||||
*
|
||||
* @param refTokens A list of strings representing the reference tokens for the JSON Pointer.
|
||||
* Each token identifies a step in the path to the targeted value.
|
||||
*/
|
||||
public JSONPointer(List<String> refTokens) {
|
||||
this.refTokens = new ArrayList<String>(refTokens);
|
||||
}
|
||||
|
@ -14,10 +14,21 @@ Public Domain.
|
||||
public class JSONPointerException extends JSONException {
|
||||
private static final long serialVersionUID = 8872944667561856751L;
|
||||
|
||||
/**
|
||||
* Constructs a new JSONPointerException with the specified error message.
|
||||
*
|
||||
* @param message The detail message describing the reason for the exception.
|
||||
*/
|
||||
public JSONPointerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new JSONPointerException with the specified error message and cause.
|
||||
*
|
||||
* @param message The detail message describing the reason for the exception.
|
||||
* @param cause The cause of the exception.
|
||||
*/
|
||||
public JSONPointerException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({METHOD})
|
||||
/**
|
||||
* Use this annotation on a getter method to override the Bean name
|
||||
* parser for Bean -> JSONObject mapping. If this annotation is
|
||||
* present at any level in the class hierarchy, then the method will
|
||||
* not be serialized from the bean into the JSONObject.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({METHOD})
|
||||
public @interface JSONPropertyIgnore { }
|
||||
|
@ -11,16 +11,17 @@ import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({METHOD})
|
||||
/**
|
||||
* Use this annotation on a getter method to override the Bean name
|
||||
* parser for Bean -> JSONObject mapping. A value set to empty string <code>""</code>
|
||||
* will have the Bean parser fall back to the default field name processing.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({METHOD})
|
||||
public @interface JSONPropertyName {
|
||||
/**
|
||||
* The value of the JSON property.
|
||||
* @return The name of the property as to be used in the JSON Object.
|
||||
*/
|
||||
String value();
|
||||
|
@ -21,3 +21,4 @@ public interface JSONString {
|
||||
*/
|
||||
public String toJSONString();
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
package org.json;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/*
|
||||
Public Domain.
|
||||
@ -61,7 +57,7 @@ public class JSONTokener {
|
||||
* @param inputStream The source.
|
||||
*/
|
||||
public JSONTokener(InputStream inputStream) {
|
||||
this(new InputStreamReader(inputStream));
|
||||
this(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
|
||||
}
|
||||
|
||||
|
||||
@ -125,7 +121,7 @@ public class JSONTokener {
|
||||
|
||||
/**
|
||||
* Checks if the end of the input has been reached.
|
||||
*
|
||||
*
|
||||
* @return true if at the end of the file and we didn't step back
|
||||
*/
|
||||
public boolean end() {
|
||||
@ -189,7 +185,7 @@ public class JSONTokener {
|
||||
this.previous = (char) c;
|
||||
return this.previous;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the last character read from the input or '\0' if nothing has been read yet.
|
||||
* @return the last character read from the input.
|
||||
@ -301,9 +297,9 @@ public class JSONTokener {
|
||||
c = this.next();
|
||||
switch (c) {
|
||||
case 0:
|
||||
case '\n':
|
||||
case '\r':
|
||||
throw this.syntaxError("Unterminated string");
|
||||
case '\r':
|
||||
break;
|
||||
case '\\':
|
||||
c = this.next();
|
||||
switch (c) {
|
||||
@ -406,12 +402,7 @@ public class JSONTokener {
|
||||
*/
|
||||
public Object nextValue() throws JSONException {
|
||||
char c = this.nextClean();
|
||||
String string;
|
||||
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\'':
|
||||
return this.nextString(c);
|
||||
case '{':
|
||||
this.back();
|
||||
try {
|
||||
@ -427,6 +418,17 @@ public class JSONTokener {
|
||||
throw new JSONException("JSON Array or Object depth too large to process.", e);
|
||||
}
|
||||
}
|
||||
return nextSimpleValue(c);
|
||||
}
|
||||
|
||||
Object nextSimpleValue(char c) {
|
||||
String string;
|
||||
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\'':
|
||||
return this.nextString(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle unquoted text. This could be the values true, false, or
|
||||
@ -522,4 +524,15 @@ public class JSONTokener {
|
||||
return " at " + this.index + " [character " + this.character + " line " +
|
||||
this.line + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying reader, releasing any resources associated with it.
|
||||
*
|
||||
* @throws IOException If an I/O error occurs while closing the reader.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if(reader!=null){
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
126
sources/main/java/org/json/ParserConfiguration.java
Normal file
126
sources/main/java/org/json/ParserConfiguration.java
Normal file
@ -0,0 +1,126 @@
|
||||
package org.json;
|
||||
/*
|
||||
Public Domain.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration base object for parsers. The configuration is immutable.
|
||||
*/
|
||||
@SuppressWarnings({""})
|
||||
public class ParserConfiguration {
|
||||
/**
|
||||
* Used to indicate there's no defined limit to the maximum nesting depth when parsing a document.
|
||||
*/
|
||||
public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
|
||||
|
||||
/**
|
||||
* The default maximum nesting depth when parsing a document.
|
||||
*/
|
||||
public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
|
||||
|
||||
/**
|
||||
* Specifies if values should be kept as strings (<code>true</code>), or if
|
||||
* they should try to be guessed into JSON values (numeric, boolean, string)
|
||||
*/
|
||||
protected boolean keepStrings;
|
||||
|
||||
/**
|
||||
* The maximum nesting depth when parsing a document.
|
||||
*/
|
||||
protected int maxNestingDepth;
|
||||
|
||||
/**
|
||||
* Constructs a new ParserConfiguration with default settings.
|
||||
*/
|
||||
public ParserConfiguration() {
|
||||
this.keepStrings = false;
|
||||
this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ParserConfiguration with the specified settings.
|
||||
*
|
||||
* @param keepStrings A boolean indicating whether to preserve strings during parsing.
|
||||
* @param maxNestingDepth An integer representing the maximum allowed nesting depth.
|
||||
*/
|
||||
protected ParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
|
||||
this.keepStrings = keepStrings;
|
||||
this.maxNestingDepth = maxNestingDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a new instance of the same configuration.
|
||||
*/
|
||||
@Override
|
||||
protected ParserConfiguration clone() {
|
||||
// future modifications to this method should always ensure a "deep"
|
||||
// clone in the case of collections. i.e. if a Map is added as a configuration
|
||||
// item, a new map instance should be created and if possible each value in the
|
||||
// map should be cloned as well. If the values of the map are known to also
|
||||
// be immutable, then a shallow clone of the map is acceptable.
|
||||
return new ParserConfiguration(
|
||||
this.keepStrings,
|
||||
this.maxNestingDepth
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
|
||||
* they should try to be guessed into JSON values (numeric, boolean, string)
|
||||
*
|
||||
* @return The <code>keepStrings</code> configuration value.
|
||||
*/
|
||||
public boolean isKeepStrings() {
|
||||
return this.keepStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
|
||||
* they should try to be guessed into JSON values (numeric, boolean, string)
|
||||
*
|
||||
* @param newVal
|
||||
* new value to use for the <code>keepStrings</code> configuration option.
|
||||
* @param <T> the type of the configuration object
|
||||
*
|
||||
* @return The existing configuration will not be modified. A new configuration is returned.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends ParserConfiguration> T withKeepStrings(final boolean newVal) {
|
||||
T newConfig = (T)this.clone();
|
||||
newConfig.keepStrings = newVal;
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum nesting depth that the parser will descend before throwing an exception
|
||||
* when parsing the XML into JSONML.
|
||||
* @return the maximum nesting depth set for this configuration
|
||||
*/
|
||||
public int getMaxNestingDepth() {
|
||||
return maxNestingDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the maximum nesting depth that the parser will descend before throwing an exception
|
||||
* when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser
|
||||
* will throw a JsonException if the maximum depth is reached.
|
||||
* Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
|
||||
* which means the parses will go as deep as the maximum call stack size allows.
|
||||
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
|
||||
* @param <T> the type of the configuration object
|
||||
*
|
||||
* @return The existing configuration will not be modified. A new configuration is returned.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends ParserConfiguration> T withMaxNestingDepth(int maxNestingDepth) {
|
||||
T newConfig = (T)this.clone();
|
||||
|
||||
if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
|
||||
newConfig.maxNestingDepth = maxNestingDepth;
|
||||
} else {
|
||||
newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
|
||||
}
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user