mirror of
https://github.com/stleary/JSON-java.git
synced 2026-01-24 00:03:17 -05:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdf3cf7f81 | ||
|
|
2565abdaaa | ||
|
|
de855c50aa | ||
|
|
4cb1ae802a | ||
|
|
2e0a8137bd | ||
|
|
f177c97258 | ||
|
|
7d8353401a | ||
|
|
7fed023080 | ||
|
|
d9b8507e6a | ||
|
|
d345bc528e | ||
|
|
6f238a3698 | ||
|
|
4dbc5ef803 | ||
|
|
5c80c9157d | ||
|
|
a129ebe8e4 | ||
|
|
641b68dd55 | ||
|
|
643b25140f | ||
|
|
5024f2d210 | ||
|
|
16baa323cf | ||
|
|
52845366bd | ||
|
|
e7e6ed9205 | ||
|
|
1add1247fa | ||
|
|
5b2e5e7579 | ||
|
|
c9ae1f17d7 | ||
|
|
246350bbcd | ||
|
|
2fbe4d96cf | ||
|
|
3645f91b55 | ||
|
|
9c092753b0 | ||
|
|
d0f5607998 | ||
|
|
ad6bdd715d | ||
|
|
ef7a5e40be | ||
|
|
237bf0adb6 | ||
|
|
f76fbe7005 | ||
|
|
4f5bf16676 | ||
|
|
fbd2be7431 | ||
|
|
757b6edb03 | ||
|
|
f2b642a1ca | ||
|
|
04d6e83fc2 | ||
|
|
849b392c01 | ||
|
|
a7f8ff24df | ||
|
|
1ab5260a7a | ||
|
|
c28a2bdf39 | ||
|
|
382f62e781 | ||
|
|
0c7bd725a6 | ||
|
|
fcdb8671b2 | ||
|
|
c46774cf13 | ||
|
|
bd4b180f4e | ||
|
|
a8d4e4734f | ||
|
|
4865f51dd5 | ||
|
|
c870094f69 | ||
|
|
ae1e9e2b6a |
11
CDL.java
11
CDL.java
@@ -22,7 +22,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This provides static methods to convert comma delimited text into a
|
* This provides static methods to convert comma delimited text into a
|
||||||
@@ -70,9 +70,12 @@ public class CDL {
|
|||||||
c = x.next();
|
c = x.next();
|
||||||
if (c == q) {
|
if (c == q) {
|
||||||
//Handle escaped double-quote
|
//Handle escaped double-quote
|
||||||
if(x.next() != '\"')
|
char nextC = x.next();
|
||||||
{
|
if(nextC != '\"') {
|
||||||
x.back();
|
// if our quote was the end of the file, don't step
|
||||||
|
if(nextC > 0) {
|
||||||
|
x.back();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.json;
|
package org.json;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2002 JSON.org
|
Copyright (c) 2002 JSON.org
|
||||||
|
|
||||||
@@ -24,8 +26,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a web browser cookie list string to a JSONObject and back.
|
* Convert a web browser cookie list string to a JSONObject and back.
|
||||||
* @author JSON.org
|
* @author JSON.org
|
||||||
@@ -39,7 +39,7 @@ public class CookieList {
|
|||||||
* The pairs are separated by ';'. The names and the values
|
* The pairs are separated by ';'. The names and the values
|
||||||
* will be unescaped, possibly converting '+' and '%' sequences.
|
* will be unescaped, possibly converting '+' and '%' sequences.
|
||||||
*
|
*
|
||||||
* To add a cookie to a cooklist,
|
* To add a cookie to a cookie list,
|
||||||
* cookielistJSONObject.put(cookieJSONObject.getString("name"),
|
* cookielistJSONObject.put(cookieJSONObject.getString("name"),
|
||||||
* cookieJSONObject.getString("value"));
|
* cookieJSONObject.getString("value"));
|
||||||
* @param string A cookie list string
|
* @param string A cookie list string
|
||||||
@@ -69,18 +69,17 @@ public class CookieList {
|
|||||||
*/
|
*/
|
||||||
public static String toString(JSONObject jo) throws JSONException {
|
public static String toString(JSONObject jo) throws JSONException {
|
||||||
boolean b = false;
|
boolean b = false;
|
||||||
Iterator<String> keys = jo.keys();
|
|
||||||
String string;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
while (keys.hasNext()) {
|
for (final Entry<String,?> entry : jo.entrySet()) {
|
||||||
string = keys.next();
|
final String key = entry.getKey();
|
||||||
if (!jo.isNull(string)) {
|
final Object value = entry.getValue();
|
||||||
|
if (!JSONObject.NULL.equals(value)) {
|
||||||
if (b) {
|
if (b) {
|
||||||
sb.append(';');
|
sb.append(';');
|
||||||
}
|
}
|
||||||
sb.append(Cookie.escape(string));
|
sb.append(Cookie.escape(key));
|
||||||
sb.append("=");
|
sb.append("=");
|
||||||
sb.append(Cookie.escape(jo.getString(string)));
|
sb.append(Cookie.escape(value.toString()));
|
||||||
b = true;
|
b = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
HTTP.java
18
HTTP.java
@@ -24,8 +24,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert an HTTP header to a JSONObject and back.
|
* Convert an HTTP header to a JSONObject and back.
|
||||||
@@ -126,8 +126,6 @@ public class HTTP {
|
|||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
public static String toString(JSONObject jo) throws JSONException {
|
public static String toString(JSONObject jo) throws JSONException {
|
||||||
Iterator<String> keys = jo.keys();
|
|
||||||
String string;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
|
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
|
||||||
sb.append(jo.getString("HTTP-Version"));
|
sb.append(jo.getString("HTTP-Version"));
|
||||||
@@ -147,14 +145,14 @@ public class HTTP {
|
|||||||
throw new JSONException("Not enough material for an HTTP header.");
|
throw new JSONException("Not enough material for an HTTP header.");
|
||||||
}
|
}
|
||||||
sb.append(CRLF);
|
sb.append(CRLF);
|
||||||
while (keys.hasNext()) {
|
for (final Entry<String,?> entry : jo.entrySet()) {
|
||||||
string = keys.next();
|
final String key = entry.getKey();
|
||||||
if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
|
if (!"HTTP-Version".equals(key) && !"Status-Code".equals(key) &&
|
||||||
!"Reason-Phrase".equals(string) && !"Method".equals(string) &&
|
!"Reason-Phrase".equals(key) && !"Method".equals(key) &&
|
||||||
!"Request-URI".equals(string) && !jo.isNull(string)) {
|
!"Request-URI".equals(key) && !JSONObject.NULL.equals(entry.getValue())) {
|
||||||
sb.append(string);
|
sb.append(key);
|
||||||
sb.append(": ");
|
sb.append(": ");
|
||||||
sb.append(jo.getString(string));
|
sb.append(jo.optString(key));
|
||||||
sb.append(CRLF);
|
sb.append(CRLF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
335
JSONArray.java
335
JSONArray.java
@@ -154,8 +154,10 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* A Collection.
|
* A Collection.
|
||||||
*/
|
*/
|
||||||
public JSONArray(Collection<?> collection) {
|
public JSONArray(Collection<?> collection) {
|
||||||
this.myArrayList = new ArrayList<Object>();
|
if (collection == null) {
|
||||||
if (collection != null) {
|
this.myArrayList = new ArrayList<Object>();
|
||||||
|
} else {
|
||||||
|
this.myArrayList = new ArrayList<Object>(collection.size());
|
||||||
for (Object o: collection){
|
for (Object o: collection){
|
||||||
this.myArrayList.add(JSONObject.wrap(o));
|
this.myArrayList.add(JSONObject.wrap(o));
|
||||||
}
|
}
|
||||||
@@ -172,6 +174,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
this();
|
this();
|
||||||
if (array.getClass().isArray()) {
|
if (array.getClass().isArray()) {
|
||||||
int length = Array.getLength(array);
|
int length = Array.getLength(array);
|
||||||
|
this.myArrayList.ensureCapacity(length);
|
||||||
for (int i = 0; i < length; i += 1) {
|
for (int i = 0; i < length; i += 1) {
|
||||||
this.put(JSONObject.wrap(Array.get(array, i)));
|
this.put(JSONObject.wrap(Array.get(array, i)));
|
||||||
}
|
}
|
||||||
@@ -183,7 +186,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Object> iterator() {
|
public Iterator<Object> iterator() {
|
||||||
return myArrayList.iterator();
|
return this.myArrayList.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -244,7 +247,50 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return object instanceof Number ? ((Number) object).doubleValue()
|
return object instanceof Number ? ((Number) object).doubleValue()
|
||||||
: Double.parseDouble((String) object);
|
: Double.parseDouble((String) object);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the float value associated with a key.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index must be between 0 and length() - 1.
|
||||||
|
* @return The numeric value.
|
||||||
|
* @throws JSONException
|
||||||
|
* if the key is not found or if the value is not a Number
|
||||||
|
* object and cannot be converted to a number.
|
||||||
|
*/
|
||||||
|
public float getFloat(int index) throws JSONException {
|
||||||
|
Object object = this.get(index);
|
||||||
|
try {
|
||||||
|
return object instanceof Number ? ((Number) object).floatValue()
|
||||||
|
: Float.parseFloat(object.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JSONException("JSONArray[" + index
|
||||||
|
+ "] is not a number.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Number value associated with a key.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index must be between 0 and length() - 1.
|
||||||
|
* @return The numeric value.
|
||||||
|
* @throws JSONException
|
||||||
|
* if the key is not found or if the value is not a Number
|
||||||
|
* object and cannot be converted to a number.
|
||||||
|
*/
|
||||||
|
public Number getNumber(int index) throws JSONException {
|
||||||
|
Object object = this.get(index);
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return (Number)object;
|
||||||
|
}
|
||||||
|
return JSONObject.stringToNumber(object.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,9 +312,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("JSONObject[" + JSONObject.quote(Integer.toString(index))
|
throw new JSONException("JSONArray[" + index + "] is not an enum of type "
|
||||||
+ "] is not an enum of type " + JSONObject.quote(clazz.getSimpleName())
|
+ JSONObject.quote(clazz.getSimpleName()) + ".");
|
||||||
+ ".");
|
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -289,7 +334,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return new BigDecimal(object.toString());
|
return new BigDecimal(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new JSONException("JSONArray[" + index +
|
throw new JSONException("JSONArray[" + index +
|
||||||
"] could not convert to BigDecimal.");
|
"] could not convert to BigDecimal.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +354,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return new BigInteger(object.toString());
|
return new BigInteger(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new JSONException("JSONArray[" + index +
|
throw new JSONException("JSONArray[" + index +
|
||||||
"] could not convert to BigInteger.");
|
"] could not convert to BigInteger.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +373,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return object instanceof Number ? ((Number) object).intValue()
|
return object instanceof Number ? ((Number) object).intValue()
|
||||||
: Integer.parseInt((String) object);
|
: Integer.parseInt((String) object);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +429,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return object instanceof Number ? ((Number) object).longValue()
|
return object instanceof Number ? ((Number) object).longValue()
|
||||||
: Long.parseLong((String) object);
|
: Long.parseLong((String) object);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
throw new JSONException("JSONArray[" + index + "] is not a number.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +498,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* Get the optional object value associated with an index.
|
* Get the optional object value associated with an index.
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
* The index must be between 0 and length() - 1.
|
* The index must be between 0 and length() - 1. If not, null is returned.
|
||||||
* @return An object value, or null if there is no object at that index.
|
* @return An object value, or null if there is no object at that index.
|
||||||
*/
|
*/
|
||||||
public Object opt(int index) {
|
public Object opt(int index) {
|
||||||
@@ -518,11 +563,63 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public double optDouble(int index, double defaultValue) {
|
public double optDouble(int index, double defaultValue) {
|
||||||
try {
|
Object val = this.opt(index);
|
||||||
return this.getDouble(index);
|
if (JSONObject.NULL.equals(val)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
if (val instanceof Number){
|
||||||
|
return ((Number) val).doubleValue();
|
||||||
|
}
|
||||||
|
if (val instanceof String) {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble((String) val);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index must be between 0 and length() - 1.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
public float optFloat(int index) {
|
||||||
|
return this.optFloat(index, Float.NaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* subscript
|
||||||
|
* @param defaultValue
|
||||||
|
* The default value.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
public float optFloat(int index, float defaultValue) {
|
||||||
|
Object val = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(val)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (val instanceof Number){
|
||||||
|
return ((Number) val).floatValue();
|
||||||
|
}
|
||||||
|
if (val instanceof String) {
|
||||||
|
try {
|
||||||
|
return Float.parseFloat((String) val);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -550,11 +647,22 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public int optInt(int index, int defaultValue) {
|
public int optInt(int index, int defaultValue) {
|
||||||
try {
|
Object val = this.opt(index);
|
||||||
return this.getInt(index);
|
if (JSONObject.NULL.equals(val)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
if (val instanceof Number){
|
||||||
|
return ((Number) val).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val instanceof String) {
|
||||||
|
try {
|
||||||
|
return new BigDecimal(val.toString()).intValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -615,8 +723,29 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
|
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
|
||||||
|
Object val = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(val)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (val instanceof BigInteger){
|
||||||
|
return (BigInteger) val;
|
||||||
|
}
|
||||||
|
if (val instanceof BigDecimal){
|
||||||
|
return ((BigDecimal) val).toBigInteger();
|
||||||
|
}
|
||||||
|
if (val instanceof Double || val instanceof Float){
|
||||||
|
return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
|
||||||
|
}
|
||||||
|
if (val instanceof Long || val instanceof Integer
|
||||||
|
|| val instanceof Short || val instanceof Byte){
|
||||||
|
return BigInteger.valueOf(((Number) val).longValue());
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigInteger(index);
|
final String valStr = val.toString();
|
||||||
|
if(JSONObject.isDecimalNotation(valStr)) {
|
||||||
|
return new BigDecimal(valStr).toBigInteger();
|
||||||
|
}
|
||||||
|
return new BigInteger(valStr);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -634,8 +763,25 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
|
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
|
||||||
|
Object val = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(val)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (val instanceof BigDecimal){
|
||||||
|
return (BigDecimal) val;
|
||||||
|
}
|
||||||
|
if (val instanceof BigInteger){
|
||||||
|
return new BigDecimal((BigInteger) val);
|
||||||
|
}
|
||||||
|
if (val instanceof Double || val instanceof Float){
|
||||||
|
return new BigDecimal(((Number) val).doubleValue());
|
||||||
|
}
|
||||||
|
if (val instanceof Long || val instanceof Integer
|
||||||
|
|| val instanceof Short || val instanceof Byte){
|
||||||
|
return new BigDecimal(((Number) val).longValue());
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigDecimal(index);
|
return new BigDecimal(val.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -693,17 +839,73 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public long optLong(int index, long defaultValue) {
|
public long optLong(int index, long defaultValue) {
|
||||||
try {
|
Object val = this.opt(index);
|
||||||
return this.getLong(index);
|
if (JSONObject.NULL.equals(val)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
if (val instanceof Number){
|
||||||
|
return ((Number) val).longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val instanceof String) {
|
||||||
|
try {
|
||||||
|
return new BigDecimal(val.toString()).longValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
* an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
|
||||||
|
* would be used in cases where type coercion of the number value is unwanted.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index must be between 0 and length() - 1.
|
||||||
|
* @return An object which is the value.
|
||||||
|
*/
|
||||||
|
public Number optNumber(int index) {
|
||||||
|
return this.optNumber(index, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an optional {@link Number} value 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 ({@link BigDecimal}). This method
|
||||||
|
* would be used in cases where type coercion of the number value is unwanted.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index must be between 0 and length() - 1.
|
||||||
|
* @param defaultValue
|
||||||
|
* The default.
|
||||||
|
* @return An object which is the value.
|
||||||
|
*/
|
||||||
|
public Number optNumber(int index, Number defaultValue) {
|
||||||
|
Object val = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(val)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (val instanceof Number){
|
||||||
|
return (Number) val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val instanceof String) {
|
||||||
|
try {
|
||||||
|
return JSONObject.stringToNumber((String) val);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the optional string value associated with an index. It returns an
|
* Get the optional string value associated with an index. It returns an
|
||||||
* empty string if there is no value at that index. If the value is not a
|
* empty string if there is no value at that index. If the value is not a
|
||||||
* string and is not null, then it is coverted to a string.
|
* string and is not null, then it is converted to a string.
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
* The index must be between 0 and length() - 1.
|
* The index must be between 0 and length() - 1.
|
||||||
@@ -951,7 +1153,13 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
if (index < this.length()) {
|
if (index < this.length()) {
|
||||||
this.myArrayList.set(index, value);
|
this.myArrayList.set(index, value);
|
||||||
|
} else if(index == this.length()){
|
||||||
|
// simple append
|
||||||
|
this.put(value);
|
||||||
} else {
|
} else {
|
||||||
|
// if we are inserting past the length, we want to grow the array all at once
|
||||||
|
// instead of incrementally.
|
||||||
|
this.myArrayList.ensureCapacity(index + 1);
|
||||||
while (index != this.length()) {
|
while (index != this.length()) {
|
||||||
this.put(JSONObject.NULL);
|
this.put(JSONObject.NULL);
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1230,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
* returns null if the query fails due to a missing key.
|
* returns null if the query fails due to a missing key.
|
||||||
*
|
*
|
||||||
* @param The JSON pointer
|
* @param jsonPointer The JSON pointer
|
||||||
* @return the queried value or {@code null}
|
* @return the queried value or {@code null}
|
||||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
*/
|
*/
|
||||||
@@ -1064,8 +1272,14 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < len; i += 1) {
|
for (int i = 0; i < len; i += 1) {
|
||||||
Object valueThis = this.get(i);
|
Object valueThis = this.myArrayList.get(i);
|
||||||
Object valueOther = ((JSONArray)other).get(i);
|
Object valueOther = ((JSONArray)other).myArrayList.get(i);
|
||||||
|
if(valueThis == valueOther) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(valueThis == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (valueThis instanceof JSONObject) {
|
if (valueThis instanceof JSONObject) {
|
||||||
if (!((JSONObject)valueThis).similar(valueOther)) {
|
if (!((JSONObject)valueThis).similar(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1097,7 +1311,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
if (names == null || names.length() == 0 || this.length() == 0) {
|
if (names == null || names.length() == 0 || this.length() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JSONObject jo = new JSONObject();
|
JSONObject jo = new JSONObject(names.length());
|
||||||
for (int i = 0; i < names.length(); i += 1) {
|
for (int i = 0; i < names.length(); i += 1) {
|
||||||
jo.put(names.getString(i), this.opt(i));
|
jo.put(names.getString(i), this.opt(i));
|
||||||
}
|
}
|
||||||
@@ -1109,12 +1323,14 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* whitespace is added. If it is not possible to produce a syntactically
|
* whitespace is added. If it is not possible to produce a syntactically
|
||||||
* correct JSON text then null will be returned instead. This could occur if
|
* correct JSON text then null will be returned instead. This could occur if
|
||||||
* the array contains an invalid number.
|
* the array contains an invalid number.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @return a printable, displayable, transmittable representation of the
|
* @return a printable, displayable, transmittable representation of the
|
||||||
* array.
|
* array.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
try {
|
try {
|
||||||
return this.toString(0);
|
return this.toString(0);
|
||||||
@@ -1124,9 +1340,24 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a prettyprinted JSON text of this JSONArray. Warning: This method
|
* Make a pretty-printed JSON text of this JSONArray.
|
||||||
* assumes that the data structure is acyclical.
|
*
|
||||||
*
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
|
||||||
|
* one element, then the array will be output on a single line:
|
||||||
|
* <pre>{@code [1]}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an array has 2 or more elements, then it will be output across
|
||||||
|
* multiple lines: <pre>{@code
|
||||||
|
* [
|
||||||
|
* 1,
|
||||||
|
* "value 2",
|
||||||
|
* 3
|
||||||
|
* ]
|
||||||
|
* }</pre>
|
||||||
|
* <p><b>
|
||||||
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
|
*
|
||||||
* @param indentFactor
|
* @param indentFactor
|
||||||
* The number of spaces to add to each level of indentation.
|
* The number of spaces to add to each level of indentation.
|
||||||
* @return a printable, displayable, transmittable representation of the
|
* @return a printable, displayable, transmittable representation of the
|
||||||
@@ -1145,8 +1376,9 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
/**
|
/**
|
||||||
* Write the contents of the JSONArray as JSON text to a writer. For
|
* Write the contents of the JSONArray as JSON text to a writer. For
|
||||||
* compactness, no whitespace is added.
|
* compactness, no whitespace is added.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
*</b>
|
||||||
*
|
*
|
||||||
* @return The writer.
|
* @return The writer.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
@@ -1156,17 +1388,30 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONArray as JSON text to a writer. For
|
* Write the contents of the JSONArray as JSON text to a writer.
|
||||||
* compactness, no whitespace is added.
|
*
|
||||||
* <p>
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
|
||||||
|
* one element, then the array will be output on a single line:
|
||||||
|
* <pre>{@code [1]}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an array has 2 or more elements, then it will be output across
|
||||||
|
* multiple lines: <pre>{@code
|
||||||
|
* [
|
||||||
|
* 1,
|
||||||
|
* "value 2",
|
||||||
|
* 3
|
||||||
|
* ]
|
||||||
|
* }</pre>
|
||||||
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* Writes the serialized JSON
|
* Writes the serialized JSON
|
||||||
* @param indentFactor
|
* @param indentFactor
|
||||||
* The number of spaces to add to each level of indentation.
|
* The number of spaces to add to each level of indentation.
|
||||||
* @param indent
|
* @param indent
|
||||||
* The indention of the top level.
|
* The indentation of the top level.
|
||||||
* @return The writer.
|
* @return The writer.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
@@ -1178,8 +1423,12 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
writer.write('[');
|
writer.write('[');
|
||||||
|
|
||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
JSONObject.writeValue(writer, this.myArrayList.get(0),
|
try {
|
||||||
indentFactor, indent);
|
JSONObject.writeValue(writer, this.myArrayList.get(0),
|
||||||
|
indentFactor, indent);
|
||||||
|
} catch (Exception 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;
|
||||||
|
|
||||||
@@ -1191,8 +1440,12 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
}
|
}
|
||||||
JSONObject.indent(writer, newindent);
|
JSONObject.indent(writer, newindent);
|
||||||
JSONObject.writeValue(writer, this.myArrayList.get(i),
|
try {
|
||||||
indentFactor, newindent);
|
JSONObject.writeValue(writer, this.myArrayList.get(i),
|
||||||
|
indentFactor, newindent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JSONException("Unable to write JSONArray value at index: " + i, e);
|
||||||
|
}
|
||||||
commanate = true;
|
commanate = true;
|
||||||
}
|
}
|
||||||
if (indentFactor > 0) {
|
if (indentFactor > 0) {
|
||||||
|
|||||||
34
JSONML.java
34
JSONML.java
@@ -1,5 +1,7 @@
|
|||||||
package org.json;
|
package org.json;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2008 JSON.org
|
Copyright (c) 2008 JSON.org
|
||||||
|
|
||||||
@@ -24,9 +26,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This provides static methods to convert an XML text into a JSONArray or
|
* This provides static methods to convert an XML text into a JSONArray or
|
||||||
* JSONObject, and to covert a JSONArray or JSONObject into an XML text using
|
* JSONObject, and to covert a JSONArray or JSONObject into an XML text using
|
||||||
@@ -42,7 +41,7 @@ public class JSONML {
|
|||||||
* @param arrayForm true if array form, false if object form.
|
* @param arrayForm true if array form, false if object form.
|
||||||
* @param ja The JSONArray that is containing the current tag or null
|
* @param ja The JSONArray that is containing the current tag or null
|
||||||
* if we are at the outermost level.
|
* if we are at the outermost level.
|
||||||
* @param keepStrings Don't type-convert text nodes and attibute values
|
* @param keepStrings Don't type-convert text nodes and attribute values
|
||||||
* @return A JSONArray if the value is the outermost tag, otherwise null.
|
* @return A JSONArray if the value is the outermost tag, otherwise null.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
@@ -175,7 +174,7 @@ public class JSONML {
|
|||||||
if (!(token instanceof String)) {
|
if (!(token instanceof String)) {
|
||||||
throw x.syntaxError("Missing value");
|
throw x.syntaxError("Missing value");
|
||||||
}
|
}
|
||||||
newjo.accumulate(attribute, keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token));
|
newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token));
|
||||||
token = null;
|
token = null;
|
||||||
} else {
|
} else {
|
||||||
newjo.accumulate(attribute, "");
|
newjo.accumulate(attribute, "");
|
||||||
@@ -397,13 +396,10 @@ public class JSONML {
|
|||||||
public static String toString(JSONArray ja) throws JSONException {
|
public static String toString(JSONArray ja) throws JSONException {
|
||||||
int i;
|
int i;
|
||||||
JSONObject jo;
|
JSONObject jo;
|
||||||
String key;
|
|
||||||
Iterator<String> keys;
|
|
||||||
int length;
|
int length;
|
||||||
Object object;
|
Object object;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String tagName;
|
String tagName;
|
||||||
String value;
|
|
||||||
|
|
||||||
// Emit <tagName
|
// Emit <tagName
|
||||||
|
|
||||||
@@ -420,17 +416,16 @@ public class JSONML {
|
|||||||
|
|
||||||
// Emit the attributes
|
// Emit the attributes
|
||||||
|
|
||||||
keys = jo.keys();
|
for (final Entry<String, ?> entry : jo.entrySet()) {
|
||||||
while (keys.hasNext()) {
|
final String key = entry.getKey();
|
||||||
key = keys.next();
|
|
||||||
XML.noSpace(key);
|
XML.noSpace(key);
|
||||||
value = jo.optString(key);
|
final Object value = entry.getValue();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
sb.append(XML.escape(key));
|
sb.append(XML.escape(key));
|
||||||
sb.append('=');
|
sb.append('=');
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
sb.append(XML.escape(value));
|
sb.append(XML.escape(value.toString()));
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -482,12 +477,10 @@ public class JSONML {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
int i;
|
int i;
|
||||||
JSONArray ja;
|
JSONArray ja;
|
||||||
String key;
|
|
||||||
Iterator<String> keys;
|
|
||||||
int length;
|
int length;
|
||||||
Object object;
|
Object object;
|
||||||
String tagName;
|
String tagName;
|
||||||
String value;
|
Object value;
|
||||||
|
|
||||||
//Emit <tagName
|
//Emit <tagName
|
||||||
|
|
||||||
@@ -502,18 +495,17 @@ public class JSONML {
|
|||||||
|
|
||||||
//Emit the attributes
|
//Emit the attributes
|
||||||
|
|
||||||
keys = jo.keys();
|
for (final Entry<String, ?> entry : jo.entrySet()) {
|
||||||
while (keys.hasNext()) {
|
final String key = entry.getKey();
|
||||||
key = keys.next();
|
|
||||||
if (!"tagName".equals(key) && !"childNodes".equals(key)) {
|
if (!"tagName".equals(key) && !"childNodes".equals(key)) {
|
||||||
XML.noSpace(key);
|
XML.noSpace(key);
|
||||||
value = jo.optString(key);
|
value = entry.getValue();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
sb.append(XML.escape(key));
|
sb.append(XML.escape(key));
|
||||||
sb.append('=');
|
sb.append('=');
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
sb.append(XML.escape(value));
|
sb.append(XML.escape(value.toString()));
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
729
JSONObject.java
729
JSONObject.java
File diff suppressed because it is too large
Load Diff
@@ -68,11 +68,11 @@ public class JSONPointer {
|
|||||||
* {@link #append(String)} method calls.
|
* {@link #append(String)} method calls.
|
||||||
*/
|
*/
|
||||||
public JSONPointer build() {
|
public JSONPointer build() {
|
||||||
return new JSONPointer(refTokens);
|
return new JSONPointer(this.refTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an arbitary token to the list of reference tokens. It can be any non-null value.
|
* Adds an arbitrary token to the list of reference tokens. It can be any non-null value.
|
||||||
*
|
*
|
||||||
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
|
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
|
||||||
* argument of this method MUST NOT be escaped. If you want to query the property called
|
* argument of this method MUST NOT be escaped. If you want to query the property called
|
||||||
@@ -87,7 +87,7 @@ public class JSONPointer {
|
|||||||
if (token == null) {
|
if (token == null) {
|
||||||
throw new NullPointerException("token cannot be null");
|
throw new NullPointerException("token cannot be null");
|
||||||
}
|
}
|
||||||
refTokens.add(token);
|
this.refTokens.add(token);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public class JSONPointer {
|
|||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public Builder append(int arrayIndex) {
|
public Builder append(int arrayIndex) {
|
||||||
refTokens.add(String.valueOf(arrayIndex));
|
this.refTokens.add(String.valueOf(arrayIndex));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,29 +134,30 @@ public class JSONPointer {
|
|||||||
* @param pointer the JSON String or URI Fragment representation of the JSON pointer.
|
* @param pointer the JSON String or URI Fragment representation of the JSON pointer.
|
||||||
* @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
|
* @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
|
||||||
*/
|
*/
|
||||||
public JSONPointer(String pointer) {
|
public JSONPointer(final String pointer) {
|
||||||
if (pointer == null) {
|
if (pointer == null) {
|
||||||
throw new NullPointerException("pointer cannot be null");
|
throw new NullPointerException("pointer cannot be null");
|
||||||
}
|
}
|
||||||
if (pointer.isEmpty() || pointer.equals("#")) {
|
if (pointer.isEmpty() || pointer.equals("#")) {
|
||||||
refTokens = Collections.emptyList();
|
this.refTokens = Collections.emptyList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
String refs;
|
||||||
if (pointer.startsWith("#/")) {
|
if (pointer.startsWith("#/")) {
|
||||||
pointer = pointer.substring(2);
|
refs = pointer.substring(2);
|
||||||
try {
|
try {
|
||||||
pointer = URLDecoder.decode(pointer, ENCODING);
|
refs = URLDecoder.decode(refs, ENCODING);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} else if (pointer.startsWith("/")) {
|
} else if (pointer.startsWith("/")) {
|
||||||
pointer = pointer.substring(1);
|
refs = pointer.substring(1);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
|
throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
|
||||||
}
|
}
|
||||||
refTokens = new ArrayList<String>();
|
this.refTokens = new ArrayList<String>();
|
||||||
for (String token : pointer.split("/")) {
|
for (String token : refs.split("/")) {
|
||||||
refTokens.add(unescape(token));
|
this.refTokens.add(unescape(token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,11 +182,11 @@ public class JSONPointer {
|
|||||||
* @throws JSONPointerException if an error occurs during evaluation
|
* @throws JSONPointerException if an error occurs during evaluation
|
||||||
*/
|
*/
|
||||||
public Object queryFrom(Object document) {
|
public Object queryFrom(Object document) {
|
||||||
if (refTokens.isEmpty()) {
|
if (this.refTokens.isEmpty()) {
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
Object current = document;
|
Object current = document;
|
||||||
for (String token : refTokens) {
|
for (String token : this.refTokens) {
|
||||||
if (current instanceof JSONObject) {
|
if (current instanceof JSONObject) {
|
||||||
current = ((JSONObject) current).opt(unescape(token));
|
current = ((JSONObject) current).opt(unescape(token));
|
||||||
} else if (current instanceof JSONArray) {
|
} else if (current instanceof JSONArray) {
|
||||||
@@ -206,6 +207,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
|
||||||
* JSONPointerException is thrown
|
* JSONPointerException is thrown
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("boxing")
|
||||||
private Object readByIndexToken(Object current, String indexToken) {
|
private Object readByIndexToken(Object current, String indexToken) {
|
||||||
try {
|
try {
|
||||||
int index = Integer.parseInt(indexToken);
|
int index = Integer.parseInt(indexToken);
|
||||||
@@ -227,7 +229,7 @@ public class JSONPointer {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder rval = new StringBuilder("");
|
StringBuilder rval = new StringBuilder("");
|
||||||
for (String token: refTokens) {
|
for (String token: this.refTokens) {
|
||||||
rval.append('/').append(escape(token));
|
rval.append('/').append(escape(token));
|
||||||
}
|
}
|
||||||
return rval.toString();
|
return rval.toString();
|
||||||
@@ -255,7 +257,7 @@ public class JSONPointer {
|
|||||||
public String toURIFragment() {
|
public String toURIFragment() {
|
||||||
try {
|
try {
|
||||||
StringBuilder rval = new StringBuilder("#");
|
StringBuilder rval = new StringBuilder("#");
|
||||||
for (String token : refTokens) {
|
for (String token : this.refTokens) {
|
||||||
rval.append('/').append(URLEncoder.encode(token, ENCODING));
|
rval.append('/').append(URLEncoder.encode(token, ENCODING));
|
||||||
}
|
}
|
||||||
return rval.toString();
|
return rval.toString();
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class JSONStringer extends JSONWriter {
|
|||||||
* <code>endArray</code>).
|
* <code>endArray</code>).
|
||||||
* @return The JSON text.
|
* @return The JSON text.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.mode == 'd' ? this.writer.toString() : null;
|
return this.mode == 'd' ? this.writer.toString() : null;
|
||||||
}
|
}
|
||||||
|
|||||||
174
JSONTokener.java
174
JSONTokener.java
@@ -29,7 +29,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JSONTokener takes a source string and extracts characters and tokens from
|
* A JSONTokener takes a source string and extracts characters and tokens from
|
||||||
@@ -39,36 +39,45 @@ SOFTWARE.
|
|||||||
* @version 2014-05-03
|
* @version 2014-05-03
|
||||||
*/
|
*/
|
||||||
public class JSONTokener {
|
public class JSONTokener {
|
||||||
|
/** current read character position on the current line. */
|
||||||
private long character;
|
private long character;
|
||||||
|
/** flag to indicate if the end of the input has been found. */
|
||||||
private boolean eof;
|
private boolean eof;
|
||||||
private long index;
|
/** current read index of the input. */
|
||||||
private long line;
|
private long index;
|
||||||
private char previous;
|
/** current line of the input. */
|
||||||
private Reader reader;
|
private long line;
|
||||||
|
/** previous character read from the input. */
|
||||||
|
private char previous;
|
||||||
|
/** Reader for the input. */
|
||||||
|
private final Reader reader;
|
||||||
|
/** flag to indicate that a previous character was requested. */
|
||||||
private boolean usePrevious;
|
private boolean usePrevious;
|
||||||
|
/** the number of characters read in the previous line. */
|
||||||
|
private long characterPreviousLine;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a JSONTokener from a Reader.
|
* Construct a JSONTokener from a Reader. The caller must close the Reader.
|
||||||
*
|
*
|
||||||
* @param reader A reader.
|
* @param reader A reader.
|
||||||
*/
|
*/
|
||||||
public JSONTokener(Reader reader) {
|
public JSONTokener(Reader reader) {
|
||||||
this.reader = reader.markSupported()
|
this.reader = reader.markSupported()
|
||||||
? reader
|
? reader
|
||||||
: new BufferedReader(reader);
|
: new BufferedReader(reader);
|
||||||
this.eof = false;
|
this.eof = false;
|
||||||
this.usePrevious = false;
|
this.usePrevious = false;
|
||||||
this.previous = 0;
|
this.previous = 0;
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.character = 1;
|
this.character = 1;
|
||||||
|
this.characterPreviousLine = 0;
|
||||||
this.line = 1;
|
this.line = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a JSONTokener from an InputStream.
|
* Construct a JSONTokener from an InputStream. The caller must close the input stream.
|
||||||
* @param inputStream The source.
|
* @param inputStream The source.
|
||||||
*/
|
*/
|
||||||
public JSONTokener(InputStream inputStream) {
|
public JSONTokener(InputStream inputStream) {
|
||||||
@@ -97,12 +106,23 @@ public class JSONTokener {
|
|||||||
if (this.usePrevious || this.index <= 0) {
|
if (this.usePrevious || this.index <= 0) {
|
||||||
throw new JSONException("Stepping back two steps is not supported");
|
throw new JSONException("Stepping back two steps is not supported");
|
||||||
}
|
}
|
||||||
this.index -= 1;
|
this.decrementIndexes();
|
||||||
this.character -= 1;
|
|
||||||
this.usePrevious = true;
|
this.usePrevious = true;
|
||||||
this.eof = false;
|
this.eof = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrements the indexes for the {@link #back()} method based on the previous character read.
|
||||||
|
*/
|
||||||
|
private void decrementIndexes() {
|
||||||
|
this.index--;
|
||||||
|
if(this.previous=='\r' || this.previous == '\n') {
|
||||||
|
this.line--;
|
||||||
|
this.character=this.characterPreviousLine ;
|
||||||
|
} else if(this.character > 0){
|
||||||
|
this.character--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the hex value of a character (base16).
|
* Get the hex value of a character (base16).
|
||||||
@@ -124,6 +144,8 @@ 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
|
* @return true if at the end of the file and we didn't step back
|
||||||
*/
|
*/
|
||||||
public boolean end() {
|
public boolean end() {
|
||||||
@@ -139,11 +161,24 @@ public class JSONTokener {
|
|||||||
* or backward while checking for more data.
|
* or backward while checking for more data.
|
||||||
*/
|
*/
|
||||||
public boolean more() throws JSONException {
|
public boolean more() throws JSONException {
|
||||||
this.next();
|
if(this.usePrevious) {
|
||||||
if (this.end()) {
|
return true;
|
||||||
return false;
|
}
|
||||||
|
try {
|
||||||
|
this.reader.mark(1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new JSONException("Unable to preserve stream position", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// -1 is EOF, but next() can not consume the null character '\0'
|
||||||
|
if(this.reader.read() <= 0) {
|
||||||
|
this.eof = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.reader.reset();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new JSONException("Unable to read the next character from the stream", e);
|
||||||
}
|
}
|
||||||
this.back();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,26 +200,39 @@ public class JSONTokener {
|
|||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
throw new JSONException(exception);
|
throw new JSONException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c <= 0) { // End of stream
|
|
||||||
this.eof = true;
|
|
||||||
c = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.index += 1;
|
if (c <= 0) { // End of stream
|
||||||
if (this.previous == '\r') {
|
this.eof = true;
|
||||||
this.line += 1;
|
return 0;
|
||||||
this.character = c == '\n' ? 0 : 1;
|
|
||||||
} else if (c == '\n') {
|
|
||||||
this.line += 1;
|
|
||||||
this.character = 0;
|
|
||||||
} else {
|
|
||||||
this.character += 1;
|
|
||||||
}
|
}
|
||||||
|
this.incrementIndexes(c);
|
||||||
this.previous = (char) c;
|
this.previous = (char) c;
|
||||||
return this.previous;
|
return this.previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the internal indexes according to the previous character
|
||||||
|
* read and the character passed as the current character.
|
||||||
|
* @param c the current character read.
|
||||||
|
*/
|
||||||
|
private void incrementIndexes(int c) {
|
||||||
|
if(c > 0) {
|
||||||
|
this.index++;
|
||||||
|
if(c=='\r') {
|
||||||
|
this.line++;
|
||||||
|
this.characterPreviousLine = this.character;
|
||||||
|
this.character=0;
|
||||||
|
}else if (c=='\n') {
|
||||||
|
if(this.previous != '\r') {
|
||||||
|
this.line++;
|
||||||
|
this.characterPreviousLine = this.character;
|
||||||
|
}
|
||||||
|
this.character=0;
|
||||||
|
} else {
|
||||||
|
this.character++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consume the next character, and check that it matches a specified
|
* Consume the next character, and check that it matches a specified
|
||||||
@@ -196,8 +244,11 @@ public class JSONTokener {
|
|||||||
public char next(char c) throws JSONException {
|
public char next(char c) throws JSONException {
|
||||||
char n = this.next();
|
char n = this.next();
|
||||||
if (n != c) {
|
if (n != c) {
|
||||||
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
|
if(n > 0) {
|
||||||
n + "'");
|
throw this.syntaxError("Expected '" + c + "' and instead saw '" +
|
||||||
|
n + "'");
|
||||||
|
}
|
||||||
|
throw this.syntaxError("Expected '" + c + "' and instead saw ''");
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -212,23 +263,23 @@ public class JSONTokener {
|
|||||||
* Substring bounds error if there are not
|
* Substring bounds error if there are not
|
||||||
* n characters remaining in the source string.
|
* n characters remaining in the source string.
|
||||||
*/
|
*/
|
||||||
public String next(int n) throws JSONException {
|
public String next(int n) throws JSONException {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] chars = new char[n];
|
char[] chars = new char[n];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
while (pos < n) {
|
while (pos < n) {
|
||||||
chars[pos] = this.next();
|
chars[pos] = this.next();
|
||||||
if (this.end()) {
|
if (this.end()) {
|
||||||
throw this.syntaxError("Substring bounds error");
|
throw this.syntaxError("Substring bounds error");
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
}
|
}
|
||||||
return new String(chars);
|
return new String(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,15 +423,15 @@ public class JSONTokener {
|
|||||||
String string;
|
String string;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
return this.nextString(c);
|
return this.nextString(c);
|
||||||
case '{':
|
case '{':
|
||||||
this.back();
|
this.back();
|
||||||
return new JSONObject(this);
|
return new JSONObject(this);
|
||||||
case '[':
|
case '[':
|
||||||
this.back();
|
this.back();
|
||||||
return new JSONArray(this);
|
return new JSONArray(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -426,13 +477,17 @@ public class JSONTokener {
|
|||||||
do {
|
do {
|
||||||
c = this.next();
|
c = this.next();
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
|
// in some readers, reset() may throw an exception if
|
||||||
|
// the remaining portion of the input is greater than
|
||||||
|
// the mark size (1,000,000 above).
|
||||||
this.reader.reset();
|
this.reader.reset();
|
||||||
this.index = startIndex;
|
this.index = startIndex;
|
||||||
this.character = startCharacter;
|
this.character = startCharacter;
|
||||||
this.line = startLine;
|
this.line = startLine;
|
||||||
return c;
|
return 0;
|
||||||
}
|
}
|
||||||
} while (c != to);
|
} while (c != to);
|
||||||
|
this.reader.mark(1);
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
throw new JSONException(exception);
|
throw new JSONException(exception);
|
||||||
}
|
}
|
||||||
@@ -440,7 +495,6 @@ public class JSONTokener {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a JSONException to signal a syntax error.
|
* Make a JSONException to signal a syntax error.
|
||||||
*
|
*
|
||||||
@@ -470,6 +524,6 @@ public class JSONTokener {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return " at " + this.index + " [character " + this.character + " line " +
|
return " at " + this.index + " [character " + this.character + " line " +
|
||||||
this.line + "]";
|
this.line + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,18 +149,18 @@ public class JSONWriter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* End something.
|
* End something.
|
||||||
* @param mode Mode
|
* @param m Mode
|
||||||
* @param c Closing character
|
* @param c Closing character
|
||||||
* @return this
|
* @return this
|
||||||
* @throws JSONException If unbalanced.
|
* @throws JSONException If unbalanced.
|
||||||
*/
|
*/
|
||||||
private JSONWriter end(char mode, char c) throws JSONException {
|
private JSONWriter end(char m, char c) throws JSONException {
|
||||||
if (this.mode != mode) {
|
if (this.mode != m) {
|
||||||
throw new JSONException(mode == 'a'
|
throw new JSONException(m == 'a'
|
||||||
? "Misplaced endArray."
|
? "Misplaced endArray."
|
||||||
: "Misplaced endObject.");
|
: "Misplaced endObject.");
|
||||||
}
|
}
|
||||||
this.pop(mode);
|
this.pop(m);
|
||||||
try {
|
try {
|
||||||
this.writer.append(c);
|
this.writer.append(c);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public class Property {
|
|||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
|
public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
|
||||||
JSONObject jo = new JSONObject();
|
JSONObject jo = new JSONObject(properties == null ? 0 : properties.size());
|
||||||
if (properties != null && !properties.isEmpty()) {
|
if (properties != null && !properties.isEmpty()) {
|
||||||
Enumeration<?> enumProperties = properties.propertyNames();
|
Enumeration<?> enumProperties = properties.propertyNames();
|
||||||
while(enumProperties.hasMoreElements()) {
|
while(enumProperties.hasMoreElements()) {
|
||||||
@@ -61,10 +61,11 @@ public class Property {
|
|||||||
public static Properties toProperties(JSONObject jo) throws JSONException {
|
public static Properties toProperties(JSONObject jo) throws JSONException {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
if (jo != null) {
|
if (jo != null) {
|
||||||
Iterator<String> keys = jo.keys();
|
for (final Entry<String, ?> entry : jo.entrySet()) {
|
||||||
while (keys.hasNext()) {
|
Object value = entry.getValue();
|
||||||
String name = keys.next();
|
if (!JSONObject.NULL.equals(value)) {
|
||||||
properties.put(name, jo.getString(name));
|
properties.put(entry.getKey(), value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return properties;
|
return properties;
|
||||||
|
|||||||
2
README
2
README
@@ -89,6 +89,8 @@ invalid number formats (1.2e6.3) will cause errors as such documents can not be
|
|||||||
reliably.
|
reliably.
|
||||||
|
|
||||||
Release history:
|
Release history:
|
||||||
|
20171018 Checkpoint for recent commits.
|
||||||
|
|
||||||
20170516 Roll up recent commits.
|
20170516 Roll up recent commits.
|
||||||
|
|
||||||
20160810 Revert code that was breaking opt*() methods.
|
20160810 Revert code that was breaking opt*() methods.
|
||||||
|
|||||||
80
XML.java
80
XML.java
@@ -25,6 +25,7 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This provides static methods to convert an XML text into a JSONObject, and to
|
* This provides static methods to convert an XML text into a JSONObject, and to
|
||||||
@@ -140,7 +141,7 @@ public class XML {
|
|||||||
if (mustEscape(cp)) {
|
if (mustEscape(cp)) {
|
||||||
sb.append("&#x");
|
sb.append("&#x");
|
||||||
sb.append(Integer.toHexString(cp));
|
sb.append(Integer.toHexString(cp));
|
||||||
sb.append(";");
|
sb.append(';');
|
||||||
} else {
|
} else {
|
||||||
sb.appendCodePoint(cp);
|
sb.appendCodePoint(cp);
|
||||||
}
|
}
|
||||||
@@ -190,36 +191,12 @@ public class XML {
|
|||||||
final int semic = string.indexOf(';', i);
|
final int semic = string.indexOf(';', i);
|
||||||
if (semic > i) {
|
if (semic > i) {
|
||||||
final String entity = string.substring(i + 1, semic);
|
final String entity = string.substring(i + 1, semic);
|
||||||
if (entity.charAt(0) == '#') {
|
sb.append(XMLTokener.unescapeEntity(entity));
|
||||||
int cp;
|
|
||||||
if (entity.charAt(1) == 'x') {
|
|
||||||
// hex encoded unicode
|
|
||||||
cp = Integer.parseInt(entity.substring(2), 16);
|
|
||||||
} else {
|
|
||||||
// decimal encoded unicode
|
|
||||||
cp = Integer.parseInt(entity.substring(1));
|
|
||||||
}
|
|
||||||
sb.appendCodePoint(cp);
|
|
||||||
} else {
|
|
||||||
if ("quot".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('"');
|
|
||||||
} else if ("amp".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('&');
|
|
||||||
} else if ("apos".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('\'');
|
|
||||||
} else if ("lt".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('<');
|
|
||||||
} else if ("gt".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('>');
|
|
||||||
} else {
|
|
||||||
sb.append('&').append(entity).append(';');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// skip past the entity we just parsed.
|
// skip past the entity we just parsed.
|
||||||
i += entity.length() + 1;
|
i += entity.length() + 1;
|
||||||
} else {
|
} else {
|
||||||
// this shouldn't happen in most cases since the parser
|
// this shouldn't happen in most cases since the parser
|
||||||
// errors on unclosed enties.
|
// errors on unclosed entries.
|
||||||
sb.append(c);
|
sb.append(c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -363,7 +340,7 @@ public class XML {
|
|||||||
throw x.syntaxError("Missing value");
|
throw x.syntaxError("Missing value");
|
||||||
}
|
}
|
||||||
jsonobject.accumulate(string,
|
jsonobject.accumulate(string,
|
||||||
keepStrings ? unescape((String)token) : stringToValue((String) token));
|
keepStrings ? ((String)token) : stringToValue((String) token));
|
||||||
token = null;
|
token = null;
|
||||||
} else {
|
} else {
|
||||||
jsonobject.accumulate(string, "");
|
jsonobject.accumulate(string, "");
|
||||||
@@ -395,7 +372,7 @@ public class XML {
|
|||||||
string = (String) token;
|
string = (String) token;
|
||||||
if (string.length() > 0) {
|
if (string.length() > 0) {
|
||||||
jsonobject.accumulate("content",
|
jsonobject.accumulate("content",
|
||||||
keepStrings ? unescape(string) : stringToValue(string));
|
keepStrings ? string : stringToValue(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (token == LT) {
|
} else if (token == LT) {
|
||||||
@@ -422,18 +399,14 @@ public class XML {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is the same as {@link JSONObject.stringToValue(String)}
|
* This method is the same as {@link JSONObject#stringToValue(String)}
|
||||||
* except that this also tries to unescape String values.
|
* except that this also tries to unescape String values.
|
||||||
*
|
*
|
||||||
* @param string String to convert
|
* @param string String to convert
|
||||||
* @return JSON value of this string or the string
|
* @return JSON value of this string or the string
|
||||||
*/
|
*/
|
||||||
public static Object stringToValue(String string) {
|
public static Object stringToValue(String string) {
|
||||||
Object ret = JSONObject.stringToValue(string);
|
return JSONObject.stringToValue(string);
|
||||||
if(ret instanceof String){
|
|
||||||
return unescape((String)ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -508,15 +481,12 @@ public class XML {
|
|||||||
* @return A string.
|
* @return A string.
|
||||||
* @throws JSONException Thrown if there is an error parsing the string
|
* @throws JSONException Thrown if there is an error parsing the string
|
||||||
*/
|
*/
|
||||||
public static String toString(Object object, String tagName)
|
public static String toString(final Object object, final String tagName)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
JSONArray ja;
|
JSONArray ja;
|
||||||
JSONObject jo;
|
JSONObject jo;
|
||||||
String key;
|
|
||||||
Iterator<String> keys;
|
|
||||||
String string;
|
String string;
|
||||||
Object value;
|
|
||||||
|
|
||||||
if (object instanceof JSONObject) {
|
if (object instanceof JSONObject) {
|
||||||
|
|
||||||
@@ -529,16 +499,14 @@ public class XML {
|
|||||||
|
|
||||||
// Loop thru the keys.
|
// Loop thru the keys.
|
||||||
jo = (JSONObject) object;
|
jo = (JSONObject) object;
|
||||||
keys = jo.keys();
|
for (final Entry<String, ?> entry : jo.entrySet()) {
|
||||||
while (keys.hasNext()) {
|
final String key = entry.getKey();
|
||||||
key = keys.next();
|
Object value = entry.getValue();
|
||||||
value = jo.opt(key);
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = "";
|
value = "";
|
||||||
} else if (value.getClass().isArray()) {
|
} else if (value.getClass().isArray()) {
|
||||||
value = new JSONArray(value);
|
value = new JSONArray(value);
|
||||||
}
|
}
|
||||||
string = value instanceof String ? (String) value : null;
|
|
||||||
|
|
||||||
// Emit content in body
|
// Emit content in body
|
||||||
if ("content".equals(key)) {
|
if ("content".equals(key)) {
|
||||||
@@ -595,21 +563,19 @@ public class XML {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object != null) {
|
if (object != null && (object instanceof JSONArray || object.getClass().isArray())) {
|
||||||
if (object.getClass().isArray()) {
|
if(object.getClass().isArray()) {
|
||||||
object = new JSONArray(object);
|
ja = new JSONArray(object);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (object instanceof JSONArray) {
|
|
||||||
ja = (JSONArray) object;
|
ja = (JSONArray) object;
|
||||||
for (Object val : ja) {
|
|
||||||
// XML does not have good support for arrays. If an array
|
|
||||||
// appears in a place where XML is lacking, synthesize an
|
|
||||||
// <array> element.
|
|
||||||
sb.append(toString(val, tagName == null ? "array" : tagName));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
for (Object val : ja) {
|
||||||
|
// XML does not have good support for arrays. If an array
|
||||||
|
// appears in a place where XML is lacking, synthesize an
|
||||||
|
// <array> element.
|
||||||
|
sb.append(toString(val, tagName == null ? "array" : tagName));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
string = (object == null) ? "null" : escape(object.toString());
|
string = (object == null) ? "null" : escape(object.toString());
|
||||||
|
|||||||
@@ -64,11 +64,8 @@ public class XMLTokener extends JSONTokener {
|
|||||||
char c;
|
char c;
|
||||||
int i;
|
int i;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (;;) {
|
while (more()) {
|
||||||
c = next();
|
c = next();
|
||||||
if (end()) {
|
|
||||||
throw syntaxError("Unclosed CDATA");
|
|
||||||
}
|
|
||||||
sb.append(c);
|
sb.append(c);
|
||||||
i = sb.length() - 3;
|
i = sb.length() - 3;
|
||||||
if (i >= 0 && sb.charAt(i) == ']' &&
|
if (i >= 0 && sb.charAt(i) == ']' &&
|
||||||
@@ -77,6 +74,7 @@ public class XMLTokener extends JSONTokener {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw syntaxError("Unclosed CDATA");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -103,7 +101,10 @@ public class XMLTokener extends JSONTokener {
|
|||||||
}
|
}
|
||||||
sb = new StringBuilder();
|
sb = new StringBuilder();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (c == '<' || c == 0) {
|
if (c == 0) {
|
||||||
|
return sb.toString().trim();
|
||||||
|
}
|
||||||
|
if (c == '<') {
|
||||||
back();
|
back();
|
||||||
return sb.toString().trim();
|
return sb.toString().trim();
|
||||||
}
|
}
|
||||||
@@ -137,8 +138,37 @@ public class XMLTokener extends JSONTokener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
String string = sb.toString();
|
String string = sb.toString();
|
||||||
Object object = entity.get(string);
|
return unescapeEntity(string);
|
||||||
return object != null ? object : ampersand + string + ";";
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes an XML entity encoding;
|
||||||
|
* @param e entity (only the actual entity value, not the preceding & or ending ;
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static String unescapeEntity(String e) {
|
||||||
|
// validate
|
||||||
|
if (e == null || e.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// if our entity is an encoded unicode point, parse it.
|
||||||
|
if (e.charAt(0) == '#') {
|
||||||
|
int cp;
|
||||||
|
if (e.charAt(1) == 'x') {
|
||||||
|
// hex encoded unicode
|
||||||
|
cp = Integer.parseInt(e.substring(2), 16);
|
||||||
|
} else {
|
||||||
|
// decimal encoded unicode
|
||||||
|
cp = Integer.parseInt(e.substring(1));
|
||||||
|
}
|
||||||
|
return new String(new int[] {cp},0,1);
|
||||||
|
}
|
||||||
|
Character knownEntity = entity.get(e);
|
||||||
|
if(knownEntity==null) {
|
||||||
|
// we don't know the entity so keep it encoded
|
||||||
|
return '&' + e + ';';
|
||||||
|
}
|
||||||
|
return knownEntity.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user