Skip to content
172 changes: 57 additions & 115 deletions src/main/java/org/json/JSONArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@
* @author JSON.org
* @version 2016-08/15
*/
public class JSONArray implements Iterable<Object> {
public class JSONArray implements Iterable<Object>, JSONSimilar {

private static final int commaMultiplier = 2; // Each value requires a comma in output
private static final int minimumBufferSize = 16; // Minimum reasonable buffer size for small arrays

/**
* The arrayList where the JSONArray's properties are kept.
Expand Down Expand Up @@ -325,27 +328,46 @@ public Object get(int index) throws JSONException {
* Get the boolean value associated with an index. The string values "true"
* and "false" are converted to boolean.
*
* @param index
* The index must be between 0 and length() - 1.
* @param index The index must be between 0 and length() - 1.
* @return The truth.
* @throws JSONException
* If there is no value for the index or if the value is not
* convertible to boolean.
* @throws JSONException If there is no value for the index or if the value is not
* convertible to boolean.
*/
public boolean getBoolean(int index) throws JSONException {
Object object = this.get(index);
if (object.equals(Boolean.FALSE)
|| (object instanceof String && ((String) object)
.equalsIgnoreCase("false"))) {

if (isFalse(object)) {
return false;
} else if (object.equals(Boolean.TRUE)
|| (object instanceof String && ((String) object)
.equalsIgnoreCase("true"))) {
}
if (isTrue(object)) {
return true;
}

throw wrongValueFormatException(index, "boolean", object, null);
}

/**
* Checks if the object represents a false value
* @param object The object to check
* @return true if the object represents false
*/
private boolean isFalse(Object object) {
if (object.equals(Boolean.FALSE)) return true;
if (!(object instanceof String)) return false;
return ((String) object).equalsIgnoreCase("false");
}

/**
* Checks if the object represents a true value
* @param object The object to check
* @return true if the object represents true
*/
private boolean isTrue(Object object) {
if (object.equals(Boolean.TRUE)) return true;
if (!(object instanceof String)) return false;
return ((String) object).equalsIgnoreCase("true");
}

/**
* Get the double value associated with an index.
*
Expand Down Expand Up @@ -604,11 +626,11 @@ public String join(String separator) throws JSONException {
}

StringBuilder sb = new StringBuilder(
JSONObject.valueToString(this.myArrayList.get(0)));
JSONWriter.valueToString(this.myArrayList.get(0)));

for (int i = 1; i < len; i++) {
sb.append(separator)
.append(JSONObject.valueToString(this.myArrayList.get(i)));
.append(JSONWriter.valueToString(this.myArrayList.get(i)));
}
return sb.toString();
}
Expand Down Expand Up @@ -1624,44 +1646,21 @@ public Object remove(int index) {
/**
* Determine if two JSONArrays are similar.
* They must contain similar sequences.
*
* @param other The other JSONArray
* @return true if they are equal
*/
@Override
public boolean similar(Object other) {
if (!(other instanceof JSONArray)) {
return false;
}
JSONArray otherArray = (JSONArray)other;
int len = this.length();
if (len != ((JSONArray)other).length()) {
if (len != otherArray.length()) {
return false;
}
for (int i = 0; i < len; i += 1) {
Object valueThis = this.myArrayList.get(i);
Object valueOther = ((JSONArray)other).myArrayList.get(i);
if(valueThis == valueOther) {
continue;
}
if(valueThis == null) {
return false;
}
if (valueThis instanceof JSONObject) {
if (!((JSONObject)valueThis).similar(valueOther)) {
return false;
}
} else if (valueThis instanceof JSONArray) {
if (!((JSONArray)valueThis).similar(valueOther)) {
return false;
}
} else if (valueThis instanceof Number && valueOther instanceof Number) {
if (!JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther)) {
return false;
}
} else if (valueThis instanceof JSONString && valueOther instanceof JSONString) {
if (!((JSONString) valueThis).toJSONString().equals(((JSONString) valueOther).toJSONString())) {
return false;
}
} else if (!valueThis.equals(valueOther)) {
if (!JSONSimilar.compare(this.myArrayList.get(i), otherArray.myArrayList.get(i))) {
return false;
}
}
Expand Down Expand Up @@ -1706,7 +1705,7 @@ public JSONObject toJSONObject(JSONArray names) throws JSONException {
@Override
public String toString() {
try {
return this.toString(0);
return JSONWriter.format(this, 0);
} catch (Exception e) {
return null;
}
Expand Down Expand Up @@ -1741,11 +1740,7 @@ public String toString() {
*/
@SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException {
// each value requires a comma, so multiply the count by 2
// We don't want to oversize the initial capacity
int initialSize = myArrayList.size() * 2;
Writer sw = new StringBuilderWriter(Math.max(initialSize, 16));
return this.write(sw, indentFactor, 0).toString();
return JSONWriter.format(this, indentFactor);
}

/**
Expand All @@ -1759,81 +1754,28 @@ public String toString(int indentFactor) throws JSONException {
* @throws JSONException if a called function fails
*/
public Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
return JSONWriter.format(this, writer, 0, 0);
}

/**
* Write the contents of the JSONArray as JSON text to a writer.
*
* <p>If <pre>{@code indentFactor > 0}</pre> 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>
* Writes the contents of the JSONArray as JSON text to a writer.
*
* @param writer
* Writes the serialized JSON
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @param indent
* The indentation of the top level.
* <p>If {@code indentFactor > 0} and the JSONArray has only one element,
* the array will be output on a single line (e.g., {@code [1]}). If the array
* has 2 or more elements, it will be output across multiple lines with proper
* indentation.</p>
*
* <p><b>Warning:</b> This method assumes that the data structure is acyclical.</p>
*
* @param writer The writer to which the JSON text is written.
* @param indentFactor The number of spaces to add to each level of indentation.
* @param indent The indentation level of the top level.
* @return The writer.
* @throws JSONException if a called function fails or unable to write
* @throws JSONException If an error occurs while writing the JSON text.
*/
@SuppressWarnings("resource")
public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException {
try {
boolean needsComma = false;
int length = this.length();
writer.write('[');

if (length == 1) {
try {
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) {
final int newIndent = indent + indentFactor;

for (int i = 0; i < length; i += 1) {
if (needsComma) {
writer.write(',');
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, newIndent);
try {
JSONObject.writeValue(writer, this.myArrayList.get(i),
indentFactor, newIndent);
} catch (Exception e) {
throw new JSONException("Unable to write JSONArray value at index: " + i, e);
}
needsComma = true;
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, indent);
}
writer.write(']');
return writer;
} catch (IOException e) {
throw new JSONException(e);
}
public Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
return JSONWriter.format(this, writer, indentFactor, indent);
}

/**
Expand Down
26 changes: 13 additions & 13 deletions src/main/java/org/json/JSONML.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private static Object parse(
int currentNestingDepth
) throws JSONException {
return parse(x,arrayForm, ja,
keepStrings ? JSONMLParserConfiguration.KEEP_STRINGS : JSONMLParserConfiguration.ORIGINAL,
keepStrings ? JSONMLParserConfiguration.getKeepStringsConfiguration() : JSONMLParserConfiguration.getOriginalConfiguration(),
currentNestingDepth);
}

Expand Down Expand Up @@ -81,10 +81,10 @@ private static Object parse(
throw x.syntaxError("Bad XML");
}
token = x.nextContent();
if (token == XML.LT) {
if (token == XMLConstants.LT) {
token = x.nextToken();
if (token instanceof Character) {
if (token == XML.SLASH) {
if (token == XMLConstants.SLASH) {

// Close tag </

Expand All @@ -94,11 +94,11 @@ private static Object parse(
"Expected a closing name instead of '" +
token + "'.");
}
if (x.nextToken() != XML.GT) {
if (x.nextToken() != XMLConstants.GT) {
throw x.syntaxError("Misshaped close tag");
}
return token;
} else if (token == XML.BANG) {
} else if (token == XMLConstants.BANG) {

// <!

Expand All @@ -124,14 +124,14 @@ private static Object parse(
token = x.nextMeta();
if (token == null) {
throw x.syntaxError("Missing '>' after '<!'.");
} else if (token == XML.LT) {
} else if (token == XMLConstants.LT) {
i += 1;
} else if (token == XML.GT) {
} else if (token == XMLConstants.GT) {
i -= 1;
}
} while (i > 0);
}
} else if (token == XML.QUEST) {
} else if (token == XMLConstants.QUEST) {

// <?

Expand Down Expand Up @@ -179,7 +179,7 @@ private static Object parse(
throw x.syntaxError("Reserved attribute.");
}
token = x.nextToken();
if (token == XML.EQ) {
if (token == XMLConstants.EQ) {
token = x.nextToken();
if (!(token instanceof String)) {
throw x.syntaxError("Missing value");
Expand All @@ -196,8 +196,8 @@ private static Object parse(

// Empty tag <.../>

if (token == XML.SLASH) {
if (x.nextToken() != XML.GT) {
if (token == XMLConstants.SLASH) {
if (x.nextToken() != XMLConstants.GT) {
throw x.syntaxError("Misshaped tag");
}
if (ja == null) {
Expand All @@ -210,7 +210,7 @@ private static Object parse(
// Content, between <...> and </...>

} else {
if (token != XML.GT) {
if (token != XMLConstants.GT) {
throw x.syntaxError("Misshaped tag");
}

Expand Down Expand Up @@ -261,7 +261,7 @@ private static Object parse(
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0);
return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.getOriginalConfiguration(), 0);
}


Expand Down
Loading
Loading