25 Commits

Author SHA1 Message Date
Sean Leary
8e5b516f2b Update README.md 2020-05-17 22:41:27 -05:00
Sean Leary
6b6e8e85d8 Merge pull request #502 from Alanscut/issue-500
update JSONTokener's brief: parse simple json text
2019-12-26 20:56:51 -06:00
Alanscut
6ecbeaa0d2 update JSONTokener's brief: parse simple json text 2019-12-25 11:38:38 +08:00
Sean Leary
3ac647a16f Merge pull request #499 from Alanscut/copyright
Add copyright notice to JSONString, JSONException.
2019-12-23 08:31:01 -06:00
Alanscut
6f06801296 add copyright 2019-12-22 19:17:58 +08:00
Sean Leary
dd7056cb6d Merge pull request #495 from harkue/master
fix typo
2019-11-20 11:20:18 -06:00
harkue
e62d763294 rename hasComma as a better name "needsComma" 2019-11-13 11:46:21 +08:00
harkue
4990c3a180 fix typo 2019-11-12 16:27:24 +08:00
Sean Leary
4b49bc94ce Merge pull request #494 from spaffrath/replace_string_arrays_with_var_args
Replace JSONObject constructor string arrays with var args
2019-11-06 09:31:23 -06:00
Sean Leary
9afa90d9a9 Merge pull request #492 from ggavriilidis/ISSUE-491_clarify_intention_of_JSONArray_toList
Issue-491 - Clarify what the output of the method JSONArray toList is
2019-10-29 22:24:45 -05:00
gavriil
065f9a94bc Issue-491 - modified the comment of JSONArray toList method to clarify what the output of the method is 2019-10-29 21:35:58 +00:00
scott
223e328161 Replace JSONObject constructor string arrays with var args 2019-10-16 21:12:02 -07:00
Sean Leary
044b035847 Merge pull request #486 from johnjaylward/StandardizeExceptionMessages
Standardize Exception Messages
2019-09-24 20:29:17 -05:00
Sean Leary
5b62cf13ff Merge pull request #485 from johnjaylward/FixMLInfiniteLoop
Fix for #484
2019-09-23 17:56:53 -05:00
John J. Aylward
e9c27ab376 standardize exception messages 2019-09-17 11:08:26 -04:00
John J. Aylward
328e7d8944 corrects EOL error when the Meta tag isn't closed properly and we reach
the end of the input.
2019-09-17 10:33:26 -04:00
Sean Leary
2a6af29235 Merge pull request #483 from viniciusls/patch-1
Update README.md to point to latest version
2019-09-07 09:01:19 -05:00
VinĂ­cius Silva
af6d3c63bd Update README.md to point to latest version
Update **Click here if you just want the latest release jar file** on README.md to point to latest version available on Maven Central.
2019-09-06 12:45:41 -03:00
Sean Leary
c3ea0249c9 Merge pull request #481 from johnjaylward/ClarifyParserExceptionsInReadMe
clarifies exception that the parser makes when reading JSON
2019-08-14 11:27:40 -05:00
John J. Aylward
b044b7db4d clarifies exception that the parser makes when reading JSON 2019-08-14 11:47:49 -04:00
Sean Leary
115f8b660b Merge pull request #475 from gaul/static-methods
Make private methods static where possible
2019-08-04 11:18:29 -05:00
Andrew Gaul
f63d21fd13 Make private methods static where possible
This avoids an unneeded object reference.  Found via error-prone.
2019-07-26 15:24:05 -07:00
Sean Leary
c8ae720caf Merge pull request #474 from gaul/stringbuilder
Prefer unsynchronized StringBuilder
2019-07-26 16:07:31 -05:00
Andrew Gaul
4d451468fd Prefer unsynchronized StringBuilder
StringBuffer provides unneeded synchronization.  Found via
error-prone.
2019-07-22 22:26:49 -07:00
Sean Leary
a03a01531a Update README.md 2019-07-22 20:33:02 -05:00
9 changed files with 272 additions and 89 deletions

