From 688634ae5a5aaf663159032e67d2132ea61c5d5f Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Sun, 4 May 2014 17:37:41 +0200 Subject: Implement "save" and "load" --- src/org/json/simple/ItemList.java | 158 ++++++ src/org/json/simple/JSONArray.java | 390 ++++++++++++++ src/org/json/simple/JSONAware.java | 14 + src/org/json/simple/JSONObject.java | 143 ++++++ src/org/json/simple/JSONStreamAware.java | 18 + src/org/json/simple/JSONValue.java | 317 ++++++++++++ src/org/json/simple/jsonsimple.gwt.xml | 4 + src/org/json/simple/parser/ContainerFactory.java | 26 + src/org/json/simple/parser/ContentHandler.java | 110 ++++ src/org/json/simple/parser/JSONParser.java | 544 ++++++++++++++++++++ src/org/json/simple/parser/ParseException.java | 92 ++++ src/org/json/simple/parser/Yylex.java | 625 +++++++++++++++++++++++ src/org/json/simple/parser/Yytoken.java | 60 +++ 13 files changed, 2501 insertions(+) create mode 100644 src/org/json/simple/ItemList.java create mode 100644 src/org/json/simple/JSONArray.java create mode 100644 src/org/json/simple/JSONAware.java create mode 100644 src/org/json/simple/JSONObject.java create mode 100644 src/org/json/simple/JSONStreamAware.java create mode 100644 src/org/json/simple/JSONValue.java create mode 100644 src/org/json/simple/jsonsimple.gwt.xml create mode 100644 src/org/json/simple/parser/ContainerFactory.java create mode 100644 src/org/json/simple/parser/ContentHandler.java create mode 100644 src/org/json/simple/parser/JSONParser.java create mode 100644 src/org/json/simple/parser/ParseException.java create mode 100644 src/org/json/simple/parser/Yylex.java create mode 100644 src/org/json/simple/parser/Yytoken.java (limited to 'src/org') diff --git a/src/org/json/simple/ItemList.java b/src/org/json/simple/ItemList.java new file mode 100644 index 0000000..fc98549 --- /dev/null +++ b/src/org/json/simple/ItemList.java @@ -0,0 +1,158 @@ +/* + * $Id: ItemList.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-3-24 + */ +package org.json.simple; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * |a:b:c| => |a|,|b|,|c| |:| => ||,|| |a:| => |a|,|| + * + * @author FangYidong + */ +public class ItemList { + private String sp = ","; + @SuppressWarnings("rawtypes") + List items = new ArrayList(); + + public ItemList() { + } + + public ItemList(final String s) { + this.split(s, this.sp, this.items); + } + + public ItemList(final String s, final String sp) { + this.sp = s; + this.split(s, sp, this.items); + } + + public ItemList(final String s, final String sp, final boolean isMultiToken) { + this.split(s, sp, this.items, isMultiToken); + } + + @SuppressWarnings("rawtypes") + public List getItems() { + return this.items; + } + + public String[] getArray() { + return (String[]) this.items.toArray(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void split(final String s, final String sp, final List append, final boolean isMultiToken) { + if ((s == null) || (sp == null)) { + return; + } + if (isMultiToken) { + final StringTokenizer tokens = new StringTokenizer(s, sp); + while (tokens.hasMoreTokens()) { + append.add(tokens.nextToken().trim()); + } + } else { + this.split(s, sp, append); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void split(final String s, final String sp, final List append) { + if ((s == null) || (sp == null)) { + return; + } + int pos = 0; + int prevPos = 0; + do { + prevPos = pos; + pos = s.indexOf(sp, pos); + if (pos == -1) { + break; + } + append.add(s.substring(prevPos, pos).trim()); + pos += sp.length(); + } while (pos != -1); + append.add(s.substring(prevPos).trim()); + } + + public void setSP(final String sp) { + this.sp = sp; + } + + @SuppressWarnings("unchecked") + public void add(final int i, final String item) { + if (item == null) { + return; + } + this.items.add(i, item.trim()); + } + + @SuppressWarnings("unchecked") + public void add(final String item) { + if (item == null) { + return; + } + this.items.add(item.trim()); + } + + @SuppressWarnings("unchecked") + public void addAll(final ItemList list) { + this.items.addAll(list.items); + } + + public void addAll(final String s) { + this.split(s, this.sp, this.items); + } + + public void addAll(final String s, final String sp) { + this.split(s, sp, this.items); + } + + public void addAll(final String s, final String sp, final boolean isMultiToken) { + this.split(s, sp, this.items, isMultiToken); + } + + /** + * @param i + * 0-based + * @return + */ + public String get(final int i) { + return (String) this.items.get(i); + } + + public int size() { + return this.items.size(); + } + + @Override + public String toString() { + return this.toString(this.sp); + } + + public String toString(final String sp) { + final StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < this.items.size(); i++) { + if (i == 0) { + sb.append(this.items.get(i)); + } else { + sb.append(sp); + sb.append(this.items.get(i)); + } + } + return sb.toString(); + + } + + public void clear() { + this.items.clear(); + } + + public void reset() { + this.sp = ","; + this.items.clear(); + } +} diff --git a/src/org/json/simple/JSONArray.java b/src/org/json/simple/JSONArray.java new file mode 100644 index 0000000..e2c7042 --- /dev/null +++ b/src/org/json/simple/JSONArray.java @@ -0,0 +1,390 @@ +/* + * $Id: JSONArray.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-10 + */ +package org.json.simple; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import rejava.io.StringWriter; +import rejava.io.Writer; + +/** + * A JSON array. JSONObject supports java.util.List interface. + * + * @author FangYidong + */ +public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware { + private static final long serialVersionUID = 3957988303675231981L; + + /** + * Constructs an empty JSONArray. + */ + public JSONArray() { + super(); + } + + /** + * Constructs a JSONArray containing the elements of the specified + * collection, in the order they are returned by the collection's iterator. + * + * @param c + * the collection whose elements are to be placed into this + * JSONArray + */ + public JSONArray(final Collection c) { + super(c); + } + + /** + * Encode a list into JSON text and write it to out. If this list is also a + * JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific + * behaviours will be ignored at this top level. + * + * @see org.json.simple.JSONValue#writeJSONString(Object, Writer) + * + * @param collection + * @param out + */ + public static void writeJSONString(final Collection collection, final Writer out) throws IOException { + if (collection == null) { + out.write("null"); + return; + } + + boolean first = true; + final Iterator iter = collection.iterator(); + + out.write('['); + while (iter.hasNext()) { + if (first) { + first = false; + } else { + out.write(','); + } + + final Object value = iter.next(); + if (value == null) { + out.write("null"); + continue; + } + + JSONValue.writeJSONString(value, out); + } + out.write(']'); + } + + @Override + public void writeJSONString(final Writer out) throws IOException { + JSONArray.writeJSONString(this, out); + } + + /** + * Convert a list to JSON text. The result is a JSON array. If this list is + * also a JSONAware, JSONAware specific behaviours will be omitted at this + * top level. + * + * @see org.json.simple.JSONValue#toJSONString(Object) + * + * @param collection + * @return JSON text, or "null" if list is null. + */ + public static String toJSONString(final Collection collection) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(collection, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final byte[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final byte[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final short[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final short[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final int[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final int[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final long[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final long[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final float[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final float[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final double[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final double[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final boolean[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write(","); + out.write(String.valueOf(array[i])); + } + + out.write("]"); + } + } + + public static String toJSONString(final boolean[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final char[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("[\""); + out.write(String.valueOf(array[0])); + + for (int i = 1; i < array.length; i++) { + out.write("\",\""); + out.write(String.valueOf(array[i])); + } + + out.write("\"]"); + } + } + + public static String toJSONString(final char[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + public static void writeJSONString(final Object[] array, final Writer out) throws IOException { + if (array == null) { + out.write("null"); + } else if (array.length == 0) { + out.write("[]"); + } else { + out.write("["); + JSONValue.writeJSONString(array[0], out); + + for (int i = 1; i < array.length; i++) { + out.write(","); + JSONValue.writeJSONString(array[i], out); + } + + out.write("]"); + } + } + + public static String toJSONString(final Object[] array) { + final StringWriter writer = new StringWriter(); + + try { + JSONArray.writeJSONString(array, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + @Override + public String toJSONString() { + return JSONArray.toJSONString(this); + } + + /** + * Returns a string representation of this array. This is equivalent to + * calling {@link JSONArray#toJSONString()}. + */ + @Override + public String toString() { + return this.toJSONString(); + } +} diff --git a/src/org/json/simple/JSONAware.java b/src/org/json/simple/JSONAware.java new file mode 100644 index 0000000..3ba2ece --- /dev/null +++ b/src/org/json/simple/JSONAware.java @@ -0,0 +1,14 @@ +package org.json.simple; + +/** + * Beans that support customized output of JSON text shall implement this + * interface. + * + * @author FangYidong + */ +public interface JSONAware { + /** + * @return JSON text + */ + String toJSONString(); +} diff --git a/src/org/json/simple/JSONObject.java b/src/org/json/simple/JSONObject.java new file mode 100644 index 0000000..55eeeb6 --- /dev/null +++ b/src/org/json/simple/JSONObject.java @@ -0,0 +1,143 @@ +/* + * $Id: JSONObject.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-10 + */ +package org.json.simple; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import rejava.io.StringWriter; +import rejava.io.Writer; + +/** + * A JSON object. Key value pairs are unordered. JSONObject supports + * java.util.Map interface. + * + * @author FangYidong + */ +@SuppressWarnings("rawtypes") +public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware { + + private static final long serialVersionUID = -503443796854799292L; + + public JSONObject() { + super(); + } + + /** + * Allows creation of a JSONObject from a Map. After that, both the + * generated JSONObject and the Map can be modified independently. + * + * @param map + */ + @SuppressWarnings({ "unchecked" }) + public JSONObject(final Map map) { + super(map); + } + + /** + * Encode a map into JSON text and write it to out. If this map is also a + * JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific + * behaviours will be ignored at this top level. + * + * @see org.json.simple.JSONValue#writeJSONString(Object, Writer) + * + * @param map + * @param out + */ + public static void writeJSONString(final Map map, final Writer out) throws IOException { + if (map == null) { + out.write("null"); + return; + } + + boolean first = true; + final Iterator iter = map.entrySet().iterator(); + + out.write('{'); + while (iter.hasNext()) { + if (first) { + first = false; + } else { + out.write(','); + } + final Map.Entry entry = (Map.Entry) iter.next(); + out.write('\"'); + out.write(JSONObject.escape(String.valueOf(entry.getKey()))); + out.write('\"'); + out.write(':'); + JSONValue.writeJSONString(entry.getValue(), out); + } + out.write('}'); + } + + @Override + public void writeJSONString(final Writer out) throws IOException { + JSONObject.writeJSONString(this, out); + } + + /** + * Convert a map to JSON text. The result is a JSON object. If this map is + * also a JSONAware, JSONAware specific behaviours will be omitted at this + * top level. + * + * @see org.json.simple.JSONValue#toJSONString(Object) + * + * @param map + * @return JSON text, or "null" if map is null. + */ + public static String toJSONString(final Map map) { + final StringWriter writer = new StringWriter(); + + try { + JSONObject.writeJSONString(map, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen with a StringWriter + throw new RuntimeException(e); + } + } + + @Override + public String toJSONString() { + return JSONObject.toJSONString(this); + } + + @Override + public String toString() { + return this.toJSONString(); + } + + public static String toString(final String key, final Object value) { + final StringBuffer sb = new StringBuffer(); + sb.append('\"'); + if (key == null) { + sb.append("null"); + } else { + JSONValue.escape(key, sb); + } + sb.append('\"').append(':'); + + sb.append(JSONValue.toJSONString(value)); + + return sb.toString(); + } + + /** + * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters + * (U+0000 through U+001F). It's the same as JSONValue.escape() only for + * compatibility here. + * + * @see org.json.simple.JSONValue#escape(String) + * + * @param s + * @return + */ + public static String escape(final String s) { + return JSONValue.escape(s); + } + +} diff --git a/src/org/json/simple/JSONStreamAware.java b/src/org/json/simple/JSONStreamAware.java new file mode 100644 index 0000000..561634d --- /dev/null +++ b/src/org/json/simple/JSONStreamAware.java @@ -0,0 +1,18 @@ +package org.json.simple; + +import java.io.IOException; + +import rejava.io.Writer; + +/** + * Beans that support customized output of JSON text to a writer shall implement + * this interface. + * + * @author FangYidong + */ +public interface JSONStreamAware { + /** + * write JSON string to out. + */ + void writeJSONString(Writer out) throws IOException; +} diff --git a/src/org/json/simple/JSONValue.java b/src/org/json/simple/JSONValue.java new file mode 100644 index 0000000..3d42315 --- /dev/null +++ b/src/org/json/simple/JSONValue.java @@ -0,0 +1,317 @@ +/* + * $Id: JSONValue.java,v 1.1 2006/04/15 14:37:04 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple; + +import java.io.IOException; +import java.util.Collection; +// import java.util.List; +import java.util.Map; + +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import rejava.io.Reader; +import rejava.io.StringReader; +import rejava.io.StringWriter; +import rejava.io.Writer; + +/** + * @author FangYidong + */ +public class JSONValue { + /** + * Parse JSON text into java object from the input source. Please use + * parseWithException() if you don't want to ignore the exception. + * + * @see org.json.simple.parser.JSONParser#parse(Reader) + * @see #parseWithException(Reader) + * + * @param in + * @return Instance of the following: org.json.simple.JSONObject, + * org.json.simple.JSONArray, java.lang.String, java.lang.Number, + * java.lang.Boolean, null + * + * @deprecated this method may throw an {@code Error} instead of returning + * {@code null}; please use + * {@link JSONValue#parseWithException(Reader)} instead + */ + @Deprecated + public static Object parse(final Reader in) { + try { + final JSONParser parser = new JSONParser(); + return parser.parse(in); + } catch (final Exception e) { + return null; + } + } + + /** + * Parse JSON text into java object from the given string. Please use + * parseWithException() if you don't want to ignore the exception. + * + * @see org.json.simple.parser.JSONParser#parse(Reader) + * @see #parseWithException(Reader) + * + * @param s + * @return Instance of the following: org.json.simple.JSONObject, + * org.json.simple.JSONArray, java.lang.String, java.lang.Number, + * java.lang.Boolean, null + * + * @deprecated this method may throw an {@code Error} instead of returning + * {@code null}; please use + * {@link JSONValue#parseWithException(String)} instead + */ + @Deprecated + public static Object parse(final String s) { + final StringReader in = new StringReader(s); + return JSONValue.parse(in); + } + + /** + * Parse JSON text into java object from the input source. + * + * @see org.json.simple.parser.JSONParser + * + * @param in + * @return Instance of the following: org.json.simple.JSONObject, + * org.json.simple.JSONArray, java.lang.String, java.lang.Number, + * java.lang.Boolean, null + * + * @throws IOException + * @throws ParseException + */ + public static Object parseWithException(final Reader in) throws IOException, ParseException { + final JSONParser parser = new JSONParser(); + return parser.parse(in); + } + + public static Object parseWithException(final String s) throws ParseException { + final JSONParser parser = new JSONParser(); + return parser.parse(s); + } + + /** + * Encode an object into JSON text and write it to out. + *

+ * If this object is a Map or a List, and it's also a JSONStreamAware or a + * JSONAware, JSONStreamAware or JSONAware will be considered firstly. + *

+ * DO NOT call this method from writeJSONString(Writer) of a class that + * implements both JSONStreamAware and (Map or List) with "this" as the + * first parameter, use JSONObject.writeJSONString(Map, Writer) or + * JSONArray.writeJSONString(List, Writer) instead. + * + * @see org.json.simple.JSONObject#writeJSONString(Map, Writer) + * @see org.json.simple.JSONArray#writeJSONString(List, Writer) + * + * @param value + * @param writer + */ + @SuppressWarnings("rawtypes") + public static void writeJSONString(final Object value, final Writer out) throws IOException { + if (value == null) { + out.write("null"); + return; + } + + if (value instanceof String) { + out.write('\"'); + out.write(JSONValue.escape((String) value)); + out.write('\"'); + return; + } + + if (value instanceof Double) { + if (((Double) value).isInfinite() || ((Double) value).isNaN()) { + out.write("null"); + } else { + out.write(value.toString()); + } + return; + } + + if (value instanceof Float) { + if (((Float) value).isInfinite() || ((Float) value).isNaN()) { + out.write("null"); + } else { + out.write(value.toString()); + } + return; + } + + if (value instanceof Number) { + out.write(value.toString()); + return; + } + + if (value instanceof Boolean) { + out.write(value.toString()); + return; + } + + if ((value instanceof JSONStreamAware)) { + ((JSONStreamAware) value).writeJSONString(out); + return; + } + + if ((value instanceof JSONAware)) { + out.write(((JSONAware) value).toJSONString()); + return; + } + + if (value instanceof Map) { + JSONObject.writeJSONString((Map) value, out); + return; + } + + if (value instanceof Collection) { + JSONArray.writeJSONString((Collection) value, out); + return; + } + + if (value instanceof byte[]) { + JSONArray.writeJSONString((byte[]) value, out); + return; + } + + if (value instanceof short[]) { + JSONArray.writeJSONString((short[]) value, out); + return; + } + + if (value instanceof int[]) { + JSONArray.writeJSONString((int[]) value, out); + return; + } + + if (value instanceof long[]) { + JSONArray.writeJSONString((long[]) value, out); + return; + } + + if (value instanceof float[]) { + JSONArray.writeJSONString((float[]) value, out); + return; + } + + if (value instanceof double[]) { + JSONArray.writeJSONString((double[]) value, out); + return; + } + + if (value instanceof boolean[]) { + JSONArray.writeJSONString((boolean[]) value, out); + return; + } + + if (value instanceof char[]) { + JSONArray.writeJSONString((char[]) value, out); + return; + } + + if (value instanceof Object[]) { + JSONArray.writeJSONString((Object[]) value, out); + return; + } + + out.write(value.toString()); + } + + /** + * Convert an object to JSON text. + *

+ * If this object is a Map or a List, and it's also a JSONAware, JSONAware + * will be considered firstly. + *

+ * DO NOT call this method from toJSONString() of a class that implements + * both JSONAware and Map or List with "this" as the parameter, use + * JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead. + * + * @see org.json.simple.JSONObject#toJSONString(Map) + * @see org.json.simple.JSONArray#toJSONString(List) + * + * @param value + * @return JSON text, or "null" if value is null or it's an NaN or an INF + * number. + */ + public static String toJSONString(final Object value) { + final StringWriter writer = new StringWriter(); + + try { + JSONValue.writeJSONString(value, writer); + return writer.toString(); + } catch (final IOException e) { + // This should never happen for a StringWriter + throw new RuntimeException(e); + } + } + + /** + * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters + * (U+0000 through U+001F). + * + * @param s + * @return + */ + public static String escape(final String s) { + if (s == null) { + return null; + } + final StringBuffer sb = new StringBuffer(); + JSONValue.escape(s, sb); + return sb.toString(); + } + + /** + * @param s + * - Must not be null. + * @param sb + */ + static void escape(final String s, final StringBuffer sb) { + final int len = s.length(); + for (int i = 0; i < len; i++) { + final char ch = s.charAt(i); + switch (ch) { + case '"': + sb.append("\\\""); + break; + case '\\': + sb.append("\\\\"); + break; + case '\b': + sb.append("\\b"); + break; + case '\f': + sb.append("\\f"); + break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\t': + sb.append("\\t"); + break; + case '/': + sb.append("\\/"); + break; + default: + // Reference: http://www.unicode.org/versions/Unicode5.1.0/ + if (((ch >= '\u0000') && (ch <= '\u001F')) || ((ch >= '\u007F') && (ch <= '\u009F')) || ((ch >= '\u2000') && (ch <= '\u20FF'))) { + final String ss = Integer.toHexString(ch); + sb.append("\\u"); + for (int k = 0; k < (4 - ss.length()); k++) { + sb.append('0'); + } + sb.append(ss.toUpperCase()); + } else { + sb.append(ch); + } + } + }// for + } + +} diff --git a/src/org/json/simple/jsonsimple.gwt.xml b/src/org/json/simple/jsonsimple.gwt.xml new file mode 100644 index 0000000..f24da1b --- /dev/null +++ b/src/org/json/simple/jsonsimple.gwt.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/org/json/simple/parser/ContainerFactory.java b/src/org/json/simple/parser/ContainerFactory.java new file mode 100644 index 0000000..182a899 --- /dev/null +++ b/src/org/json/simple/parser/ContainerFactory.java @@ -0,0 +1,26 @@ +package org.json.simple.parser; + +import java.util.List; +import java.util.Map; + +/** + * Container factory for creating containers for JSON object and JSON array. + * + * @see org.json.simple.parser.JSONParser#parse(java.io.Reader, + * ContainerFactory) + * + * @author FangYidong + */ +public interface ContainerFactory { + /** + * @return A Map instance to store JSON object, or null if you want to use + * org.json.simple.JSONObject. + */ + Map createObjectContainer(); + + /** + * @return A List instance to store JSON array, or null if you want to use + * org.json.simple.JSONArray. + */ + List creatArrayContainer(); +} diff --git a/src/org/json/simple/parser/ContentHandler.java b/src/org/json/simple/parser/ContentHandler.java new file mode 100644 index 0000000..a704485 --- /dev/null +++ b/src/org/json/simple/parser/ContentHandler.java @@ -0,0 +1,110 @@ +package org.json.simple.parser; + +import java.io.IOException; + +/** + * A simplified and stoppable SAX-like content handler for stream processing of + * JSON text. + * + * @see org.xml.sax.ContentHandler + * @see org.json.simple.parser.JSONParser#parse(rejava.io.Reader, + * ContentHandler, boolean) + * + * @author FangYidong + */ +public interface ContentHandler { + /** + * Receive notification of the beginning of JSON processing. The parser will + * invoke this method only once. + * + * @throws ParseException + * - JSONParser will stop and throw the same exception to the + * caller when receiving this exception. + */ + void startJSON() throws ParseException, IOException; + + /** + * Receive notification of the end of JSON processing. + * + * @throws ParseException + */ + void endJSON() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON object. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * - JSONParser will stop and throw the same exception to the + * caller when receiving this exception. + * @see #endJSON + */ + boolean startObject() throws ParseException, IOException; + + /** + * Receive notification of the end of a JSON object. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startObject + */ + boolean endObject() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON object entry. + * + * @param key + * - Key of a JSON object entry. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #endObjectEntry + */ + boolean startObjectEntry(String key) throws ParseException, IOException; + + /** + * Receive notification of the end of the value of previous object entry. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startObjectEntry + */ + boolean endObjectEntry() throws ParseException, IOException; + + /** + * Receive notification of the beginning of a JSON array. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #endArray + */ + boolean startArray() throws ParseException, IOException; + + /** + * Receive notification of the end of a JSON array. + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + * + * @see #startArray + */ + boolean endArray() throws ParseException, IOException; + + /** + * Receive notification of the JSON primitive values: java.lang.String, + * java.lang.Number, java.lang.Boolean null + * + * @param value + * - Instance of the following: java.lang.String, + * java.lang.Number, java.lang.Boolean null + * + * @return false if the handler wants to stop parsing after return. + * @throws ParseException + */ + boolean primitive(Object value) throws ParseException, IOException; + +} diff --git a/src/org/json/simple/parser/JSONParser.java b/src/org/json/simple/parser/JSONParser.java new file mode 100644 index 0000000..4874eea --- /dev/null +++ b/src/org/json/simple/parser/JSONParser.java @@ -0,0 +1,544 @@ +/* + * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple.parser; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import rejava.io.Reader; +import rejava.io.StringReader; + +/** + * Parser for JSON text. Please note that JSONParser is NOT thread-safe. + * + * @author FangYidong + */ +public class JSONParser { + public static final int S_INIT = 0; + public static final int S_IN_FINISHED_VALUE = 1;// string,number,boolean,null,object,array + public static final int S_IN_OBJECT = 2; + public static final int S_IN_ARRAY = 3; + public static final int S_PASSED_PAIR_KEY = 4; + public static final int S_IN_PAIR_VALUE = 5; + public static final int S_END = 6; + public static final int S_IN_ERROR = -1; + + private LinkedList handlerStatusStack; + private final Yylex lexer = new Yylex((Reader) null); + private Yytoken token = null; + private int status = JSONParser.S_INIT; + + private int peekStatus(final LinkedList statusStack) { + if (statusStack.size() == 0) { + return -1; + } + final Integer status = (Integer) statusStack.getFirst(); + return status.intValue(); + } + + /** + * Reset the parser to the initial state without resetting the underlying + * reader. + * + */ + public void reset() { + this.token = null; + this.status = JSONParser.S_INIT; + this.handlerStatusStack = null; + } + + /** + * Reset the parser to the initial state with a new character reader. + * + * @param in + * - The new character reader. + * @throws IOException + * @throws ParseException + */ + public void reset(final Reader in) { + this.lexer.yyreset(in); + this.reset(); + } + + /** + * @return The position of the beginning of the current token. + */ + public int getPosition() { + return this.lexer.getPosition(); + } + + public Object parse(final String s) throws ParseException { + return this.parse(s, (ContainerFactory) null); + } + + public Object parse(final String s, final ContainerFactory containerFactory) throws ParseException { + final StringReader in = new StringReader(s); + try { + return this.parse(in, containerFactory); + } catch (final IOException ie) { + /* + * Actually it will never happen. + */ + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); + } + } + + public Object parse(final Reader in) throws IOException, ParseException { + return this.parse(in, (ContainerFactory) null); + } + + /** + * Parse JSON text into java object from the input source. + * + * @param in + * @param containerFactory + * - Use this factory to createyour own JSON object and JSON + * array containers. + * @return Instance of the following: org.json.simple.JSONObject, + * org.json.simple.JSONArray, java.lang.String, java.lang.Number, + * java.lang.Boolean, null + * + * @throws IOException + * @throws ParseException + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object parse(final Reader in, final ContainerFactory containerFactory) throws IOException, ParseException { + this.reset(in); + final LinkedList statusStack = new LinkedList(); + final LinkedList valueStack = new LinkedList(); + + try { + do { + this.nextToken(); + switch (this.status) { + case S_INIT: + switch (this.token.type) { + case Yytoken.TYPE_VALUE: + this.status = JSONParser.S_IN_FINISHED_VALUE; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(this.token.value); + break; + case Yytoken.TYPE_LEFT_BRACE: + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(this.createObjectContainer(containerFactory)); + break; + case Yytoken.TYPE_LEFT_SQUARE: + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(this.createArrayContainer(containerFactory)); + break; + default: + this.status = JSONParser.S_IN_ERROR; + }// inner switch + break; + + case S_IN_FINISHED_VALUE: + if (this.token.type == Yytoken.TYPE_EOF) { + return valueStack.removeFirst(); + } else { + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } + + case S_IN_OBJECT: + switch (this.token.type) { + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if (this.token.value instanceof String) { + final String key = (String) this.token.value; + valueStack.addFirst(key); + this.status = JSONParser.S_PASSED_PAIR_KEY; + statusStack.addFirst(new Integer(this.status)); + } else { + this.status = JSONParser.S_IN_ERROR; + } + break; + case Yytoken.TYPE_RIGHT_BRACE: + if (valueStack.size() > 1) { + statusStack.removeFirst(); + valueStack.removeFirst(); + this.status = this.peekStatus(statusStack); + } else { + this.status = JSONParser.S_IN_FINISHED_VALUE; + } + break; + default: + this.status = JSONParser.S_IN_ERROR; + break; + }// inner switch + break; + + case S_PASSED_PAIR_KEY: + switch (this.token.type) { + case Yytoken.TYPE_COLON: + break; + case Yytoken.TYPE_VALUE: + statusStack.removeFirst(); + String key = (String) valueStack.removeFirst(); + Map parent = (Map) valueStack.getFirst(); + parent.put(key, this.token.value); + this.status = this.peekStatus(statusStack); + break; + case Yytoken.TYPE_LEFT_SQUARE: + statusStack.removeFirst(); + key = (String) valueStack.removeFirst(); + parent = (Map) valueStack.getFirst(); + final List newArray = this.createArrayContainer(containerFactory); + parent.put(key, newArray); + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(newArray); + break; + case Yytoken.TYPE_LEFT_BRACE: + statusStack.removeFirst(); + key = (String) valueStack.removeFirst(); + parent = (Map) valueStack.getFirst(); + final Map newObject = this.createObjectContainer(containerFactory); + parent.put(key, newObject); + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(newObject); + break; + default: + this.status = JSONParser.S_IN_ERROR; + } + break; + + case S_IN_ARRAY: + switch (this.token.type) { + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + List val = (List) valueStack.getFirst(); + val.add(this.token.value); + break; + case Yytoken.TYPE_RIGHT_SQUARE: + if (valueStack.size() > 1) { + statusStack.removeFirst(); + valueStack.removeFirst(); + this.status = this.peekStatus(statusStack); + } else { + this.status = JSONParser.S_IN_FINISHED_VALUE; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + val = (List) valueStack.getFirst(); + final Map newObject = this.createObjectContainer(containerFactory); + val.add(newObject); + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(newObject); + break; + case Yytoken.TYPE_LEFT_SQUARE: + val = (List) valueStack.getFirst(); + final List newArray = this.createArrayContainer(containerFactory); + val.add(newArray); + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + valueStack.addFirst(newArray); + break; + default: + this.status = JSONParser.S_IN_ERROR; + }// inner switch + break; + case S_IN_ERROR: + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + }// switch + if (this.status == JSONParser.S_IN_ERROR) { + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } + } while (this.token.type != Yytoken.TYPE_EOF); + } catch (final IOException ie) { + throw ie; + } + + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } + + private void nextToken() throws ParseException, IOException { + this.token = this.lexer.yylex(); + if (this.token == null) { + this.token = new Yytoken(Yytoken.TYPE_EOF, null); + } + } + + private Map createObjectContainer(final ContainerFactory containerFactory) { + if (containerFactory == null) { + return new JSONObject(); + } + final Map m = containerFactory.createObjectContainer(); + + if (m == null) { + return new JSONObject(); + } + return m; + } + + private List createArrayContainer(final ContainerFactory containerFactory) { + if (containerFactory == null) { + return new JSONArray(); + } + final List l = containerFactory.creatArrayContainer(); + + if (l == null) { + return new JSONArray(); + } + return l; + } + + public void parse(final String s, final ContentHandler contentHandler) throws ParseException { + this.parse(s, contentHandler, false); + } + + public void parse(final String s, final ContentHandler contentHandler, final boolean isResume) throws ParseException { + final StringReader in = new StringReader(s); + try { + this.parse(in, contentHandler, isResume); + } catch (final IOException ie) { + /* + * Actually it will never happen. + */ + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); + } + } + + public void parse(final Reader in, final ContentHandler contentHandler) throws IOException, ParseException { + this.parse(in, contentHandler, false); + } + + /** + * Stream processing of JSON text. + * + * @see ContentHandler + * + * @param in + * @param contentHandler + * @param isResume + * - Indicates if it continues previous parsing operation. If set + * to true, resume parsing the old stream, and parameter 'in' + * will be ignored. If this method is called for the first time + * in this instance, isResume will be ignored. + * + * @throws IOException + * @throws ParseException + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void parse(final Reader in, final ContentHandler contentHandler, boolean isResume) throws IOException, ParseException { + if (!isResume) { + this.reset(in); + this.handlerStatusStack = new LinkedList<>(); + } else { + if (this.handlerStatusStack == null) { + isResume = false; + this.reset(in); + this.handlerStatusStack = new LinkedList<>(); + } + } + + final LinkedList statusStack = this.handlerStatusStack; + + try { + do { + switch (this.status) { + case S_INIT: + contentHandler.startJSON(); + this.nextToken(); + switch (this.token.type) { + case Yytoken.TYPE_VALUE: + this.status = JSONParser.S_IN_FINISHED_VALUE; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.primitive(this.token.value)) { + return; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startObject()) { + return; + } + break; + case Yytoken.TYPE_LEFT_SQUARE: + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startArray()) { + return; + } + break; + default: + this.status = JSONParser.S_IN_ERROR; + }// inner switch + break; + + case S_IN_FINISHED_VALUE: + this.nextToken(); + if (this.token.type == Yytoken.TYPE_EOF) { + contentHandler.endJSON(); + this.status = JSONParser.S_END; + return; + } else { + this.status = JSONParser.S_IN_ERROR; + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } + + case S_IN_OBJECT: + this.nextToken(); + switch (this.token.type) { + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if (this.token.value instanceof String) { + final String key = (String) this.token.value; + this.status = JSONParser.S_PASSED_PAIR_KEY; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startObjectEntry(key)) { + return; + } + } else { + this.status = JSONParser.S_IN_ERROR; + } + break; + case Yytoken.TYPE_RIGHT_BRACE: + if (statusStack.size() > 1) { + statusStack.removeFirst(); + this.status = this.peekStatus(statusStack); + } else { + this.status = JSONParser.S_IN_FINISHED_VALUE; + } + if (!contentHandler.endObject()) { + return; + } + break; + default: + this.status = JSONParser.S_IN_ERROR; + break; + }// inner switch + break; + + case S_PASSED_PAIR_KEY: + this.nextToken(); + switch (this.token.type) { + case Yytoken.TYPE_COLON: + break; + case Yytoken.TYPE_VALUE: + statusStack.removeFirst(); + this.status = this.peekStatus(statusStack); + if (!contentHandler.primitive(this.token.value)) { + return; + } + if (!contentHandler.endObjectEntry()) { + return; + } + break; + case Yytoken.TYPE_LEFT_SQUARE: + statusStack.removeFirst(); + statusStack.addFirst(new Integer(JSONParser.S_IN_PAIR_VALUE)); + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startArray()) { + return; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + statusStack.removeFirst(); + statusStack.addFirst(new Integer(JSONParser.S_IN_PAIR_VALUE)); + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startObject()) { + return; + } + break; + default: + this.status = JSONParser.S_IN_ERROR; + } + break; + + case S_IN_PAIR_VALUE: + /* + * S_IN_PAIR_VALUE is just a marker to indicate the end of + * an object entry, it doesn't proccess any token, therefore + * delay consuming token until next round. + */ + statusStack.removeFirst(); + this.status = this.peekStatus(statusStack); + if (!contentHandler.endObjectEntry()) { + return; + } + break; + + case S_IN_ARRAY: + this.nextToken(); + switch (this.token.type) { + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if (!contentHandler.primitive(this.token.value)) { + return; + } + break; + case Yytoken.TYPE_RIGHT_SQUARE: + if (statusStack.size() > 1) { + statusStack.removeFirst(); + this.status = this.peekStatus(statusStack); + } else { + this.status = JSONParser.S_IN_FINISHED_VALUE; + } + if (!contentHandler.endArray()) { + return; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + this.status = JSONParser.S_IN_OBJECT; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startObject()) { + return; + } + break; + case Yytoken.TYPE_LEFT_SQUARE: + this.status = JSONParser.S_IN_ARRAY; + statusStack.addFirst(new Integer(this.status)); + if (!contentHandler.startArray()) { + return; + } + break; + default: + this.status = JSONParser.S_IN_ERROR; + }// inner switch + break; + + case S_END: + return; + + case S_IN_ERROR: + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + }// switch + if (this.status == JSONParser.S_IN_ERROR) { + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } + } while (this.token.type != Yytoken.TYPE_EOF); + } catch (final IOException ie) { + this.status = JSONParser.S_IN_ERROR; + throw ie; + } catch (final ParseException pe) { + this.status = JSONParser.S_IN_ERROR; + throw pe; + } catch (final RuntimeException re) { + this.status = JSONParser.S_IN_ERROR; + throw re; + } catch (final Error e) { + this.status = JSONParser.S_IN_ERROR; + throw e; + } + + this.status = JSONParser.S_IN_ERROR; + throw new ParseException(this.getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, this.token); + } +} diff --git a/src/org/json/simple/parser/ParseException.java b/src/org/json/simple/parser/ParseException.java new file mode 100644 index 0000000..df1b1d1 --- /dev/null +++ b/src/org/json/simple/parser/ParseException.java @@ -0,0 +1,92 @@ +package org.json.simple.parser; + +/** + * ParseException explains why and where the error occurs in source JSON text. + * + * @author FangYidong + * + */ +public class ParseException extends Exception { + private static final long serialVersionUID = -7880698968187728547L; + + public static final int ERROR_UNEXPECTED_CHAR = 0; + public static final int ERROR_UNEXPECTED_TOKEN = 1; + public static final int ERROR_UNEXPECTED_EXCEPTION = 2; + + private int errorType; + private Object unexpectedObject; + private int position; + + public ParseException(final int errorType) { + this(-1, errorType, null); + } + + public ParseException(final int errorType, final Object unexpectedObject) { + this(-1, errorType, unexpectedObject); + } + + public ParseException(final int position, final int errorType, final Object unexpectedObject) { + this.position = position; + this.errorType = errorType; + this.unexpectedObject = unexpectedObject; + } + + public int getErrorType() { + return this.errorType; + } + + public void setErrorType(final int errorType) { + this.errorType = errorType; + } + + /** + * @see org.json.simple.parser.JSONParser#getPosition() + * + * @return The character position (starting with 0) of the input where the + * error occurs. + */ + public int getPosition() { + return this.position; + } + + public void setPosition(final int position) { + this.position = position; + } + + /** + * @see org.json.simple.parser.Yytoken + * + * @return One of the following base on the value of errorType: + * ERROR_UNEXPECTED_CHAR java.lang.Character ERROR_UNEXPECTED_TOKEN + * org.json.simple.parser.Yytoken ERROR_UNEXPECTED_EXCEPTION + * java.lang.Exception + */ + public Object getUnexpectedObject() { + return this.unexpectedObject; + } + + public void setUnexpectedObject(final Object unexpectedObject) { + this.unexpectedObject = unexpectedObject; + } + + @Override + public String getMessage() { + final StringBuffer sb = new StringBuffer(); + + switch (this.errorType) { + case ERROR_UNEXPECTED_CHAR: + sb.append("Unexpected character (").append(this.unexpectedObject).append(") at position ").append(this.position).append("."); + break; + case ERROR_UNEXPECTED_TOKEN: + sb.append("Unexpected token ").append(this.unexpectedObject).append(" at position ").append(this.position).append("."); + break; + case ERROR_UNEXPECTED_EXCEPTION: + sb.append("Unexpected exception at position ").append(this.position).append(": ").append(this.unexpectedObject); + break; + default: + sb.append("Unkown error at position ").append(this.position).append("."); + break; + } + return sb.toString(); + } +} diff --git a/src/org/json/simple/parser/Yylex.java b/src/org/json/simple/parser/Yylex.java new file mode 100644 index 0000000..1ccf1b4 --- /dev/null +++ b/src/org/json/simple/parser/Yylex.java @@ -0,0 +1,625 @@ +/* The following code was generated by JFlex 1.4.2 */ + +package org.json.simple.parser; + +class Yylex { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int STRING_BEGIN = 2; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l at the + * beginning of a line l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { 0, 0, 1, 1 }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = "\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5" + "\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21" + "\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20" + "\5\0\1\25\1\0\1\26\uff82\0"; + + /** + * Translates characters to character classes + */ + private static final char[] ZZ_CMAP = Yylex.zzUnpackCMap(Yylex.ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int[] ZZ_ACTION = Yylex.zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = "\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0" + "\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24" + "\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0" + "\1\30"; + + private static int[] zzUnpackAction() { + final int[] result = new int[45]; + int offset = 0; + offset = Yylex.zzUnpackAction(Yylex.ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(final String packed, final int offset, final int[] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + final int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + final int value = packed.charAt(i++); + do { + result[j++] = value; + } while (--count > 0); + } + return j; + } + + /** + * Translates a state to a row index in the transition table + */ + private static final int[] ZZ_ROWMAP = Yylex.zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66" + "\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195" + "\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66" + "\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252" + "\0\66\0\66\0\u026d\0\u0288\0\66"; + + private static int[] zzUnpackRowMap() { + final int[] result = new int[45]; + int offset = 0; + offset = Yylex.zzUnpackRowMap(Yylex.ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(final String packed, final int offset, final int[] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + final int l = packed.length(); + while (i < l) { + final int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int ZZ_TRANS[] = { 2, 2, 3, 4, 2, 2, 2, 5, 2, 6, 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, 2, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, + 16, 16, 16, 16, 16, 16, 16, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 35, -1, -1, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, 42, -1, 42, -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1, 44, -1, 44, -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, -1, -1, -1, -1, }; + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { "Unkown internal scanner error", "Error: could not match input", "Error: pushback value was too large" }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int[] ZZ_ATTRIBUTE = Yylex.zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = "\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" + "\2\0\1\11"; + + private static int[] zzUnpackAttribute() { + final int[] result = new int[45]; + int offset = 0; + offset = Yylex.zzUnpackAttribute(Yylex.ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(final String packed, final int offset, final int[] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + final int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + final int value = packed.charAt(i++); + do { + result[j++] = value; + } while (--count > 0); + } + return j; + } + + /** the input device */ + private rejava.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = Yylex.YYINITIAL; + + /** + * this buffer contains the current text to be matched and is the source of + * the yytext() string + */ + private char zzBuffer[] = new char[Yylex.ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** + * endRead marks the last character in the buffer, that has been read from + * input + */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + // private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + // private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + // private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ + private StringBuffer sb = new StringBuffer(); + + int getPosition() { + return this.yychar; + } + + /** + * Creates a new scanner There is also a java.io.InputStream version of this + * constructor. + * + * @param in + * the java.io.Reader to read input from. + */ + Yylex(final rejava.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. There is also java.io.Reader version of this + * constructor. + * + * @param in + * the java.io.Inputstream to read input from. + */ + // Yylex(java.io.InputStream in) { + // this(new java.io.InputStreamReader(in)); + // } + + /** + * Unpacks the compressed character translation table. + * + * @param packed + * the packed character translation table + * @return the unpacked character translation table + */ + private static char[] zzUnpackCMap(final String packed) { + final char[] m