S8 apply Palantir formatting to maintained Java sources
All checks were successful
Build, test and publish / verify (push) Successful in 1m39s
All checks were successful
Build, test and publish / verify (push) Successful in 1m39s
This commit is contained in:
110
ci/Json.java
110
ci/Json.java
@@ -5,93 +5,145 @@ import java.util.*;
|
||||
final class Json {
|
||||
static Object parse(String source) {
|
||||
Parser parser = new Parser(source);
|
||||
Object result = parser.value(); parser.space();
|
||||
Object result = parser.value();
|
||||
parser.space();
|
||||
if (parser.pos != source.length()) throw parser.invalid();
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> object(Object value) {
|
||||
if (!(value instanceof Map<?, ?>)) throw new IllegalArgumentException("Expected a JSON object");
|
||||
return (Map<String, Object>) value;
|
||||
}
|
||||
|
||||
static String write(Object value) {
|
||||
if (value == null) return "null";
|
||||
if (value instanceof String text) {
|
||||
StringBuilder out = new StringBuilder("\"");
|
||||
for (char c : text.toCharArray()) {
|
||||
switch (c) {
|
||||
case '"' -> out.append("\\\""); case '\\' -> out.append("\\\\");
|
||||
case '\n' -> out.append("\\n"); case '\r' -> out.append("\\r"); case '\t' -> out.append("\\t");
|
||||
default -> { if (c < 32) out.append(String.format("\\u%04x", (int)c)); else out.append(c); }
|
||||
case '"' -> out.append("\\\"");
|
||||
case '\\' -> out.append("\\\\");
|
||||
case '\n' -> out.append("\\n");
|
||||
case '\r' -> out.append("\\r");
|
||||
case '\t' -> out.append("\\t");
|
||||
default -> {
|
||||
if (c < 32) out.append(String.format("\\u%04x", (int) c));
|
||||
else out.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out.append('"').toString();
|
||||
}
|
||||
if (value instanceof Boolean || value instanceof BigDecimal || value instanceof Integer || value instanceof Long)
|
||||
return value.toString();
|
||||
if (value instanceof Boolean
|
||||
|| value instanceof BigDecimal
|
||||
|| value instanceof Integer
|
||||
|| value instanceof Long) return value.toString();
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
StringJoiner out = new StringJoiner(",", "{", "}");
|
||||
map.forEach((k,v) -> out.add(write(Objects.toString(k)) + ":" + write(v))); return out.toString();
|
||||
map.forEach((k, v) -> out.add(write(Objects.toString(k)) + ":" + write(v)));
|
||||
return out.toString();
|
||||
}
|
||||
if (value instanceof List<?> list) {
|
||||
StringJoiner out = new StringJoiner(",", "[", "]"); list.forEach(v -> out.add(write(v))); return out.toString();
|
||||
StringJoiner out = new StringJoiner(",", "[", "]");
|
||||
list.forEach(v -> out.add(write(v)));
|
||||
return out.toString();
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported JSON value");
|
||||
}
|
||||
|
||||
private static final class Parser {
|
||||
final String source; int pos;
|
||||
Parser(String source) { this.source = source; }
|
||||
IllegalArgumentException invalid() { return new IllegalArgumentException("Invalid JSON at offset " + pos); }
|
||||
void space() { while (pos < source.length() && " \r\n\t".indexOf(source.charAt(pos)) >= 0) pos++; }
|
||||
boolean take(char c) { space(); if (pos < source.length() && source.charAt(pos) == c) { pos++; return true; } return false; }
|
||||
final String source;
|
||||
int pos;
|
||||
|
||||
Parser(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
IllegalArgumentException invalid() {
|
||||
return new IllegalArgumentException("Invalid JSON at offset " + pos);
|
||||
}
|
||||
|
||||
void space() {
|
||||
while (pos < source.length() && " \r\n\t".indexOf(source.charAt(pos)) >= 0) pos++;
|
||||
}
|
||||
|
||||
boolean take(char c) {
|
||||
space();
|
||||
if (pos < source.length() && source.charAt(pos) == c) {
|
||||
pos++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Object value() {
|
||||
space(); if (pos >= source.length()) throw invalid();
|
||||
space();
|
||||
if (pos >= source.length()) throw invalid();
|
||||
char c = source.charAt(pos);
|
||||
if (c == '"') return string();
|
||||
if (take('{')) {
|
||||
Map<String,Object> out = new LinkedHashMap<>();
|
||||
Map<String, Object> out = new LinkedHashMap<>();
|
||||
if (take('}')) return out;
|
||||
do {
|
||||
space(); if (pos >= source.length() || source.charAt(pos) != '"') throw invalid();
|
||||
String key = string(); if (!take(':') || out.containsKey(key)) throw invalid();
|
||||
space();
|
||||
if (pos >= source.length() || source.charAt(pos) != '"') throw invalid();
|
||||
String key = string();
|
||||
if (!take(':') || out.containsKey(key)) throw invalid();
|
||||
out.put(key, value());
|
||||
} while (take(','));
|
||||
if (!take('}')) throw invalid(); return out;
|
||||
if (!take('}')) throw invalid();
|
||||
return out;
|
||||
}
|
||||
if (take('[')) {
|
||||
List<Object> out = new ArrayList<>(); if (take(']')) return out;
|
||||
do { out.add(value()); } while (take(','));
|
||||
if (!take(']')) throw invalid(); return out;
|
||||
List<Object> out = new ArrayList<>();
|
||||
if (take(']')) return out;
|
||||
do {
|
||||
out.add(value());
|
||||
} while (take(','));
|
||||
if (!take(']')) throw invalid();
|
||||
return out;
|
||||
}
|
||||
for (String token : List.of("true", "false", "null")) {
|
||||
if (source.startsWith(token, pos)) {
|
||||
pos += token.length(); return token.equals("null") ? null : Boolean.valueOf(token);
|
||||
pos += token.length();
|
||||
return token.equals("null") ? null : Boolean.valueOf(token);
|
||||
}
|
||||
}
|
||||
int start = pos;
|
||||
while (pos < source.length() && "-+0123456789.eE".indexOf(source.charAt(pos)) >= 0) pos++;
|
||||
String number = source.substring(start,pos);
|
||||
String number = source.substring(start, pos);
|
||||
if (!number.matches("-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?")) throw invalid();
|
||||
return new BigDecimal(number);
|
||||
}
|
||||
|
||||
String string() {
|
||||
pos++; StringBuilder out = new StringBuilder();
|
||||
pos++;
|
||||
StringBuilder out = new StringBuilder();
|
||||
while (pos < source.length()) {
|
||||
char c = source.charAt(pos++);
|
||||
if (c == '"') return out.toString();
|
||||
if (c < 32) throw invalid();
|
||||
if (c != '\\') { out.append(c); continue; }
|
||||
if (c != '\\') {
|
||||
out.append(c);
|
||||
continue;
|
||||
}
|
||||
if (pos >= source.length()) throw invalid();
|
||||
char escaped = source.charAt(pos++);
|
||||
switch (escaped) {
|
||||
case '"', '\\', '/' -> out.append(escaped);
|
||||
case 'b' -> out.append('\b'); case 'f' -> out.append('\f');
|
||||
case 'n' -> out.append('\n'); case 'r' -> out.append('\r'); case 't' -> out.append('\t');
|
||||
case 'b' -> out.append('\b');
|
||||
case 'f' -> out.append('\f');
|
||||
case 'n' -> out.append('\n');
|
||||
case 'r' -> out.append('\r');
|
||||
case 't' -> out.append('\t');
|
||||
case 'u' -> {
|
||||
if (pos + 4 > source.length()) throw invalid();
|
||||
String digits = source.substring(pos,pos+4);
|
||||
String digits = source.substring(pos, pos + 4);
|
||||
if (!digits.matches("[0-9a-fA-F]{4}")) throw invalid();
|
||||
out.append((char) Integer.parseInt(digits,16)); pos += 4;
|
||||
out.append((char) Integer.parseInt(digits, 16));
|
||||
pos += 4;
|
||||
}
|
||||
default -> throw invalid();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user