View File

@@ -55,7 +55,7 @@ public class CDL {
private static String getValue(JSONTokener x) throws JSONException { private static String getValue(JSONTokener x) throws JSONException {
char c; char c;
char q; char q;
StringBuffer sb; StringBuilder sb;
do { do {
c = x.next(); c = x.next();
} while (c == ' ' || c == '\t'); } while (c == ' ' || c == '\t');
@@ -65,7 +65,7 @@ public class CDL {
case '"': case '"':
case '\'': case '\'':
q = c; q = c;
sb = new StringBuffer(); sb = new StringBuilder();
for (;;) { for (;;) {
c = x.next(); c = x.next();
if (c == q) { if (c == q) {
@@ -275,7 +275,7 @@ public class CDL {
if (names == null || names.length() == 0) { if (names == null || names.length() == 0) {
return null; return null;
} }
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < ja.length(); i += 1) { for (int i = 0; i < ja.length(); i += 1) {
JSONObject jo = ja.optJSONObject(i); JSONObject jo = ja.optJSONObject(i);
if (jo != null) { if (jo != null) {

View File

@@ -249,7 +249,7 @@ public class JSONArray implements Iterable<Object> {
.equalsIgnoreCase("true"))) { .equalsIgnoreCase("true"))) {
return true; return true;
} }
throw new JSONException("JSONArray[" + index + "] is not a boolean."); throw wrongValueFormatException(index, "boolean", null);
} }
/** /**
@@ -263,7 +263,15 @@ public class JSONArray implements Iterable<Object> {
* to a number. * to a number.
*/ */
public double getDouble(int index) throws JSONException { public double getDouble(int index) throws JSONException {
return this.getNumber(index).doubleValue(); final Object object = this.get(index);
if(object instanceof Number) {
return ((Number)object).doubleValue();
}
try {
return Double.parseDouble(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(index, "double", e);
}
} }
/** /**
@@ -277,7 +285,15 @@ public class JSONArray implements Iterable<Object> {
* object and cannot be converted to a number. * object and cannot be converted to a number.
*/ */
public float getFloat(int index) throws JSONException { public float getFloat(int index) throws JSONException {
return this.getNumber(index).floatValue(); final Object object = this.get(index);
if(object instanceof Number) {
return ((Float)object).floatValue();
}
try {
return Float.parseFloat(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(index, "float", e);
}
} }
/** /**
@@ -298,7 +314,7 @@ public class JSONArray implements Iterable<Object> {
} }
return JSONObject.stringToNumber(object.toString()); return JSONObject.stringToNumber(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw new JSONException("JSONArray[" + index + "] is not a number.", e); throw wrongValueFormatException(index, "number", e);
} }
} }
@@ -322,8 +338,8 @@ public class JSONArray implements Iterable<Object> {
// JSONException should really take a throwable argument. // JSONException should really take a throwable argument.
// If it did, I would re-implement this with the Enum.valueOf // If it did, I would re-implement this with the Enum.valueOf
// method and place any thrown exception in the JSONException // method and place any thrown exception in the JSONException
throw new JSONException("JSONArray[" + index + "] is not an enum of type " throw wrongValueFormatException(index, "enum of type "
+ JSONObject.quote(clazz.getSimpleName()) + "."); + JSONObject.quote(clazz.getSimpleName()), null);
} }
return val; return val;
} }
@@ -345,8 +361,7 @@ public class JSONArray implements Iterable<Object> {
Object object = this.get(index); Object object = this.get(index);
BigDecimal val = JSONObject.objectToBigDecimal(object, null); BigDecimal val = JSONObject.objectToBigDecimal(object, null);
if(val == null) { if(val == null) {
throw new JSONException("JSONArray[" + index + throw wrongValueFormatException(index, "BigDecimal", object, null);
"] could not convert to BigDecimal ("+ object + ").");
} }
return val; return val;
} }
@@ -365,8 +380,7 @@ public class JSONArray implements Iterable<Object> {
Object object = this.get(index); Object object = this.get(index);
BigInteger val = JSONObject.objectToBigInteger(object, null); BigInteger val = JSONObject.objectToBigInteger(object, null);
if(val == null) { if(val == null) {
throw new JSONException("JSONArray[" + index + throw wrongValueFormatException(index, "BigInteger", object, null);
"] could not convert to BigDecimal ("+ object + ").");
} }
return val; return val;
} }
@@ -381,7 +395,15 @@ public class JSONArray implements Iterable<Object> {
* If the key is not found or if the value is not a number. * If the key is not found or if the value is not a number.
*/ */
public int getInt(int index) throws JSONException { public int getInt(int index) throws JSONException {
return this.getNumber(index).intValue(); final Object object = this.get(index);
if(object instanceof Number) {
return ((Number)object).intValue();
}
try {
return Integer.parseInt(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(index, "int", e);
}
} }
/** /**
@@ -399,7 +421,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof JSONArray) { if (object instanceof JSONArray) {
return (JSONArray) object; return (JSONArray) object;
} }
throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); throw wrongValueFormatException(index, "JSONArray", null);
} }
/** /**
@@ -417,7 +439,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof JSONObject) { if (object instanceof JSONObject) {
return (JSONObject) object; return (JSONObject) object;
} }
throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); throw wrongValueFormatException(index, "JSONObject", null);
} }
/** /**
@@ -431,7 +453,15 @@ public class JSONArray implements Iterable<Object> {
* to a number. * to a number.
*/ */
public long getLong(int index) throws JSONException { public long getLong(int index) throws JSONException {
return this.getNumber(index).longValue(); final Object object = this.get(index);
if(object instanceof Number) {
return ((Number)object).longValue();
}
try {
return Long.parseLong(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(index, "long", e);
}
} }
/** /**
@@ -448,7 +478,7 @@ public class JSONArray implements Iterable<Object> {
if (object instanceof String) { if (object instanceof String) {
return (String) object; return (String) object;
} }
throw new JSONException("JSONArray[" + index + "] not a string."); throw wrongValueFormatException(index, "String", null);
} }
/** /**
@@ -1379,7 +1409,7 @@ public class JSONArray implements Iterable<Object> {
public Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
boolean commanate = false; boolean needsComma = false;
int length = this.length(); int length = this.length();
writer.write('['); writer.write('[');
@@ -1391,23 +1421,23 @@ public class JSONArray implements Iterable<Object> {
throw new JSONException("Unable to write JSONArray value at index: 0", e); throw new JSONException("Unable to write JSONArray value at index: 0", e);
} }
} else if (length != 0) { } else if (length != 0) {
final int newindent = indent + indentFactor; final int newIndent = indent + indentFactor;
for (int i = 0; i < length; i += 1) { for (int i = 0; i < length; i += 1) {
if (commanate) { if (needsComma) {
writer.write(','); writer.write(',');
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write('\n'); writer.write('\n');
} }
JSONObject.indent(writer, newindent); JSONObject.indent(writer, newIndent);
try { try {
JSONObject.writeValue(writer, this.myArrayList.get(i), JSONObject.writeValue(writer, this.myArrayList.get(i),
indentFactor, newindent); indentFactor, newIndent);
} catch (Exception e) { } catch (Exception e) {
throw new JSONException("Unable to write JSONArray value at index: " + i, e); throw new JSONException("Unable to write JSONArray value at index: " + i, e);
} }
commanate = true; needsComma = true;
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write('\n'); writer.write('\n');
@@ -1424,7 +1454,7 @@ public class JSONArray implements Iterable<Object> {
/** /**
* Returns a java.util.List containing all of the elements in this array. * Returns a java.util.List containing all of the elements in this array.
* If an element in the array is a JSONArray or JSONObject it will also * If an element in the array is a JSONArray or JSONObject it will also
* be converted. * be converted to a List and a Map respectively.
* <p> * <p>
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* *
@@ -1454,5 +1484,38 @@ public class JSONArray implements Iterable<Object> {
public boolean isEmpty() { public boolean isEmpty() {
return this.myArrayList.isEmpty(); return this.myArrayList.isEmpty();
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + "."
, cause);
}
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param idx index of the item
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
int idx,
String valueType,
Object value,
Throwable cause) {
return new JSONException(
"JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")."
, cause);
}
} }

View File

@@ -1,5 +1,29 @@
package org.json; package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/** /**
* The JSONException is thrown by the JSON.org classes when things are amiss. * The JSONException is thrown by the JSON.org classes when things are amiss.
* *

View File

@@ -194,7 +194,7 @@ public class JSONObject {
* @param names * @param names
* An array of strings. * An array of strings.
*/ */
public JSONObject(JSONObject jo, String[] names) { public JSONObject(JSONObject jo, String ... names) {
this(names.length); this(names.length);
for (int i = 0; i < names.length; i += 1) { for (int i = 0; i < names.length; i += 1) {
try { try {
@@ -378,7 +378,7 @@ public class JSONObject {
* An array of strings, the names of the fields to be obtained * An array of strings, the names of the fields to be obtained
* from the object. * from the object.
*/ */
public JSONObject(Object object, String names[]) { public JSONObject(Object object, String ... names) {
this(names.length); this(names.length);
Class<?> c = object.getClass(); Class<?> c = object.getClass();
for (int i = 0; i < names.length; i += 1) { for (int i = 0; i < names.length; i += 1) {
@@ -521,8 +521,7 @@ public class JSONObject {
} else if (object instanceof JSONArray) { } else if (object instanceof JSONArray) {
this.put(key, ((JSONArray) object).put(value)); this.put(key, ((JSONArray) object).put(value));
} else { } else {
throw new JSONException("JSONObject[" + key throw wrongValueFormatException(key, "JSONArray", null, null);
+ "] is not a JSONArray.");
} }
return this; return this;
} }
@@ -595,9 +594,7 @@ public class JSONObject {
// JSONException should really take a throwable argument. // JSONException should really take a throwable argument.
// If it did, I would re-implement this with the Enum.valueOf // If it did, I would re-implement this with the Enum.valueOf
// method and place any thrown exception in the JSONException // method and place any thrown exception in the JSONException
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), null);
+ "] is not an enum of type " + quote(clazz.getSimpleName())
+ ".");
} }
return val; return val;
} }
@@ -623,8 +620,7 @@ public class JSONObject {
.equalsIgnoreCase("true"))) { .equalsIgnoreCase("true"))) {
return true; return true;
} }
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "Boolean", null);
+ "] is not a Boolean.");
} }
/** /**
@@ -643,8 +639,7 @@ public class JSONObject {
if (ret != null) { if (ret != null) {
return ret; return ret;
} }
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "BigInteger", object, null);
+ "] could not be converted to BigInteger (" + object + ").");
} }
/** /**
@@ -666,8 +661,7 @@ public class JSONObject {
if (ret != null) { if (ret != null) {
return ret; return ret;
} }
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "BigDecimal", object, null);
+ "] could not be converted to BigDecimal (" + object + ").");
} }
/** /**
@@ -681,7 +675,15 @@ public class JSONObject {
* object and cannot be converted to a number. * object and cannot be converted to a number.
*/ */
public double getDouble(String key) throws JSONException { public double getDouble(String key) throws JSONException {
return this.getNumber(key).doubleValue(); final Object object = this.get(key);
if(object instanceof Number) {
return ((Number)object).doubleValue();
}
try {
return Double.parseDouble(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(key, "double", e);
}
} }
/** /**
@@ -695,7 +697,15 @@ public class JSONObject {
* object and cannot be converted to a number. * object and cannot be converted to a number.
*/ */
public float getFloat(String key) throws JSONException { public float getFloat(String key) throws JSONException {
return this.getNumber(key).floatValue(); final Object object = this.get(key);
if(object instanceof Number) {
return ((Number)object).floatValue();
}
try {
return Float.parseFloat(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(key, "float", e);
}
} }
/** /**
@@ -716,8 +726,7 @@ public class JSONObject {
} }
return stringToNumber(object.toString()); return stringToNumber(object.toString());
} catch (Exception e) { } catch (Exception e) {
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "number", e);
+ "] is not a number.", e);
} }
} }
@@ -732,7 +741,15 @@ public class JSONObject {
* to an integer. * to an integer.
*/ */
public int getInt(String key) throws JSONException { public int getInt(String key) throws JSONException {
return this.getNumber(key).intValue(); final Object object = this.get(key);
if(object instanceof Number) {
return ((Number)object).intValue();
}
try {
return Integer.parseInt(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(key, "int", e);
}
} }
/** /**
@@ -749,8 +766,7 @@ public class JSONObject {
if (object instanceof JSONArray) { if (object instanceof JSONArray) {
return (JSONArray) object; return (JSONArray) object;
} }
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "JSONArray", null);
+ "] is not a JSONArray.");
} }
/** /**
@@ -767,8 +783,7 @@ public class JSONObject {
if (object instanceof JSONObject) { if (object instanceof JSONObject) {
return (JSONObject) object; return (JSONObject) object;
} }
throw new JSONException("JSONObject[" + quote(key) throw wrongValueFormatException(key, "JSONObject", null);
+ "] is not a JSONObject.");
} }
/** /**
@@ -782,7 +797,15 @@ public class JSONObject {
* to a long. * to a long.
*/ */
public long getLong(String key) throws JSONException { public long getLong(String key) throws JSONException {
return this.getNumber(key).longValue(); final Object object = this.get(key);
if(object instanceof Number) {
return ((Number)object).longValue();
}
try {
return Long.parseLong(object.toString());
} catch (Exception e) {
throw wrongValueFormatException(key, "long", e);
}
} }
/** /**
@@ -837,7 +860,7 @@ public class JSONObject {
if (object instanceof String) { if (object instanceof String) {
return (String) object; return (String) object;
} }
throw new JSONException("JSONObject[" + quote(key) + "] not a string."); throw wrongValueFormatException(key, "string", null);
} }
/** /**
@@ -853,8 +876,11 @@ public class JSONObject {
/** /**
* Increment a property of a JSONObject. If there is no such property, * Increment a property of a JSONObject. If there is no such property,
* create one with a value of 1. If there is such a property, and if it is * create one with a value of 1 (Integer). If there is such a property, and if it is
* an Integer, Long, Double, or Float, then add one to it. * an Integer, Long, Double, Float, BigInteger, or BigDecimal then add one to it.
* No overflow bounds checking is performed, so callers should initialize the key
* prior to this call with an appropriate type that can handle the maximum expected
* value.
* *
* @param key * @param key
* A key string. * A key string.
@@ -867,18 +893,18 @@ public class JSONObject {
Object value = this.opt(key); Object value = this.opt(key);
if (value == null) { if (value == null) {
this.put(key, 1); this.put(key, 1);
} else if (value instanceof BigInteger) {
this.put(key, ((BigInteger)value).add(BigInteger.ONE));
} else if (value instanceof BigDecimal) {
this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
} else if (value instanceof Integer) { } else if (value instanceof Integer) {
this.put(key, ((Integer) value).intValue() + 1); this.put(key, ((Integer) value).intValue() + 1);
} else if (value instanceof Long) { } else if (value instanceof Long) {
this.put(key, ((Long) value).longValue() + 1L); this.put(key, ((Long) value).longValue() + 1L);
} else if (value instanceof Double) { } else if (value instanceof BigInteger) {
this.put(key, ((Double) value).doubleValue() + 1.0d); this.put(key, ((BigInteger)value).add(BigInteger.ONE));
} else if (value instanceof Float) { } else if (value instanceof Float) {
this.put(key, ((Float) value).floatValue() + 1.0f); this.put(key, ((Float) value).floatValue() + 1.0f);
} else if (value instanceof Double) {
this.put(key, ((Double) value).doubleValue() + 1.0d);
} else if (value instanceof BigDecimal) {
this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
} else { } else {
throw new JSONException("Unable to increment [" + quote(key) + "]."); throw new JSONException("Unable to increment [" + quote(key) + "].");
} }
@@ -1496,11 +1522,11 @@ public class JSONObject {
} }
} }
private boolean isValidMethodName(String name) { private static boolean isValidMethodName(String name) {
return !"getClass".equals(name) && !"getDeclaringClass".equals(name); return !"getClass".equals(name) && !"getDeclaringClass".equals(name);
} }
private String getKeyNameFromMethod(Method method) { private static String getKeyNameFromMethod(Method method) {
final int ignoreDepth = getAnnotationDepth(method, JSONPropertyIgnore.class); final int ignoreDepth = getAnnotationDepth(method, JSONPropertyIgnore.class);
if (ignoreDepth > 0) { if (ignoreDepth > 0) {
final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class); final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class);
@@ -2115,7 +2141,7 @@ public class JSONObject {
//} //}
//return new BigInteger(val); //return new BigInteger(val);
// BigInteger version: We use a similar bitLenth compare as // BigInteger version: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold // BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is // only what they need. i.e. Less runtime overhead if the value is
// long lived. Which is the better tradeoff? This is closer to what's // long lived. Which is the better tradeoff? This is closer to what's
@@ -2470,7 +2496,7 @@ public class JSONObject {
public Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
boolean commanate = false; boolean needsComma = false;
final int length = this.length(); final int length = this.length();
writer.write('{'); writer.write('{');
@@ -2488,15 +2514,15 @@ public class JSONObject {
throw new JSONException("Unable to write JSONObject value for key: " + key, e); throw new JSONException("Unable to write JSONObject value for key: " + key, e);
} }
} else if (length != 0) { } else if (length != 0) {
final int newindent = indent + indentFactor; final int newIndent = indent + indentFactor;
for (final Entry<String,?> entry : this.entrySet()) { for (final Entry<String,?> entry : this.entrySet()) {
if (commanate) { if (needsComma) {
writer.write(','); writer.write(',');
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write('\n'); writer.write('\n');
} }
indent(writer, newindent); indent(writer, newIndent);
final String key = entry.getKey(); final String key = entry.getKey();
writer.write(quote(key)); writer.write(quote(key));
writer.write(':'); writer.write(':');
@@ -2504,11 +2530,11 @@ public class JSONObject {
writer.write(' '); writer.write(' ');
} }
try { try {
writeValue(writer, entry.getValue(), indentFactor, newindent); writeValue(writer, entry.getValue(), indentFactor, newIndent);
} catch (Exception e) { } catch (Exception e) {
throw new JSONException("Unable to write JSONObject value for key: " + key, e); throw new JSONException("Unable to write JSONObject value for key: " + key, e);
} }
commanate = true; needsComma = true;
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write('\n'); writer.write('\n');
@@ -2548,4 +2574,37 @@ public class JSONObject {
} }
return results; return results;
} }
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
String key,
String valueType,
Throwable cause) {
return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + "."
, cause);
}
/**
* Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key
* @param valueType the type of value being coerced to
* @param cause optional cause of the coercion failure
* @return JSONException that can be thrown.
*/
private static JSONException wrongValueFormatException(
String key,
String valueType,
Object value,
Throwable cause) {
return new JSONException(
"JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")."
, cause);
}
} }

View File

@@ -186,7 +186,7 @@ public class JSONPointer {
this.refTokens = new ArrayList<String>(refTokens); this.refTokens = new ArrayList<String>(refTokens);
} }
private String unescape(String token) { private static String unescape(String token) {
return token.replace("~1", "/").replace("~0", "~") return token.replace("~1", "/").replace("~0", "~")
.replace("\\\"", "\"") .replace("\\\"", "\"")
.replace("\\\\", "\\"); .replace("\\\\", "\\");
@@ -228,7 +228,7 @@ public class JSONPointer {
* @return the matched object. If no matching item is found a * @return the matched object. If no matching item is found a
* @throws JSONPointerException is thrown if the index is out of bounds * @throws JSONPointerException is thrown if the index is out of bounds
*/ */
private Object readByIndexToken(Object current, String indexToken) throws JSONPointerException { private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException {
try { try {
int index = Integer.parseInt(indexToken); int index = Integer.parseInt(indexToken);
JSONArray currentArr = (JSONArray) current; JSONArray currentArr = (JSONArray) current;
@@ -267,7 +267,7 @@ public class JSONPointer {
* @param token the JSONPointer segment value to be escaped * @param token the JSONPointer segment value to be escaped
* @return the escaped value for the token * @return the escaped value for the token
*/ */
private String escape(String token) { private static String escape(String token) {
return token.replace("~", "~0") return token.replace("~", "~0")
.replace("/", "~1") .replace("/", "~1")
.replace("\\", "\\\\") .replace("\\", "\\\\")

View File

@@ -1,4 +1,29 @@
package org.json; package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/** /**
* The <code>JSONString</code> interface allows a <code>toJSONString()</code> * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
* method so that a class can change the behavior of * method so that a class can change the behavior of

View File

@@ -3,7 +3,7 @@ JSON in Java [package org.json]
[![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json) [![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json)
**[Click here if you just want the latest release jar file.](http://central.maven.org/maven2/org/json/json/20180813/json-20180813.jar)** **[Click here if you just want the latest release jar file.](https://repo1.maven.org/maven2/org/json/json/20190722/json-20190722.jar)**
JSON is a light-weight, language independent, data interchange format. JSON is a light-weight, language independent, data interchange format.
See http://www.JSON.org/ See http://www.JSON.org/
@@ -32,7 +32,9 @@ to produce a vector-like object. The object provides methods for manipulating
its contents, and for producing a JSON compliant array serialization. its contents, and for producing a JSON compliant array serialization.
**JSONTokener.java**: The `JSONTokener` breaks a text into a sequence of individual **JSONTokener.java**: The `JSONTokener` breaks a text into a sequence of individual
tokens. It can be constructed from a `String`, `Reader`, or `InputStream`. tokens. It can be constructed from a `String`, `Reader`, or `InputStream`. It also can
parse text from a `String`, `Number`, `Boolean` or `null` like `"hello"`, `42`, `true`,
`null` to produce a simple json object.
**JSONException.java**: The `JSONException` is the standard exception type thrown **JSONException.java**: The `JSONException` is the standard exception type thrown
by this package. by this package.
@@ -102,11 +104,21 @@ JSON Text strings, but when output by the Generator, tab is properly converted t
the string. Other instances may occur where reading invalid JSON text does not cause an the string. Other instances may occur where reading invalid JSON text does not cause an
error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
invalid number formats (1.2e6.3) will cause errors as such documents can not be read invalid number formats (1.2e6.3) will cause errors as such documents can not be read
reliably. reliably.
Some notible exceptions that the JSON Parser in this library accepts are:
* Unquoted keys `{ key: "value" }`
* Unquoted values `{ "key": value }`
* Unescaped literals like "tab" in string values `{ "key": "value with an unescaped tab" }`
* Numbers out of range for `Double` or `Long` are parsed as strings
Release history: Release history:
~~~ ~~~
20200518 Recent commits and snapshot before project structure change
20190722 Recent commits
20180813 POM change to include Automatic-Module-Name (#431) 20180813 POM change to include Automatic-Module-Name (#431)
20180130 Recent commits 20180130 Recent commits

View File

@@ -66,7 +66,7 @@ public class XML {
public static final Character SLASH = '/'; public static final Character SLASH = '/';
/** /**
* Null attrubute name * Null attribute name
*/ */
public static final String NULL_ATTR = "xsi:nil"; public static final String NULL_ATTR = "xsi:nil";
@@ -251,7 +251,7 @@ public class XML {
throws JSONException { throws JSONException {
char c; char c;
int i; int i;
JSONObject jsonobject = null; JSONObject jsonObject = null;
String string; String string;
String tagName; String tagName;
Object token; Object token;
@@ -332,7 +332,7 @@ public class XML {
} else { } else {
tagName = (String) token; tagName = (String) token;
token = null; token = null;
jsonobject = new JSONObject(); jsonObject = new JSONObject();
boolean nilAttributeFound = false; boolean nilAttributeFound = false;
for (;;) { for (;;) {
if (token == null) { if (token == null) {
@@ -353,14 +353,14 @@ public class XML {
&& Boolean.parseBoolean((String) token)) { && Boolean.parseBoolean((String) token)) {
nilAttributeFound = true; nilAttributeFound = true;
} else if (!nilAttributeFound) { } else if (!nilAttributeFound) {
jsonobject.accumulate(string, jsonObject.accumulate(string,
config.keepStrings config.keepStrings
? ((String) token) ? ((String) token)
: stringToValue((String) token)); : stringToValue((String) token));
} }
token = null; token = null;
} else { } else {
jsonobject.accumulate(string, ""); jsonObject.accumulate(string, "");
} }
@@ -371,8 +371,8 @@ public class XML {
} }
if (nilAttributeFound) { if (nilAttributeFound) {
context.accumulate(tagName, JSONObject.NULL); context.accumulate(tagName, JSONObject.NULL);
} else if (jsonobject.length() > 0) { } else if (jsonObject.length() > 0) {
context.accumulate(tagName, jsonobject); context.accumulate(tagName, jsonObject);
} else { } else {
context.accumulate(tagName, ""); context.accumulate(tagName, "");
} }
@@ -390,21 +390,20 @@ public class XML {
} else if (token instanceof String) { } else if (token instanceof String) {
string = (String) token; string = (String) token;
if (string.length() > 0) { if (string.length() > 0) {
jsonobject.accumulate(config.cDataTagName, jsonObject.accumulate(config.cDataTagName,
config.keepStrings ? string : stringToValue(string)); config.keepStrings ? string : stringToValue(string));
} }
} else if (token == LT) { } else if (token == LT) {
// Nested element // Nested element
if (parse(x, jsonobject, tagName, config)) { if (parse(x, jsonObject, tagName, config)) {
if (jsonobject.length() == 0) { if (jsonObject.length() == 0) {
context.accumulate(tagName, ""); context.accumulate(tagName, "");
} else if (jsonobject.length() == 1 } else if (jsonObject.length() == 1
&& jsonobject.opt(config.cDataTagName) != null) { && jsonObject.opt(config.cDataTagName) != null) {
context.accumulate(tagName, context.accumulate(tagName, jsonObject.opt(config.cDataTagName));
jsonobject.opt(config.cDataTagName));
} else { } else {
context.accumulate(tagName, jsonobject); context.accumulate(tagName, jsonObject);
} }
return false; return false;
} }
@@ -731,7 +730,7 @@ public class XML {
} }
if (tagName != null) { if (tagName != null) {
// Emit the </tagname> close tag // Emit the </tagName> close tag
sb.append("</"); sb.append("</");
sb.append(tagName); sb.append(tagName);
sb.append('>'); sb.append('>');

View File

@@ -152,7 +152,7 @@ public class XMLTokener extends JSONTokener {
} }
/** /**
* Unescapes an XML entity encoding; * Unescape an XML entity encoding;
* @param e entity (only the actual entity value, not the preceding & or ending ; * @param e entity (only the actual entity value, not the preceding & or ending ;
* @return * @return
*/ */
@@ -232,6 +232,7 @@ public class XMLTokener extends JSONTokener {
} }
switch (c) { switch (c) {
case 0: case 0:
throw syntaxError("Unterminated string");
case '<': case '<':
case '>': case '>':
case '/': case '/':