--- /dev/null
+/*******************************************************************************\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> <small>(double quote)</small> or\r
+ * <code>'</code> <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