1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/thirdparty/org/json/simple/parser/JSONParser.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,533 @@ 1.4 +/* 1.5 + * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $ 1.6 + * Created on 2006-4-15 1.7 + */ 1.8 +package org.json.simple.parser; 1.9 + 1.10 +import java.io.IOException; 1.11 +import java.io.Reader; 1.12 +import java.io.StringReader; 1.13 +import java.util.LinkedList; 1.14 +import java.util.List; 1.15 +import java.util.Map; 1.16 + 1.17 +import org.json.simple.JSONArray; 1.18 +import org.json.simple.JSONObject; 1.19 + 1.20 + 1.21 +/** 1.22 + * Parser for JSON text. Please note that JSONParser is NOT thread-safe. 1.23 + * 1.24 + * @author FangYidong<fangyidong@yahoo.com.cn> 1.25 + */ 1.26 +public class JSONParser { 1.27 + public static final int S_INIT=0; 1.28 + public static final int S_IN_FINISHED_VALUE=1;//string,number,boolean,null,object,array 1.29 + public static final int S_IN_OBJECT=2; 1.30 + public static final int S_IN_ARRAY=3; 1.31 + public static final int S_PASSED_PAIR_KEY=4; 1.32 + public static final int S_IN_PAIR_VALUE=5; 1.33 + public static final int S_END=6; 1.34 + public static final int S_IN_ERROR=-1; 1.35 + 1.36 + private LinkedList handlerStatusStack; 1.37 + private Yylex lexer = new Yylex((Reader)null); 1.38 + private Yytoken token = null; 1.39 + private int status = S_INIT; 1.40 + 1.41 + private int peekStatus(LinkedList statusStack){ 1.42 + if(statusStack.size()==0) 1.43 + return -1; 1.44 + Integer status=(Integer)statusStack.getFirst(); 1.45 + return status.intValue(); 1.46 + } 1.47 + 1.48 + /** 1.49 + * Reset the parser to the initial state without resetting the underlying reader. 1.50 + * 1.51 + */ 1.52 + public void reset(){ 1.53 + token = null; 1.54 + status = S_INIT; 1.55 + handlerStatusStack = null; 1.56 + } 1.57 + 1.58 + /** 1.59 + * Reset the parser to the initial state with a new character reader. 1.60 + * 1.61 + * @param in - The new character reader. 1.62 + * @throws IOException 1.63 + * @throws ParseException 1.64 + */ 1.65 + public void reset(Reader in){ 1.66 + lexer.yyreset(in); 1.67 + reset(); 1.68 + } 1.69 + 1.70 + /** 1.71 + * @return The position of the beginning of the current token. 1.72 + */ 1.73 + public int getPosition(){ 1.74 + return lexer.getPosition(); 1.75 + } 1.76 + 1.77 + public Object parse(String s) throws ParseException{ 1.78 + return parse(s, (ContainerFactory)null); 1.79 + } 1.80 + 1.81 + public Object parse(String s, ContainerFactory containerFactory) throws ParseException{ 1.82 + StringReader in=new StringReader(s); 1.83 + try{ 1.84 + return parse(in, containerFactory); 1.85 + } 1.86 + catch(IOException ie){ 1.87 + /* 1.88 + * Actually it will never happen. 1.89 + */ 1.90 + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); 1.91 + } 1.92 + } 1.93 + 1.94 + public Object parse(Reader in) throws IOException, ParseException{ 1.95 + return parse(in, (ContainerFactory)null); 1.96 + } 1.97 + 1.98 + /** 1.99 + * Parse JSON text into java object from the input source. 1.100 + * 1.101 + * @param in 1.102 + * @param containerFactory - Use this factory to createyour own JSON object and JSON array containers. 1.103 + * @return Instance of the following: 1.104 + * org.json.simple.JSONObject, 1.105 + * org.json.simple.JSONArray, 1.106 + * java.lang.String, 1.107 + * java.lang.Number, 1.108 + * java.lang.Boolean, 1.109 + * null 1.110 + * 1.111 + * @throws IOException 1.112 + * @throws ParseException 1.113 + */ 1.114 + public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{ 1.115 + reset(in); 1.116 + LinkedList statusStack = new LinkedList(); 1.117 + LinkedList valueStack = new LinkedList(); 1.118 + 1.119 + try{ 1.120 + do{ 1.121 + nextToken(); 1.122 + switch(status){ 1.123 + case S_INIT: 1.124 + switch(token.type){ 1.125 + case Yytoken.TYPE_VALUE: 1.126 + status=S_IN_FINISHED_VALUE; 1.127 + statusStack.addFirst(new Integer(status)); 1.128 + valueStack.addFirst(token.value); 1.129 + break; 1.130 + case Yytoken.TYPE_LEFT_BRACE: 1.131 + status=S_IN_OBJECT; 1.132 + statusStack.addFirst(new Integer(status)); 1.133 + valueStack.addFirst(createObjectContainer(containerFactory)); 1.134 + break; 1.135 + case Yytoken.TYPE_LEFT_SQUARE: 1.136 + status=S_IN_ARRAY; 1.137 + statusStack.addFirst(new Integer(status)); 1.138 + valueStack.addFirst(createArrayContainer(containerFactory)); 1.139 + break; 1.140 + default: 1.141 + status=S_IN_ERROR; 1.142 + }//inner switch 1.143 + break; 1.144 + 1.145 + case S_IN_FINISHED_VALUE: 1.146 + if(token.type==Yytoken.TYPE_EOF) 1.147 + return valueStack.removeFirst(); 1.148 + else 1.149 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.150 + 1.151 + case S_IN_OBJECT: 1.152 + switch(token.type){ 1.153 + case Yytoken.TYPE_COMMA: 1.154 + break; 1.155 + case Yytoken.TYPE_VALUE: 1.156 + if(token.value instanceof String){ 1.157 + String key=(String)token.value; 1.158 + valueStack.addFirst(key); 1.159 + status=S_PASSED_PAIR_KEY; 1.160 + statusStack.addFirst(new Integer(status)); 1.161 + } 1.162 + else{ 1.163 + status=S_IN_ERROR; 1.164 + } 1.165 + break; 1.166 + case Yytoken.TYPE_RIGHT_BRACE: 1.167 + if(valueStack.size()>1){ 1.168 + statusStack.removeFirst(); 1.169 + valueStack.removeFirst(); 1.170 + status=peekStatus(statusStack); 1.171 + } 1.172 + else{ 1.173 + status=S_IN_FINISHED_VALUE; 1.174 + } 1.175 + break; 1.176 + default: 1.177 + status=S_IN_ERROR; 1.178 + break; 1.179 + }//inner switch 1.180 + break; 1.181 + 1.182 + case S_PASSED_PAIR_KEY: 1.183 + switch(token.type){ 1.184 + case Yytoken.TYPE_COLON: 1.185 + break; 1.186 + case Yytoken.TYPE_VALUE: 1.187 + statusStack.removeFirst(); 1.188 + String key=(String)valueStack.removeFirst(); 1.189 + Map parent=(Map)valueStack.getFirst(); 1.190 + parent.put(key,token.value); 1.191 + status=peekStatus(statusStack); 1.192 + break; 1.193 + case Yytoken.TYPE_LEFT_SQUARE: 1.194 + statusStack.removeFirst(); 1.195 + key=(String)valueStack.removeFirst(); 1.196 + parent=(Map)valueStack.getFirst(); 1.197 + List newArray=createArrayContainer(containerFactory); 1.198 + parent.put(key,newArray); 1.199 + status=S_IN_ARRAY; 1.200 + statusStack.addFirst(new Integer(status)); 1.201 + valueStack.addFirst(newArray); 1.202 + break; 1.203 + case Yytoken.TYPE_LEFT_BRACE: 1.204 + statusStack.removeFirst(); 1.205 + key=(String)valueStack.removeFirst(); 1.206 + parent=(Map)valueStack.getFirst(); 1.207 + Map newObject=createObjectContainer(containerFactory); 1.208 + parent.put(key,newObject); 1.209 + status=S_IN_OBJECT; 1.210 + statusStack.addFirst(new Integer(status)); 1.211 + valueStack.addFirst(newObject); 1.212 + break; 1.213 + default: 1.214 + status=S_IN_ERROR; 1.215 + } 1.216 + break; 1.217 + 1.218 + case S_IN_ARRAY: 1.219 + switch(token.type){ 1.220 + case Yytoken.TYPE_COMMA: 1.221 + break; 1.222 + case Yytoken.TYPE_VALUE: 1.223 + List val=(List)valueStack.getFirst(); 1.224 + val.add(token.value); 1.225 + break; 1.226 + case Yytoken.TYPE_RIGHT_SQUARE: 1.227 + if(valueStack.size()>1){ 1.228 + statusStack.removeFirst(); 1.229 + valueStack.removeFirst(); 1.230 + status=peekStatus(statusStack); 1.231 + } 1.232 + else{ 1.233 + status=S_IN_FINISHED_VALUE; 1.234 + } 1.235 + break; 1.236 + case Yytoken.TYPE_LEFT_BRACE: 1.237 + val=(List)valueStack.getFirst(); 1.238 + Map newObject=createObjectContainer(containerFactory); 1.239 + val.add(newObject); 1.240 + status=S_IN_OBJECT; 1.241 + statusStack.addFirst(new Integer(status)); 1.242 + valueStack.addFirst(newObject); 1.243 + break; 1.244 + case Yytoken.TYPE_LEFT_SQUARE: 1.245 + val=(List)valueStack.getFirst(); 1.246 + List newArray=createArrayContainer(containerFactory); 1.247 + val.add(newArray); 1.248 + status=S_IN_ARRAY; 1.249 + statusStack.addFirst(new Integer(status)); 1.250 + valueStack.addFirst(newArray); 1.251 + break; 1.252 + default: 1.253 + status=S_IN_ERROR; 1.254 + }//inner switch 1.255 + break; 1.256 + case S_IN_ERROR: 1.257 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.258 + }//switch 1.259 + if(status==S_IN_ERROR){ 1.260 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.261 + } 1.262 + }while(token.type!=Yytoken.TYPE_EOF); 1.263 + } 1.264 + catch(IOException ie){ 1.265 + throw ie; 1.266 + } 1.267 + 1.268 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.269 + } 1.270 + 1.271 + private void nextToken() throws ParseException, IOException{ 1.272 + token = lexer.yylex(); 1.273 + if(token == null) 1.274 + token = new Yytoken(Yytoken.TYPE_EOF, null); 1.275 + } 1.276 + 1.277 + private Map createObjectContainer(ContainerFactory containerFactory){ 1.278 + if(containerFactory == null) 1.279 + return new JSONObject(); 1.280 + Map m = containerFactory.createObjectContainer(); 1.281 + 1.282 + if(m == null) 1.283 + return new JSONObject(); 1.284 + return m; 1.285 + } 1.286 + 1.287 + private List createArrayContainer(ContainerFactory containerFactory){ 1.288 + if(containerFactory == null) 1.289 + return new JSONArray(); 1.290 + List l = containerFactory.creatArrayContainer(); 1.291 + 1.292 + if(l == null) 1.293 + return new JSONArray(); 1.294 + return l; 1.295 + } 1.296 + 1.297 + public void parse(String s, ContentHandler contentHandler) throws ParseException{ 1.298 + parse(s, contentHandler, false); 1.299 + } 1.300 + 1.301 + public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException{ 1.302 + StringReader in=new StringReader(s); 1.303 + try{ 1.304 + parse(in, contentHandler, isResume); 1.305 + } 1.306 + catch(IOException ie){ 1.307 + /* 1.308 + * Actually it will never happen. 1.309 + */ 1.310 + throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie); 1.311 + } 1.312 + } 1.313 + 1.314 + public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException{ 1.315 + parse(in, contentHandler, false); 1.316 + } 1.317 + 1.318 + /** 1.319 + * Stream processing of JSON text. 1.320 + * 1.321 + * @see ContentHandler 1.322 + * 1.323 + * @param in 1.324 + * @param contentHandler 1.325 + * @param isResume - Indicates if it continues previous parsing operation. 1.326 + * If set to true, resume parsing the old stream, and parameter 'in' will be ignored. 1.327 + * If this method is called for the first time in this instance, isResume will be ignored. 1.328 + * 1.329 + * @throws IOException 1.330 + * @throws ParseException 1.331 + */ 1.332 + public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{ 1.333 + if(!isResume){ 1.334 + reset(in); 1.335 + handlerStatusStack = new LinkedList(); 1.336 + } 1.337 + else{ 1.338 + if(handlerStatusStack == null){ 1.339 + isResume = false; 1.340 + reset(in); 1.341 + handlerStatusStack = new LinkedList(); 1.342 + } 1.343 + } 1.344 + 1.345 + LinkedList statusStack = handlerStatusStack; 1.346 + 1.347 + try{ 1.348 + do{ 1.349 + switch(status){ 1.350 + case S_INIT: 1.351 + contentHandler.startJSON(); 1.352 + nextToken(); 1.353 + switch(token.type){ 1.354 + case Yytoken.TYPE_VALUE: 1.355 + status=S_IN_FINISHED_VALUE; 1.356 + statusStack.addFirst(new Integer(status)); 1.357 + if(!contentHandler.primitive(token.value)) 1.358 + return; 1.359 + break; 1.360 + case Yytoken.TYPE_LEFT_BRACE: 1.361 + status=S_IN_OBJECT; 1.362 + statusStack.addFirst(new Integer(status)); 1.363 + if(!contentHandler.startObject()) 1.364 + return; 1.365 + break; 1.366 + case Yytoken.TYPE_LEFT_SQUARE: 1.367 + status=S_IN_ARRAY; 1.368 + statusStack.addFirst(new Integer(status)); 1.369 + if(!contentHandler.startArray()) 1.370 + return; 1.371 + break; 1.372 + default: 1.373 + status=S_IN_ERROR; 1.374 + }//inner switch 1.375 + break; 1.376 + 1.377 + case S_IN_FINISHED_VALUE: 1.378 + nextToken(); 1.379 + if(token.type==Yytoken.TYPE_EOF){ 1.380 + contentHandler.endJSON(); 1.381 + status = S_END; 1.382 + return; 1.383 + } 1.384 + else{ 1.385 + status = S_IN_ERROR; 1.386 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.387 + } 1.388 + 1.389 + case S_IN_OBJECT: 1.390 + nextToken(); 1.391 + switch(token.type){ 1.392 + case Yytoken.TYPE_COMMA: 1.393 + break; 1.394 + case Yytoken.TYPE_VALUE: 1.395 + if(token.value instanceof String){ 1.396 + String key=(String)token.value; 1.397 + status=S_PASSED_PAIR_KEY; 1.398 + statusStack.addFirst(new Integer(status)); 1.399 + if(!contentHandler.startObjectEntry(key)) 1.400 + return; 1.401 + } 1.402 + else{ 1.403 + status=S_IN_ERROR; 1.404 + } 1.405 + break; 1.406 + case Yytoken.TYPE_RIGHT_BRACE: 1.407 + if(statusStack.size()>1){ 1.408 + statusStack.removeFirst(); 1.409 + status=peekStatus(statusStack); 1.410 + } 1.411 + else{ 1.412 + status=S_IN_FINISHED_VALUE; 1.413 + } 1.414 + if(!contentHandler.endObject()) 1.415 + return; 1.416 + break; 1.417 + default: 1.418 + status=S_IN_ERROR; 1.419 + break; 1.420 + }//inner switch 1.421 + break; 1.422 + 1.423 + case S_PASSED_PAIR_KEY: 1.424 + nextToken(); 1.425 + switch(token.type){ 1.426 + case Yytoken.TYPE_COLON: 1.427 + break; 1.428 + case Yytoken.TYPE_VALUE: 1.429 + statusStack.removeFirst(); 1.430 + status=peekStatus(statusStack); 1.431 + if(!contentHandler.primitive(token.value)) 1.432 + return; 1.433 + if(!contentHandler.endObjectEntry()) 1.434 + return; 1.435 + break; 1.436 + case Yytoken.TYPE_LEFT_SQUARE: 1.437 + statusStack.removeFirst(); 1.438 + statusStack.addFirst(new Integer(S_IN_PAIR_VALUE)); 1.439 + status=S_IN_ARRAY; 1.440 + statusStack.addFirst(new Integer(status)); 1.441 + if(!contentHandler.startArray()) 1.442 + return; 1.443 + break; 1.444 + case Yytoken.TYPE_LEFT_BRACE: 1.445 + statusStack.removeFirst(); 1.446 + statusStack.addFirst(new Integer(S_IN_PAIR_VALUE)); 1.447 + status=S_IN_OBJECT; 1.448 + statusStack.addFirst(new Integer(status)); 1.449 + if(!contentHandler.startObject()) 1.450 + return; 1.451 + break; 1.452 + default: 1.453 + status=S_IN_ERROR; 1.454 + } 1.455 + break; 1.456 + 1.457 + case S_IN_PAIR_VALUE: 1.458 + /* 1.459 + * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token, 1.460 + * therefore delay consuming token until next round. 1.461 + */ 1.462 + statusStack.removeFirst(); 1.463 + status = peekStatus(statusStack); 1.464 + if(!contentHandler.endObjectEntry()) 1.465 + return; 1.466 + break; 1.467 + 1.468 + case S_IN_ARRAY: 1.469 + nextToken(); 1.470 + switch(token.type){ 1.471 + case Yytoken.TYPE_COMMA: 1.472 + break; 1.473 + case Yytoken.TYPE_VALUE: 1.474 + if(!contentHandler.primitive(token.value)) 1.475 + return; 1.476 + break; 1.477 + case Yytoken.TYPE_RIGHT_SQUARE: 1.478 + if(statusStack.size()>1){ 1.479 + statusStack.removeFirst(); 1.480 + status=peekStatus(statusStack); 1.481 + } 1.482 + else{ 1.483 + status=S_IN_FINISHED_VALUE; 1.484 + } 1.485 + if(!contentHandler.endArray()) 1.486 + return; 1.487 + break; 1.488 + case Yytoken.TYPE_LEFT_BRACE: 1.489 + status=S_IN_OBJECT; 1.490 + statusStack.addFirst(new Integer(status)); 1.491 + if(!contentHandler.startObject()) 1.492 + return; 1.493 + break; 1.494 + case Yytoken.TYPE_LEFT_SQUARE: 1.495 + status=S_IN_ARRAY; 1.496 + statusStack.addFirst(new Integer(status)); 1.497 + if(!contentHandler.startArray()) 1.498 + return; 1.499 + break; 1.500 + default: 1.501 + status=S_IN_ERROR; 1.502 + }//inner switch 1.503 + break; 1.504 + 1.505 + case S_END: 1.506 + return; 1.507 + 1.508 + case S_IN_ERROR: 1.509 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.510 + }//switch 1.511 + if(status==S_IN_ERROR){ 1.512 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.513 + } 1.514 + }while(token.type!=Yytoken.TYPE_EOF); 1.515 + } 1.516 + catch(IOException ie){ 1.517 + status = S_IN_ERROR; 1.518 + throw ie; 1.519 + } 1.520 + catch(ParseException pe){ 1.521 + status = S_IN_ERROR; 1.522 + throw pe; 1.523 + } 1.524 + catch(RuntimeException re){ 1.525 + status = S_IN_ERROR; 1.526 + throw re; 1.527 + } 1.528 + catch(Error e){ 1.529 + status = S_IN_ERROR; 1.530 + throw e; 1.531 + } 1.532 + 1.533 + status = S_IN_ERROR; 1.534 + throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token); 1.535 + } 1.536 +}