• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // line 1 "JsonReader.rl"
2 // Do not edit this file! Generated by Ragel.
3 // Ragel.exe -G2 -J -o JsonReader.java JsonReader.rl
4 /*******************************************************************************
5  * Copyright 2011 See AUTHORS file.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  ******************************************************************************/
19 
20 package com.badlogic.gdx.utils;
21 
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.Reader;
26 
27 import com.badlogic.gdx.files.FileHandle;
28 import com.badlogic.gdx.utils.JsonValue.ValueType;
29 
30 /** Lightweight JSON parser.<br>
31  * <br>
32  * The default behavior is to parse the JSON into a DOM containing {@link JsonValue} objects. Extend this class and override
33  * methods to perform event driven parsing. When this is done, the parse methods will return null.
34  * @author Nathan Sweet */
35 public class JsonReader implements BaseJsonReader {
parse(String json)36 	public JsonValue parse (String json) {
37 		char[] data = json.toCharArray();
38 		return parse(data, 0, data.length);
39 	}
40 
parse(Reader reader)41 	public JsonValue parse (Reader reader) {
42 		try {
43 			char[] data = new char[1024];
44 			int offset = 0;
45 			while (true) {
46 				int length = reader.read(data, offset, data.length - offset);
47 				if (length == -1) break;
48 				if (length == 0) {
49 					char[] newData = new char[data.length * 2];
50 					System.arraycopy(data, 0, newData, 0, data.length);
51 					data = newData;
52 				} else
53 					offset += length;
54 			}
55 			return parse(data, 0, offset);
56 		} catch (IOException ex) {
57 			throw new SerializationException(ex);
58 		} finally {
59 			StreamUtils.closeQuietly(reader);
60 		}
61 	}
62 
parse(InputStream input)63 	public JsonValue parse (InputStream input) {
64 		try {
65 			return parse(new InputStreamReader(input, "UTF-8"));
66 		} catch (IOException ex) {
67 			throw new SerializationException(ex);
68 		} finally {
69 			StreamUtils.closeQuietly(input);
70 		}
71 	}
72 
parse(FileHandle file)73 	public JsonValue parse (FileHandle file) {
74 		try {
75 			return parse(file.reader("UTF-8"));
76 		} catch (Exception ex) {
77 			throw new SerializationException("Error parsing file: " + file, ex);
78 		}
79 	}
80 
parse(char[] data, int offset, int length)81 	public JsonValue parse (char[] data, int offset, int length) {
82 		int cs, p = offset, pe = length, eof = pe, top = 0;
83 		int[] stack = new int[4];
84 
85 		int s = 0;
86 		Array<String> names = new Array(8);
87 		boolean needsUnescape = false, stringIsName = false, stringIsUnquoted = false;
88 		RuntimeException parseRuntimeEx = null;
89 
90 		boolean debug = false;
91 		if (debug) System.out.println();
92 
93 		try {
94 
95 			// line 97 "JsonReader.java"
96 			{
97 				cs = json_start;
98 				top = 0;
99 			}
100 
101 			// line 103 "JsonReader.java"
102 			{
103 				int _klen;
104 				int _trans = 0;
105 				int _acts;
106 				int _nacts;
107 				int _keys;
108 				int _goto_targ = 0;
109 
110 				_goto:
111 				while (true) {
112 					switch (_goto_targ) {
113 					case 0:
114 						if (p == pe) {
115 							_goto_targ = 4;
116 							continue _goto;
117 						}
118 						if (cs == 0) {
119 							_goto_targ = 5;
120 							continue _goto;
121 						}
122 					case 1:
123 						_match:
124 						do {
125 							_keys = _json_key_offsets[cs];
126 							_trans = _json_index_offsets[cs];
127 							_klen = _json_single_lengths[cs];
128 							if (_klen > 0) {
129 								int _lower = _keys;
130 								int _mid;
131 								int _upper = _keys + _klen - 1;
132 								while (true) {
133 									if (_upper < _lower) break;
134 
135 									_mid = _lower + ((_upper - _lower) >> 1);
136 									if (data[p] < _json_trans_keys[_mid])
137 										_upper = _mid - 1;
138 									else if (data[p] > _json_trans_keys[_mid])
139 										_lower = _mid + 1;
140 									else {
141 										_trans += (_mid - _keys);
142 										break _match;
143 									}
144 								}
145 								_keys += _klen;
146 								_trans += _klen;
147 							}
148 
149 							_klen = _json_range_lengths[cs];
150 							if (_klen > 0) {
151 								int _lower = _keys;
152 								int _mid;
153 								int _upper = _keys + (_klen << 1) - 2;
154 								while (true) {
155 									if (_upper < _lower) break;
156 
157 									_mid = _lower + (((_upper - _lower) >> 1) & ~1);
158 									if (data[p] < _json_trans_keys[_mid])
159 										_upper = _mid - 2;
160 									else if (data[p] > _json_trans_keys[_mid + 1])
161 										_lower = _mid + 2;
162 									else {
163 										_trans += ((_mid - _keys) >> 1);
164 										break _match;
165 									}
166 								}
167 								_trans += _klen;
168 							}
169 						} while (false);
170 
171 						_trans = _json_indicies[_trans];
172 						cs = _json_trans_targs[_trans];
173 
174 						if (_json_trans_actions[_trans] != 0) {
175 							_acts = _json_trans_actions[_trans];
176 							_nacts = (int)_json_actions[_acts++];
177 							while (_nacts-- > 0) {
178 								switch (_json_actions[_acts++]) {
179 								case 0:
180 								// line 104 "JsonReader.rl"
181 								{
182 									stringIsName = true;
183 								}
184 									break;
185 								case 1:
186 								// line 107 "JsonReader.rl"
187 								{
188 									String value = new String(data, s, p - s);
189 									if (needsUnescape) value = unescape(value);
190 									outer:
191 									if (stringIsName) {
192 										stringIsName = false;
193 										if (debug) System.out.println("name: " + value);
194 										names.add(value);
195 									} else {
196 										String name = names.size > 0 ? names.pop() : null;
197 										if (stringIsUnquoted) {
198 											if (value.equals("true")) {
199 												if (debug) System.out.println("boolean: " + name + "=true");
200 												bool(name, true);
201 												break outer;
202 											} else if (value.equals("false")) {
203 												if (debug) System.out.println("boolean: " + name + "=false");
204 												bool(name, false);
205 												break outer;
206 											} else if (value.equals("null")) {
207 												string(name, null);
208 												break outer;
209 											}
210 											boolean couldBeDouble = false, couldBeLong = true;
211 											outer2:
212 											for (int i = s; i < p; i++) {
213 												switch (data[i]) {
214 												case '0':
215 												case '1':
216 												case '2':
217 												case '3':
218 												case '4':
219 												case '5':
220 												case '6':
221 												case '7':
222 												case '8':
223 												case '9':
224 												case '-':
225 												case '+':
226 													break;
227 												case '.':
228 												case 'e':
229 												case 'E':
230 													couldBeDouble = true;
231 													couldBeLong = false;
232 													break;
233 												default:
234 													couldBeDouble = false;
235 													couldBeLong = false;
236 													break outer2;
237 												}
238 											}
239 											if (couldBeDouble) {
240 												try {
241 													if (debug) System.out.println("double: " + name + "=" + Double.parseDouble(value));
242 													number(name, Double.parseDouble(value), value);
243 													break outer;
244 												} catch (NumberFormatException ignored) {
245 												}
246 											} else if (couldBeLong) {
247 												if (debug) System.out.println("double: " + name + "=" + Double.parseDouble(value));
248 												try {
249 													number(name, Long.parseLong(value), value);
250 													break outer;
251 												} catch (NumberFormatException ignored) {
252 												}
253 											}
254 										}
255 										if (debug) System.out.println("string: " + name + "=" + value);
256 										string(name, value);
257 									}
258 									stringIsUnquoted = false;
259 									s = p;
260 								}
261 									break;
262 								case 2:
263 								// line 181 "JsonReader.rl"
264 								{
265 									String name = names.size > 0 ? names.pop() : null;
266 									if (debug) System.out.println("startObject: " + name);
267 									startObject(name);
268 									{
269 										if (top == stack.length) {
270 											int[] newStack = new int[stack.length * 2];
271 											System.arraycopy(stack, 0, newStack, 0, stack.length);
272 											stack = newStack;
273 										}
274 										{
275 											stack[top++] = cs;
276 											cs = 5;
277 											_goto_targ = 2;
278 											if (true) continue _goto;
279 										}
280 									}
281 								}
282 									break;
283 								case 3:
284 								// line 187 "JsonReader.rl"
285 								{
286 									if (debug) System.out.println("endObject");
287 									pop();
288 									{
289 										cs = stack[--top];
290 										_goto_targ = 2;
291 										if (true) continue _goto;
292 									}
293 								}
294 									break;
295 								case 4:
296 								// line 192 "JsonReader.rl"
297 								{
298 									String name = names.size > 0 ? names.pop() : null;
299 									if (debug) System.out.println("startArray: " + name);
300 									startArray(name);
301 									{
302 										if (top == stack.length) {
303 											int[] newStack = new int[stack.length * 2];
304 											System.arraycopy(stack, 0, newStack, 0, stack.length);
305 											stack = newStack;
306 										}
307 										{
308 											stack[top++] = cs;
309 											cs = 23;
310 											_goto_targ = 2;
311 											if (true) continue _goto;
312 										}
313 									}
314 								}
315 									break;
316 								case 5:
317 								// line 198 "JsonReader.rl"
318 								{
319 									if (debug) System.out.println("endArray");
320 									pop();
321 									{
322 										cs = stack[--top];
323 										_goto_targ = 2;
324 										if (true) continue _goto;
325 									}
326 								}
327 									break;
328 								case 6:
329 								// line 203 "JsonReader.rl"
330 								{
331 									int start = p - 1;
332 									if (data[p++] == '/') {
333 										while (p != eof && data[p] != '\n')
334 											p++;
335 										p--;
336 									} else {
337 										while (p + 1 < eof && data[p] != '*' || data[p + 1] != '/')
338 											p++;
339 										p++;
340 									}
341 									if (debug) System.out.println("comment " + new String(data, start, p - start));
342 								}
343 									break;
344 								case 7:
345 								// line 216 "JsonReader.rl"
346 								{
347 									if (debug) System.out.println("unquotedChars");
348 									s = p;
349 									needsUnescape = false;
350 									stringIsUnquoted = true;
351 									if (stringIsName) {
352 										outer:
353 										while (true) {
354 											switch (data[p]) {
355 											case '\\':
356 												needsUnescape = true;
357 												break;
358 											case '/':
359 												if (p + 1 == eof) break;
360 												char c = data[p + 1];
361 												if (c == '/' || c == '*') break outer;
362 												break;
363 											case ':':
364 											case '\r':
365 											case '\n':
366 												break outer;
367 											}
368 											if (debug) System.out.println("unquotedChar (name): '" + data[p] + "'");
369 											p++;
370 											if (p == eof) break;
371 										}
372 									} else {
373 										outer:
374 										while (true) {
375 											switch (data[p]) {
376 											case '\\':
377 												needsUnescape = true;
378 												break;
379 											case '/':
380 												if (p + 1 == eof) break;
381 												char c = data[p + 1];
382 												if (c == '/' || c == '*') break outer;
383 												break;
384 											case '}':
385 											case ']':
386 											case ',':
387 											case '\r':
388 											case '\n':
389 												break outer;
390 											}
391 											if (debug) System.out.println("unquotedChar (value): '" + data[p] + "'");
392 											p++;
393 											if (p == eof) break;
394 										}
395 									}
396 									p--;
397 									while (Character.isSpace(data[p]))
398 										p--;
399 								}
400 									break;
401 								case 8:
402 								// line 270 "JsonReader.rl"
403 								{
404 									if (debug) System.out.println("quotedChars");
405 									s = ++p;
406 									needsUnescape = false;
407 									outer:
408 									while (true) {
409 										switch (data[p]) {
410 										case '\\':
411 											needsUnescape = true;
412 											p++;
413 											break;
414 										case '"':
415 											break outer;
416 										}
417 										// if (debug) System.out.println("quotedChar: '" + data[p] + "'");
418 										p++;
419 										if (p == eof) break;
420 									}
421 									p--;
422 								}
423 									break;
424 								// line 408 "JsonReader.java"
425 								}
426 							}
427 						}
428 
429 					case 2:
430 						if (cs == 0) {
431 							_goto_targ = 5;
432 							continue _goto;
433 						}
434 						if (++p != pe) {
435 							_goto_targ = 1;
436 							continue _goto;
437 						}
438 					case 4:
439 						if (p == eof) {
440 							int __acts = _json_eof_actions[cs];
441 							int __nacts = (int)_json_actions[__acts++];
442 							while (__nacts-- > 0) {
443 								switch (_json_actions[__acts++]) {
444 								case 1:
445 								// line 107 "JsonReader.rl"
446 								{
447 									String value = new String(data, s, p - s);
448 									if (needsUnescape) value = unescape(value);
449 									outer:
450 									if (stringIsName) {
451 										stringIsName = false;
452 										if (debug) System.out.println("name: " + value);
453 										names.add(value);
454 									} else {
455 										String name = names.size > 0 ? names.pop() : null;
456 										if (stringIsUnquoted) {
457 											if (value.equals("true")) {
458 												if (debug) System.out.println("boolean: " + name + "=true");
459 												bool(name, true);
460 												break outer;
461 											} else if (value.equals("false")) {
462 												if (debug) System.out.println("boolean: " + name + "=false");
463 												bool(name, false);
464 												break outer;
465 											} else if (value.equals("null")) {
466 												string(name, null);
467 												break outer;
468 											}
469 											boolean couldBeDouble = false, couldBeLong = true;
470 											outer2:
471 											for (int i = s; i < p; i++) {
472 												switch (data[i]) {
473 												case '0':
474 												case '1':
475 												case '2':
476 												case '3':
477 												case '4':
478 												case '5':
479 												case '6':
480 												case '7':
481 												case '8':
482 												case '9':
483 												case '-':
484 												case '+':
485 													break;
486 												case '.':
487 												case 'e':
488 												case 'E':
489 													couldBeDouble = true;
490 													couldBeLong = false;
491 													break;
492 												default:
493 													couldBeDouble = false;
494 													couldBeLong = false;
495 													break outer2;
496 												}
497 											}
498 											if (couldBeDouble) {
499 												try {
500 													if (debug) System.out.println("double: " + name + "=" + Double.parseDouble(value));
501 													number(name, Double.parseDouble(value), value);
502 													break outer;
503 												} catch (NumberFormatException ignored) {
504 												}
505 											} else if (couldBeLong) {
506 												if (debug) System.out.println("double: " + name + "=" + Double.parseDouble(value));
507 												try {
508 													number(name, Long.parseLong(value), value);
509 													break outer;
510 												} catch (NumberFormatException ignored) {
511 												}
512 											}
513 										}
514 										if (debug) System.out.println("string: " + name + "=" + value);
515 										string(name, value);
516 									}
517 									stringIsUnquoted = false;
518 									s = p;
519 								}
520 									break;
521 								// line 506 "JsonReader.java"
522 								}
523 							}
524 						}
525 
526 					case 5:
527 					}
528 					break;
529 				}
530 			}
531 
532 			// line 306 "JsonReader.rl"
533 
534 		} catch (RuntimeException ex) {
535 			parseRuntimeEx = ex;
536 		}
537 
538 		JsonValue root = this.root;
539 		this.root = null;
540 		current = null;
541 		lastChild.clear();
542 
543 		if (p < pe) {
544 			int lineNumber = 1;
545 			for (int i = 0; i < p; i++)
546 				if (data[i] == '\n') lineNumber++;
547 			int start = Math.max(0, p - 32);
548 			throw new SerializationException("Error parsing JSON on line " + lineNumber + " near: "
549 				+ new String(data, start, p - start) + "*ERROR*" + new String(data, p, Math.min(64, pe - p)), parseRuntimeEx);
550 		} else if (elements.size != 0) {
551 			JsonValue element = elements.peek();
552 			elements.clear();
553 			if (element != null && element.isObject())
554 				throw new SerializationException("Error parsing JSON, unmatched brace.");
555 			else
556 				throw new SerializationException("Error parsing JSON, unmatched bracket.");
557 		} else if (parseRuntimeEx != null) {
558 			throw new SerializationException("Error parsing JSON: " + new String(data), parseRuntimeEx);
559 		}
560 		return root;
561 	}
562 
563 	// line 548 "JsonReader.java"
init__json_actions_0()564 	private static byte[] init__json_actions_0 () {
565 		return new byte[] {0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 2, 0, 7, 2, 0, 8, 2, 1, 3, 2, 1, 5};
566 	}
567 
568 	private static final byte _json_actions[] = init__json_actions_0();
569 
init__json_key_offsets_0()570 	private static short[] init__json_key_offsets_0 () {
571 		return new short[] {0, 0, 11, 13, 14, 16, 25, 31, 37, 39, 50, 57, 64, 73, 74, 83, 85, 87, 96, 98, 100, 101, 103, 105, 116,
572 			123, 130, 141, 142, 153, 155, 157, 168, 170, 172, 174, 179, 184, 184};
573 	}
574 
575 	private static final short _json_key_offsets[] = init__json_key_offsets_0();
576 
init__json_trans_keys_0()577 	private static char[] init__json_trans_keys_0 () {
578 		return new char[] {13, 32, 34, 44, 47, 58, 91, 93, 123, 9, 10, 42, 47, 34, 42, 47, 13, 32, 34, 44, 47, 58, 125, 9, 10, 13,
579 			32, 47, 58, 9, 10, 13, 32, 47, 58, 9, 10, 42, 47, 13, 32, 34, 44, 47, 58, 91, 93, 123, 9, 10, 9, 10, 13, 32, 44, 47, 125,
580 			9, 10, 13, 32, 44, 47, 125, 13, 32, 34, 44, 47, 58, 125, 9, 10, 34, 13, 32, 34, 44, 47, 58, 125, 9, 10, 42, 47, 42, 47,
581 			13, 32, 34, 44, 47, 58, 125, 9, 10, 42, 47, 42, 47, 34, 42, 47, 42, 47, 13, 32, 34, 44, 47, 58, 91, 93, 123, 9, 10, 9,
582 			10, 13, 32, 44, 47, 93, 9, 10, 13, 32, 44, 47, 93, 13, 32, 34, 44, 47, 58, 91, 93, 123, 9, 10, 34, 13, 32, 34, 44, 47,
583 			58, 91, 93, 123, 9, 10, 42, 47, 42, 47, 13, 32, 34, 44, 47, 58, 91, 93, 123, 9, 10, 42, 47, 42, 47, 42, 47, 13, 32, 47,
584 			9, 10, 13, 32, 47, 9, 10, 0};
585 	}
586 
587 	private static final char _json_trans_keys[] = init__json_trans_keys_0();
588 
init__json_single_lengths_0()589 	private static byte[] init__json_single_lengths_0 () {
590 		return new byte[] {0, 9, 2, 1, 2, 7, 4, 4, 2, 9, 7, 7, 7, 1, 7, 2, 2, 7, 2, 2, 1, 2, 2, 9, 7, 7, 9, 1, 9, 2, 2, 9, 2, 2, 2,
591 			3, 3, 0, 0};
592 	}
593 
594 	private static final byte _json_single_lengths[] = init__json_single_lengths_0();
595 
init__json_range_lengths_0()596 	private static byte[] init__json_range_lengths_0 () {
597 		return new byte[] {0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0,
598 			1, 1, 0, 0};
599 	}
600 
601 	private static final byte _json_range_lengths[] = init__json_range_lengths_0();
602 
init__json_index_offsets_0()603 	private static short[] init__json_index_offsets_0 () {
604 		return new short[] {0, 0, 11, 14, 16, 19, 28, 34, 40, 43, 54, 62, 70, 79, 81, 90, 93, 96, 105, 108, 111, 113, 116, 119, 130,
605 			138, 146, 157, 159, 170, 173, 176, 187, 190, 193, 196, 201, 206, 207};
606 	}
607 
608 	private static final short _json_index_offsets[] = init__json_index_offsets_0();
609 
init__json_indicies_0()610 	private static byte[] init__json_indicies_0 () {
611 		return new byte[] {1, 1, 2, 3, 4, 3, 5, 3, 6, 1, 0, 7, 7, 3, 8, 3, 9, 9, 3, 11, 11, 12, 13, 14, 3, 15, 11, 10, 16, 16, 17,
612 			18, 16, 3, 19, 19, 20, 21, 19, 3, 22, 22, 3, 21, 21, 24, 3, 25, 3, 26, 3, 27, 21, 23, 28, 29, 28, 28, 30, 31, 32, 3, 33,
613 			34, 33, 33, 13, 35, 15, 3, 34, 34, 12, 36, 37, 3, 15, 34, 10, 16, 3, 36, 36, 12, 3, 38, 3, 3, 36, 10, 39, 39, 3, 40, 40,
614 			3, 13, 13, 12, 3, 41, 3, 15, 13, 10, 42, 42, 3, 43, 43, 3, 28, 3, 44, 44, 3, 45, 45, 3, 47, 47, 48, 49, 50, 3, 51, 52,
615 			53, 47, 46, 54, 55, 54, 54, 56, 57, 58, 3, 59, 60, 59, 59, 49, 61, 52, 3, 60, 60, 48, 62, 63, 3, 51, 52, 53, 60, 46, 54,
616 			3, 62, 62, 48, 3, 64, 3, 51, 3, 53, 62, 46, 65, 65, 3, 66, 66, 3, 49, 49, 48, 3, 67, 3, 51, 52, 53, 49, 46, 68, 68, 3,
617 			69, 69, 3, 70, 70, 3, 8, 8, 71, 8, 3, 72, 72, 73, 72, 3, 3, 3, 0};
618 	}
619 
620 	private static final byte _json_indicies[] = init__json_indicies_0();
621 
init__json_trans_targs_0()622 	private static byte[] init__json_trans_targs_0 () {
623 		return new byte[] {35, 1, 3, 0, 4, 36, 36, 36, 36, 1, 6, 5, 13, 17, 22, 37, 7, 8, 9, 7, 8, 9, 7, 10, 20, 21, 11, 11, 11, 12,
624 			17, 19, 37, 11, 12, 19, 14, 16, 15, 14, 12, 18, 17, 11, 9, 5, 24, 23, 27, 31, 34, 25, 38, 25, 25, 26, 31, 33, 38, 25, 26,
625 			33, 28, 30, 29, 28, 26, 32, 31, 25, 23, 2, 36, 2};
626 	}
627 
628 	private static final byte _json_trans_targs[] = init__json_trans_targs_0();
629 
init__json_trans_actions_0()630 	private static byte[] init__json_trans_actions_0 () {
631 		return new byte[] {13, 0, 15, 0, 0, 7, 3, 11, 1, 11, 17, 0, 20, 0, 0, 5, 1, 1, 1, 0, 0, 0, 11, 13, 15, 0, 7, 3, 1, 1, 1, 1,
632 			23, 0, 0, 0, 0, 0, 0, 11, 11, 0, 11, 11, 11, 11, 13, 0, 15, 0, 0, 7, 9, 3, 1, 1, 1, 1, 26, 0, 0, 0, 0, 0, 0, 11, 11, 0,
633 			11, 11, 11, 1, 0, 0};
634 	}
635 
636 	private static final byte _json_trans_actions[] = init__json_trans_actions_0();
637 
init__json_eof_actions_0()638 	private static byte[] init__json_eof_actions_0 () {
639 		return new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
640 			1, 0, 0, 0};
641 	}
642 
643 	private static final byte _json_eof_actions[] = init__json_eof_actions_0();
644 
645 	static final int json_start = 1;
646 	static final int json_first_final = 35;
647 	static final int json_error = 0;
648 
649 	static final int json_en_object = 5;
650 	static final int json_en_array = 23;
651 	static final int json_en_main = 1;
652 
653 	// line 337 "JsonReader.rl"
654 
655 	private final Array<JsonValue> elements = new Array(8);
656 	private final Array<JsonValue> lastChild = new Array(8);
657 	private JsonValue root, current;
658 
addChild(String name, JsonValue child)659 	private void addChild (String name, JsonValue child) {
660 		child.setName(name);
661 		if (current == null) {
662 			current = child;
663 			root = child;
664 		} else if (current.isArray() || current.isObject()) {
665 			child.parent = current;
666 			if (current.size == 0)
667 				current.child = child;
668 			else {
669 				JsonValue last = lastChild.pop();
670 				last.next = child;
671 				child.prev = last;
672 			}
673 			lastChild.add(child);
674 			current.size++;
675 		} else
676 			root = current;
677 	}
678 
startObject(String name)679 	protected void startObject (String name) {
680 		JsonValue value = new JsonValue(ValueType.object);
681 		if (current != null) addChild(name, value);
682 		elements.add(value);
683 		current = value;
684 	}
685 
startArray(String name)686 	protected void startArray (String name) {
687 		JsonValue value = new JsonValue(ValueType.array);
688 		if (current != null) addChild(name, value);
689 		elements.add(value);
690 		current = value;
691 	}
692 
pop()693 	protected void pop () {
694 		root = elements.pop();
695 		if (current.size > 0) lastChild.pop();
696 		current = elements.size > 0 ? elements.peek() : null;
697 	}
698 
string(String name, String value)699 	protected void string (String name, String value) {
700 		addChild(name, new JsonValue(value));
701 	}
702 
number(String name, double value, String stringValue)703 	protected void number (String name, double value, String stringValue) {
704 		addChild(name, new JsonValue(value, stringValue));
705 	}
706 
number(String name, long value, String stringValue)707 	protected void number (String name, long value, String stringValue) {
708 		addChild(name, new JsonValue(value, stringValue));
709 	}
710 
bool(String name, boolean value)711 	protected void bool (String name, boolean value) {
712 		addChild(name, new JsonValue(value));
713 	}
714 
unescape(String value)715 	private String unescape (String value) {
716 		int length = value.length();
717 		StringBuilder buffer = new StringBuilder(length + 16);
718 		for (int i = 0; i < length;) {
719 			char c = value.charAt(i++);
720 			if (c != '\\') {
721 				buffer.append(c);
722 				continue;
723 			}
724 			if (i == length) break;
725 			c = value.charAt(i++);
726 			if (c == 'u') {
727 				buffer.append(Character.toChars(Integer.parseInt(value.substring(i, i + 4), 16)));
728 				i += 4;
729 				continue;
730 			}
731 			switch (c) {
732 			case '"':
733 			case '\\':
734 			case '/':
735 				break;
736 			case 'b':
737 				c = '\b';
738 				break;
739 			case 'f':
740 				c = '\f';
741 				break;
742 			case 'n':
743 				c = '\n';
744 				break;
745 			case 'r':
746 				c = '\r';
747 				break;
748 			case 't':
749 				c = '\t';
750 				break;
751 			default:
752 				throw new SerializationException("Illegal escaped character: \\" + c);
753 			}
754 			buffer.append(c);
755 		}
756 		return buffer.toString();
757 	}
758 }
759