--- /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.util.HashMap;\r
+import java.util.Map;\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
+ * The XMLTokener extends the JSONTokener to provide additional methods\r
+ * for the parsing of XML texts.\r
+ * @author JSON.org\r
+ * @version 2012-11-13\r
+ */\r
+public class XMLTokener extends JSONTokener {\r
+\r
+\r
+ /** The table of entity values. It initially contains Character values for\r
+ * amp, apos, gt, lt, quot.\r
+ */\r
+ public static final Map<String,Character> entity;\r
+\r
+ static {\r
+ entity = new HashMap<String,Character>(8);\r
+ entity.put("amp", XML.AMP);\r
+ entity.put("apos", XML.APOS);\r
+ entity.put("gt", XML.GT);\r
+ entity.put("lt", XML.LT);\r
+ entity.put("quot", XML.QUOT);\r
+ }\r
+\r
+ /**\r
+ * Construct an XMLTokener from a string.\r
+ * @param s A source string.\r
+ */\r
+ public XMLTokener(String s) {\r
+ super(s);\r
+ }\r
+\r
+ /**\r
+ * Get the text in the CDATA block.\r
+ * @return The string up to the <code>]]></code>.\r
+ * @throws JSONException If the <code>]]></code> is not found.\r
+ */\r
+ public String nextCDATA() throws JSONException {\r
+ char c;\r
+ int i;\r
+ StringBuffer sb = new StringBuffer();\r
+ for (;;) {\r
+ c = next();\r
+ if (end()) {\r
+ throw syntaxError("Unclosed CDATA");\r
+ }\r
+ sb.append(c);\r
+ i = sb.length() - 3;\r
+ if (i >= 0 && sb.charAt(i) == ']' &&\r
+ sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {\r
+ sb.setLength(i);\r
+ return sb.toString();\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Get the next XML outer token, trimming whitespace. There are two kinds\r
+ * of tokens: the '<' character which begins a markup tag, and the content\r
+ * text between markup tags.\r
+ *\r
+ * @return A string, or a '<' Character, or null if there is no more\r
+ * source text.\r
+ * @throws JSONException\r
+ */\r
+ public Object nextContent() throws JSONException {\r
+ char c;\r
+ StringBuffer sb;\r
+ do {\r
+ c = next();\r
+ } while (Character.isWhitespace(c));\r
+ if (c == 0) {\r
+ return null;\r
+ }\r
+ if (c == '<') {\r
+ return XML.LT;\r
+ }\r
+ sb = new StringBuffer();\r
+ for (;;) {\r
+ if (c == '<' || c == 0) {\r
+ back();\r
+ return sb.toString().trim();\r
+ }\r
+ if (c == '&') {\r
+ sb.append(nextEntity(c));\r
+ } else {\r
+ sb.append(c);\r
+ }\r
+ c = next();\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Return the next entity. These entities are translated to Characters:\r
+ * <code>& ' > < "</code>.\r
+ * @param ampersand An ampersand character.\r
+ * @return A Character or an entity String if the entity is not recognized.\r
+ * @throws JSONException If missing ';' in XML entity.\r
+ */\r
+ public Object nextEntity(char ampersand) throws JSONException {\r
+ StringBuffer sb = new StringBuffer();\r
+ for (;;) {\r
+ char c = next();\r
+ if (Character.isLetterOrDigit(c) || c == '#') {\r
+ sb.append(Character.toLowerCase(c));\r
+ } else if (c == ';') {\r
+ break;\r
+ } else {\r
+ throw syntaxError("Missing ';' in XML entity: &" + sb);\r
+ }\r
+ }\r
+ String string = sb.toString();\r
+ Object object = entity.get(string);\r
+ return object != null ? object : ampersand + string + ";";\r
+ }\r
+\r
+\r
+ /**\r
+ * Returns the next XML meta token. This is used for skipping over <!...>\r
+ * and <?...?> structures.\r
+ * @return Syntax characters (<code>< > / = ! ?</code>) are returned as\r
+ * Character, and strings and names are returned as Boolean. We don't care\r
+ * what the values actually are.\r
+ * @throws JSONException If a string is not properly closed or if the XML\r
+ * is badly structured.\r
+ */\r
+ public Object nextMeta() throws JSONException {\r
+ char c;\r
+ char q;\r
+ do {\r
+ c = next();\r
+ } while (Character.isWhitespace(c));\r
+ switch (c) {\r
+ case 0:\r
+ throw syntaxError("Misshaped meta tag");\r
+ case '<':\r
+ return XML.LT;\r
+ case '>':\r
+ return XML.GT;\r
+ case '/':\r
+ return XML.SLASH;\r
+ case '=':\r
+ return XML.EQ;\r
+ case '!':\r
+ return XML.BANG;\r
+ case '?':\r
+ return XML.QUEST;\r
+ case '"':\r
+ case '\'':\r
+ q = c;\r
+ for (;;) {\r
+ c = next();\r
+ if (c == 0) {\r
+ throw syntaxError("Unterminated string");\r
+ }\r
+ if (c == q) {\r
+ return Boolean.TRUE;\r
+ }\r
+ }\r
+ default:\r
+ for (;;) {\r
+ c = next();\r
+ if (Character.isWhitespace(c)) {\r
+ return Boolean.TRUE;\r
+ }\r
+ switch (c) {\r
+ case 0:\r
+ case '<':\r
+ case '>':\r
+ case '/':\r
+ case '=':\r
+ case '!':\r
+ case '?':\r
+ case '"':\r
+ case '\'':\r
+ back();\r
+ return Boolean.TRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Get the next XML Token. These tokens are found inside of angle\r
+ * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it\r
+ * may be a string wrapped in single quotes or double quotes, or it may be a\r
+ * name.\r
+ * @return a String or a Character.\r
+ * @throws JSONException If the XML is not well formed.\r
+ */\r
+ public Object nextToken() throws JSONException {\r
+ char c;\r
+ char q;\r
+ StringBuffer sb;\r
+ do {\r
+ c = next();\r
+ } while (Character.isWhitespace(c));\r
+ switch (c) {\r
+ case 0:\r
+ throw syntaxError("Misshaped element");\r
+ case '<':\r
+ throw syntaxError("Misplaced '<'");\r
+ case '>':\r
+ return XML.GT;\r
+ case '/':\r
+ return XML.SLASH;\r
+ case '=':\r
+ return XML.EQ;\r
+ case '!':\r
+ return XML.BANG;\r
+ case '?':\r
+ return XML.QUEST;\r
+\r
+// Quoted string\r
+\r
+ case '"':\r
+ case '\'':\r
+ q = c;\r
+ sb = new StringBuffer();\r
+ for (;;) {\r
+ c = next();\r
+ if (c == 0) {\r
+ throw syntaxError("Unterminated string");\r
+ }\r
+ if (c == q) {\r
+ return sb.toString();\r
+ }\r
+ if (c == '&') {\r
+ sb.append(nextEntity(c));\r
+ } else {\r
+ sb.append(c);\r
+ }\r
+ }\r
+ default:\r
+\r
+// Name\r
+\r
+ sb = new StringBuffer();\r
+ for (;;) {\r
+ sb.append(c);\r
+ c = next();\r
+ if (Character.isWhitespace(c)) {\r
+ return sb.toString();\r
+ }\r
+ switch (c) {\r
+ case 0:\r
+ return sb.toString();\r
+ case '>':\r
+ case '/':\r
+ case '=':\r
+ case '!':\r
+ case '?':\r
+ case '[':\r
+ case ']':\r
+ back();\r
+ return sb.toString();\r
+ case '<':\r
+ case '"':\r
+ case '\'':\r
+ throw syntaxError("Bad character in a name");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Skip characters until past the requested string.\r
+ * If it is not found, we are left at the end of the source with a result of false.\r
+ * @param to A string to skip past.\r
+ * @throws JSONException\r
+ */\r
+ public boolean skipPast(String to) throws JSONException {\r
+ boolean b;\r
+ char c;\r
+ int i;\r
+ int j;\r
+ int offset = 0;\r
+ int length = to.length();\r
+ char[] circle = new char[length];\r
+\r
+ /*\r
+ * First fill the circle buffer with as many characters as are in the\r
+ * to string. If we reach an early end, bail.\r
+ */\r
+\r
+ for (i = 0; i < length; i += 1) {\r
+ c = next();\r
+ if (c == 0) {\r
+ return false;\r
+ }\r
+ circle[i] = c;\r
+ }\r
+\r
+ /* We will loop, possibly for all of the remaining characters. */\r
+\r
+ for (;;) {\r
+ j = offset;\r
+ b = true;\r
+\r
+ /* Compare the circle buffer with the to string. */\r
+\r
+ for (i = 0; i < length; i += 1) {\r
+ if (circle[j] != to.charAt(i)) {\r
+ b = false;\r
+ break;\r
+ }\r
+ j += 1;\r
+ if (j >= length) {\r
+ j -= length;\r
+ }\r
+ }\r
+\r
+ /* If we exit the loop with b intact, then victory is ours. */\r
+\r
+ if (b) {\r
+ return true;\r
+ }\r
+\r
+ /* Get the next character. If there isn't one, then defeat is ours. */\r
+\r
+ c = next();\r
+ if (c == 0) {\r
+ return false;\r
+ }\r
+ /*\r
+ * Shove the character in the circle buffer and advance the\r
+ * circle offset. The offset is mod n.\r
+ */\r
+ circle[offset] = c;\r
+ offset += 1;\r
+ if (offset >= length) {\r
+ offset -= length;\r
+ }\r
+ }\r
+ }\r
+}\r