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