Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package org.json.simple.parser

File JSONParser.java

 

Coverage histogram

../../../../img/srcFileCovDistChart4.png
44% of files have more coverage

Code metrics

68
321
15
1
611
499
100
0.31
21.4
15
6.67

Classes

Class Line # Actions
JSONParser 22 321 100
0.3514851635.1%
 

Contributing tests

This file is covered by 20 tests. .

Source view

1    /*
2    * $Id: JSONParser.java,v 1.1 2006/04/15 14:10:48 platform Exp $
3    * Created on 2006-4-15
4    */
5    package org.json.simple.parser;
6   
7    import java.io.IOException;
8    import java.io.Reader;
9    import java.io.StringReader;
10    import java.util.LinkedList;
11    import java.util.List;
12    import java.util.Map;
13   
14    import org.json.simple.JSONArray;
15    import org.json.simple.JSONObject;
16   
17    /**
18    * Parser for JSON text. Please note that JSONParser is NOT thread-safe.
19    *
20    * @author FangYidong<fangyidong@yahoo.com.cn>
21    */
 
22    public class JSONParser
23    {
24    public static final int S_INIT = 0;
25   
26    public static final int S_IN_FINISHED_VALUE = 1;// string,number,boolean,null,object,array
27   
28    public static final int S_IN_OBJECT = 2;
29   
30    public static final int S_IN_ARRAY = 3;
31   
32    public static final int S_PASSED_PAIR_KEY = 4;
33   
34    public static final int S_IN_PAIR_VALUE = 5;
35   
36    public static final int S_END = 6;
37   
38    public static final int S_IN_ERROR = -1;
39   
40    private LinkedList handlerStatusStack;
41   
42    private Yylex lexer = new Yylex((Reader) null);
43   
44    private Yytoken token = null;
45   
46    private int status = S_INIT;
47   
 
48  55941 toggle private int peekStatus(LinkedList statusStack)
49    {
50  55941 if (statusStack.size() == 0)
51  0 return -1;
52  55941 Integer status = (Integer) statusStack.getFirst();
53  55941 return status.intValue();
54    }
55   
56    /**
57    * Reset the parser to the initial state without resetting the underlying
58    * reader.
59    *
60    */
 
61  59 toggle public void reset()
62    {
63  59 token = null;
64  59 status = S_INIT;
65  59 handlerStatusStack = null;
66    }
67   
68    /**
69    * Reset the parser to the initial state with a new character reader.
70    *
71    * @param in
72    * - The new character reader.
73    * @throws IOException
74    * @throws ParseException
75    */
 
76  59 toggle public void reset(Reader in)
77    {
78  59 lexer.yyreset(in);
79  59 reset();
80    }
81   
82    /**
83    * @return The position of the beginning of the current token.
84    */
 
85  0 toggle public int getPosition()
86    {
87  0 return lexer.getPosition();
88    }
89   
 
90  21 toggle public Object parse(String s) throws ParseException
91    {
92  21 return parse(s, (ContainerFactory) null);
93    }
94   
 
95  21 toggle public Object parse(String s, ContainerFactory containerFactory)
96    throws ParseException
97    {
98  21 StringReader in = new StringReader(s);
99  20 try
100    {
101  20 return parse(in, containerFactory);
102    } catch (IOException ie)
103    {
104    /*
105    * Actually it will never happen.
106    */
107  0 throw new ParseException(-1,
108    ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
109    }
110    }
111   
 
112  39 toggle public Object parse(Reader in) throws IOException, ParseException
113    {
114  39 return parse(in, (ContainerFactory) null);
115    }
116   
117    /**
118    * Parse JSON text into java object from the input source.
119    *
120    * @param in
121    * @param containerFactory
122    * - Use this factory to createyour own JSON object and JSON array
123    * containers.
124    * @return Instance of the following: org.json.simple.JSONObject,
125    * org.json.simple.JSONArray, java.lang.String, java.lang.Number,
126    * java.lang.Boolean, null
127    *
128    * @throws IOException
129    * @throws ParseException
130    */
 
131  59 toggle public Object parse(Reader in, ContainerFactory containerFactory)
132    throws IOException, ParseException
133    {
134  59 reset(in);
135  59 LinkedList statusStack = new LinkedList();
136  59 LinkedList valueStack = new LinkedList();
137   
138  59 try
139    {
140  59 do
141    {
142  201665 nextToken();
143  201665 switch (status)
144    {
145  59 case S_INIT:
146  59 switch (token.type)
147    {
148  0 case Yytoken.TYPE_VALUE:
149  0 status = S_IN_FINISHED_VALUE;
150  0 statusStack.addFirst(new Integer(status));
151  0 valueStack.addFirst(token.value);
152  0 break;
153  58 case Yytoken.TYPE_LEFT_BRACE:
154  58 status = S_IN_OBJECT;
155  58 statusStack.addFirst(new Integer(status));
156  58 valueStack.addFirst(createObjectContainer(containerFactory));
157  58 break;
158  1 case Yytoken.TYPE_LEFT_SQUARE:
159  1 status = S_IN_ARRAY;
160  1 statusStack.addFirst(new Integer(status));
161  1 valueStack.addFirst(createArrayContainer(containerFactory));
162  1 break;
163  0 default:
164  0 status = S_IN_ERROR;
165    }// inner switch
166  59 break;
167   
168  59 case S_IN_FINISHED_VALUE:
169  59 if (token.type == Yytoken.TYPE_EOF)
170  59 return valueStack.removeFirst();
171    else
172  0 throw new ParseException(getPosition(),
173    ParseException.ERROR_UNEXPECTED_TOKEN, token);
174   
175  89619 case S_IN_OBJECT:
176  89619 switch (token.type)
177    {
178  33610 case Yytoken.TYPE_COMMA:
179  33610 break;
180  44818 case Yytoken.TYPE_VALUE:
181  44818 if (token.value instanceof String)
182    {
183  44818 String key = (String) token.value;
184  44818 valueStack.addFirst(key);
185  44818 status = S_PASSED_PAIR_KEY;
186  44818 statusStack.addFirst(new Integer(status));
187    }
188    else
189    {
190  0 status = S_IN_ERROR;
191    }
192  44818 break;
193  11191 case Yytoken.TYPE_RIGHT_BRACE:
194  11191 if (valueStack.size() > 1)
195    {
196  11133 statusStack.removeFirst();
197  11133 valueStack.removeFirst();
198  11133 status = peekStatus(statusStack);
199    }
200    else
201    {
202  58 status = S_IN_FINISHED_VALUE;
203    }
204  11191 break;
205  0 default:
206  0 status = S_IN_ERROR;
207  0 break;
208    }// inner switch
209  89619 break;
210   
211  89636 case S_PASSED_PAIR_KEY:
212  89636 switch (token.type)
213    {
214  44818 case Yytoken.TYPE_COLON:
215  44818 break;
216  44722 case Yytoken.TYPE_VALUE:
217  44722 statusStack.removeFirst();
218  44722 String key = (String) valueStack.removeFirst();
219  44722 Map parent = (Map) valueStack.getFirst();
220  44722 parent.put(key, token.value);
221  44722 status = peekStatus(statusStack);
222  44722 break;
223  86 case Yytoken.TYPE_LEFT_SQUARE:
224  86 statusStack.removeFirst();
225  86 key = (String) valueStack.removeFirst();
226  86 parent = (Map) valueStack.getFirst();
227  86 List newArray = createArrayContainer(containerFactory);
228  86 parent.put(key, newArray);
229  86 status = S_IN_ARRAY;
230  86 statusStack.addFirst(new Integer(status));
231  86 valueStack.addFirst(newArray);
232  86 break;
233  10 case Yytoken.TYPE_LEFT_BRACE:
234  10 statusStack.removeFirst();
235  10 key = (String) valueStack.removeFirst();
236  10 parent = (Map) valueStack.getFirst();
237  10 Map newObject = createObjectContainer(containerFactory);
238  10 parent.put(key, newObject);
239  10 status = S_IN_OBJECT;
240  10 statusStack.addFirst(new Integer(status));
241  10 valueStack.addFirst(newObject);
242  10 break;
243  0 default:
244  0 status = S_IN_ERROR;
245    }
246  89636 break;
247   
248  22292 case S_IN_ARRAY:
249  22292 switch (token.type)
250    {
251  11061 case Yytoken.TYPE_COMMA:
252  11061 break;
253  21 case Yytoken.TYPE_VALUE:
254  21 List val = (List) valueStack.getFirst();
255  21 val.add(token.value);
256  21 break;
257  87 case Yytoken.TYPE_RIGHT_SQUARE:
258  87 if (valueStack.size() > 1)
259    {
260  86 statusStack.removeFirst();
261  86 valueStack.removeFirst();
262  86 status = peekStatus(statusStack);
263    }
264    else
265    {
266  1 status = S_IN_FINISHED_VALUE;
267    }
268  87 break;
269  11123 case Yytoken.TYPE_LEFT_BRACE:
270  11123 val = (List) valueStack.getFirst();
271  11123 Map newObject = createObjectContainer(containerFactory);
272  11123 val.add(newObject);
273  11123 status = S_IN_OBJECT;
274  11123 statusStack.addFirst(new Integer(status));
275  11123 valueStack.addFirst(newObject);
276  11123 break;
277  0 case Yytoken.TYPE_LEFT_SQUARE:
278  0 val = (List) valueStack.getFirst();
279  0 List newArray = createArrayContainer(containerFactory);
280  0 val.add(newArray);
281  0 status = S_IN_ARRAY;
282  0 statusStack.addFirst(new Integer(status));
283  0 valueStack.addFirst(newArray);
284  0 break;
285  0 default:
286  0 status = S_IN_ERROR;
287    }// inner switch
288  22292 break;
289  0 case S_IN_ERROR:
290  0 throw new ParseException(getPosition(),
291    ParseException.ERROR_UNEXPECTED_TOKEN, token);
292    }// switch
293  201606 if (status == S_IN_ERROR)
294    {
295  0 throw new ParseException(getPosition(),
296    ParseException.ERROR_UNEXPECTED_TOKEN, token);
297    }
298  201606 } while (token.type != Yytoken.TYPE_EOF);
299    } catch (IOException ie)
300    {
301  0 throw ie;
302    }
303   
304  0 throw new ParseException(getPosition(),
305    ParseException.ERROR_UNEXPECTED_TOKEN, token);
306    }
307   
 
308  201665 toggle private void nextToken() throws ParseException, IOException
309    {
310  201665 token = lexer.yylex();
311  201665 if (token == null)
312  59 token = new Yytoken(Yytoken.TYPE_EOF, null);
313    }
314   
 
315  11191 toggle private Map createObjectContainer(ContainerFactory containerFactory)
316    {
317  11191 if (containerFactory == null)
318  11191 return new JSONObject();
319  0 Map m = containerFactory.createObjectContainer();
320   
321  0 if (m == null)
322  0 return new JSONObject();
323  0 return m;
324    }
325   
 
326  87 toggle private List createArrayContainer(ContainerFactory containerFactory)
327    {
328  87 if (containerFactory == null)
329  87 return new JSONArray();
330  0 List l = containerFactory.creatArrayContainer();
331   
332  0 if (l == null)
333  0 return new JSONArray();
334  0 return l;
335    }
336   
 
337  0 toggle public void parse(String s, ContentHandler contentHandler)
338    throws ParseException
339    {
340  0 parse(s, contentHandler, false);
341    }
342   
 
343  0 toggle public void parse(String s, ContentHandler contentHandler,
344    boolean isResume) throws ParseException
345    {
346  0 StringReader in = new StringReader(s);
347  0 try
348    {
349  0 parse(in, contentHandler, isResume);
350    } catch (IOException ie)
351    {
352    /*
353    * Actually it will never happen.
354    */
355  0 throw new ParseException(-1,
356    ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
357    }
358    }
359   
 
360  0 toggle public void parse(Reader in, ContentHandler contentHandler)
361    throws IOException, ParseException
362    {
363  0 parse(in, contentHandler, false);
364    }
365   
366    /**
367    * Stream processing of JSON text.
368    *
369    * @see ContentHandler
370    *
371    * @param in
372    * @param contentHandler
373    * @param isResume
374    * - Indicates if it continues previous parsing operation. If set to
375    * true, resume parsing the old stream, and parameter 'in' will be
376    * ignored. If this method is called for the first time in this
377    * instance, isResume will be ignored.
378    *
379    * @throws IOException
380    * @throws ParseException
381    */
 
382  0 toggle public void parse(Reader in, ContentHandler contentHandler,
383    boolean isResume) throws IOException, ParseException
384    {
385  0 if (!isResume)
386    {
387  0 reset(in);
388  0 handlerStatusStack = new LinkedList();
389    }
390    else
391    {
392  0 if (handlerStatusStack == null)
393    {
394  0 isResume = false;
395  0 reset(in);
396  0 handlerStatusStack = new LinkedList();
397    }
398    }
399   
400  0 LinkedList statusStack = handlerStatusStack;
401   
402  0 try
403    {
404  0 do
405    {
406  0 switch (status)
407    {
408  0 case S_INIT:
409  0 contentHandler.startJSON();
410  0 nextToken();
411  0 switch (token.type)
412    {
413  0 case Yytoken.TYPE_VALUE:
414  0 status = S_IN_FINISHED_VALUE;
415  0 statusStack.addFirst(new Integer(status));
416  0 if (!contentHandler.primitive(token.value))
417  0 return;
418  0 break;
419  0 case Yytoken.TYPE_LEFT_BRACE:
420  0 status = S_IN_OBJECT;
421  0 statusStack.addFirst(new Integer(status));
422  0 if (!contentHandler.startObject())
423  0 return;
424  0 break;
425  0 case Yytoken.TYPE_LEFT_SQUARE:
426  0 status = S_IN_ARRAY;
427  0 statusStack.addFirst(new Integer(status));
428  0 if (!contentHandler.startArray())
429  0 return;
430  0 break;
431  0 default:
432  0 status = S_IN_ERROR;
433    }// inner switch
434  0 break;
435   
436  0 case S_IN_FINISHED_VALUE:
437  0 nextToken();
438  0 if (token.type == Yytoken.TYPE_EOF)
439    {
440  0 contentHandler.endJSON();
441  0 status = S_END;
442  0 return;
443    }
444    else
445    {
446  0 status = S_IN_ERROR;
447  0 throw new ParseException(getPosition(),
448    ParseException.ERROR_UNEXPECTED_TOKEN, token);
449    }
450   
451  0 case S_IN_OBJECT:
452  0 nextToken();
453  0 switch (token.type)
454    {
455  0 case Yytoken.TYPE_COMMA:
456  0 break;
457  0 case Yytoken.TYPE_VALUE:
458  0 if (token.value instanceof String)
459    {
460  0 String key = (String) token.value;
461  0 status = S_PASSED_PAIR_KEY;
462  0 statusStack.addFirst(new Integer(status));
463  0 if (!contentHandler.startObjectEntry(key))
464  0 return;
465    }
466    else
467    {
468  0 status = S_IN_ERROR;
469    }
470  0 break;
471  0 case Yytoken.TYPE_RIGHT_BRACE:
472  0 if (statusStack.size() > 1)
473    {
474  0 statusStack.removeFirst();
475  0 status = peekStatus(statusStack);
476    }
477    else
478    {
479  0 status = S_IN_FINISHED_VALUE;
480    }
481  0 if (!contentHandler.endObject())
482  0 return;
483  0 break;
484  0 default:
485  0 status = S_IN_ERROR;
486  0 break;
487    }// inner switch
488  0 break;
489   
490  0 case S_PASSED_PAIR_KEY:
491  0 nextToken();
492  0 switch (token.type)
493    {
494  0 case Yytoken.TYPE_COLON:
495  0 break;
496  0 case Yytoken.TYPE_VALUE:
497  0 statusStack.removeFirst();
498  0 status = peekStatus(statusStack);
499  0 if (!contentHandler.primitive(token.value))
500  0 return;
501  0 if (!contentHandler.endObjectEntry())
502  0 return;
503  0 break;
504  0 case Yytoken.TYPE_LEFT_SQUARE:
505  0 statusStack.removeFirst();
506  0 statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
507  0 status = S_IN_ARRAY;
508  0 statusStack.addFirst(new Integer(status));
509  0 if (!contentHandler.startArray())
510  0 return;
511  0 break;
512  0 case Yytoken.TYPE_LEFT_BRACE:
513  0 statusStack.removeFirst();
514  0 statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
515  0 status = S_IN_OBJECT;
516  0 statusStack.addFirst(new Integer(status));
517  0 if (!contentHandler.startObject())
518  0 return;
519  0 break;
520  0 default:
521  0 status = S_IN_ERROR;
522    }
523  0 break;
524   
525  0 case S_IN_PAIR_VALUE:
526    /*
527    * S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
528    * therefore delay consuming token until next round.
529    */
530  0 statusStack.removeFirst();
531  0 status = peekStatus(statusStack);
532  0 if (!contentHandler.endObjectEntry())
533  0 return;
534  0 break;
535   
536  0 case S_IN_ARRAY:
537  0 nextToken();
538  0 switch (token.type)
539    {
540  0 case Yytoken.TYPE_COMMA:
541  0 break;
542  0 case Yytoken.TYPE_VALUE:
543  0 if (!contentHandler.primitive(token.value))
544  0 return;
545  0 break;
546  0 case Yytoken.TYPE_RIGHT_SQUARE:
547  0 if (statusStack.size() > 1)
548    {
549  0 statusStack.removeFirst();
550  0 status = peekStatus(statusStack);
551    }
552    else
553    {
554  0 status = S_IN_FINISHED_VALUE;
555    }
556  0 if (!contentHandler.endArray())
557  0 return;
558  0 break;
559  0 case Yytoken.TYPE_LEFT_BRACE:
560  0 status = S_IN_OBJECT;
561  0 statusStack.addFirst(new Integer(status));
562  0 if (!contentHandler.startObject())
563  0 return;
564  0 break;
565  0 case Yytoken.TYPE_LEFT_SQUARE:
566  0 status = S_IN_ARRAY;
567  0 statusStack.addFirst(new Integer(status));
568  0 if (!contentHandler.startArray())
569  0 return;
570  0 break;
571  0 default:
572  0 status = S_IN_ERROR;
573    }// inner switch
574  0 break;
575   
576  0 case S_END:
577  0 return;
578   
579  0 case S_IN_ERROR:
580  0 throw new ParseException(getPosition(),
581    ParseException.ERROR_UNEXPECTED_TOKEN, token);
582    }// switch
583  0 if (status == S_IN_ERROR)
584    {
585  0 throw new ParseException(getPosition(),
586    ParseException.ERROR_UNEXPECTED_TOKEN, token);
587    }
588  0 } while (token.type != Yytoken.TYPE_EOF);
589    } catch (IOException ie)
590    {
591  0 status = S_IN_ERROR;
592  0 throw ie;
593    } catch (ParseException pe)
594    {
595  0 status = S_IN_ERROR;
596  0 throw pe;
597    } catch (RuntimeException re)
598    {
599  0 status = S_IN_ERROR;
600  0 throw re;
601    } catch (Error e)
602    {
603  0 status = S_IN_ERROR;
604  0 throw e;
605    }
606   
607  0 status = S_IN_ERROR;
608  0 throw new ParseException(getPosition(),
609    ParseException.ERROR_UNEXPECTED_TOKEN, token);
610    }
611    }