3 import java.util.HashMap;
4 import java.util.Hashtable;
7 import javajs.J2SIgnoreImport;
12 * a very simple JSON parser for JSON objects that are compatible with JavaScript
13 * A gross simplification of https://github.com/douglascrockford/JSON-java
15 * A SUBSET of JSON with similarly to window.JSON.parse():
17 * In JavaScript returns "null" for a null value, not null
19 * -- requires quoted strings for keys and values
21 * -- does not allow /xxx/ objects
26 @J2SIgnoreImport({ HashMap.class })
27 public class JSJSONParser {
32 private boolean asHashTable;
34 public JSJSONParser () {
39 * requires { "key":"value", "key":"value",....}
42 * @param asHashTable TODO
46 @SuppressWarnings("unchecked")
47 public Map<String, Object> parseMap(String str, boolean asHashTable) {
49 this.asHashTable = asHashTable;
55 return (Map<String, Object>) getValue(false);
59 * Could return Integer, Float, Boolean, String, Map<String, Object>, Lst<Object>, or null
62 * @return a object equivalent to the JSON string str
65 public Object parse(String str) {
69 return getValue(false);
73 return (index < len ? str.charAt(index++) : '\0');
76 private void returnChar() {
81 * Get the next char in the string, skipping whitespace.
83 * @throws JSONException
84 * @return one character, or 0 if there are no more characters.
86 private char getChar() throws JSONException {
89 if (c == 0 || c > ' ') {
96 * only allowing the following values:
109 * @param isKey if we should allow {...} and [...]
110 * @return a subclass of Object
111 * @throws JSONException
113 private Object getValue(boolean isKey) throws JSONException {
133 // standard syntax is assumed; not checking all possible invalid keys
134 // for example, "-" is not allowed in JavaScript, which is what this is for
136 while (c >= ' ' && "[,]{:}'\"".indexOf(c) < 0)
139 if (isKey && c != ':')
144 throw new JSONException("invalid key");
146 String string = str.substring(i, index);
148 // check for the only valid simple words: true, false, null (lower case)
149 // and in this case, only for
152 if (string.equals("true")) {
155 if (string.equals("false")) {
156 return Boolean.FALSE;
158 if (string.equals("null")) {
159 return (asHashTable ? string : null);
162 // only numbers from here on:
164 c = string.charAt(0);
165 if (c >= '0' && c <= '9' || c == '-')
167 if (string.indexOf('.') < 0 && string.indexOf('e') < 0
168 && string.indexOf('E') < 0)
169 return new Integer(string);
170 // not allowing infinity or NaN
171 // using float here because Jmol does not use Double
172 Float d = Float.valueOf(string);
173 if (!d.isInfinite() && !d.isNaN())
175 } catch (Exception e) {
177 // not a valid number
178 System.out.println("JSON parser cannot parse " + string);
179 throw new JSONException("invalid value");
182 private String getString(char quote) throws JSONException {
188 switch (c = next()) {
192 throw syntaxError("Unterminated string");
194 switch (c = next()) {
219 c = (char) Integer.parseInt(str.substring(i, index), 16);
220 } catch (Exception e) {
221 throw syntaxError("Substring bounds error");
225 throw syntaxError("Illegal escape.");
230 return (sb == null ? str.substring(i0, i1) : sb.toString());
233 if (index > i1 + 1) {
236 sb.append(str.substring(i0, i1));
244 private Object getObject() {
245 Map<String, Object> map = (asHashTable ? new Hashtable<String, Object>() : new HashMap<String, Object>());
251 throw new JSONException("invalid object");
254 boolean isKey = false;
256 if ((isKey = !isKey) == true)
257 key = getValue(true).toString();
259 map.put(key, getValue(false));
273 throw syntaxError("Expected ',' or ':' or '}'");
278 private Object getArray() {
279 Lst<Object> l = new Lst<Object>();
284 throw new JSONException("invalid array");
287 boolean isNull = false;
293 l.addLast(getValue(false));
312 throw syntaxError("Expected ',' or ']'");
318 * Make a JSONException to signal a syntax error.
322 * @return A JSONException object, suitable for throwing
324 public JSONException syntaxError(String message) {
325 return new JSONException(message + " for " + str.substring(0, Math.min(index, len)));