X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosJson.java;h=ce50b872f13c6c4bc9b68ccd9dcff4b352396171;hp=22f81d037c06ef43907fb633e8fa3a5c5bf46877;hb=da914cd72411af8c36af05b13c11b9093c8a378c;hpb=1085ec5d57e0ed5d132f2bbdac1a0b6a32c0ab4a diff --git a/altoslib/AltosJson.java b/altoslib/AltosJson.java index 22f81d03..ce50b872 100644 --- a/altoslib/AltosJson.java +++ b/altoslib/AltosJson.java @@ -25,39 +25,39 @@ import java.lang.*; import java.lang.reflect.*; class JsonUtil { - StringBuffer quote(StringBuffer result, String a) { - result.append("\""); + Writer quote(Writer writer, String a) throws IOException { + writer.append("\""); for (int i = 0; i < a.length(); i++) { char c = a.charAt(i); switch (c) { case '"': case '\\': - result.append('\\').append(c); + writer.append('\\').append(c); break; case '\n': - result.append("\\n"); + writer.append("\\n"); break; default: - result.append(c); + writer.append(c); break; } } - result.append("\""); - return result; + writer.append("\""); + return writer; } - StringBuffer append(StringBuffer result, AltosJson value, int indent, boolean pretty) { + Writer append(Writer result, AltosJson value, int indent, boolean pretty) throws IOException { value.append(result, indent, pretty); return result; } - StringBuffer append(StringBuffer result, String string) { + Writer append(Writer result, String string) throws IOException { result.append(string); return result; } - StringBuffer indent(StringBuffer result, int indent) { + Writer indent(Writer result, int indent) throws IOException { result.append("\n"); for (int i = 0; i < indent; i++) result.append("\t"); @@ -80,7 +80,7 @@ class JsonUtil { class JsonHash extends JsonUtil { Hashtable hash; - void append_hash(StringBuffer result, int indent, boolean pretty) { + void append_hash(Writer result, int indent, boolean pretty) throws IOException { boolean first = true; result.append("{"); @@ -125,7 +125,7 @@ class JsonHash extends JsonUtil { class JsonArray extends JsonUtil { ArrayList array; - void append_array(StringBuffer result, int indent, boolean pretty) { + void append_array(Writer result, int indent, boolean pretty) throws IOException { boolean first = true; append(result, "["); @@ -185,6 +185,7 @@ class JsonToken { static final int _colon = 9; static final int _end = 10; static final int _error = 11; + static final int _none = 12; static String token_name(int token) { switch (token) { @@ -245,7 +246,7 @@ class JsonToken { this.sval = sval; } - JsonToken(int token, StringBuffer bval) { + JsonToken(int token, Writer bval) { this(token, bval.toString()); } } @@ -254,11 +255,11 @@ class JsonToken { * Lexer for json */ class JsonLexer extends JsonUtil { - StringReader f; - int line; - int ungot = -2; - StringBuffer pending_token; - JsonToken token; + InputStream f; + int line; + int ungot = -2; + StringBuffer pending_token; + private JsonToken token; static class keyword { String word; @@ -382,7 +383,7 @@ class JsonLexer extends JsonUtil { return new JsonToken(JsonToken._long, lval); } case '"': - StringBuffer bval = new StringBuffer(); + Writer bval = new StringWriter(); for (;;) { c = ch(); if (c == '"') @@ -400,7 +401,7 @@ class JsonLexer extends JsonUtil { break; } } - bval.appendCodePoint(c); + bval.write(c); } return new JsonToken(JsonToken._string, bval); default: @@ -424,11 +425,17 @@ class JsonLexer extends JsonUtil { } void next() { - token = lex(); + token = null; + } + + JsonToken token() { + if (token == null) + token = lex(); + return token; } JsonToken expect(int e) { - JsonToken t = token; + JsonToken t = token(); if (t.token != e) throw new IllegalArgumentException(String.format("got \"%s\" while expecting \"%s\"", token.token_name(), @@ -438,7 +445,13 @@ class JsonLexer extends JsonUtil { } JsonLexer(String s) { - f = new StringReader(s); + f = new AltosStringInputStream(s); + line = 1; + token = null; + } + + JsonLexer(InputStream f) { + this.f = f; line = 1; token = null; } @@ -464,7 +477,7 @@ class JsonParse { lexer.next(); for (;;) { /* Allow for empty hashes */ - if (lexer.token.token == JsonToken._cc) { + if (lexer.token().token == JsonToken._cc) { lexer.next(); return hash; } @@ -475,7 +488,7 @@ class JsonParse { AltosJson value = value(); hash.put(key, value); - switch (lexer.token.token) { + switch (lexer.token().token) { case JsonToken._comma: lexer.next(); break; @@ -483,7 +496,7 @@ class JsonParse { lexer.next(); return hash; default: - parse_error("got %s expect \",\" or \"}\"", lexer.token.token_name()); + parse_error("got %s expect \",\" or \"}\"", lexer.token().token_name()); return null; } } @@ -496,14 +509,14 @@ class JsonParse { lexer.next(); for (int i = 0;; i++) { /* Allow for empty arrays */ - if (lexer.token.token == JsonToken._cs) { + if (lexer.token().token == JsonToken._cs) { lexer.next(); return array; } AltosJson value = value(); array.put(i, value); - switch (lexer.token.token) { + switch (lexer.token().token) { case JsonToken._comma: lexer.next(); break; @@ -511,7 +524,7 @@ class JsonParse { lexer.next(); return array; default: - parse_error("got %s expect \",\" or \"]\"", lexer.token.token_name()); + parse_error("got %s expect \",\" or \"]\"", lexer.token().token_name()); return null; } } @@ -521,29 +534,29 @@ class JsonParse { * identify the next object in the input */ AltosJson value() { - switch (lexer.token.token) { + switch (lexer.token().token) { case JsonToken._oc: return new AltosJson(hash()); case JsonToken._os: return new AltosJson(array()); case JsonToken._double: - double dval = lexer.token.dval; + double dval = lexer.token().dval; lexer.next(); return new AltosJson(dval); case JsonToken._long: - long lval = lexer.token.lval; + long lval = lexer.token().lval; lexer.next(); return new AltosJson(lval); case JsonToken._string: - String sval = lexer.token.sval; + String sval = lexer.token().sval; lexer.next(); return new AltosJson(sval); case JsonToken._boolean: - boolean bval = lexer.token.bval; + boolean bval = lexer.token().bval; lexer.next(); return new AltosJson(bval); default: - parse_error("Unexpected token \"%s\"", lexer.token.token_name()); + parse_error("Unexpected token \"%s\"", lexer.token().token_name()); } return null; } @@ -556,6 +569,10 @@ class JsonParse { JsonParse(String s) { lexer = new JsonLexer(s); } + + JsonParse(InputStream f) { + lexer = new JsonLexer(f); + } } public class AltosJson extends JsonUtil { @@ -578,7 +595,7 @@ public class AltosJson extends JsonUtil { /* Generate string representation of the value */ - StringBuffer append(StringBuffer result, int indent, boolean pretty) { + Writer append(Writer result, int indent, boolean pretty) throws IOException { switch (type) { case type_hash: hash.append_hash(result, indent, pretty); @@ -615,9 +632,13 @@ public class AltosJson extends JsonUtil { } private String toString(int indent, boolean pretty) { - StringBuffer result = new StringBuffer(); - append(result, indent, pretty); - return result.toString(); + try { + Writer result = new StringWriter(); + append(result, indent, pretty); + return result.toString(); + } catch (Exception e) { + return null; + } } public String toString() { @@ -628,6 +649,14 @@ public class AltosJson extends JsonUtil { return toString(0, true); } + public void write(Writer w, int indent, boolean pretty) throws IOException { + append(w, indent, pretty); + } + + public void write(Writer w) throws IOException { + write(w, 0, true); + } + /* Parse string representation to a value */ @@ -641,6 +670,16 @@ public class AltosJson extends JsonUtil { } } + public static AltosJson fromInputStream(InputStream f) { + JsonParse parse = new JsonParse(f); + try { + return parse.parse(); + } catch (IllegalArgumentException ie) { + System.out.printf("json:\n%s\n", ie.getMessage()); + return null; + } + } + /* Accessor functions */ private boolean assert_type(boolean setting, int type, int other_type, String error) { @@ -1213,6 +1252,10 @@ public class AltosJson extends JsonUtil { for (Field field : c.getDeclaredFields()) { String fieldName = field.getName(); + /* XXX hack to allow fields to be not converted */ + if (fieldName.startsWith("__")) + continue; + /* Skip static fields */ if (Modifier.isStatic(field.getModifiers())) continue;