From d65cf1822b908124a29d0b37e11a9f64a7627dfb Mon Sep 17 00:00:00 2001 From: fangyidong Date: Tue, 25 Nov 2008 13:25:49 +0000 Subject: [PATCH] init --- .classpath | 8 + .project | 17 + AUTHORS.txt | 1 + ChangeLog.txt | 11 + LICENSE.txt | 202 ++++++ README.txt | 153 +++++ VERSION.txt | 1 + build.xml | 32 + doc/json.lex | 47 ++ lib/json_simple-1.0.1.jar | Bin 0 -> 10770 bytes src/org/json/simple/ItemList.java | 147 ++++ src/org/json/simple/JSONArray.java | 31 + src/org/json/simple/JSONObject.java | 100 +++ src/org/json/simple/JSONValue.java | 36 + src/org/json/simple/parser/JSONParser.java | 190 ++++++ src/org/json/simple/parser/Yylex.java | 736 +++++++++++++++++++++ src/org/json/simple/parser/Yytoken.java | 31 + src/org/json/simple/rope/Node.java | 12 + src/org/json/simple/rope/Rope.java | 68 ++ svn-commit.tmp | 1 + test.xml | 49 ++ test/org/json/simple/Test.java | 75 +++ test/org/json/simple/parser/YylexTest.java | 52 ++ test/org/json/simple/rope/RopeTest.java | 44 ++ 24 files changed, 2044 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 AUTHORS.txt create mode 100644 ChangeLog.txt create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100644 VERSION.txt create mode 100644 build.xml create mode 100644 doc/json.lex create mode 100644 lib/json_simple-1.0.1.jar 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/JSONObject.java create mode 100644 src/org/json/simple/JSONValue.java create mode 100644 src/org/json/simple/parser/JSONParser.java create mode 100644 src/org/json/simple/parser/Yylex.java create mode 100644 src/org/json/simple/parser/Yytoken.java create mode 100644 src/org/json/simple/rope/Node.java create mode 100644 src/org/json/simple/rope/Rope.java create mode 100644 svn-commit.tmp create mode 100644 test.xml create mode 100644 test/org/json/simple/Test.java create mode 100644 test/org/json/simple/parser/YylexTest.java create mode 100644 test/org/json/simple/rope/RopeTest.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..bddcb9d --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..6715d34 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + json.simple + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 0000000..f5ff495 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1 @@ +Fang Yidong \ No newline at end of file diff --git a/ChangeLog.txt b/ChangeLog.txt new file mode 100644 index 0000000..1030c68 --- /dev/null +++ b/ChangeLog.txt @@ -0,0 +1,11 @@ +ChangeLog + +Version 1.01 (2008/08/26) +* License changed to a more commerce friendly and clear one, Apache License 2.0 +* Use JFlex to generate a faster Yylex.java +* Added Rope.java to get faster string operations +* Separate test codes from source codes +* Added ant build file build.xml + +Version 1.0 (2006/04/15) +* Initial version diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..ec4d4ca --- /dev/null +++ b/README.txt @@ -0,0 +1,153 @@ +Simple Java toolkit for JSON (JSON.simple) +========================================== + +http://www.JSON.org/java/json_simple.zip + +1.Why the Simple Java toolkit (also named as JSON.simple) for JSON? + + When I use JSON as the data exchange format between the AJAX client and JSP + for the first time, what worry me mostly is how to encode Java strings and + numbers correctly in the server side so the AJAX client will receive a well + formed JSON data. When I looked into the 'JSON in Java' directory in JSON + website,I found that wrappers to JSONObject and JSONArray can be simpler, + due to the simplicity of JSON itself. So I wrote the JSON.simple package. + +2.Is it simple,really? + + I think so. Take an example: + + import org.json.simple.JSONObject; + + JSONObject obj=new JSONObject(); + obj.put("name","foo"); + obj.put("num",new Integer(100)); + obj.put("balance",new Double(1000.21)); + obj.put("is_vip",new Boolean(true)); + obj.put("nickname",null); + System.out.print(obj); + + Result: + {"nickname":null,"num":100,"balance":1000.21,"is_vip":true,"name":"foo"} + + The JSONObject.toString() will escape controls and specials correctly. + +3.How to use JSON.simple in JSP? + + Take an example in JSP: + + <%@page contentType="text/html; charset=UTF-8"%> + <%@page import="org.json.simple.JSONObject"%> + <% + JSONObject obj=new JSONObject(); + obj.put("name","foo"); + obj.put("num",new Integer(100)); + obj.put("balance",new Double(1000.21)); + obj.put("is_vip",new Boolean(true)); + obj.put("nickname",null); + out.print(obj); + out.flush(); + %> + + So the AJAX client will get the responseText. + +4.Some details about JSONObject? + + JSONObject inherits java.util.HashMap,so it don't have to worry about the + mapping things between keys and values. Feel free to use the Map methods + like get(), put(), and remove() and others. JSONObject.toString() will + combine key value pairs to get the JSON data string. Values will be escaped + into JSON quote string format if it's an instance of java.lang.String. Other + type of instance like java.lang.Number,java.lang.Boolean,null,JSONObject and + JSONArray will NOT escape, just take their java.lang.String.valueOf() result. + null value will be the JSON 'null' in the result. + + It's still correct if you put an instance of JSONObject or JSONArray into an + instance of JSONObject or JSONArray. Take the example about: + + JSONObject obj2=new JSONObject(); + obj2.put("phone","123456"); + obj2.put("zip","7890"); + obj.put("contact",obj2); + System.out.print(obj); + + Result: + {"nickname":null,"num":100,"contact":{"phone":"123456","zip":"7890"},"balance":1000.21,"is_vip":true,"name":"foo"} + + The method JSONObject.escape() is used to escape Java string into JSON quote + string. Controls and specials will be escaped correctly into \b,\f,\r,\n,\t, + \",\\,\/,\uhhhh. + +5.Some detail about JSONArray? + + org.json.simple.JSONArray inherits java.util.ArrayList. Feel free to use the + List methods like get(),add(),remove(),iterator() and so on. The rules of + JSONArray.toString() is similar to JSONObject.toString(). Here's the example: + + import org.json.simple.JSONArray; + + JSONArray array=new JSONArray(); + array.add("hello"); + array.add(new Integer(123)); + array.add(new Boolean(false)); + array.add(null); + array.add(new Double(123.45)); + array.add(obj2);//see above + System.out.print(array); + + Result: + ["hello",123,false,null,123.45,{"phone":"123456","zip":"7890"}] + +6.What is JSONValue for? + + org.json.simple.JSONValue is use to parse JSON data into Java Object. + In JSON, the topmost entity is JSON value, not the JSON object. But + it's not necessary to wrap JSON string,boolean,number and null again, + for the Java has already had the according classes: java.lang.String, + java.lang.Boolean,java.lang.Number and null. The mapping is: + + JSON Java + ------------------------------------------------ + string <=> java.lang.String + number <=> java.lang.Number + true|false <=> java.lang.Boolean + null <=> null + array <=> org.json.simple.JSONArray + object <=> org.json.simple.JSONObject + ------------------------------------------------ + + JSONValue has only one kind of method, JSONValue.parse(), which receives + a java.io.Reader or java.lang.String. Return type of JSONValue.parse() + is according to the mapping above. If the input is incorrect in syntax or + there's exceptions during the parsing, I choose to return null, ignoring + the exception: I have no idea if it's a serious implementaion, but I think + it's convenient to the user. + + Here's the example: + + String s="[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]"; + Object obj=JSONValue.parse(s); + JSONArray array=(JSONArray)obj; + System.out.println(array.get(1)); + JSONObject obj2=(JSONObject)array.get(1); + System.out.println(obj2.get("1")); + + Result: + {"1":{"2":{"3":{"4":[5,{"6":7}]}}}} + {"2":{"3":{"4":[5,{"6":7}]}}} + +7.About the author. + + I'm a Java EE developer on Linux. + I'm working on web systems and information retrieval systems. + I also develop 3D games and Flash games. + + You can contact me through: + Fang Yidong + Fang Yidong + +8.Project home. + + http://code.google.com/p/json-simple/ + + +http://www.JSON.org/java/json_simple.zip \ No newline at end of file diff --git a/VERSION.txt b/VERSION.txt new file mode 100644 index 0000000..7f20734 --- /dev/null +++ b/VERSION.txt @@ -0,0 +1 @@ +1.0.1 \ No newline at end of file diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..b7acbc7 --- /dev/null +++ b/build.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/json.lex b/doc/json.lex new file mode 100644 index 0000000..ec5f05c --- /dev/null +++ b/doc/json.lex @@ -0,0 +1,47 @@ +package org.json.simple.parser; + +import org.json.simple.rope.Rope; + +%% + +%{ +private Rope sb=new Rope(); + +%} + +%switch +%unicode +%state STRING_BEGIN + +HEX_D = [a-fA-F0-9] +INT = [-]?[0-9]+ +DOUBLE = {INT}((\.[0-9]+)?([eE][-+]?[0-9]+)?) +WS = [ \t\r\n] +%% + + \\\" {sb.append('"');} + \\\\ {sb.append('\\');} + \\\/ {sb.append('/');} + \\b {sb.append('\b');} + \\f {sb.append('\f');} + \\n {sb.append('\n');} + \\r {sb.append('\r');} + \\t {sb.append('\t');} + \\u{HEX_D}{HEX_D}{HEX_D}{HEX_D} { int ch=Integer.parseInt(yytext().substring(2),16); + sb.append((char)ch); + } + + \" { yybegin(YYINITIAL);return new Yytoken(Yytoken.TYPE_VALUE,sb.toString());} + . { sb.append(yytext());} + \" { sb.clear();yybegin(STRING_BEGIN);} + {INT} { Long val=Long.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);} + {DOUBLE} { Double val=Double.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);} + "true"|"false" { Boolean val=Boolean.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);} + "null" { return new Yytoken(Yytoken.TYPE_VALUE,null);} + "{" { return new Yytoken(Yytoken.TYPE_LEFT_BRACE,null);} + "}" { return new Yytoken(Yytoken.TYPE_RIGHT_BRACE,null);} + "[" { return new Yytoken(Yytoken.TYPE_LEFT_SQUARE,null);} + "]" { return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE,null);} + "," { return new Yytoken(Yytoken.TYPE_COMMA,null);} + ":" { return new Yytoken(Yytoken.TYPE_COLON,null);} + {WS} {} diff --git a/lib/json_simple-1.0.1.jar b/lib/json_simple-1.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..e856c14b6795bb86cbbb59eafe0d9da71173f04e GIT binary patch literal 10770 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 L@{&iA{rL5N?h&lu literal 0 HcmV?d00001 diff --git a/src/org/json/simple/ItemList.java b/src/org/json/simple/ItemList.java new file mode 100644 index 0000000..07231e6 --- /dev/null +++ b/src/org/json/simple/ItemList.java @@ -0,0 +1,147 @@ +/* + * $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=","; + List items=new ArrayList(); + + + public ItemList(){} + + + public ItemList(String s){ + this.split(s,sp,items); + } + + public ItemList(String s,String sp){ + this.sp=s; + this.split(s,sp,items); + } + + public ItemList(String s,String sp,boolean isMultiToken){ + split(s,sp,items,isMultiToken); + } + + public List getItems(){ + return this.items; + } + + public String[] getArray(){ + return (String[])this.items.toArray(); + } + + public void split(String s,String sp,List append,boolean isMultiToken){ + if(s==null || sp==null) + return; + if(isMultiToken){ + StringTokenizer tokens=new StringTokenizer(s,sp); + while(tokens.hasMoreTokens()){ + append.add(tokens.nextToken().trim()); + } + } + else{ + this.split(s,sp,append); + } + } + + public void split(String s,String sp,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(String sp){ + this.sp=sp; + } + + public void add(int i,String item){ + if(item==null) + return; + items.add(i,item.trim()); + } + + public void add(String item){ + if(item==null) + return; + items.add(item.trim()); + } + + public void addAll(ItemList list){ + items.addAll(list.items); + } + + public void addAll(String s){ + this.split(s,sp,items); + } + + public void addAll(String s,String sp){ + this.split(s,sp,items); + } + + public void addAll(String s,String sp,boolean isMultiToken){ + this.split(s,sp,items,isMultiToken); + } + + /** + * @param i 0-based + * @return + */ + public String get(int i){ + return (String)items.get(i); + } + + public int size(){ + return items.size(); + } + + public String toString(){ + return toString(sp); + } + + public String toString(String sp){ + StringBuffer sb=new StringBuffer(); + + for(int i=0;i + */ +public class JSONArray extends ArrayList { + public String toString(){ + ItemList list=new ItemList(); + + Iterator iter=iterator(); + + while(iter.hasNext()){ + Object value=iter.next(); + if(value instanceof String){ + list.add("\""+JSONObject.escape((String)value)+"\""); + } + else + list.add(String.valueOf(value)); + } + return "["+list.toString()+"]"; + } + +} diff --git a/src/org/json/simple/JSONObject.java b/src/org/json/simple/JSONObject.java new file mode 100644 index 0000000..387411a --- /dev/null +++ b/src/org/json/simple/JSONObject.java @@ -0,0 +1,100 @@ +/* + * $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.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author FangYidong + */ +public class JSONObject extends HashMap{ + + public String toString(){ + ItemList list=new ItemList(); + Iterator iter=entrySet().iterator(); + + while(iter.hasNext()){ + Map.Entry entry=(Map.Entry)iter.next(); + list.add(toString(entry.getKey().toString(),entry.getValue())); + } + return "{"+list.toString()+"}"; + } + + public static String toString(String key,Object value){ + StringBuffer sb=new StringBuffer(); + + sb.append("\""); + sb.append(escape(key)); + sb.append("\":"); + if(value==null){ + sb.append("null"); + return sb.toString(); + } + + if(value instanceof String){ + sb.append("\""); + sb.append(escape((String)value)); + sb.append("\""); + } + else + sb.append(value); + return sb.toString(); + } + + /** + * " => \" , \ => \\ + * @param s + * @return + */ + public static String escape(String s){ + if(s==null) + return null; + StringBuffer sb=new StringBuffer(); + for(int i=0;i='\u0000' && ch<='\u001F'){ + 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 + return sb.toString(); + } +} diff --git a/src/org/json/simple/JSONValue.java b/src/org/json/simple/JSONValue.java new file mode 100644 index 0000000..662a1b9 --- /dev/null +++ b/src/org/json/simple/JSONValue.java @@ -0,0 +1,36 @@ +/* + * $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.Reader; +import java.io.StringReader; + +import org.json.simple.parser.JSONParser; + + +/** + * @author FangYidong + */ +public class JSONValue { + /** + * parse into java object from input source. + * @param in + * @return instance of : JSONObject,JSONArray,String,Boolean,Long,Double or null + */ + public static Object parse(Reader in){ + try{ + JSONParser parser=new JSONParser(); + return parser.parse(in); + } + catch(Exception e){ + return null; + } + } + + public static Object parse(String s){ + StringReader in=new StringReader(s); + return parse(in); + } +} diff --git a/src/org/json/simple/parser/JSONParser.java b/src/org/json/simple/parser/JSONParser.java new file mode 100644 index 0000000..e58d276 --- /dev/null +++ b/src/org/json/simple/parser/JSONParser.java @@ -0,0 +1,190 @@ +/* + * $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.Reader; +import java.util.LinkedList; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + + +/** + * @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_ERROR=-1; + + private int peekStatus(LinkedList statusStack){ + if(statusStack.size()==0) + return -1; + Integer status=(Integer)statusStack.getFirst(); + return status.intValue(); + } + + public Object parse(Reader in) throws Exception{ + LinkedList statusStack=new LinkedList(); + LinkedList valueStack=new LinkedList(); + Yylex lexer=new Yylex(in); + Yytoken token=null; + int status=S_INIT; + + try{ + do{ + token=lexer.yylex(); + if(token==null) + token=new Yytoken(Yytoken.TYPE_EOF,null); + switch(status){ + case S_INIT: + switch(token.type){ + case Yytoken.TYPE_VALUE: + status=S_IN_FINISHED_VALUE; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(token.value); + break; + case Yytoken.TYPE_LEFT_BRACE: + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(new JSONObject()); + break; + case Yytoken.TYPE_LEFT_SQUARE: + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(new JSONArray()); + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + + case S_IN_FINISHED_VALUE: + if(token.type==Yytoken.TYPE_EOF) + return valueStack.removeFirst(); + else + return null; + + case S_IN_OBJECT: + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + if(token.value instanceof String){ + String key=(String)token.value; + valueStack.addFirst(key); + status=S_PASSED_PAIR_KEY; + statusStack.addFirst(new Integer(status)); + } + else{ + status=S_IN_ERROR; + } + break; + case Yytoken.TYPE_RIGHT_BRACE: + if(valueStack.size()>1){ + statusStack.removeFirst(); + valueStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + break; + default: + status=S_IN_ERROR; + break; + }//inner switch + break; + + case S_PASSED_PAIR_KEY: + switch(token.type){ + case Yytoken.TYPE_COLON: + break; + case Yytoken.TYPE_VALUE: + statusStack.removeFirst(); + String key=(String)valueStack.removeFirst(); + JSONObject parent=(JSONObject)valueStack.getFirst(); + parent.put(key,token.value); + status=peekStatus(statusStack); + break; + case Yytoken.TYPE_LEFT_SQUARE: + statusStack.removeFirst(); + key=(String)valueStack.removeFirst(); + parent=(JSONObject)valueStack.getFirst(); + JSONArray newArray=new JSONArray(); + parent.put(key,newArray); + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newArray); + break; + case Yytoken.TYPE_LEFT_BRACE: + statusStack.removeFirst(); + key=(String)valueStack.removeFirst(); + parent=(JSONObject)valueStack.getFirst(); + JSONObject newObject=new JSONObject(); + parent.put(key,newObject); + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newObject); + break; + default: + status=S_IN_ERROR; + } + break; + + case S_IN_ARRAY: + switch(token.type){ + case Yytoken.TYPE_COMMA: + break; + case Yytoken.TYPE_VALUE: + JSONArray val=(JSONArray)valueStack.getFirst(); + val.add(token.value); + break; + case Yytoken.TYPE_RIGHT_SQUARE: + if(valueStack.size()>1){ + statusStack.removeFirst(); + valueStack.removeFirst(); + status=peekStatus(statusStack); + } + else{ + status=S_IN_FINISHED_VALUE; + } + break; + case Yytoken.TYPE_LEFT_BRACE: + val=(JSONArray)valueStack.getFirst(); + JSONObject newObject=new JSONObject(); + val.add(newObject); + status=S_IN_OBJECT; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newObject); + break; + case Yytoken.TYPE_LEFT_SQUARE: + val=(JSONArray)valueStack.getFirst(); + JSONArray newArray=new JSONArray(); + val.add(newArray); + status=S_IN_ARRAY; + statusStack.addFirst(new Integer(status)); + valueStack.addFirst(newArray); + break; + default: + status=S_IN_ERROR; + }//inner switch + break; + case S_IN_ERROR: + return null; + }//switch + if(status==S_IN_ERROR) + return null; + }while(token.type!=Yytoken.TYPE_EOF); + } + catch(Exception e){ + throw e; + } + return null; + } +} diff --git a/src/org/json/simple/parser/Yylex.java b/src/org/json/simple/parser/Yylex.java new file mode 100644 index 0000000..229670d --- /dev/null +++ b/src/org/json/simple/parser/Yylex.java @@ -0,0 +1,736 @@ +/* The following code was generated by JFlex 1.4.2 on 2008-11-25 */ + +package org.json.simple.parser; + +import org.json.simple.rope.Rope; + +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\21\2\0\1\7\22\0\1\7\1\0\1\11\10\0"+ + "\1\6\1\32\1\2\1\4\1\12\12\3\1\33\6\0\4\1\1\5"+ + "\1\1\24\0\1\30\1\10\1\31\3\0\1\23\1\13\2\1\1\22"+ + "\1\14\5\0\1\24\1\0\1\15\3\0\1\16\1\25\1\17\1\20"+ + "\5\0\1\26\1\0\1\27\uff82\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\3\0\1\1\1\2\1\3\3\0\1\4\1\5\1\6"+ + "\1\7\1\10\1\11\2\12\1\13\5\0\1\14\1\15"+ + "\1\16\1\17\1\20\1\21\1\22\1\23\1\0\1\24"+ + "\1\0\1\24\4\0\1\25\1\26\2\0\1\27"; + + private static int [] zzUnpackAction() { + int [] result = new int[44]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* 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" + }; + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[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 Rope sb=new Rope(); + + + + /** + * 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(java.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(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 90) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead > 0) { + zzEndRead+= numRead; + return false; + } + // unlikely but not impossible: read 0 characters, but not at end of stream + if (numRead == 0) { + int c = zzReader.read(); + if (c == -1) { + return true; + } else { + zzBuffer[zzEndRead++] = (char) c; + return false; + } + } + + // numRead < 0 + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Yytoken yylex() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + zzInput = zzCMapL[zzInput]; + + boolean zzIsFinal = false; + boolean zzNoLookAhead = false; + + zzForNext: { switch (zzState) { + case 0: + switch (zzInput) { + case 2: zzState = 2; break zzForNext; + case 3: zzIsFinal = true; zzState = 3; break zzForNext; + case 7: + case 17: zzIsFinal = true; zzNoLookAhead = true; zzState = 4; break zzForNext; + case 9: zzIsFinal = true; zzNoLookAhead = true; zzState = 5; break zzForNext; + case 12: zzState = 6; break zzForNext; + case 13: zzState = 7; break zzForNext; + case 15: zzState = 8; break zzForNext; + case 22: zzIsFinal = true; zzNoLookAhead = true; zzState = 9; break zzForNext; + case 23: zzIsFinal = true; zzNoLookAhead = true; zzState = 10; break zzForNext; + case 24: zzIsFinal = true; zzNoLookAhead = true; zzState = 11; break zzForNext; + case 25: zzIsFinal = true; zzNoLookAhead = true; zzState = 12; break zzForNext; + case 26: zzIsFinal = true; zzNoLookAhead = true; zzState = 13; break zzForNext; + case 27: zzIsFinal = true; zzNoLookAhead = true; zzState = 14; break zzForNext; + default: break zzForAction; + } + + case 1: + switch (zzInput) { + case 8: zzIsFinal = true; zzState = 16; break zzForNext; + case 9: zzIsFinal = true; zzNoLookAhead = true; zzState = 17; break zzForNext; + case 17: break zzForAction; + default: zzIsFinal = true; zzNoLookAhead = true; zzState = 15; break zzForNext; + } + + case 2: + switch (zzInput) { + case 3: zzIsFinal = true; zzState = 3; break zzForNext; + default: break zzForAction; + } + + case 3: + switch (zzInput) { + case 3: zzIsFinal = true; break zzForNext; + case 4: zzState = 18; break zzForNext; + case 5: + case 18: zzState = 19; break zzForNext; + default: break zzForAction; + } + + case 6: + switch (zzInput) { + case 19: zzState = 20; break zzForNext; + default: break zzForAction; + } + + case 7: + switch (zzInput) { + case 16: zzState = 21; break zzForNext; + default: break zzForAction; + } + + case 8: + switch (zzInput) { + case 14: zzState = 22; break zzForNext; + default: break zzForAction; + } + + case 16: + switch (zzInput) { + case 8: zzIsFinal = true; zzNoLookAhead = true; zzState = 23; break zzForNext; + case 9: zzIsFinal = true; zzNoLookAhead = true; zzState = 24; break zzForNext; + case 10: zzIsFinal = true; zzNoLookAhead = true; zzState = 25; break zzForNext; + case 11: zzIsFinal = true; zzNoLookAhead = true; zzState = 26; break zzForNext; + case 12: zzIsFinal = true; zzNoLookAhead = true; zzState = 27; break zzForNext; + case 13: zzIsFinal = true; zzNoLookAhead = true; zzState = 28; break zzForNext; + case 14: zzIsFinal = true; zzNoLookAhead = true; zzState = 29; break zzForNext; + case 15: zzIsFinal = true; zzNoLookAhead = true; zzState = 30; break zzForNext; + case 16: zzState = 31; break zzForNext; + default: break zzForAction; + } + + case 18: + switch (zzInput) { + case 3: zzIsFinal = true; zzState = 32; break zzForNext; + default: break zzForAction; + } + + case 19: + switch (zzInput) { + case 2: + case 6: zzState = 33; break zzForNext; + case 3: zzIsFinal = true; zzState = 34; break zzForNext; + default: break zzForAction; + } + + case 20: + switch (zzInput) { + case 20: zzState = 35; break zzForNext; + default: break zzForAction; + } + + case 21: + switch (zzInput) { + case 20: zzState = 36; break zzForNext; + default: break zzForAction; + } + + case 22: + switch (zzInput) { + case 16: zzState = 37; break zzForNext; + default: break zzForAction; + } + + case 31: + switch (zzInput) { + case 1: + case 3: + case 5: + case 11: + case 12: + case 18: + case 19: zzState = 38; break zzForNext; + default: break zzForAction; + } + + case 32: + switch (zzInput) { + case 5: + case 18: zzState = 19; break zzForNext; + case 3: zzIsFinal = true; break zzForNext; + default: break zzForAction; + } + + case 33: + switch (zzInput) { + case 3: zzIsFinal = true; zzState = 34; break zzForNext; + default: break zzForAction; + } + + case 34: + switch (zzInput) { + case 3: zzIsFinal = true; break zzForNext; + default: break zzForAction; + } + + case 35: + switch (zzInput) { + case 21: zzState = 37; break zzForNext; + default: break zzForAction; + } + + case 36: + switch (zzInput) { + case 20: zzIsFinal = true; zzNoLookAhead = true; zzState = 39; break zzForNext; + default: break zzForAction; + } + + case 37: + switch (zzInput) { + case 18: zzIsFinal = true; zzNoLookAhead = true; zzState = 40; break zzForNext; + default: break zzForAction; + } + + case 38: + switch (zzInput) { + case 1: + case 3: + case 5: + case 11: + case 12: + case 18: + case 19: zzState = 41; break zzForNext; + default: break zzForAction; + } + + case 41: + switch (zzInput) { + case 1: + case 3: + case 5: + case 11: + case 12: + case 18: + case 19: zzState = 42; break zzForNext; + default: break zzForAction; + } + + case 42: + switch (zzInput) { + case 1: + case 3: + case 5: + case 11: + case 12: + case 18: + case 19: zzIsFinal = true; zzNoLookAhead = true; zzState = 43; break zzForNext; + default: break zzForAction; + } + + default: + // if this is ever reached, there is a serious bug in JFlex + zzScanError(ZZ_UNKNOWN_ERROR); + break; + } } + + if ( zzIsFinal ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( zzNoLookAhead ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 10: + { sb.append(yytext()); + } + case 24: break; + case 3: + { sb.clear();yybegin(STRING_BEGIN); + } + case 25: break; + case 15: + { sb.append('\b'); + } + case 26: break; + case 5: + { return new Yytoken(Yytoken.TYPE_RIGHT_BRACE,null); + } + case 27: break; + case 12: + { sb.append('\\'); + } + case 28: break; + case 20: + { Double val=Double.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val); + } + case 29: break; + case 1: + { Long val=Long.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val); + } + case 30: break; + case 7: + { return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE,null); + } + case 31: break; + case 18: + { sb.append('\r'); + } + case 32: break; + case 21: + { return new Yytoken(Yytoken.TYPE_VALUE,null); + } + case 33: break; + case 14: + { sb.append('/'); + } + case 34: break; + case 9: + { return new Yytoken(Yytoken.TYPE_COLON,null); + } + case 35: break; + case 11: + { yybegin(YYINITIAL);return new Yytoken(Yytoken.TYPE_VALUE,sb.toString()); + } + case 36: break; + case 13: + { sb.append('"'); + } + case 37: break; + case 4: + { return new Yytoken(Yytoken.TYPE_LEFT_BRACE,null); + } + case 38: break; + case 16: + { sb.append('\f'); + } + case 39: break; + case 19: + { sb.append('\t'); + } + case 40: break; + case 6: + { return new Yytoken(Yytoken.TYPE_LEFT_SQUARE,null); + } + case 41: break; + case 23: + { int ch=Integer.parseInt(yytext().substring(2),16); + sb.append((char)ch); + } + case 42: break; + case 22: + { Boolean val=Boolean.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val); + } + case 43: break; + case 17: + { sb.append('\n'); + } + case 44: break; + case 8: + { return new Yytoken(Yytoken.TYPE_COMMA,null); + } + case 45: break; + case 2: + { + } + case 46: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/src/org/json/simple/parser/Yytoken.java b/src/org/json/simple/parser/Yytoken.java new file mode 100644 index 0000000..46bfe64 --- /dev/null +++ b/src/org/json/simple/parser/Yytoken.java @@ -0,0 +1,31 @@ +/* + * $Id: Yytoken.java,v 1.1 2006/04/15 14:10:48 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple.parser; + +/** + * @author FangYidong + */ +public class Yytoken { + public static final int TYPE_VALUE=0;//JSON primitive value: string,number,boolean,null + public static final int TYPE_LEFT_BRACE=1; + public static final int TYPE_RIGHT_BRACE=2; + public static final int TYPE_LEFT_SQUARE=3; + public static final int TYPE_RIGHT_SQUARE=4; + public static final int TYPE_COMMA=5; + public static final int TYPE_COLON=6; + public static final int TYPE_EOF=-1;//end of file + + public int type=0; + public Object value=null; + + public Yytoken(int type,Object value){ + this.type=type; + this.value=value; + } + + public String toString(){ + return String.valueOf(type+"=>|"+value+"|"); + } +} diff --git a/src/org/json/simple/rope/Node.java b/src/org/json/simple/rope/Node.java new file mode 100644 index 0000000..a172ef2 --- /dev/null +++ b/src/org/json/simple/rope/Node.java @@ -0,0 +1,12 @@ +package org.json.simple.rope; + +class Node { + static final int TYPE_STR = 0; + static final int TYPE_CH = 1; + static final int TYPE_UNKNOWN = -1; + + int type = TYPE_UNKNOWN; + Node next; + char content_ch; + String content_str; +} diff --git a/src/org/json/simple/rope/Rope.java b/src/org/json/simple/rope/Rope.java new file mode 100644 index 0000000..8c23496 --- /dev/null +++ b/src/org/json/simple/rope/Rope.java @@ -0,0 +1,68 @@ +package org.json.simple.rope; + +public class Rope { + private Node first; + private Node current; + private int count = 0; + + public void clear(){ + count = 0; + first = null; + current = null; + } + + public int length(){ + return count; + } + + public String toString(){ + if(count == 0) + return ""; + + char[] chs = new char[count]; + int pos = 0; + + Node p = first; + do{ + if(p.type == Node.TYPE_CH){ + chs[pos] = p.content_ch; + pos++; + } + else{ + int len = p.content_str.length(); + p.content_str.getChars(0, len, chs, pos); + pos += len; + } + p = p.next; + }while(p != null); + + return new String(chs); + } + + public void append(char ch){ + Node node = new Node(); + node.type = Node.TYPE_CH; + node.content_ch = ch; + if(first == null) + first = node; + if(current != null) + current.next = node; + current = node; + count++; + } + + public void append(String s){ + if(s == null || s.equals("")) + return; + + Node node = new Node(); + node.type = Node.TYPE_STR; + node.content_str = s; + if(first == null) + first = node; + if(current != null) + current.next = node; + current = node; + count += s.length(); + } +} diff --git a/svn-commit.tmp b/svn-commit.tmp new file mode 100644 index 0000000..8cae831 --- /dev/null +++ b/svn-commit.tmp @@ -0,0 +1 @@ +init diff --git a/test.xml b/test.xml new file mode 100644 index 0000000..2265e9f --- /dev/null +++ b/test.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/org/json/simple/Test.java b/test/org/json/simple/Test.java new file mode 100644 index 0000000..be2ed57 --- /dev/null +++ b/test/org/json/simple/Test.java @@ -0,0 +1,75 @@ +/* + * $Id: Test.java,v 1.1 2006/04/15 14:40:06 platform Exp $ + * Created on 2006-4-15 + */ +package org.json.simple; + +import junit.framework.TestCase; + + +/** + * @author FangYidong + */ +public class Test extends TestCase{ + + public void testDecode() throws Exception{ + System.out.println("=======decode======="); + + String s="[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]"; + Object obj=JSONValue.parse(s); + JSONArray array=(JSONArray)obj; + System.out.println("======the 2nd element of array======"); + System.out.println(array.get(1)); + System.out.println(); + assertEquals("{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}",array.get(1).toString()); + + JSONObject obj2=(JSONObject)array.get(1); + System.out.println("======field \"1\"=========="); + System.out.println(obj2.get("1")); + assertEquals("{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}",obj2.get("1").toString()); + + s="{}"; + obj=JSONValue.parse(s); + assertEquals("{}",obj.toString()); + + s="[5,]"; + obj=JSONValue.parse(s); + assertEquals("[5]",obj.toString()); + + s="[5,,2]"; + obj=JSONValue.parse(s); + assertEquals("[5,2]",obj.toString()); + } + + public void testEncode() throws Exception{ + System.out.println("=======encode======="); + + JSONArray array1=new JSONArray(); + array1.add("abc\u0010a/"); + array1.add(new Integer(123)); + array1.add(new Double(222.123)); + array1.add(new Boolean(true)); + System.out.println("======array1=========="); + System.out.println(array1); + System.out.println(); + assertEquals("[\"abc\\u0010a\\/\",123,222.123,true]",array1.toString()); + + JSONObject obj1=new JSONObject(); + obj1.put("name","fang"); + obj1.put("age",new Integer(27)); + obj1.put("is_developer",new Boolean(true)); + obj1.put("weight",new Double(60.21)); + obj1.put("array1",array1); + System.out.println("======obj1 with array1==========="); + System.out.println(obj1); + System.out.println(); + assertEquals("{\"array1\":[\"abc\\u0010a\\/\",123,222.123,true],\"weight\":60.21,\"age\":27,\"name\":\"fang\",\"is_developer\":true}",obj1.toString()); + + obj1.remove("array1"); + array1.add(obj1); + System.out.println("======array1 with obj1========"); + System.out.println(array1); + System.out.println(); + assertEquals("[\"abc\\u0010a\\/\",123,222.123,true,{\"weight\":60.21,\"age\":27,\"name\":\"fang\",\"is_developer\":true}]",array1.toString()); + } +} diff --git a/test/org/json/simple/parser/YylexTest.java b/test/org/json/simple/parser/YylexTest.java new file mode 100644 index 0000000..d0eaf40 --- /dev/null +++ b/test/org/json/simple/parser/YylexTest.java @@ -0,0 +1,52 @@ +package org.json.simple.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +public class YylexTest extends TestCase { + + public void testYylex() throws Exception{ + String s="\"\\/\""; + System.out.println(s); + StringReader in = new StringReader(s); + Yylex lexer=new Yylex(in); + Yytoken token=lexer.yylex(); + assertEquals(Yytoken.TYPE_VALUE,token.type); + assertEquals("/",token.value); + + s="\"abc\\/\\r\\b\\n\\t\\f\\\\\""; + System.out.println(s); + in = new StringReader(s); + lexer=new Yylex(in); + token=lexer.yylex(); + assertEquals(Yytoken.TYPE_VALUE,token.type); + assertEquals("abc/\r\b\n\t\f\\",token.value); + + s="[\t \n\r\n{ \t \t\n\r}"; + System.out.println(s); + in = new StringReader(s); + lexer=new Yylex(in); + token=lexer.yylex(); + assertEquals(Yytoken.TYPE_LEFT_SQUARE,token.type); + token=lexer.yylex(); + assertEquals(Yytoken.TYPE_LEFT_BRACE,token.type); + token=lexer.yylex(); + assertEquals(Yytoken.TYPE_RIGHT_BRACE,token.type); + + s="\b\f{"; + System.out.println(s); + in = new StringReader(s); + lexer=new Yylex(in); + Error err=null; + try{ + token=lexer.yylex(); + } + catch(Error e){ + err=e; + System.out.println("error:"+err); + } + assertTrue(err!=null); + } + +} diff --git a/test/org/json/simple/rope/RopeTest.java b/test/org/json/simple/rope/RopeTest.java new file mode 100644 index 0000000..da58c3b --- /dev/null +++ b/test/org/json/simple/rope/RopeTest.java @@ -0,0 +1,44 @@ +package org.json.simple.rope; + +import junit.framework.TestCase; + +public class RopeTest extends TestCase { + public void testOpts(){ + Rope rope = new Rope(); + + assertEquals("",rope.toString()); + assertEquals(0,rope.length()); + + rope.append('c'); + assertEquals("c",rope.toString()); + assertEquals(1,rope.length()); + + rope.append("fang"); + assertEquals("cfang",rope.toString()); + assertEquals(5,rope.length()); + + rope.append('1'); + assertEquals("cfang1",rope.toString()); + assertEquals(6,rope.length()); + + rope.append("你好"); + assertEquals("cfang1你好",rope.toString()); + assertEquals(8,rope.length()); + + rope.append('世'); + assertEquals("cfang1你好世",rope.toString()); + assertEquals(9,rope.length()); + + rope.append("界"); + assertEquals("cfang1你好世界",rope.toString()); + assertEquals(10,rope.length()); + + rope.append(""); + assertEquals("cfang1你好世界",rope.toString()); + assertEquals(10,rope.length()); + + rope.clear(); + assertEquals("",rope.toString()); + assertEquals(0,rope.length()); + } +}