mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-03 15:44:27 +02:00
225 lines
7.4 KiB
Java
225 lines
7.4 KiB
Java
/*
|
|
* Copyright (c) 2002 JSON.org (now "Public Domain")
|
|
* This is NOT property of REAndroid
|
|
* This package is renamed from org.json.* to avoid class conflict when used on anroid platforms
|
|
*/
|
|
package com.reandroid.json;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Collection;
|
|
import java.util.Map;
|
|
|
|
public class JSONWriter {
|
|
private static final int maxdepth = 200;
|
|
|
|
private boolean comma;
|
|
|
|
protected char mode;
|
|
|
|
private final JSONObject stack[];
|
|
|
|
private int top;
|
|
|
|
protected Appendable writer;
|
|
|
|
public JSONWriter(Appendable w) {
|
|
this.comma = false;
|
|
this.mode = 'i';
|
|
this.stack = new JSONObject[maxdepth];
|
|
this.top = 0;
|
|
this.writer = w;
|
|
}
|
|
|
|
private JSONWriter append(String string) throws JSONException {
|
|
if (string == null) {
|
|
throw new JSONException("Null pointer");
|
|
}
|
|
if (this.mode == 'o' || this.mode == 'a') {
|
|
try {
|
|
if (this.comma && this.mode == 'a') {
|
|
this.writer.append(',');
|
|
}
|
|
this.writer.append(string);
|
|
} catch (IOException e) {
|
|
// Android as of API 25 does not support this exception constructor
|
|
// however we won't worry about it. If an exception is happening here
|
|
// it will just throw a "Method not found" exception instead.
|
|
throw new JSONException(e);
|
|
}
|
|
if (this.mode == 'o') {
|
|
this.mode = 'k';
|
|
}
|
|
this.comma = true;
|
|
return this;
|
|
}
|
|
throw new JSONException("Value out of sequence.");
|
|
}
|
|
|
|
public JSONWriter array() throws JSONException {
|
|
if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
|
|
this.push(null);
|
|
this.append("[");
|
|
this.comma = false;
|
|
return this;
|
|
}
|
|
throw new JSONException("Misplaced array.");
|
|
}
|
|
|
|
private JSONWriter end(char m, char c) throws JSONException {
|
|
if (this.mode != m) {
|
|
throw new JSONException(m == 'a'
|
|
? "Misplaced endArray."
|
|
: "Misplaced endObject.");
|
|
}
|
|
this.pop(m);
|
|
try {
|
|
this.writer.append(c);
|
|
} catch (IOException e) {
|
|
// Android as of API 25 does not support this exception constructor
|
|
// however we won't worry about it. If an exception is happening here
|
|
// it will just throw a "Method not found" exception instead.
|
|
throw new JSONException(e);
|
|
}
|
|
this.comma = true;
|
|
return this;
|
|
}
|
|
|
|
public JSONWriter endArray() throws JSONException {
|
|
return this.end('a', ']');
|
|
}
|
|
|
|
public JSONWriter endObject() throws JSONException {
|
|
return this.end('k', '}');
|
|
}
|
|
|
|
public JSONWriter key(String string) throws JSONException {
|
|
if (string == null) {
|
|
throw new JSONException("Null key.");
|
|
}
|
|
if (this.mode == 'k') {
|
|
try {
|
|
JSONObject topObject = this.stack[this.top - 1];
|
|
// don't use the built in putOnce method to maintain Android support
|
|
if(topObject.has(string)) {
|
|
throw new JSONException("Duplicate key \"" + string + "\"");
|
|
}
|
|
topObject.put(string, true);
|
|
if (this.comma) {
|
|
this.writer.append(',');
|
|
}
|
|
this.writer.append(JSONObject.quote(string));
|
|
this.writer.append(':');
|
|
this.comma = false;
|
|
this.mode = 'o';
|
|
return this;
|
|
} catch (IOException e) {
|
|
// Android as of API 25 does not support this exception constructor
|
|
// however we won't worry about it. If an exception is happening here
|
|
// it will just throw a "Method not found" exception instead.
|
|
throw new JSONException(e);
|
|
}
|
|
}
|
|
throw new JSONException("Misplaced key.");
|
|
}
|
|
public JSONWriter object() throws JSONException {
|
|
if (this.mode == 'i') {
|
|
this.mode = 'o';
|
|
}
|
|
if (this.mode == 'o' || this.mode == 'a') {
|
|
this.append("{");
|
|
this.push(new JSONObject());
|
|
this.comma = false;
|
|
return this;
|
|
}
|
|
throw new JSONException("Misplaced object.");
|
|
|
|
}
|
|
private void pop(char c) throws JSONException {
|
|
if (this.top <= 0) {
|
|
throw new JSONException("Nesting error.");
|
|
}
|
|
char m = this.stack[this.top - 1] == null ? 'a' : 'k';
|
|
if (m != c) {
|
|
throw new JSONException("Nesting error.");
|
|
}
|
|
this.top -= 1;
|
|
this.mode = this.top == 0
|
|
? 'd'
|
|
: this.stack[this.top - 1] == null
|
|
? 'a'
|
|
: 'k';
|
|
}
|
|
|
|
private void push(JSONObject jo) throws JSONException {
|
|
if (this.top >= maxdepth) {
|
|
throw new JSONException("Nesting too deep.");
|
|
}
|
|
this.stack[this.top] = jo;
|
|
this.mode = jo == null ? 'a' : 'k';
|
|
this.top += 1;
|
|
}
|
|
|
|
public static String valueToString(Object value) throws JSONException {
|
|
if (value == null || value.equals(null)) {
|
|
return "null";
|
|
}
|
|
if (value instanceof JSONString) {
|
|
String object;
|
|
try {
|
|
object = ((JSONString) value).toJSONString();
|
|
} catch (Exception e) {
|
|
throw new JSONException(e);
|
|
}
|
|
if (object != null) {
|
|
return object;
|
|
}
|
|
throw new JSONException("Bad value from toJSONString: " + object);
|
|
}
|
|
if (value instanceof Number) {
|
|
// not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
|
|
final String numberAsString = JSONObject.numberToString((Number) value);
|
|
if(JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) {
|
|
// Close enough to a JSON number that we will return it unquoted
|
|
return numberAsString;
|
|
}
|
|
// The Number value is not a valid JSON number.
|
|
// Instead we will quote it as a string
|
|
return JSONObject.quote(numberAsString);
|
|
}
|
|
if (value instanceof Boolean || value instanceof JSONObject
|
|
|| value instanceof JSONArray) {
|
|
return value.toString();
|
|
}
|
|
if (value instanceof Map) {
|
|
Map<?, ?> map = (Map<?, ?>) value;
|
|
return new JSONObject(map).toString();
|
|
}
|
|
if (value instanceof Collection) {
|
|
Collection<?> coll = (Collection<?>) value;
|
|
return new JSONArray(coll).toString();
|
|
}
|
|
if (value.getClass().isArray()) {
|
|
return new JSONArray(value).toString();
|
|
}
|
|
if(value instanceof Enum<?>){
|
|
return JSONObject.quote(((Enum<?>)value).name());
|
|
}
|
|
return JSONObject.quote(value.toString());
|
|
}
|
|
|
|
public JSONWriter value(boolean b) throws JSONException {
|
|
return this.append(b ? "true" : "false");
|
|
}
|
|
|
|
public JSONWriter value(double d) throws JSONException {
|
|
return this.value(Double.valueOf(d));
|
|
}
|
|
|
|
public JSONWriter value(long l) throws JSONException {
|
|
return this.append(Long.toString(l));
|
|
}
|
|
public JSONWriter value(Object object) throws JSONException {
|
|
return this.append(valueToString(object));
|
|
}
|
|
}
|