mobile/android/thirdparty/org/json/simple/parser/JSONParser.java

changeset 0
6474c204b198
     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 +}

mercurial