/** * Construct a JSONArray from a JSONTokener. * * @param x A JSONTokener * @throws JSONException If there is a syntax error. */ public JSONArray(JSONTokener x) throws JSONException { this(); if (x.nextClean() != '[') { throw x.syntaxError("A JSONArray text must start with '['"); } if (x.nextClean() != ']') { x.back(); for (; ; ) { if (x.nextClean() == ',') { x.back(); this.myArrayList.add(JSONObject.NULL); } else { x.back(); this.myArrayList.add(x.nextValue()); } switch (x.nextClean()) { case ',': if (x.nextClean() == ']') { return; } x.back(); break; case ']': return; default: throw x.syntaxError("Expected a ',' or ']'"); } } } }
/** * Construct a JSONObject from a JSONTokener. * * @param x A JSONTokener object containing the source string. * @throws JSONException If there is a syntax error in the source string or a duplicated key. */ public JSONObject(JSONTokener x) throws JSONException { this(); char c; String key; if (x.nextClean() != '{') { throw x.syntaxError("A JSONObject text must begin with '{'"); } for (; ; ) { c = x.nextClean(); switch (c) { case 0: throw x.syntaxError("A JSONObject text must end with '}'"); case '}': return; default: x.back(); key = x.nextValue().toString(); } /* * The key is followed by ':'. We will also tolerate '=' or '=>'. */ c = x.nextClean(); if (c == '=') { if (x.next() != '>') { x.back(); } } else if (c != ':') { throw x.syntaxError("Expected a ':' after a key"); } putOnce(key, x.nextValue()); /* * Pairs are separated by ','. We will also tolerate ';'. */ switch (x.nextClean()) { case ';': case ',': if (x.nextClean() == '}') { return; } x.back(); break; case '}': return; default: throw x.syntaxError("Expected a ',' or '}'"); } } }
/** * Convert a cookie specification string into a JSONObject. The string will contain a name value * pair separated by '='. The name and the value will be unescaped, possibly converting '+' and * '%' sequences. The cookie properties may follow, separated by ';', also represented as * name=value (except the secure property, which does not have a value). The name will be stored * under the key "name", and the value will be stored under the key "value". This method does not * do checking or validation of the parameters. It only converts the cookie string into a * JSONObject. * * @param string The cookie specification string. * @return A JSONObject containing "name", "value", and possibly other members. * @throws JSONException */ public static JSONObject toJSONObject(String string) throws JSONException { String name; JSONObject jo = new JSONObject(); Object value; JSONTokener x = new JSONTokener(string); jo.put("name", x.nextTo('=')); x.next('='); jo.put("value", x.nextTo(';')); x.next(); while (x.more()) { name = unescape(x.nextTo("=;")); if (x.next() != '=') { if (name.equals("secure")) { value = Boolean.TRUE; } else { throw x.syntaxError("Missing '=' in cookie parameter."); } } else { value = unescape(x.nextTo(';')); x.next(); } jo.put(name, value); } return jo; }
/** * Produce a JSONArray of strings from a row of comma delimited values. * @param x A JSONTokener of the source text. * @return A JSONArray of strings. * @throws JSONException */ public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { JSONArray ja = new JSONArray(); for (;;) { String value = getValue(x); char c = x.next(); if (value == null || (ja.length() == 0 && value.length() == 0 && c != ',')) { return null; } ja.put(value); for (;;) { if (c == ',') { break; } if (c != ' ') { if (c == '\n' || c == '\r' || c == 0) { return ja; } throw x.syntaxError("Bad character '" + c + "' (" + (int)c + ")."); } c = x.next(); } } }
/** * Get the next value. The value can be wrapped in quotes. The value can * be empty. * @param x A JSONTokener of the source text. * @return The value string, or null if empty. * @throws JSONException if the quoted string is badly formed. */ private static String getValue(JSONTokener x) throws JSONException { char c; char q; StringBuffer sb; do { c = x.next(); } while (c == ' ' || c == '\t'); switch (c) { case 0: return null; case '"': case '\'': q = c; sb = new StringBuffer(); for (;;) { c = x.next(); if (c == q) { break; } if (c == 0 || c == '\n' || c == '\r') { throw x.syntaxError("Missing close quote '" + q + "'."); } sb.append(c); } return sb.toString(); case ',': x.back(); return ""; default: x.back(); return x.nextTo(','); } }
/** * Construct a JSONArray from a JSONTokener. * * @param x A JSONTokener * @throws JSONException If there is a syntax error. */ @SuppressWarnings("unchecked") public JSONArray(JSONTokener x) throws JSONException { this(); char c = x.nextClean(); char q; if (c == '[') { q = ']'; } else if (c == '(') { q = ')'; } else { throw x.syntaxError("A JSONArray text must start with '['"); } if (x.nextClean() == ']') { return; } x.back(); for (; ; ) { if (x.nextClean() == ',') { x.back(); this.myArrayList.add(null); } else { x.back(); this.myArrayList.add(x.nextValue()); } c = x.nextClean(); switch (c) { case ';': case ',': if (x.nextClean() == ']') { return; } x.back(); break; case ']': case ')': if (q != c) { throw x.syntaxError("Expected a '" + new Character(q) + "'"); } return; default: throw x.syntaxError("Expected a ',' or ']'"); } } }
private void parse(JSONTokener tokenizer) { if (tokenizer.nextClean() != '[') { throw tokenizer.syntaxError("A JSONArray text must start with '['"); } if (tokenizer.nextClean() == ']') { return; } tokenizer.back(); while (true) { if (tokenizer.nextClean() == ',') { tokenizer.back(); list.add(JSONObject.NULL); } else { tokenizer.back(); list.add(tokenizer.nextValue()); } switch (tokenizer.nextClean()) { case ';': case ',': if (tokenizer.nextClean() == ']') { return; } tokenizer.back(); break; case ']': return; default: throw tokenizer.syntaxError("Expected a ',' or ']'"); } } }
private JSONObject(JSONTokener x) throws JSONException { this.map = new HashMap<String, Object>(); char c; String key; if (x.nextClean() != '{') { throw x.syntaxError("A JSONObject text must begin with '{'"); } for (; ; ) { c = x.nextClean(); switch (c) { case 0: throw x.syntaxError("A JSONObject text must end with '}'"); case '}': return; default: x.back(); key = x.nextValue().toString(); } // The key is followed by ':'. We will also tolerate '=' or '=>'. c = x.nextClean(); if (c == '=') { if (x.next() != '>') { x.back(); } } else if (c != ':') { throw x.syntaxError("Expected a ':' after a key"); } if (key == null) throw new JSONException("Null key."); Object value = x.nextValue(); if (value != null) { if (this.has(key)) { throw new JSONException("Duplicate key \"" + key + "\""); } if (value instanceof Double) { if (((Double) value).isInfinite() || ((Double) value).isNaN()) { throw new JSONException("JSON does not allow non-finite numbers."); } } else if (value instanceof Float) { if (((Float) value).isInfinite() || ((Float) value).isNaN()) { throw new JSONException("JSON does not allow non-finite numbers."); } } this.map.put(key, value); } // Pairs are separated by ','. We will also tolerate ';'. switch (x.nextClean()) { case ';': case ',': if (x.nextClean() == '}') { return; } x.back(); break; case '}': return; default: throw x.syntaxError("Expected a ',' or '}'"); } } }