This commit is contained in:
fangyidong
2008-11-25 13:25:49 +00:00
commit d65cf1822b
24 changed files with 2044 additions and 0 deletions

8
.classpath Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**/.svn|**/.svn/**/*" kind="src" output="build/main" path="src"/>
<classpathentry excluding="**/.svn|**/.svn/**/*" kind="src" output="build/test" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3.8.1"/>
<classpathentry kind="output" path="build/main"/>
</classpath>

17
.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>json.simple</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

1
AUTHORS.txt Normal file
View File

@@ -0,0 +1 @@
Fang Yidong <fangyidong@yahoo.com.cn>

11
ChangeLog.txt Normal file
View File

@@ -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

202
LICENSE.txt Normal file
View File

@@ -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.

153
README.txt Normal file
View File

@@ -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<fangyidong@yahoo.com.cn>
Fang Yidong<fangyidong@gmail.com>
8.Project home.
http://code.google.com/p/json-simple/
http://www.JSON.org/java/json_simple.zip

1
VERSION.txt Normal file
View File

@@ -0,0 +1 @@
1.0.1

32
build.xml Normal file
View File

@@ -0,0 +1,32 @@
<project name="json-simple" default="main" basedir=".">
<property name="current-version" value="1.0.1"/>
<property name="jar-name" value="json_simple-${current-version}.jar"/>
<target name="main" depends="mkdir,compile,jar">
</target>
<target name="clean">
<delete includeemptydirs="true">
<fileset dir="build/main" includes="**/*"/>
</delete>
<delete file="lib/${jar-name}"/>
</target>
<target name="mkdir">
<mkdir dir="build/main"/>
</target>
<target name="compile">
<javac srcdir="src"
destdir="build/main"
includes="**/*.java"
target="1.2"
source="1.2"/>
</target>
<target name="jar">
<jar destfile="lib/${jar-name}"
basedir="build/main"
includes="**/*.class"/>
</target>
</project>

47
doc/json.lex Normal file
View File

@@ -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]
%%
<STRING_BEGIN> \\\" {sb.append('"');}
<STRING_BEGIN> \\\\ {sb.append('\\');}
<STRING_BEGIN> \\\/ {sb.append('/');}
<STRING_BEGIN> \\b {sb.append('\b');}
<STRING_BEGIN> \\f {sb.append('\f');}
<STRING_BEGIN> \\n {sb.append('\n');}
<STRING_BEGIN> \\r {sb.append('\r');}
<STRING_BEGIN> \\t {sb.append('\t');}
<STRING_BEGIN> \\u{HEX_D}{HEX_D}{HEX_D}{HEX_D} { int ch=Integer.parseInt(yytext().substring(2),16);
sb.append((char)ch);
}
<STRING_BEGIN> \" { yybegin(YYINITIAL);return new Yytoken(Yytoken.TYPE_VALUE,sb.toString());}
<STRING_BEGIN> . { sb.append(yytext());}
<YYINITIAL> \" { sb.clear();yybegin(STRING_BEGIN);}
<YYINITIAL> {INT} { Long val=Long.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);}
<YYINITIAL> {DOUBLE} { Double val=Double.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);}
<YYINITIAL> "true"|"false" { Boolean val=Boolean.valueOf(yytext()); return new Yytoken(Yytoken.TYPE_VALUE,val);}
<YYINITIAL> "null" { return new Yytoken(Yytoken.TYPE_VALUE,null);}
<YYINITIAL> "{" { return new Yytoken(Yytoken.TYPE_LEFT_BRACE,null);}
<YYINITIAL> "}" { return new Yytoken(Yytoken.TYPE_RIGHT_BRACE,null);}
<YYINITIAL> "[" { return new Yytoken(Yytoken.TYPE_LEFT_SQUARE,null);}
<YYINITIAL> "]" { return new Yytoken(Yytoken.TYPE_RIGHT_SQUARE,null);}
<YYINITIAL> "," { return new Yytoken(Yytoken.TYPE_COMMA,null);}
<YYINITIAL> ":" { return new Yytoken(Yytoken.TYPE_COLON,null);}
<YYINITIAL> {WS} {}

BIN
lib/json_simple-1.0.1.jar Normal file

Binary file not shown.

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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<items.size();i++){
if(i==0)
sb.append(items.get(i));
else{
sb.append(sp);
sb.append(items.get(i));
}
}
return sb.toString();
}
public void clear(){
items.clear();
}
public void reset(){
sp=",";
items.clear();
}
}

View File

@@ -0,0 +1,31 @@
/*
* $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.util.ArrayList;
import java.util.Iterator;
/**
* @author FangYidong<fangyidong@yahoo.com.cn>
*/
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()+"]";
}
}

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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<s.length();i++){
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:
if(ch>='\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();
}
}

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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);
}
}

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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;
}
}

View File

@@ -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 <code>false</code>, 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
* <b>cannot</b> be reused (internal buffer is discarded and lost).
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
*
* @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 <tt>pos</tt> 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);
}
}
}
}
}

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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+"|");
}
}

View File

@@ -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;
}

View File

@@ -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();
}
}

1
svn-commit.tmp Normal file
View File

@@ -0,0 +1 @@
init

49
test.xml Normal file
View File

@@ -0,0 +1,49 @@
<project name="json-simple" default="main" basedir=".">
<path id="runtime.path">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement location="build/test"/>
</path>
<path id="compile.path">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="main" depends="mkdir,compile,junit">
</target>
<target name="clean">
<delete includeemptydirs="true">
<fileset dir="build/test" includes="**/*"/>
<fileset dir="." includes="TEST-*.txt"/>
</delete>
</target>
<target name="mkdir">
<mkdir dir="build/test"/>
</target>
<target name="compile">
<javac srcdir="test"
destdir="build/test"
includes="**/*.java"
encoding="UTF-8"
target="1.2"
source="1.2">
<classpath refid="compile.path"/>
</javac>
</target>
<target name="junit">
<junit>
<classpath refid="runtime.path"/>
<formatter type="plain"/>
<test name="org.json.simple.Test"/>
<test name="org.json.simple.parser.YylexTest"/>
<test name="org.json.simple.rope.RopeTest"/>
</junit>
</target>
</project>

View File

@@ -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<fangyidong@yahoo.com.cn>
*/
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());
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}