17c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetpackage com.google.polo.json;
27c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
37c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.BufferedReader;
47c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.IOException;
57c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.Reader;
67c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.StringReader;
77c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
87c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet/*
97c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetCopyright (c) 2002 JSON.org
107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
117c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetPermission is hereby granted, free of charge, to any person obtaining a copy
127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetof this software and associated documentation files (the "Software"), to deal
137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetin the Software without restriction, including without limitation the rights
147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetcopies of the Software, and to permit persons to whom the Software is
167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetfurnished to do so, subject to the following conditions:
177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
187c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetThe above copyright notice and this permission notice shall be included in all
197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetcopies or substantial portions of the Software.
207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
217c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetThe Software shall be used for Good, not Evil.
227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
237c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
247c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
257c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
267c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
277c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
287c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
297c9978567a202d6aa98beac5da5e1b3b34792862Jerome PoichetSOFTWARE.
307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet*/
317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet/**
337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * A JSONTokener takes a source string and extracts characters and tokens from
347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * it. It is used by the JSONObject and JSONArray constructors to parse
357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * JSON source strings.
367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @author JSON.org
377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @version 2008-09-18
387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */
397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetpublic class JSONTokener {
407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    private int index;
427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    private Reader reader;
437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    private char lastChar;
447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    private boolean useLastChar;
457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Construct a JSONTokener from a string.
497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param reader     A reader.
517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public JSONTokener(Reader reader) {
537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        this.reader = reader.markSupported() ?
547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        		reader : new BufferedReader(reader);
557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        this.useLastChar = false;
567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        this.index = 0;
577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Construct a JSONTokener from a string.
627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param s     A source string.
647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public JSONTokener(String s) {
667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        this(new StringReader(s));
677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Back up one character. This provides a sort of lookahead capability,
727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * so that you can test for a digit or letter before attempting to parse
737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * the next number or identifier.
747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public void back() throws JSONException {
767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (useLastChar || index <= 0) {
777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            throw new JSONException("Stepping back two steps is not supported");
787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        index -= 1;
807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        useLastChar = true;
817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the hex value of a character (base16).
877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param c A character between '0' and '9' or between 'A' and 'F' or
887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * between 'a' and 'f'.
897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return  An int between 0 and 15, or -1 if c was not a hex digit.
907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public static int dehexchar(char c) {
927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (c >= '0' && c <= '9') {
937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return c - '0';
947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (c >= 'A' && c <= 'F') {
967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return c - ('A' - 10);
977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (c >= 'a' && c <= 'f') {
997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return c - ('a' - 10);
1007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return -1;
1027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
1037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
1067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Determine if the source string still contains characters that next()
1077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * can consume.
1087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return true if not yet at the end of the source.
1097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
1107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public boolean more() throws JSONException {
1117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char nextChar = next();
1127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (nextChar == 0) {
1137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return false;
1147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        back();
1167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return true;
1177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
1187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
1217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the next character in the source string.
1227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
1237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return The next character, or 0 if past the end of the source string.
1247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
1257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public char next() throws JSONException {
1267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (this.useLastChar) {
1277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        	this.useLastChar = false;
1287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            if (this.lastChar != 0) {
1297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            	this.index += 1;
1307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            }
1317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return this.lastChar;
1327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        int c;
1347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        try {
1357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            c = this.reader.read();
1367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        } catch (IOException exc) {
1377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            throw new JSONException(exc);
1387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (c <= 0) { // End of stream
1417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        	this.lastChar = 0;
1427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            return 0;
1437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    	this.index += 1;
1457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    	this.lastChar = (char) c;
1467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return this.lastChar;
1477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
1487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
1517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Consume the next character, and check that it matches a specified
1527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * character.
1537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param c The character to match.
1547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return The character.
1557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @throws JSONException if the character does not match.
1567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
1577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public char next(char c) throws JSONException {
1587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char n = next();
1597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (n != c) {
1607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            throw syntaxError("Expected '" + c + "' and instead saw '" +
1617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    n + "'");
1627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
1637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return n;
1647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
1657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
1687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the next n characters.
1697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
1707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param n     The number of characters to take.
1717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return      A string of n characters.
1727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @throws JSONException
1737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *   Substring bounds error if there are not
1747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *   n characters remaining in the source string.
1757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
1767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     public String next(int n) throws JSONException {
1777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         if (n == 0) {
1787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             return "";
1797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         }
1807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         char[] buffer = new char[n];
1827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         int pos = 0;
1837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         if (this.useLastChar) {
1857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        	 this.useLastChar = false;
1867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             buffer[0] = this.lastChar;
1877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             pos = 1;
1887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         }
1897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
1907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         try {
1917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             int len;
1927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             while ((pos < n) && ((len = reader.read(buffer, pos, n - pos)) != -1)) {
1937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                 pos += len;
1947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             }
1957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         } catch (IOException exc) {
1967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             throw new JSONException(exc);
1977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         }
1987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         this.index += pos;
1997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         if (pos < n) {
2017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet             throw syntaxError("Substring bounds error");
2027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         }
2037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         this.lastChar = buffer[n - 1];
2057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         return new String(buffer);
2067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     }
2077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
2107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the next char in the string, skipping whitespace.
2117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @throws JSONException
2127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return  A character, or 0 if there are no more characters.
2137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
2147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public char nextClean() throws JSONException {
2157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        for (;;) {
2167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            char c = next();
2177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            if (c == 0 || c > ' ') {
2187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return c;
2197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            }
2207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
2217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
2227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
2257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Return the characters up to the next close quote character.
2267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Backslash processing is done. The formal JSON format does not
2277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * allow strings in single quotes, but an implementation is allowed to
2287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * accept them.
2297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param quote The quoting character, either
2307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *      <code>"</code>&nbsp;<small>(double quote)</small> or
2317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *      <code>'</code>&nbsp;<small>(single quote)</small>.
2327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return      A String.
2337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @throws JSONException Unterminated string.
2347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
2357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public String nextString(char quote) throws JSONException {
2367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char c;
2377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        StringBuffer sb = new StringBuffer();
2387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        for (;;) {
2397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            c = next();
2407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            switch (c) {
2417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case 0:
2427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '\n':
2437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '\r':
2447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                throw syntaxError("Unterminated string");
2457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '\\':
2467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                c = next();
2477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                switch (c) {
2487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'b':
2497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append('\b');
2507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 't':
2527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append('\t');
2537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'n':
2557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append('\n');
2567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'f':
2587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append('\f');
2597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'r':
2617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append('\r');
2627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'u':
2647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append((char)Integer.parseInt(next(4), 16));
2657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                case 'x' :
2677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append((char) Integer.parseInt(next(2), 16));
2687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    break;
2697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                default:
2707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    sb.append(c);
2717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                }
2727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                break;
2737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            default:
2747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                if (c == quote) {
2757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    return sb.toString();
2767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                }
2777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                sb.append(c);
2787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            }
2797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
2807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
2817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
2837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
2847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the text up but not including the specified character or the
2857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * end of line, whichever comes first.
2867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param  d A delimiter character.
2877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return   A string.
2887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
2897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public String nextTo(char d) throws JSONException {
2907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        StringBuffer sb = new StringBuffer();
2917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        for (;;) {
2927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            char c = next();
2937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            if (c == d || c == 0 || c == '\n' || c == '\r') {
2947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                if (c != 0) {
2957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    back();
2967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                }
2977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return sb.toString().trim();
2987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            }
2997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            sb.append(c);
3007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
3027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
3057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the text up but not including one of the specified delimiter
3067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * characters or the end of line, whichever comes first.
3077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param delimiters A set of delimiter characters.
3087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return A string, trimmed.
3097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
3107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public String nextTo(String delimiters) throws JSONException {
3117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char c;
3127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        StringBuffer sb = new StringBuffer();
3137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        for (;;) {
3147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            c = next();
3157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            if (delimiters.indexOf(c) >= 0 || c == 0 ||
3167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    c == '\n' || c == '\r') {
3177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                if (c != 0) {
3187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    back();
3197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                }
3207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return sb.toString().trim();
3217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            }
3227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            sb.append(c);
3237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
3257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
3287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Get the next value. The value can be a Boolean, Double, Integer,
3297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
3307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @throws JSONException If syntax error.
3317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
3327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return An object.
3337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
3347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public Object nextValue() throws JSONException {
3357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char c = nextClean();
3367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        String s;
3377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        switch (c) {
3397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '"':
3407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '\'':
3417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return nextString(c);
3427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '{':
3437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                back();
3447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return new JSONObject(this);
3457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '[':
3467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            case '(':
3477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                back();
3487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                return new JSONArray(this);
3497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        /*
3527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         * Handle unquoted text. This could be the values true, false, or
3537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         * null, or it can be a number. An implementation (such as this one)
3547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         * is allowed to also accept non-standard forms.
3557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         *
3567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         * Accumulate characters until we reach the end of the text or a
3577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         * formatting character.
3587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet         */
3597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        StringBuffer sb = new StringBuffer();
3617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
3627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            sb.append(c);
3637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            c = next();
3647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        back();
3667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        s = sb.toString().trim();
3687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        if (s.equals("")) {
3697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            throw syntaxError("Missing value");
3707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return JSONObject.stringToValue(s);
3727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
3737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
3767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Skip characters until the next character is the requested character.
3777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * If the requested character is not found, no characters are skipped.
3787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param to A character to skip to.
3797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return The requested character, or zero if the requested character
3807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * is not found.
3817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
3827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public char skipTo(char to) throws JSONException {
3837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        char c;
3847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        try {
3857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            int startIndex = this.index;
3867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            reader.mark(Integer.MAX_VALUE);
3877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            do {
3887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                c = next();
3897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                if (c == 0) {
3907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    reader.reset();
3917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    this.index = startIndex;
3927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                    return c;
3937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet                }
3947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            } while (c != to);
3957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        } catch (IOException exc) {
3967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet            throw new JSONException(exc);
3977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        }
3987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
3997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        back();
4007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return c;
4017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
4027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
4037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
4047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Make a JSONException to signal a syntax error.
4057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
4067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @param message The error message.
4077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return  A JSONException object, suitable for throwing
4087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
4097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public JSONException syntaxError(String message) {
4107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return new JSONException(message + toString());
4117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
4127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
4137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet
4147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    /**
4157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * Make a printable string of this JSONTokener.
4167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     *
4177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     * @return " at character [this.index]"
4187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet     */
4197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    public String toString() {
4207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet        return " at character " + index;
4217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet    }
4227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet}