S19: establish engineering repository

This commit is contained in:
2026-11-08 15:15:50 +01:00
commit c25ce11a1b
84 changed files with 6599 additions and 0 deletions

154
resources/ci/Json.java Normal file
View File

@@ -0,0 +1,154 @@
import java.math.BigDecimal;
import java.util.*;
/** Small dependency-free JSON codec for API/configuration objects, not application data. */
final class Json {
static Object parse(String source) {
Parser parser = new Parser(source);
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);
}
}
}
return out.append('"').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();
}
if (value instanceof List<?> list) {
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;
}
Object value() {
space();
if (pos >= source.length()) throw invalid();
char c = source.charAt(pos);
if (c == '"') return string();
if (take('{')) {
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();
out.put(key, value());
} while (take(','));
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;
}
for (String token : List.of("true", "false", "null")) {
if (source.startsWith(token, pos)) {
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);
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();
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 (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 'u' -> {
if (pos + 4 > source.length()) throw invalid();
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;
}
default -> throw invalid();
}
}
throw invalid();
}
}
}