[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / json / JSONTokener.java
diff --git a/datarouter-prov/src/main/java/org/json/JSONTokener.java b/datarouter-prov/src/main/java/org/json/JSONTokener.java
new file mode 100644 (file)
index 0000000..816f52e
--- /dev/null
@@ -0,0 +1,468 @@
+/*******************************************************************************\r
+ * ============LICENSE_START==================================================\r
+ * * org.onap.dmaap\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.json;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.io.Reader;\r
+import java.io.StringReader;\r
+\r
+/*\r
+Copyright (c) 2002 JSON.org\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all\r
+copies or substantial portions of the Software.\r
+\r
+The Software shall be used for Good, not Evil.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+SOFTWARE.\r
+*/\r
+\r
+/**\r
+ * A JSONTokener takes a source string and extracts characters and tokens from\r
+ * it. It is used by the JSONObject and JSONArray constructors to parse\r
+ * JSON source strings.\r
+ * @author JSON.org\r
+ * @version 2012-02-16\r
+ */\r
+public class JSONTokener {\r
+\r
+    private long    character;\r
+    private boolean eof;\r
+    private long    index;\r
+    private long    line;\r
+    private char    previous;\r
+    private Reader  reader;\r
+    private boolean usePrevious;\r
+\r
+\r
+    /**\r
+     * Construct a JSONTokener from a Reader.\r
+     *\r
+     * @param reader     A reader.\r
+     */\r
+    public JSONTokener(Reader reader) {\r
+        this.reader = reader.markSupported()\r
+            ? reader\r
+            : new BufferedReader(reader);\r
+        this.eof = false;\r
+        this.usePrevious = false;\r
+        this.previous = 0;\r
+        this.index = 0;\r
+        this.character = 1;\r
+        this.line = 1;\r
+    }\r
+\r
+\r
+    /**\r
+     * Construct a JSONTokener from an InputStream.\r
+     */\r
+    public JSONTokener(InputStream inputStream) throws JSONException {\r
+        this(new InputStreamReader(inputStream));\r
+    }\r
+\r
+\r
+    /**\r
+     * Construct a JSONTokener from a string.\r
+     *\r
+     * @param s     A source string.\r
+     */\r
+    public JSONTokener(String s) {\r
+        this(new StringReader(s));\r
+    }\r
+\r
+\r
+    /**\r
+     * Back up one character. This provides a sort of lookahead capability,\r
+     * so that you can test for a digit or letter before attempting to parse\r
+     * the next number or identifier.\r
+     */\r
+    public void back() throws JSONException {\r
+        if (this.usePrevious || this.index <= 0) {\r
+            throw new JSONException("Stepping back two steps is not supported");\r
+        }\r
+        this.index -= 1;\r
+        this.character -= 1;\r
+        this.usePrevious = true;\r
+        this.eof = false;\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the hex value of a character (base16).\r
+     * @param c A character between '0' and '9' or between 'A' and 'F' or\r
+     * between 'a' and 'f'.\r
+     * @return  An int between 0 and 15, or -1 if c was not a hex digit.\r
+     */\r
+    public static int dehexchar(char c) {\r
+        if (c >= '0' && c <= '9') {\r
+            return c - '0';\r
+        }\r
+        if (c >= 'A' && c <= 'F') {\r
+            return c - ('A' - 10);\r
+        }\r
+        if (c >= 'a' && c <= 'f') {\r
+            return c - ('a' - 10);\r
+        }\r
+        return -1;\r
+    }\r
+\r
+    public boolean end() {\r
+        return this.eof && !this.usePrevious;\r
+    }\r
+\r
+\r
+    /**\r
+     * Determine if the source string still contains characters that next()\r
+     * can consume.\r
+     * @return true if not yet at the end of the source.\r
+     */\r
+    public boolean more() throws JSONException {\r
+        this.next();\r
+        if (this.end()) {\r
+            return false;\r
+        }\r
+        this.back();\r
+        return true;\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the next character in the source string.\r
+     *\r
+     * @return The next character, or 0 if past the end of the source string.\r
+     */\r
+    public char next() throws JSONException {\r
+        int c;\r
+        if (this.usePrevious) {\r
+            this.usePrevious = false;\r
+            c = this.previous;\r
+        } else {\r
+            try {\r
+                c = this.reader.read();\r
+            } catch (IOException exception) {\r
+                throw new JSONException(exception);\r
+            }\r
+\r
+            if (c <= 0) { // End of stream\r
+                this.eof = true;\r
+                c = 0;\r
+            }\r
+        }\r
+        this.index += 1;\r
+        if (this.previous == '\r') {\r
+            this.line += 1;\r
+            this.character = c == '\n' ? 0 : 1;\r
+        } else if (c == '\n') {\r
+            this.line += 1;\r
+            this.character = 0;\r
+        } else {\r
+            this.character += 1;\r
+        }\r
+        this.previous = (char) c;\r
+        return this.previous;\r
+    }\r
+\r
+\r
+    /**\r
+     * Consume the next character, and check that it matches a specified\r
+     * character.\r
+     * @param c The character to match.\r
+     * @return The character.\r
+     * @throws JSONException if the character does not match.\r
+     */\r
+    public char next(char c) throws JSONException {\r
+        char n = this.next();\r
+        if (n != c) {\r
+            throw this.syntaxError("Expected '" + c + "' and instead saw '" +\r
+                    n + "'");\r
+        }\r
+        return n;\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the next n characters.\r
+     *\r
+     * @param n     The number of characters to take.\r
+     * @return      A string of n characters.\r
+     * @throws JSONException\r
+     *   Substring bounds error if there are not\r
+     *   n characters remaining in the source string.\r
+     */\r
+     public String next(int n) throws JSONException {\r
+         if (n == 0) {\r
+             return "";\r
+         }\r
+\r
+         char[] chars = new char[n];\r
+         int pos = 0;\r
+\r
+         while (pos < n) {\r
+             chars[pos] = this.next();\r
+             if (this.end()) {\r
+                 throw this.syntaxError("Substring bounds error");\r
+             }\r
+             pos += 1;\r
+         }\r
+         return new String(chars);\r
+     }\r
+\r
+\r
+    /**\r
+     * Get the next char in the string, skipping whitespace.\r
+     * @throws JSONException\r
+     * @return  A character, or 0 if there are no more characters.\r
+     */\r
+    public char nextClean() throws JSONException {\r
+        for (;;) {\r
+            char c = this.next();\r
+            if (c == 0 || c > ' ') {\r
+                return c;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Return the characters up to the next close quote character.\r
+     * Backslash processing is done. The formal JSON format does not\r
+     * allow strings in single quotes, but an implementation is allowed to\r
+     * accept them.\r
+     * @param quote The quoting character, either\r
+     *      <code>"</code>&nbsp;<small>(double quote)</small> or\r
+     *      <code>'</code>&nbsp;<small>(single quote)</small>.\r
+     * @return      A String.\r
+     * @throws JSONException Unterminated string.\r
+     */\r
+    public String nextString(char quote) throws JSONException {\r
+        char c;\r
+        StringBuffer sb = new StringBuffer();\r
+        for (;;) {\r
+            c = this.next();\r
+            switch (c) {\r
+            case 0:\r
+            case '\n':\r
+            case '\r':\r
+                throw this.syntaxError("Unterminated string");\r
+            case '\\':\r
+                c = this.next();\r
+                switch (c) {\r
+                case 'b':\r
+                    sb.append('\b');\r
+                    break;\r
+                case 't':\r
+                    sb.append('\t');\r
+                    break;\r
+                case 'n':\r
+                    sb.append('\n');\r
+                    break;\r
+                case 'f':\r
+                    sb.append('\f');\r
+                    break;\r
+                case 'r':\r
+                    sb.append('\r');\r
+                    break;\r
+                case 'u':\r
+                    sb.append((char)Integer.parseInt(this.next(4), 16));\r
+                    break;\r
+                case '"':\r
+                case '\'':\r
+                case '\\':\r
+                case '/':\r
+                    sb.append(c);\r
+                    break;\r
+                default:\r
+                    throw this.syntaxError("Illegal escape.");\r
+                }\r
+                break;\r
+            default:\r
+                if (c == quote) {\r
+                    return sb.toString();\r
+                }\r
+                sb.append(c);\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the text up but not including the specified character or the\r
+     * end of line, whichever comes first.\r
+     * @param  delimiter A delimiter character.\r
+     * @return   A string.\r
+     */\r
+    public String nextTo(char delimiter) throws JSONException {\r
+        StringBuffer sb = new StringBuffer();\r
+        for (;;) {\r
+            char c = this.next();\r
+            if (c == delimiter || c == 0 || c == '\n' || c == '\r') {\r
+                if (c != 0) {\r
+                    this.back();\r
+                }\r
+                return sb.toString().trim();\r
+            }\r
+            sb.append(c);\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the text up but not including one of the specified delimiter\r
+     * characters or the end of line, whichever comes first.\r
+     * @param delimiters A set of delimiter characters.\r
+     * @return A string, trimmed.\r
+     */\r
+    public String nextTo(String delimiters) throws JSONException {\r
+        char c;\r
+        StringBuffer sb = new StringBuffer();\r
+        for (;;) {\r
+            c = this.next();\r
+            if (delimiters.indexOf(c) >= 0 || c == 0 ||\r
+                    c == '\n' || c == '\r') {\r
+                if (c != 0) {\r
+                    this.back();\r
+                }\r
+                return sb.toString().trim();\r
+            }\r
+            sb.append(c);\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the next value. The value can be a Boolean, Double, Integer,\r
+     * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.\r
+     * @throws JSONException If syntax error.\r
+     *\r
+     * @return An object.\r
+     */\r
+    public Object nextValue() throws JSONException {\r
+        char c = this.nextClean();\r
+        String string;\r
+\r
+        switch (c) {\r
+            case '"':\r
+            case '\'':\r
+                return this.nextString(c);\r
+            case '{':\r
+                this.back();\r
+                return new JSONObject(this);\r
+            case '[':\r
+                this.back();\r
+                return new JSONArray(this);\r
+        }\r
+\r
+        /*\r
+         * Handle unquoted text. This could be the values true, false, or\r
+         * null, or it can be a number. An implementation (such as this one)\r
+         * is allowed to also accept non-standard forms.\r
+         *\r
+         * Accumulate characters until we reach the end of the text or a\r
+         * formatting character.\r
+         */\r
+\r
+        StringBuffer sb = new StringBuffer();\r
+        while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {\r
+            sb.append(c);\r
+            c = this.next();\r
+        }\r
+        this.back();\r
+\r
+        string = sb.toString().trim();\r
+        if ("".equals(string)) {\r
+            throw this.syntaxError("Missing value");\r
+        }\r
+        return JSONObject.stringToValue(string);\r
+    }\r
+\r
+\r
+    /**\r
+     * Skip characters until the next character is the requested character.\r
+     * If the requested character is not found, no characters are skipped.\r
+     * @param to A character to skip to.\r
+     * @return The requested character, or zero if the requested character\r
+     * is not found.\r
+     */\r
+    public char skipTo(char to) throws JSONException {\r
+        char c;\r
+        try {\r
+            long startIndex = this.index;\r
+            long startCharacter = this.character;\r
+            long startLine = this.line;\r
+            this.reader.mark(1000000);\r
+            do {\r
+                c = this.next();\r
+                if (c == 0) {\r
+                    this.reader.reset();\r
+                    this.index = startIndex;\r
+                    this.character = startCharacter;\r
+                    this.line = startLine;\r
+                    return c;\r
+                }\r
+            } while (c != to);\r
+        } catch (IOException exc) {\r
+            throw new JSONException(exc);\r
+        }\r
+\r
+        this.back();\r
+        return c;\r
+    }\r
+\r
+\r
+    /**\r
+     * Make a JSONException to signal a syntax error.\r
+     *\r
+     * @param message The error message.\r
+     * @return  A JSONException object, suitable for throwing\r
+     */\r
+    public JSONException syntaxError(String message) {\r
+        return new JSONException(message + this.toString());\r
+    }\r
+\r
+\r
+    /**\r
+     * Make a printable string of this JSONTokener.\r
+     *\r
+     * @return " at {index} [character {character} line {line}]"\r
+     */\r
+    public String toString() {\r
+        return " at " + this.index + " [character " + this.character + " line " +\r
+            this.line + "]";\r
+    }\r
+}\r