| @@ -0,0 +1,111 @@ | ||
| import java.util.HashMap; | ||
| import java.util.Vector; | ||
|
|
||
| import org.json.JSONObject; | ||
| import org.json.JSONStringer; | ||
|
|
||
| public class MoveEffect { | ||
| private boolean useConditions = false; | ||
| private MoveDesignSpecifics m_designSpecifics; | ||
| private Vector<Condition> m_ANDconditions = new Vector<Condition>(); | ||
| private Vector<Condition> m_ORconditions = new Vector<Condition>(); | ||
| private HashMap<String, Integer> m_boosts = new HashMap<String, Integer>(); | ||
| private StateChange m_StateChange = new StateChange(); | ||
| private int chance = 100; | ||
|
|
||
| public MoveEffect() { | ||
|
|
||
| } | ||
| public MoveEffect setParent(MoveEffect p_parent) { | ||
| return this; | ||
| } | ||
| private InputFileHandler getInFileHandler() { | ||
| return Main.getInputFileHandler(); | ||
| } | ||
| private MoveDesignSpecifics getDesignSpecifics() { | ||
| return m_designSpecifics; | ||
| } | ||
| public MoveEffect setMoveDesignSpecifics(MoveDesignSpecifics p_designSpecifics) { | ||
| this.m_designSpecifics = p_designSpecifics; | ||
| return this; | ||
| } | ||
| public String toJSONString() { | ||
| JSONStringer stringer = new JSONStringer(); | ||
| stringer.object(); | ||
| if (this.useConditions) { | ||
| stringer.key("AND").value(JSONObject.wrap(m_ANDconditions)) | ||
| .key("OR").value(JSONObject.wrap(m_ORconditions)); | ||
| } | ||
| if (this.m_StateChange != null) { | ||
| stringer.key("status").value(m_StateChange.toJSONObject()); | ||
| } | ||
| if (this.m_boosts != null) { | ||
| stringer.key("boosts").value(JSONObject.wrap(m_boosts)); | ||
| } | ||
| if (this.getDesignSpecifics().changesHP() && !this.getDesignSpecifics().hasMaliciousIntent()) { | ||
| stringer.key("heal").value(".5"); | ||
| } | ||
| stringer.key("chance").value(chance); | ||
| stringer.endObject(); | ||
|
|
||
| return stringer.toString(); | ||
| } | ||
| public void randomize() { | ||
| int statusCost = 0; | ||
| int statBoostCost = 0; | ||
|
|
||
| if (this.getDesignSpecifics().changesStatus()) { | ||
| statusCost += 3; | ||
|
|
||
| m_StateChange.setMoveDesignSpecifics(getDesignSpecifics()); | ||
| m_StateChange.randomize(); | ||
| } | ||
| else { | ||
| m_StateChange = null; | ||
| } | ||
|
|
||
| if (this.getDesignSpecifics().changesStats()) { | ||
| int maxBoostCount = 0; | ||
| maxBoostCount = (int) (1 + Math.random() * 2); | ||
| maxBoostCount += this.getDesignSpecifics().changesHP() ? 0 : 1; | ||
| statBoostCost = maxBoostCount; | ||
| for (int i = 0; i < maxBoostCount; i++) { | ||
| if (this.getInFileHandler() != null) { | ||
| String key = getInFileHandler().getRandomStat(); | ||
| boolean hasMaliciousIntent = this.getDesignSpecifics().hasMaliciousIntent(); | ||
| if (Math.random() > .5) { | ||
| if (!hasMaliciousIntent) { | ||
| key = getInFileHandler().getBoostFromType(this.getDesignSpecifics().getType()); | ||
| } | ||
| else { | ||
| key = getInFileHandler().getNerfFromType(this.getDesignSpecifics().getType()); | ||
| } | ||
| } | ||
| int value = hasMaliciousIntent ? -1 : 1; | ||
| int currValue = (m_boosts.get(key) != null) ? m_boosts.get(key) : 0; | ||
| m_boosts.put(key, currValue + value); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| m_boosts = null; | ||
| } | ||
|
|
||
| chance = 100; | ||
| chance -= statusCost * 10; | ||
| chance -= statBoostCost * 10; | ||
| if (this.getDesignSpecifics().changesHP()) { | ||
| chance -= 30; | ||
| } | ||
|
|
||
| if (!this.getDesignSpecifics().hasMaliciousIntent() && !this.getDesignSpecifics().changesHP()) { | ||
| chance = 100; | ||
| } | ||
| } | ||
| public int getChance() { | ||
| return chance; | ||
| } | ||
| public JSONObject toJSONObject() { | ||
| return new JSONObject(this.toJSONString()); | ||
| } | ||
| } |
| @@ -0,0 +1,21 @@ | ||
|
|
||
| public enum StatBoostOperationEnum { | ||
| ADD, RESET; | ||
| public String toString() { | ||
| String ret = ""; | ||
|
|
||
| switch (this) { | ||
| case ADD: | ||
| ret = "add"; | ||
| break; | ||
| case RESET: | ||
| ret = "reset"; | ||
| break; | ||
| default: | ||
| break; | ||
|
|
||
| } | ||
|
|
||
| return ret; | ||
| } | ||
| } |
| @@ -0,0 +1,40 @@ | ||
| import org.json.JSONObject; | ||
| import org.json.JSONStringer; | ||
|
|
||
| public class StateChange { | ||
| private MoveDesignSpecifics m_designSpecifics; | ||
| private boolean m_doStart = false; | ||
| private String m_id = ""; | ||
| public StateChange() { | ||
|
|
||
| } | ||
| private InputFileHandler getInFileHandler() { | ||
| return Main.getInputFileHandler(); | ||
| } | ||
| private MoveDesignSpecifics getDesignSpecifics() { | ||
| return m_designSpecifics; | ||
| } | ||
| public StateChange setMoveDesignSpecifics(MoveDesignSpecifics p_designSpecifics) { | ||
| this.m_designSpecifics = p_designSpecifics; | ||
| return this; | ||
| } | ||
| public void randomize() { | ||
| m_doStart = this.getDesignSpecifics().hasMaliciousIntent(); | ||
| if (this.getInFileHandler() != null) { | ||
| m_id = this.getInFileHandler().getStatusFromType(this.getDesignSpecifics().getType()); | ||
| } | ||
| } | ||
| public String toJSONString() { | ||
| JSONStringer stringer = new JSONStringer(); | ||
|
|
||
| stringer.object() | ||
| .key("operation").value(m_doStart ? "start" : "stop") | ||
| .key("status").value(m_id.toString()) | ||
| .endObject(); | ||
|
|
||
| return stringer.toString(); | ||
| } | ||
| public JSONObject toJSONObject() { | ||
| return new JSONObject(this.toJSONString()); | ||
| } | ||
| } |
| @@ -0,0 +1,279 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * This provides static methods to convert comma delimited text into a | ||
| * JSONArray, and to covert a JSONArray into comma delimited text. Comma | ||
| * delimited text is a very popular format for data interchange. It is | ||
| * understood by most database, spreadsheet, and organizer programs. | ||
| * <p> | ||
| * Each row of text represents a row in a table or a data record. Each row | ||
| * ends with a NEWLINE character. Each row contains one or more values. | ||
| * Values are separated by commas. A value can contain any character except | ||
| * for comma, unless is is wrapped in single quotes or double quotes. | ||
| * <p> | ||
| * The first row usually contains the names of the columns. | ||
| * <p> | ||
| * A comma delimited list can be converted into a JSONArray of JSONObjects. | ||
| * The names for the elements in the JSONObjects can be taken from the names | ||
| * in the first row. | ||
| * @author JSON.org | ||
| * @version 2012-11-13 | ||
| */ | ||
| public class CDL { | ||
|
|
||
| /** | ||
| * 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(','); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * 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(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Produce a JSONObject from a row of comma delimited text, using a | ||
| * parallel JSONArray of strings to provides the names of the elements. | ||
| * @param names A JSONArray of names. This is commonly obtained from the | ||
| * first row of a comma delimited text file using the rowToJSONArray | ||
| * method. | ||
| * @param x A JSONTokener of the source text. | ||
| * @return A JSONObject combining the names and values. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) | ||
| throws JSONException { | ||
| JSONArray ja = rowToJSONArray(x); | ||
| return ja != null ? ja.toJSONObject(names) : null; | ||
| } | ||
|
|
||
| /** | ||
| * Produce a comma delimited text row from a JSONArray. Values containing | ||
| * the comma character will be quoted. Troublesome characters may be | ||
| * removed. | ||
| * @param ja A JSONArray of strings. | ||
| * @return A string ending in NEWLINE. | ||
| */ | ||
| public static String rowToString(JSONArray ja) { | ||
| StringBuffer sb = new StringBuffer(); | ||
| for (int i = 0; i < ja.length(); i += 1) { | ||
| if (i > 0) { | ||
| sb.append(','); | ||
| } | ||
| Object object = ja.opt(i); | ||
| if (object != null) { | ||
| String string = object.toString(); | ||
| if (string.length() > 0 && (string.indexOf(',') >= 0 || | ||
| string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 || | ||
| string.indexOf(0) >= 0 || string.charAt(0) == '"')) { | ||
| sb.append('"'); | ||
| int length = string.length(); | ||
| for (int j = 0; j < length; j += 1) { | ||
| char c = string.charAt(j); | ||
| if (c >= ' ' && c != '"') { | ||
| sb.append(c); | ||
| } | ||
| } | ||
| sb.append('"'); | ||
| } else { | ||
| sb.append(string); | ||
| } | ||
| } | ||
| } | ||
| sb.append('\n'); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Produce a JSONArray of JSONObjects from a comma delimited text string, | ||
| * using the first row as a source of names. | ||
| * @param string The comma delimited text. | ||
| * @return A JSONArray of JSONObjects. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONArray toJSONArray(String string) throws JSONException { | ||
| return toJSONArray(new JSONTokener(string)); | ||
| } | ||
|
|
||
| /** | ||
| * Produce a JSONArray of JSONObjects from a comma delimited text string, | ||
| * using the first row as a source of names. | ||
| * @param x The JSONTokener containing the comma delimited text. | ||
| * @return A JSONArray of JSONObjects. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONArray toJSONArray(JSONTokener x) throws JSONException { | ||
| return toJSONArray(rowToJSONArray(x), x); | ||
| } | ||
|
|
||
| /** | ||
| * Produce a JSONArray of JSONObjects from a comma delimited text string | ||
| * using a supplied JSONArray as the source of element names. | ||
| * @param names A JSONArray of strings. | ||
| * @param string The comma delimited text. | ||
| * @return A JSONArray of JSONObjects. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONArray toJSONArray(JSONArray names, String string) | ||
| throws JSONException { | ||
| return toJSONArray(names, new JSONTokener(string)); | ||
| } | ||
|
|
||
| /** | ||
| * Produce a JSONArray of JSONObjects from a comma delimited text string | ||
| * using a supplied JSONArray as the source of element names. | ||
| * @param names A JSONArray of strings. | ||
| * @param x A JSONTokener of the source text. | ||
| * @return A JSONArray of JSONObjects. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONArray toJSONArray(JSONArray names, JSONTokener x) | ||
| throws JSONException { | ||
| if (names == null || names.length() == 0) { | ||
| return null; | ||
| } | ||
| JSONArray ja = new JSONArray(); | ||
| for (;;) { | ||
| JSONObject jo = rowToJSONObject(names, x); | ||
| if (jo == null) { | ||
| break; | ||
| } | ||
| ja.put(jo); | ||
| } | ||
| if (ja.length() == 0) { | ||
| return null; | ||
| } | ||
| return ja; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Produce a comma delimited text from a JSONArray of JSONObjects. The | ||
| * first row will be a list of names obtained by inspecting the first | ||
| * JSONObject. | ||
| * @param ja A JSONArray of JSONObjects. | ||
| * @return A comma delimited text. | ||
| * @throws JSONException | ||
| */ | ||
| public static String toString(JSONArray ja) throws JSONException { | ||
| JSONObject jo = ja.optJSONObject(0); | ||
| if (jo != null) { | ||
| JSONArray names = jo.names(); | ||
| if (names != null) { | ||
| return rowToString(names) + toString(names, ja); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Produce a comma delimited text from a JSONArray of JSONObjects using | ||
| * a provided list of names. The list of names is not included in the | ||
| * output. | ||
| * @param names A JSONArray of strings. | ||
| * @param ja A JSONArray of JSONObjects. | ||
| * @return A comma delimited text. | ||
| * @throws JSONException | ||
| */ | ||
| public static String toString(JSONArray names, JSONArray ja) | ||
| throws JSONException { | ||
| if (names == null || names.length() == 0) { | ||
| return null; | ||
| } | ||
| StringBuffer sb = new StringBuffer(); | ||
| for (int i = 0; i < ja.length(); i += 1) { | ||
| JSONObject jo = ja.optJSONObject(i); | ||
| if (jo != null) { | ||
| sb.append(rowToString(jo.toJSONArray(names))); | ||
| } | ||
| } | ||
| return sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,169 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * Convert a web browser cookie specification to a JSONObject and back. | ||
| * JSON and Cookies are both notations for name/value pairs. | ||
| * @author JSON.org | ||
| * @version 2010-12-24 | ||
| */ | ||
| public class Cookie { | ||
|
|
||
| /** | ||
| * Produce a copy of a string in which the characters '+', '%', '=', ';' | ||
| * and control characters are replaced with "%hh". This is a gentle form | ||
| * of URL encoding, attempting to cause as little distortion to the | ||
| * string as possible. The characters '=' and ';' are meta characters in | ||
| * cookies. By convention, they are escaped using the URL-encoding. This is | ||
| * only a convention, not a standard. Often, cookies are expected to have | ||
| * encoded values. We encode '=' and ';' because we must. We encode '%' and | ||
| * '+' because they are meta characters in URL encoding. | ||
| * @param string The source string. | ||
| * @return The escaped result. | ||
| */ | ||
| public static String escape(String string) { | ||
| char c; | ||
| String s = string.trim(); | ||
| StringBuffer sb = new StringBuffer(); | ||
| int length = s.length(); | ||
| for (int i = 0; i < length; i += 1) { | ||
| c = s.charAt(i); | ||
| if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') { | ||
| sb.append('%'); | ||
| sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16)); | ||
| sb.append(Character.forDigit((char)(c & 0x0f), 16)); | ||
| } else { | ||
| sb.append(c); | ||
| } | ||
| } | ||
| return sb.toString(); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * 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; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Convert a JSONObject into a cookie specification string. The JSONObject | ||
| * must contain "name" and "value" members. | ||
| * If the JSONObject contains "expires", "domain", "path", or "secure" | ||
| * members, they will be appended to the cookie specification string. | ||
| * All other members are ignored. | ||
| * @param jo A JSONObject | ||
| * @return A cookie specification string | ||
| * @throws JSONException | ||
| */ | ||
| public static String toString(JSONObject jo) throws JSONException { | ||
| StringBuffer sb = new StringBuffer(); | ||
|
|
||
| sb.append(escape(jo.getString("name"))); | ||
| sb.append("="); | ||
| sb.append(escape(jo.getString("value"))); | ||
| if (jo.has("expires")) { | ||
| sb.append(";expires="); | ||
| sb.append(jo.getString("expires")); | ||
| } | ||
| if (jo.has("domain")) { | ||
| sb.append(";domain="); | ||
| sb.append(escape(jo.getString("domain"))); | ||
| } | ||
| if (jo.has("path")) { | ||
| sb.append(";path="); | ||
| sb.append(escape(jo.getString("path"))); | ||
| } | ||
| if (jo.optBoolean("secure")) { | ||
| sb.append(";secure"); | ||
| } | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Convert <code>%</code><i>hh</i> sequences to single characters, and | ||
| * convert plus to space. | ||
| * @param string A string that may contain | ||
| * <code>+</code> <small>(plus)</small> and | ||
| * <code>%</code><i>hh</i> sequences. | ||
| * @return The unescaped string. | ||
| */ | ||
| public static String unescape(String string) { | ||
| int length = string.length(); | ||
| StringBuffer sb = new StringBuffer(); | ||
| for (int i = 0; i < length; ++i) { | ||
| char c = string.charAt(i); | ||
| if (c == '+') { | ||
| c = ' '; | ||
| } else if (c == '%' && i + 2 < length) { | ||
| int d = JSONTokener.dehexchar(string.charAt(i + 1)); | ||
| int e = JSONTokener.dehexchar(string.charAt(i + 2)); | ||
| if (d >= 0 && e >= 0) { | ||
| c = (char)(d * 16 + e); | ||
| i += 2; | ||
| } | ||
| } | ||
| sb.append(c); | ||
| } | ||
| return sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,90 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| import java.util.Iterator; | ||
|
|
||
| /** | ||
| * Convert a web browser cookie list string to a JSONObject and back. | ||
| * @author JSON.org | ||
| * @version 2010-12-24 | ||
| */ | ||
| public class CookieList { | ||
|
|
||
| /** | ||
| * Convert a cookie list into a JSONObject. A cookie list is a sequence | ||
| * of name/value pairs. The names are separated from the values by '='. | ||
| * The pairs are separated by ';'. The names and the values | ||
| * will be unescaped, possibly converting '+' and '%' sequences. | ||
| * | ||
| * To add a cookie to a cooklist, | ||
| * cookielistJSONObject.put(cookieJSONObject.getString("name"), | ||
| * cookieJSONObject.getString("value")); | ||
| * @param string A cookie list string | ||
| * @return A JSONObject | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONObject toJSONObject(String string) throws JSONException { | ||
| JSONObject jo = new JSONObject(); | ||
| JSONTokener x = new JSONTokener(string); | ||
| while (x.more()) { | ||
| String name = Cookie.unescape(x.nextTo('=')); | ||
| x.next('='); | ||
| jo.put(name, Cookie.unescape(x.nextTo(';'))); | ||
| x.next(); | ||
| } | ||
| return jo; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Convert a JSONObject into a cookie list. A cookie list is a sequence | ||
| * of name/value pairs. The names are separated from the values by '='. | ||
| * The pairs are separated by ';'. The characters '%', '+', '=', and ';' | ||
| * in the names and values are replaced by "%hh". | ||
| * @param jo A JSONObject | ||
| * @return A cookie list string | ||
| * @throws JSONException | ||
| */ | ||
| public static String toString(JSONObject jo) throws JSONException { | ||
| boolean b = false; | ||
| Iterator keys = jo.keys(); | ||
| String string; | ||
| StringBuffer sb = new StringBuffer(); | ||
| while (keys.hasNext()) { | ||
| string = keys.next().toString(); | ||
| if (!jo.isNull(string)) { | ||
| if (b) { | ||
| sb.append(';'); | ||
| } | ||
| sb.append(Cookie.escape(string)); | ||
| sb.append("="); | ||
| sb.append(Cookie.escape(jo.getString(string))); | ||
| b = true; | ||
| } | ||
| } | ||
| return sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,163 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| import java.util.Iterator; | ||
|
|
||
| /** | ||
| * Convert an HTTP header to a JSONObject and back. | ||
| * @author JSON.org | ||
| * @version 2010-12-24 | ||
| */ | ||
| public class HTTP { | ||
|
|
||
| /** Carriage return/line feed. */ | ||
| public static final String CRLF = "\r\n"; | ||
|
|
||
| /** | ||
| * Convert an HTTP header string into a JSONObject. It can be a request | ||
| * header or a response header. A request header will contain | ||
| * <pre>{ | ||
| * Method: "POST" (for example), | ||
| * "Request-URI": "/" (for example), | ||
| * "HTTP-Version": "HTTP/1.1" (for example) | ||
| * }</pre> | ||
| * A response header will contain | ||
| * <pre>{ | ||
| * "HTTP-Version": "HTTP/1.1" (for example), | ||
| * "Status-Code": "200" (for example), | ||
| * "Reason-Phrase": "OK" (for example) | ||
| * }</pre> | ||
| * In addition, the other parameters in the header will be captured, using | ||
| * the HTTP field names as JSON names, so that <pre> | ||
| * Date: Sun, 26 May 2002 18:06:04 GMT | ||
| * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s | ||
| * Cache-Control: no-cache</pre> | ||
| * become | ||
| * <pre>{... | ||
| * Date: "Sun, 26 May 2002 18:06:04 GMT", | ||
| * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s", | ||
| * "Cache-Control": "no-cache", | ||
| * ...}</pre> | ||
| * It does no further checking or conversion. It does not parse dates. | ||
| * It does not do '%' transforms on URLs. | ||
| * @param string An HTTP header string. | ||
| * @return A JSONObject containing the elements and attributes | ||
| * of the XML string. | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONObject toJSONObject(String string) throws JSONException { | ||
| JSONObject jo = new JSONObject(); | ||
| HTTPTokener x = new HTTPTokener(string); | ||
| String token; | ||
|
|
||
| token = x.nextToken(); | ||
| if (token.toUpperCase().startsWith("HTTP")) { | ||
|
|
||
| // Response | ||
|
|
||
| jo.put("HTTP-Version", token); | ||
| jo.put("Status-Code", x.nextToken()); | ||
| jo.put("Reason-Phrase", x.nextTo('\0')); | ||
| x.next(); | ||
|
|
||
| } else { | ||
|
|
||
| // Request | ||
|
|
||
| jo.put("Method", token); | ||
| jo.put("Request-URI", x.nextToken()); | ||
| jo.put("HTTP-Version", x.nextToken()); | ||
| } | ||
|
|
||
| // Fields | ||
|
|
||
| while (x.more()) { | ||
| String name = x.nextTo(':'); | ||
| x.next(':'); | ||
| jo.put(name, x.nextTo('\0')); | ||
| x.next(); | ||
| } | ||
| return jo; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Convert a JSONObject into an HTTP header. A request header must contain | ||
| * <pre>{ | ||
| * Method: "POST" (for example), | ||
| * "Request-URI": "/" (for example), | ||
| * "HTTP-Version": "HTTP/1.1" (for example) | ||
| * }</pre> | ||
| * A response header must contain | ||
| * <pre>{ | ||
| * "HTTP-Version": "HTTP/1.1" (for example), | ||
| * "Status-Code": "200" (for example), | ||
| * "Reason-Phrase": "OK" (for example) | ||
| * }</pre> | ||
| * Any other members of the JSONObject will be output as HTTP fields. | ||
| * The result will end with two CRLF pairs. | ||
| * @param jo A JSONObject | ||
| * @return An HTTP header string. | ||
| * @throws JSONException if the object does not contain enough | ||
| * information. | ||
| */ | ||
| public static String toString(JSONObject jo) throws JSONException { | ||
| Iterator keys = jo.keys(); | ||
| String string; | ||
| StringBuffer sb = new StringBuffer(); | ||
| if (jo.has("Status-Code") && jo.has("Reason-Phrase")) { | ||
| sb.append(jo.getString("HTTP-Version")); | ||
| sb.append(' '); | ||
| sb.append(jo.getString("Status-Code")); | ||
| sb.append(' '); | ||
| sb.append(jo.getString("Reason-Phrase")); | ||
| } else if (jo.has("Method") && jo.has("Request-URI")) { | ||
| sb.append(jo.getString("Method")); | ||
| sb.append(' '); | ||
| sb.append('"'); | ||
| sb.append(jo.getString("Request-URI")); | ||
| sb.append('"'); | ||
| sb.append(' '); | ||
| sb.append(jo.getString("HTTP-Version")); | ||
| } else { | ||
| throw new JSONException("Not enough material for an HTTP header."); | ||
| } | ||
| sb.append(CRLF); | ||
| while (keys.hasNext()) { | ||
| string = keys.next().toString(); | ||
| if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) && | ||
| !"Reason-Phrase".equals(string) && !"Method".equals(string) && | ||
| !"Request-URI".equals(string) && !jo.isNull(string)) { | ||
| sb.append(string); | ||
| sb.append(": "); | ||
| sb.append(jo.getString(string)); | ||
| sb.append(CRLF); | ||
| } | ||
| } | ||
| sb.append(CRLF); | ||
| return sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,77 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * The HTTPTokener extends the JSONTokener to provide additional methods | ||
| * for the parsing of HTTP headers. | ||
| * @author JSON.org | ||
| * @version 2012-11-13 | ||
| */ | ||
| public class HTTPTokener extends JSONTokener { | ||
|
|
||
| /** | ||
| * Construct an HTTPTokener from a string. | ||
| * @param string A source string. | ||
| */ | ||
| public HTTPTokener(String string) { | ||
| super(string); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Get the next token or string. This is used in parsing HTTP headers. | ||
| * @throws JSONException | ||
| * @return A String. | ||
| */ | ||
| public String nextToken() throws JSONException { | ||
| char c; | ||
| char q; | ||
| StringBuffer sb = new StringBuffer(); | ||
| do { | ||
| c = next(); | ||
| } while (Character.isWhitespace(c)); | ||
| if (c == '"' || c == '\'') { | ||
| q = c; | ||
| for (;;) { | ||
| c = next(); | ||
| if (c < ' ') { | ||
| throw syntaxError("Unterminated string."); | ||
| } | ||
| if (c == q) { | ||
| return sb.toString(); | ||
| } | ||
| sb.append(c); | ||
| } | ||
| } | ||
| for (;;) { | ||
| if (c == 0 || Character.isWhitespace(c)) { | ||
| return sb.toString(); | ||
| } | ||
| sb.append(c); | ||
| c = next(); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,41 @@ | ||
| package org.json; | ||
|
|
||
| /** | ||
| * The JSONException is thrown by the JSON.org classes when things are amiss. | ||
| * | ||
| * @author JSON.org | ||
| * @version 2013-02-10 | ||
| */ | ||
| public class JSONException extends RuntimeException { | ||
| private static final long serialVersionUID = 0; | ||
| private Throwable cause; | ||
|
|
||
| /** | ||
| * Constructs a JSONException with an explanatory message. | ||
| * | ||
| * @param message | ||
| * Detail about the reason for the exception. | ||
| */ | ||
| public JSONException(String message) { | ||
| super(message); | ||
| } | ||
|
|
||
| /** | ||
| * Constructs a new JSONException with the specified cause. | ||
| */ | ||
| public JSONException(Throwable cause) { | ||
| super(cause.getMessage()); | ||
| this.cause = cause; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the cause of this exception or null if the cause is nonexistent | ||
| * or unknown. | ||
| * | ||
| * @returns the cause of this exception or null if the cause is nonexistent | ||
| * or unknown. | ||
| */ | ||
| public Throwable getCause() { | ||
| return this.cause; | ||
| } | ||
| } |
| @@ -0,0 +1,18 @@ | ||
| package org.json; | ||
| /** | ||
| * The <code>JSONString</code> interface allows a <code>toJSONString()</code> | ||
| * method so that a class can change the behavior of | ||
| * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, | ||
| * and <code>JSONWriter.value(</code>Object<code>)</code>. The | ||
| * <code>toJSONString</code> method will be used instead of the default behavior | ||
| * of using the Object's <code>toString()</code> method and quoting the result. | ||
| */ | ||
| public interface JSONString { | ||
| /** | ||
| * The <code>toJSONString</code> method allows a class to produce its own JSON | ||
| * serialization. | ||
| * | ||
| * @return A strictly syntactically correct JSON text. | ||
| */ | ||
| public String toJSONString(); | ||
| } |
| @@ -0,0 +1,78 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2006 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| import java.io.StringWriter; | ||
|
|
||
| /** | ||
| * JSONStringer provides a quick and convenient way of producing JSON text. | ||
| * The texts produced strictly conform to JSON syntax rules. No whitespace is | ||
| * added, so the results are ready for transmission or storage. Each instance of | ||
| * JSONStringer can produce one JSON text. | ||
| * <p> | ||
| * A JSONStringer instance provides a <code>value</code> method for appending | ||
| * values to the | ||
| * text, and a <code>key</code> | ||
| * method for adding keys before values in objects. There are <code>array</code> | ||
| * and <code>endArray</code> methods that make and bound array values, and | ||
| * <code>object</code> and <code>endObject</code> methods which make and bound | ||
| * object values. All of these methods return the JSONWriter instance, | ||
| * permitting cascade style. For example, <pre> | ||
| * myString = new JSONStringer() | ||
| * .object() | ||
| * .key("JSON") | ||
| * .value("Hello, World!") | ||
| * .endObject() | ||
| * .toString();</pre> which produces the string <pre> | ||
| * {"JSON":"Hello, World!"}</pre> | ||
| * <p> | ||
| * The first method called must be <code>array</code> or <code>object</code>. | ||
| * There are no methods for adding commas or colons. JSONStringer adds them for | ||
| * you. Objects and arrays can be nested up to 20 levels deep. | ||
| * <p> | ||
| * This can sometimes be easier than using a JSONObject to build a string. | ||
| * @author JSON.org | ||
| * @version 2008-09-18 | ||
| */ | ||
| public class JSONStringer extends JSONWriter { | ||
| /** | ||
| * Make a fresh JSONStringer. It can be used to build one JSON text. | ||
| */ | ||
| public JSONStringer() { | ||
| super(new StringWriter()); | ||
| } | ||
|
|
||
| /** | ||
| * Return the JSON text. This method is used to obtain the product of the | ||
| * JSONStringer instance. It will return <code>null</code> if there was a | ||
| * problem in the construction of the JSON text (such as the calls to | ||
| * <code>array</code> were not properly balanced with calls to | ||
| * <code>endArray</code>). | ||
| * @return The JSON text. | ||
| */ | ||
| public String toString() { | ||
| return this.mode == 'd' ? this.writer.toString() : null; | ||
| } | ||
| } |
| @@ -0,0 +1,327 @@ | ||
| package org.json; | ||
|
|
||
| import java.io.IOException; | ||
| import java.io.Writer; | ||
|
|
||
| /* | ||
| Copyright (c) 2006 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * JSONWriter provides a quick and convenient way of producing JSON text. | ||
| * The texts produced strictly conform to JSON syntax rules. No whitespace is | ||
| * added, so the results are ready for transmission or storage. Each instance of | ||
| * JSONWriter can produce one JSON text. | ||
| * <p> | ||
| * A JSONWriter instance provides a <code>value</code> method for appending | ||
| * values to the | ||
| * text, and a <code>key</code> | ||
| * method for adding keys before values in objects. There are <code>array</code> | ||
| * and <code>endArray</code> methods that make and bound array values, and | ||
| * <code>object</code> and <code>endObject</code> methods which make and bound | ||
| * object values. All of these methods return the JSONWriter instance, | ||
| * permitting a cascade style. For example, <pre> | ||
| * new JSONWriter(myWriter) | ||
| * .object() | ||
| * .key("JSON") | ||
| * .value("Hello, World!") | ||
| * .endObject();</pre> which writes <pre> | ||
| * {"JSON":"Hello, World!"}</pre> | ||
| * <p> | ||
| * The first method called must be <code>array</code> or <code>object</code>. | ||
| * There are no methods for adding commas or colons. JSONWriter adds them for | ||
| * you. Objects and arrays can be nested up to 20 levels deep. | ||
| * <p> | ||
| * This can sometimes be easier than using a JSONObject to build a string. | ||
| * @author JSON.org | ||
| * @version 2011-11-24 | ||
| */ | ||
| public class JSONWriter { | ||
| private static final int maxdepth = 200; | ||
|
|
||
| /** | ||
| * The comma flag determines if a comma should be output before the next | ||
| * value. | ||
| */ | ||
| private boolean comma; | ||
|
|
||
| /** | ||
| * The current mode. Values: | ||
| * 'a' (array), | ||
| * 'd' (done), | ||
| * 'i' (initial), | ||
| * 'k' (key), | ||
| * 'o' (object). | ||
| */ | ||
| protected char mode; | ||
|
|
||
| /** | ||
| * The object/array stack. | ||
| */ | ||
| private final JSONObject stack[]; | ||
|
|
||
| /** | ||
| * The stack top index. A value of 0 indicates that the stack is empty. | ||
| */ | ||
| private int top; | ||
|
|
||
| /** | ||
| * The writer that will receive the output. | ||
| */ | ||
| protected Writer writer; | ||
|
|
||
| /** | ||
| * Make a fresh JSONWriter. It can be used to build one JSON text. | ||
| */ | ||
| public JSONWriter(Writer w) { | ||
| this.comma = false; | ||
| this.mode = 'i'; | ||
| this.stack = new JSONObject[maxdepth]; | ||
| this.top = 0; | ||
| this.writer = w; | ||
| } | ||
|
|
||
| /** | ||
| * Append a value. | ||
| * @param string A string value. | ||
| * @return this | ||
| * @throws JSONException If the value is out of sequence. | ||
| */ | ||
| private JSONWriter append(String string) throws JSONException { | ||
| if (string == null) { | ||
| throw new JSONException("Null pointer"); | ||
| } | ||
| if (this.mode == 'o' || this.mode == 'a') { | ||
| try { | ||
| if (this.comma && this.mode == 'a') { | ||
| this.writer.write(','); | ||
| } | ||
| this.writer.write(string); | ||
| } catch (IOException e) { | ||
| throw new JSONException(e); | ||
| } | ||
| if (this.mode == 'o') { | ||
| this.mode = 'k'; | ||
| } | ||
| this.comma = true; | ||
| return this; | ||
| } | ||
| throw new JSONException("Value out of sequence."); | ||
| } | ||
|
|
||
| /** | ||
| * Begin appending a new array. All values until the balancing | ||
| * <code>endArray</code> will be appended to this array. The | ||
| * <code>endArray</code> method must be called to mark the array's end. | ||
| * @return this | ||
| * @throws JSONException If the nesting is too deep, or if the object is | ||
| * started in the wrong place (for example as a key or after the end of the | ||
| * outermost array or object). | ||
| */ | ||
| public JSONWriter array() throws JSONException { | ||
| if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { | ||
| this.push(null); | ||
| this.append("["); | ||
| this.comma = false; | ||
| return this; | ||
| } | ||
| throw new JSONException("Misplaced array."); | ||
| } | ||
|
|
||
| /** | ||
| * End something. | ||
| * @param mode Mode | ||
| * @param c Closing character | ||
| * @return this | ||
| * @throws JSONException If unbalanced. | ||
| */ | ||
| private JSONWriter end(char mode, char c) throws JSONException { | ||
| if (this.mode != mode) { | ||
| throw new JSONException(mode == 'a' | ||
| ? "Misplaced endArray." | ||
| : "Misplaced endObject."); | ||
| } | ||
| this.pop(mode); | ||
| try { | ||
| this.writer.write(c); | ||
| } catch (IOException e) { | ||
| throw new JSONException(e); | ||
| } | ||
| this.comma = true; | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * End an array. This method most be called to balance calls to | ||
| * <code>array</code>. | ||
| * @return this | ||
| * @throws JSONException If incorrectly nested. | ||
| */ | ||
| public JSONWriter endArray() throws JSONException { | ||
| return this.end('a', ']'); | ||
| } | ||
|
|
||
| /** | ||
| * End an object. This method most be called to balance calls to | ||
| * <code>object</code>. | ||
| * @return this | ||
| * @throws JSONException If incorrectly nested. | ||
| */ | ||
| public JSONWriter endObject() throws JSONException { | ||
| return this.end('k', '}'); | ||
| } | ||
|
|
||
| /** | ||
| * Append a key. The key will be associated with the next value. In an | ||
| * object, every value must be preceded by a key. | ||
| * @param string A key string. | ||
| * @return this | ||
| * @throws JSONException If the key is out of place. For example, keys | ||
| * do not belong in arrays or if the key is null. | ||
| */ | ||
| public JSONWriter key(String string) throws JSONException { | ||
| if (string == null) { | ||
| throw new JSONException("Null key."); | ||
| } | ||
| if (this.mode == 'k') { | ||
| try { | ||
| this.stack[this.top - 1].putOnce(string, Boolean.TRUE); | ||
| if (this.comma) { | ||
| this.writer.write(','); | ||
| } | ||
| this.writer.write(JSONObject.quote(string)); | ||
| this.writer.write(':'); | ||
| this.comma = false; | ||
| this.mode = 'o'; | ||
| return this; | ||
| } catch (IOException e) { | ||
| throw new JSONException(e); | ||
| } | ||
| } | ||
| throw new JSONException("Misplaced key."); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Begin appending a new object. All keys and values until the balancing | ||
| * <code>endObject</code> will be appended to this object. The | ||
| * <code>endObject</code> method must be called to mark the object's end. | ||
| * @return this | ||
| * @throws JSONException If the nesting is too deep, or if the object is | ||
| * started in the wrong place (for example as a key or after the end of the | ||
| * outermost array or object). | ||
| */ | ||
| public JSONWriter object() throws JSONException { | ||
| if (this.mode == 'i') { | ||
| this.mode = 'o'; | ||
| } | ||
| if (this.mode == 'o' || this.mode == 'a') { | ||
| this.append("{"); | ||
| this.push(new JSONObject()); | ||
| this.comma = false; | ||
| return this; | ||
| } | ||
| throw new JSONException("Misplaced object."); | ||
|
|
||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Pop an array or object scope. | ||
| * @param c The scope to close. | ||
| * @throws JSONException If nesting is wrong. | ||
| */ | ||
| private void pop(char c) throws JSONException { | ||
| if (this.top <= 0) { | ||
| throw new JSONException("Nesting error."); | ||
| } | ||
| char m = this.stack[this.top - 1] == null ? 'a' : 'k'; | ||
| if (m != c) { | ||
| throw new JSONException("Nesting error."); | ||
| } | ||
| this.top -= 1; | ||
| this.mode = this.top == 0 | ||
| ? 'd' | ||
| : this.stack[this.top - 1] == null | ||
| ? 'a' | ||
| : 'k'; | ||
| } | ||
|
|
||
| /** | ||
| * Push an array or object scope. | ||
| * @param c The scope to open. | ||
| * @throws JSONException If nesting is too deep. | ||
| */ | ||
| private void push(JSONObject jo) throws JSONException { | ||
| if (this.top >= maxdepth) { | ||
| throw new JSONException("Nesting too deep."); | ||
| } | ||
| this.stack[this.top] = jo; | ||
| this.mode = jo == null ? 'a' : 'k'; | ||
| this.top += 1; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Append either the value <code>true</code> or the value | ||
| * <code>false</code>. | ||
| * @param b A boolean. | ||
| * @return this | ||
| * @throws JSONException | ||
| */ | ||
| public JSONWriter value(boolean b) throws JSONException { | ||
| return this.append(b ? "true" : "false"); | ||
| } | ||
|
|
||
| /** | ||
| * Append a double value. | ||
| * @param d A double. | ||
| * @return this | ||
| * @throws JSONException If the number is not finite. | ||
| */ | ||
| public JSONWriter value(double d) throws JSONException { | ||
| return this.value(new Double(d)); | ||
| } | ||
|
|
||
| /** | ||
| * Append a long value. | ||
| * @param l A long. | ||
| * @return this | ||
| * @throws JSONException | ||
| */ | ||
| public JSONWriter value(long l) throws JSONException { | ||
| return this.append(Long.toString(l)); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Append an object value. | ||
| * @param object The object to append. It can be null, or a Boolean, Number, | ||
| * String, JSONObject, or JSONArray, or an object that implements JSONString. | ||
| * @return this | ||
| * @throws JSONException If the value is out of sequence. | ||
| */ | ||
| public JSONWriter value(Object object) throws JSONException { | ||
| return this.append(JSONObject.valueToString(object)); | ||
| } | ||
| } |
| @@ -0,0 +1,373 @@ | ||
| package org.json; | ||
|
|
||
|
|
||
| /* | ||
| Copyright (c) 2013 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * Kim makes immutable eight bit Unicode strings. If the MSB of a byte is set, | ||
| * then the next byte is a continuation byte. The last byte of a character | ||
| * never has the MSB reset. Every byte that is not the last byte has the MSB | ||
| * set. Kim stands for "Keep it minimal". A Unicode character is never longer | ||
| * than 3 bytes. Every byte contributes 7 bits to the character. ASCII is | ||
| * unmodified. | ||
| * | ||
| * Kim UTF-8 | ||
| * one byte U+007F U+007F | ||
| * two bytes U+3FFF U+07FF | ||
| * three bytes U+10FFF U+FFFF | ||
| * four bytes U+10FFFF | ||
| * | ||
| * Characters in the ranges U+0800..U+3FFF and U+10000..U+10FFFF will be one | ||
| * byte smaller when encoded in Kim compared to UTF-8. | ||
| * | ||
| * Kim is beneficial when using scripts such as Old South Arabian, Aramaic, | ||
| * Avestan, Balinese, Batak, Bopomofo, Buginese, Buhid, Carian, Cherokee, | ||
| * Coptic, Cyrillic, Deseret, Egyptian Hieroglyphs, Ethiopic, Georgian, | ||
| * Glagolitic, Gothic, Hangul Jamo, Hanunoo, Hiragana, Kanbun, Kaithi, | ||
| * Kannada, Katakana, Kharoshthi, Khmer, Lao, Lepcha, Limbu, Lycian, Lydian, | ||
| * Malayalam, Mandaic, Meroitic, Miao, Mongolian, Myanmar, New Tai Lue, | ||
| * Ol Chiki, Old Turkic, Oriya, Osmanya, Pahlavi, Parthian, Phags-Pa, | ||
| * Phoenician, Samaritan, Sharada, Sinhala, Sora Sompeng, Tagalog, Tagbanwa, | ||
| * Takri, Tai Le, Tai Tham, Tamil, Telugu, Thai, Tibetan, Tifinagh, UCAS. | ||
| * | ||
| * A kim object can be constructed from an ordinary UTF-16 string, or from a | ||
| * byte array. A kim object can produce a UTF-16 string. | ||
| * | ||
| * As with UTF-8, it is possible to detect character boundaries within a byte | ||
| * sequence. UTF-8 is one of the world's great inventions. While Kim is more | ||
| * efficient, it is not clear that it is worth the expense of transition. | ||
| * | ||
| * @version 2013-04-18 | ||
| */ | ||
| public class Kim { | ||
|
|
||
| /** | ||
| * The byte array containing the kim's content. | ||
| */ | ||
| private byte[] bytes = null; | ||
|
|
||
| /** | ||
| * The kim's hashcode, conforming to Java's hashcode conventions. | ||
| */ | ||
| private int hashcode = 0; | ||
|
|
||
| /** | ||
| * The number of bytes in the kim. The number of bytes can be as much as | ||
| * three times the number of characters. | ||
| */ | ||
| public int length = 0; | ||
|
|
||
| /** | ||
| * The memoization of toString(). | ||
| */ | ||
| private String string = null; | ||
|
|
||
| /** | ||
| * Make a kim from a portion of a byte array. | ||
| * | ||
| * @param bytes | ||
| * A byte array. | ||
| * @param from | ||
| * The index of the first byte. | ||
| * @param thru | ||
| * The index of the last byte plus one. | ||
| */ | ||
| public Kim(byte[] bytes, int from, int thru) { | ||
|
|
||
| // As the bytes are copied into the new kim, a hashcode is computed using a | ||
| // modified Fletcher code. | ||
|
|
||
| int sum = 1; | ||
| int value; | ||
| this.hashcode = 0; | ||
| this.length = thru - from; | ||
| if (this.length > 0) { | ||
| this.bytes = new byte[this.length]; | ||
| for (int at = 0; at < this.length; at += 1) { | ||
| value = (int) bytes[at + from] & 0xFF; | ||
| sum += value; | ||
| this.hashcode += sum; | ||
| this.bytes[at] = (byte) value; | ||
| } | ||
| this.hashcode += sum << 16; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Make a kim from a byte array. | ||
| * | ||
| * @param bytes | ||
| * The byte array. | ||
| * @param length | ||
| * The number of bytes. | ||
| */ | ||
| public Kim(byte[] bytes, int length) { | ||
| this(bytes, 0, length); | ||
| } | ||
|
|
||
| /** | ||
| * Make a new kim from a substring of an existing kim. The coordinates are | ||
| * in byte units, not character units. | ||
| * | ||
| * @param kim | ||
| * The source of bytes. | ||
| * @param from | ||
| * The point at which to take bytes. | ||
| * @param thru | ||
| * The point at which to stop taking bytes. | ||
| * @return the substring | ||
| */ | ||
| public Kim(Kim kim, int from, int thru) { | ||
| this(kim.bytes, from, thru); | ||
| } | ||
|
|
||
| /** | ||
| * Make a kim from a string. | ||
| * | ||
| * @param string | ||
| * The string. | ||
| * @throws JSONException | ||
| * if surrogate pair mismatch. | ||
| */ | ||
| public Kim(String string) throws JSONException { | ||
| int stringLength = string.length(); | ||
| this.hashcode = 0; | ||
| this.length = 0; | ||
|
|
||
| // First pass: Determine the length of the kim, allowing for the UTF-16 | ||
| // to UTF-32 conversion, and then the UTF-32 to Kim conversion. | ||
|
|
||
| if (stringLength > 0) { | ||
| for (int i = 0; i < stringLength; i += 1) { | ||
| int c = string.charAt(i); | ||
| if (c <= 0x7F) { | ||
| this.length += 1; | ||
| } else if (c <= 0x3FFF) { | ||
| this.length += 2; | ||
| } else { | ||
| if (c >= 0xD800 && c <= 0xDFFF) { | ||
| i += 1; | ||
| int d = string.charAt(i); | ||
| if (c > 0xDBFF || d < 0xDC00 || d > 0xDFFF) { | ||
| throw new JSONException("Bad UTF16"); | ||
| } | ||
| } | ||
| this.length += 3; | ||
| } | ||
| } | ||
|
|
||
| // Second pass: Allocate a byte array and fill that array with the conversion | ||
| // while computing the hashcode. | ||
|
|
||
| this.bytes = new byte[length]; | ||
| int at = 0; | ||
| int b; | ||
| int sum = 1; | ||
| for (int i = 0; i < stringLength; i += 1) { | ||
| int character = string.charAt(i); | ||
| if (character <= 0x7F) { | ||
| bytes[at] = (byte) character; | ||
| sum += character; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| } else if (character <= 0x3FFF) { | ||
| b = 0x80 | (character >>> 7); | ||
| bytes[at] = (byte) b; | ||
| sum += b; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| b = character & 0x7F; | ||
| bytes[at] = (byte) b; | ||
| sum += b; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| } else { | ||
| if (character >= 0xD800 && character <= 0xDBFF) { | ||
| i += 1; | ||
| character = (((character & 0x3FF) << 10) | (string | ||
| .charAt(i) & 0x3FF)) + 65536; | ||
| } | ||
| b = 0x80 | (character >>> 14); | ||
| bytes[at] = (byte) b; | ||
| sum += b; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| b = 0x80 | ((character >>> 7) & 0xFF); | ||
| bytes[at] = (byte) b; | ||
| sum += b; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| b = character & 0x7F; | ||
| bytes[at] = (byte) b; | ||
| sum += b; | ||
| this.hashcode += sum; | ||
| at += 1; | ||
| } | ||
| } | ||
| this.hashcode += sum << 16; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns the character at the specified index. The index refers to byte | ||
| * values and ranges from 0 to length - 1. The index of the next character | ||
| * is at index + Kim.characterSize(kim.characterAt(index)). | ||
| * | ||
| * @param at | ||
| * the index of the char value. The first character is at 0. | ||
| * @returns a Unicode character between 0 and 0x10FFFF. | ||
| * @throws JSONException | ||
| * if at does not point to a valid character. | ||
| */ | ||
| public int characterAt(int at) throws JSONException { | ||
| int c = get(at); | ||
| if ((c & 0x80) == 0) { | ||
| return c; | ||
| } | ||
| int character; | ||
| int c1 = get(at + 1); | ||
| if ((c1 & 0x80) == 0) { | ||
| character = ((c & 0x7F) << 7) | c1; | ||
| if (character > 0x7F) { | ||
| return character; | ||
| } | ||
| } else { | ||
| int c2 = get(at + 2); | ||
| character = ((c & 0x7F) << 14) | ((c1 & 0x7F) << 7) | c2; | ||
| if ((c2 & 0x80) == 0 && character > 0x3FFF && character <= 0x10FFFF | ||
| && (character < 0xD800 || character > 0xDFFF)) { | ||
| return character; | ||
| } | ||
| } | ||
| throw new JSONException("Bad character at " + at); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the number of bytes needed to contain the character in Kim | ||
| * format. | ||
| * | ||
| * @param character | ||
| * a Unicode character between 0 and 0x10FFFF. | ||
| * @return 1, 2, or 3 | ||
| * @throws JSONException | ||
| * if the character is not representable in a kim. | ||
| */ | ||
| public static int characterSize(int character) throws JSONException { | ||
| if (character < 0 || character > 0x10FFFF) { | ||
| throw new JSONException("Bad character " + character); | ||
| } | ||
| return character <= 0x7F ? 1 : character <= 0x3FFF ? 2 : 3; | ||
| } | ||
|
|
||
| /** | ||
| * Copy the contents of this kim to a byte array. | ||
| * | ||
| * @param bytes | ||
| * A byte array of sufficient size. | ||
| * @param at | ||
| * The position within the byte array to take the byes. | ||
| * @return The position immediately after the copy. | ||
| */ | ||
| public int copy(byte[] bytes, int at) { | ||
| System.arraycopy(this.bytes, 0, bytes, at, this.length); | ||
| return at + this.length; | ||
| } | ||
|
|
||
| /** | ||
| * Two kim objects containing exactly the same bytes in the same order are | ||
| * equal to each other. | ||
| * | ||
| * @param obj | ||
| * the other kim with which to compare. | ||
| * @returns true if this and obj are both kim objects containing identical | ||
| * byte sequences. | ||
| */ | ||
| public boolean equals(Object obj) { | ||
| if (!(obj instanceof Kim)) { | ||
| return false; | ||
| } | ||
| Kim that = (Kim) obj; | ||
| if (this == that) { | ||
| return true; | ||
| } | ||
| if (this.hashcode != that.hashcode) { | ||
| return false; | ||
| } | ||
| return java.util.Arrays.equals(this.bytes, that.bytes); | ||
| } | ||
|
|
||
| /** | ||
| * Get a byte from a kim. | ||
| * @param at | ||
| * The position of the byte. The first byte is at 0. | ||
| * @return The byte. | ||
| * @throws JSONException | ||
| * if there is no byte at that position. | ||
| */ | ||
| public int get(int at) throws JSONException { | ||
| if (at < 0 || at > this.length) { | ||
| throw new JSONException("Bad character at " + at); | ||
| } | ||
| return ((int) this.bytes[at]) & 0xFF; | ||
| } | ||
|
|
||
| /** | ||
| * Returns a hash code value for the kim. | ||
| */ | ||
| public int hashCode() { | ||
| return this.hashcode; | ||
| } | ||
|
|
||
| /** | ||
| * Produce a UTF-16 String from this kim. The number of codepoints in the | ||
| * string will not be greater than the number of bytes in the kim, although | ||
| * it could be less. | ||
| * | ||
| * @return The string. A kim memoizes its string representation. | ||
| * @throws JSONException | ||
| * if the kim is not valid. | ||
| */ | ||
| public String toString() throws JSONException { | ||
| if (this.string == null) { | ||
| int c; | ||
| int length = 0; | ||
| char chars[] = new char[this.length]; | ||
| for (int at = 0; at < this.length; at += characterSize(c)) { | ||
| c = this.characterAt(at); | ||
| if (c < 0x10000) { | ||
| chars[length] = (char) c; | ||
| length += 1; | ||
| } else { | ||
| chars[length] = (char) (0xD800 | ((c - 0x10000) >>> 10)); | ||
| length += 1; | ||
| chars[length] = (char) (0xDC00 | (c & 0x03FF)); | ||
| length += 1; | ||
| } | ||
| } | ||
| this.string = new String(chars, 0, length); | ||
| } | ||
| return this.string; | ||
| } | ||
| } |
| @@ -0,0 +1,74 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| import java.util.Enumeration; | ||
| import java.util.Iterator; | ||
| import java.util.Properties; | ||
|
|
||
| /** | ||
| * Converts a Property file data into JSONObject and back. | ||
| * @author JSON.org | ||
| * @version 2013-05-23 | ||
| */ | ||
| public class Property { | ||
| /** | ||
| * Converts a property file object into a JSONObject. The property file object is a table of name value pairs. | ||
| * @param properties java.util.Properties | ||
| * @return JSONObject | ||
| * @throws JSONException | ||
| */ | ||
| public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException { | ||
| JSONObject jo = new JSONObject(); | ||
| if (properties != null && !properties.isEmpty()) { | ||
| Enumeration enumProperties = properties.propertyNames(); | ||
| while(enumProperties.hasMoreElements()) { | ||
| String name = (String)enumProperties.nextElement(); | ||
| jo.put(name, properties.getProperty(name)); | ||
| } | ||
| } | ||
| return jo; | ||
|
|
||
| } | ||
|
|
||
| /** | ||
| * Converts the JSONObject into a property file object. | ||
| * @param jo JSONObject | ||
| * @return java.util.Properties | ||
| * @throws JSONException | ||
| */ | ||
| public static Properties toProperties(JSONObject jo) throws JSONException { | ||
| Properties properties = new Properties(); | ||
| if (jo != null) { | ||
| Iterator keys = jo.keys(); | ||
|
|
||
| while (keys.hasNext()) { | ||
| String name = keys.next().toString(); | ||
| properties.put(name, jo.getString(name)); | ||
| } | ||
| } | ||
| return properties; | ||
| } | ||
| } |
| @@ -0,0 +1,68 @@ | ||
| JSON in Java [package org.json] | ||
|
|
||
| Douglas Crockford | ||
| douglas@crockford.com | ||
|
|
||
| 2011-02-02 | ||
|
|
||
|
|
||
| JSON is a light-weight, language independent, data interchange format. | ||
| See http://www.JSON.org/ | ||
|
|
||
| The files in this package implement JSON encoders/decoders in Java. | ||
| It also includes the capability to convert between JSON and XML, HTTP | ||
| headers, Cookies, and CDL. | ||
|
|
||
| This is a reference implementation. There is a large number of JSON packages | ||
| in Java. Perhaps someday the Java community will standardize on one. Until | ||
| then, choose carefully. | ||
|
|
||
| The license includes this restriction: "The software shall be used for good, | ||
| not evil." If your conscience cannot live with that, then choose a different | ||
| package. | ||
|
|
||
| The package compiles on Java 1.2 thru Java 1.4. | ||
|
|
||
|
|
||
| JSONObject.java: The JSONObject can parse text from a String or a JSONTokener | ||
| to produce a map-like object. The object provides methods for manipulating its | ||
| contents, and for producing a JSON compliant object serialization. | ||
|
|
||
| JSONArray.java: The JSONObject can parse text from a String or a JSONTokener | ||
| to produce a vector-like object. The object provides methods for manipulating | ||
| its contents, and for producing a JSON compliant array serialization. | ||
|
|
||
| JSONTokener.java: The JSONTokener breaks a text into a sequence of individual | ||
| tokens. It can be constructed from a String, Reader, or InputStream. | ||
|
|
||
| JSONException.java: The JSONException is the standard exception type thrown | ||
| by this package. | ||
|
|
||
|
|
||
| JSONString.java: The JSONString interface requires a toJSONString method, | ||
| allowing an object to provide its own serialization. | ||
|
|
||
| JSONStringer.java: The JSONStringer provides a convenient facility for | ||
| building JSON strings. | ||
|
|
||
| JSONWriter.java: The JSONWriter provides a convenient facility for building | ||
| JSON text through a writer. | ||
|
|
||
|
|
||
| CDL.java: CDL provides support for converting between JSON and comma | ||
| delimited lists. | ||
|
|
||
| Cookie.java: Cookie provides support for converting between JSON and cookies. | ||
|
|
||
| CookieList.java: CookieList provides support for converting between JSON and | ||
| cookie lists. | ||
|
|
||
| HTTP.java: HTTP provides support for converting between JSON and HTTP headers. | ||
|
|
||
| HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers. | ||
|
|
||
| XML.java: XML provides support for converting between JSON and XML. | ||
|
|
||
| JSONML.java: JSONML provides support for converting between JSONML and XML. | ||
|
|
||
| XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text. |
| @@ -0,0 +1,365 @@ | ||
| package org.json; | ||
|
|
||
| /* | ||
| Copyright (c) 2002 JSON.org | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| The Software shall be used for Good, not Evil. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| */ | ||
|
|
||
| /** | ||
| * The XMLTokener extends the JSONTokener to provide additional methods | ||
| * for the parsing of XML texts. | ||
| * @author JSON.org | ||
| * @version 2012-11-13 | ||
| */ | ||
| public class XMLTokener extends JSONTokener { | ||
|
|
||
|
|
||
| /** The table of entity values. It initially contains Character values for | ||
| * amp, apos, gt, lt, quot. | ||
| */ | ||
| public static final java.util.HashMap entity; | ||
|
|
||
| static { | ||
| entity = new java.util.HashMap(8); | ||
| entity.put("amp", XML.AMP); | ||
| entity.put("apos", XML.APOS); | ||
| entity.put("gt", XML.GT); | ||
| entity.put("lt", XML.LT); | ||
| entity.put("quot", XML.QUOT); | ||
| } | ||
|
|
||
| /** | ||
| * Construct an XMLTokener from a string. | ||
| * @param s A source string. | ||
| */ | ||
| public XMLTokener(String s) { | ||
| super(s); | ||
| } | ||
|
|
||
| /** | ||
| * Get the text in the CDATA block. | ||
| * @return The string up to the <code>]]></code>. | ||
| * @throws JSONException If the <code>]]></code> is not found. | ||
| */ | ||
| public String nextCDATA() throws JSONException { | ||
| char c; | ||
| int i; | ||
| StringBuffer sb = new StringBuffer(); | ||
| for (;;) { | ||
| c = next(); | ||
| if (end()) { | ||
| throw syntaxError("Unclosed CDATA"); | ||
| } | ||
| sb.append(c); | ||
| i = sb.length() - 3; | ||
| if (i >= 0 && sb.charAt(i) == ']' && | ||
| sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { | ||
| sb.setLength(i); | ||
| return sb.toString(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Get the next XML outer token, trimming whitespace. There are two kinds | ||
| * of tokens: the '<' character which begins a markup tag, and the content | ||
| * text between markup tags. | ||
| * | ||
| * @return A string, or a '<' Character, or null if there is no more | ||
| * source text. | ||
| * @throws JSONException | ||
| */ | ||
| public Object nextContent() throws JSONException { | ||
| char c; | ||
| StringBuffer sb; | ||
| do { | ||
| c = next(); | ||
| } while (Character.isWhitespace(c)); | ||
| if (c == 0) { | ||
| return null; | ||
| } | ||
| if (c == '<') { | ||
| return XML.LT; | ||
| } | ||
| sb = new StringBuffer(); | ||
| for (;;) { | ||
| if (c == '<' || c == 0) { | ||
| back(); | ||
| return sb.toString().trim(); | ||
| } | ||
| if (c == '&') { | ||
| sb.append(nextEntity(c)); | ||
| } else { | ||
| sb.append(c); | ||
| } | ||
| c = next(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Return the next entity. These entities are translated to Characters: | ||
| * <code>& ' > < "</code>. | ||
| * @param ampersand An ampersand character. | ||
| * @return A Character or an entity String if the entity is not recognized. | ||
| * @throws JSONException If missing ';' in XML entity. | ||
| */ | ||
| public Object nextEntity(char ampersand) throws JSONException { | ||
| StringBuffer sb = new StringBuffer(); | ||
| for (;;) { | ||
| char c = next(); | ||
| if (Character.isLetterOrDigit(c) || c == '#') { | ||
| sb.append(Character.toLowerCase(c)); | ||
| } else if (c == ';') { | ||
| break; | ||
| } else { | ||
| throw syntaxError("Missing ';' in XML entity: &" + sb); | ||
| } | ||
| } | ||
| String string = sb.toString(); | ||
| Object object = entity.get(string); | ||
| return object != null ? object : ampersand + string + ";"; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Returns the next XML meta token. This is used for skipping over <!...> | ||
| * and <?...?> structures. | ||
| * @return Syntax characters (<code>< > / = ! ?</code>) are returned as | ||
| * Character, and strings and names are returned as Boolean. We don't care | ||
| * what the values actually are. | ||
| * @throws JSONException If a string is not properly closed or if the XML | ||
| * is badly structured. | ||
| */ | ||
| public Object nextMeta() throws JSONException { | ||
| char c; | ||
| char q; | ||
| do { | ||
| c = next(); | ||
| } while (Character.isWhitespace(c)); | ||
| switch (c) { | ||
| case 0: | ||
| throw syntaxError("Misshaped meta tag"); | ||
| case '<': | ||
| return XML.LT; | ||
| case '>': | ||
| return XML.GT; | ||
| case '/': | ||
| return XML.SLASH; | ||
| case '=': | ||
| return XML.EQ; | ||
| case '!': | ||
| return XML.BANG; | ||
| case '?': | ||
| return XML.QUEST; | ||
| case '"': | ||
| case '\'': | ||
| q = c; | ||
| for (;;) { | ||
| c = next(); | ||
| if (c == 0) { | ||
| throw syntaxError("Unterminated string"); | ||
| } | ||
| if (c == q) { | ||
| return Boolean.TRUE; | ||
| } | ||
| } | ||
| default: | ||
| for (;;) { | ||
| c = next(); | ||
| if (Character.isWhitespace(c)) { | ||
| return Boolean.TRUE; | ||
| } | ||
| switch (c) { | ||
| case 0: | ||
| case '<': | ||
| case '>': | ||
| case '/': | ||
| case '=': | ||
| case '!': | ||
| case '?': | ||
| case '"': | ||
| case '\'': | ||
| back(); | ||
| return Boolean.TRUE; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Get the next XML Token. These tokens are found inside of angle | ||
| * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it | ||
| * may be a string wrapped in single quotes or double quotes, or it may be a | ||
| * name. | ||
| * @return a String or a Character. | ||
| * @throws JSONException If the XML is not well formed. | ||
| */ | ||
| public Object nextToken() throws JSONException { | ||
| char c; | ||
| char q; | ||
| StringBuffer sb; | ||
| do { | ||
| c = next(); | ||
| } while (Character.isWhitespace(c)); | ||
| switch (c) { | ||
| case 0: | ||
| throw syntaxError("Misshaped element"); | ||
| case '<': | ||
| throw syntaxError("Misplaced '<'"); | ||
| case '>': | ||
| return XML.GT; | ||
| case '/': | ||
| return XML.SLASH; | ||
| case '=': | ||
| return XML.EQ; | ||
| case '!': | ||
| return XML.BANG; | ||
| case '?': | ||
| return XML.QUEST; | ||
|
|
||
| // Quoted string | ||
|
|
||
| case '"': | ||
| case '\'': | ||
| q = c; | ||
| sb = new StringBuffer(); | ||
| for (;;) { | ||
| c = next(); | ||
| if (c == 0) { | ||
| throw syntaxError("Unterminated string"); | ||
| } | ||
| if (c == q) { | ||
| return sb.toString(); | ||
| } | ||
| if (c == '&') { | ||
| sb.append(nextEntity(c)); | ||
| } else { | ||
| sb.append(c); | ||
| } | ||
| } | ||
| default: | ||
|
|
||
| // Name | ||
|
|
||
| sb = new StringBuffer(); | ||
| for (;;) { | ||
| sb.append(c); | ||
| c = next(); | ||
| if (Character.isWhitespace(c)) { | ||
| return sb.toString(); | ||
| } | ||
| switch (c) { | ||
| case 0: | ||
| return sb.toString(); | ||
| case '>': | ||
| case '/': | ||
| case '=': | ||
| case '!': | ||
| case '?': | ||
| case '[': | ||
| case ']': | ||
| back(); | ||
| return sb.toString(); | ||
| case '<': | ||
| case '"': | ||
| case '\'': | ||
| throw syntaxError("Bad character in a name"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Skip characters until past the requested string. | ||
| * If it is not found, we are left at the end of the source with a result of false. | ||
| * @param to A string to skip past. | ||
| * @throws JSONException | ||
| */ | ||
| public boolean skipPast(String to) throws JSONException { | ||
| boolean b; | ||
| char c; | ||
| int i; | ||
| int j; | ||
| int offset = 0; | ||
| int length = to.length(); | ||
| char[] circle = new char[length]; | ||
|
|
||
| /* | ||
| * First fill the circle buffer with as many characters as are in the | ||
| * to string. If we reach an early end, bail. | ||
| */ | ||
|
|
||
| for (i = 0; i < length; i += 1) { | ||
| c = next(); | ||
| if (c == 0) { | ||
| return false; | ||
| } | ||
| circle[i] = c; | ||
| } | ||
|
|
||
| /* We will loop, possibly for all of the remaining characters. */ | ||
|
|
||
| for (;;) { | ||
| j = offset; | ||
| b = true; | ||
|
|
||
| /* Compare the circle buffer with the to string. */ | ||
|
|
||
| for (i = 0; i < length; i += 1) { | ||
| if (circle[j] != to.charAt(i)) { | ||
| b = false; | ||
| break; | ||
| } | ||
| j += 1; | ||
| if (j >= length) { | ||
| j -= length; | ||
| } | ||
| } | ||
|
|
||
| /* If we exit the loop with b intact, then victory is ours. */ | ||
|
|
||
| if (b) { | ||
| return true; | ||
| } | ||
|
|
||
| /* Get the next character. If there isn't one, then defeat is ours. */ | ||
|
|
||
| c = next(); | ||
| if (c == 0) { | ||
| return false; | ||
| } | ||
| /* | ||
| * Shove the character in the circle buffer and advance the | ||
| * circle offset. The offset is mod n. | ||
| */ | ||
| circle[offset] = c; | ||
| offset += 1; | ||
| if (offset >= length) { | ||
| offset -= length; | ||
| } | ||
| } | ||
| } | ||
| } |