Returns the long read... only significant if valstate==LONG after this call. firstChar should be the first numeric digit read.
(int firstChar, boolean isNeg)
| 475 | * be the first numeric digit read. |
| 476 | */ |
| 477 | private long readNumber(int firstChar, boolean isNeg) throws IOException { |
| 478 | out.unsafeWrite(firstChar); // unsafe OK since we know output is big enough |
| 479 | // We build up the number in the negative plane since it's larger (by one) than |
| 480 | // the positive plane. |
| 481 | long v = (long) '0' - firstChar; |
| 482 | // can't overflow a long in 18 decimal digits (i.e. 17 additional after the first). |
| 483 | // we also need 22 additional to handle double, so we'll handle in 2 separate loops. |
| 484 | int i; |
| 485 | for (i = 0; i < 17; i++) { |
| 486 | int ch = getChar(); |
| 487 | // TODO: is this switch faster as an if-then-else? |
| 488 | switch (ch) { |
| 489 | case '0': |
| 490 | case '1': |
| 491 | case '2': |
| 492 | case '3': |
| 493 | case '4': |
| 494 | case '5': |
| 495 | case '6': |
| 496 | case '7': |
| 497 | case '8': |
| 498 | case '9': |
| 499 | v = v * 10 - (ch - '0'); |
| 500 | out.unsafeWrite(ch); |
| 501 | continue; |
| 502 | case '.': |
| 503 | out.unsafeWrite('.'); |
| 504 | valstate = readFrac(out, 22 - i); |
| 505 | return 0; |
| 506 | case 'e': |
| 507 | case 'E': |
| 508 | out.unsafeWrite(ch); |
| 509 | nstate = 0; |
| 510 | valstate = readExp(out, 22 - i); |
| 511 | return 0; |
| 512 | default: |
| 513 | // return the number, relying on nextEvent() to return an error |
| 514 | // for invalid chars following the number. |
| 515 | if (ch != -1) --start; // push back last char if not EOF |
| 516 | |
| 517 | valstate = LONG; |
| 518 | return isNeg ? v : -v; |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | // after this, we could overflow a long and need to do extra checking |
| 523 | boolean overflow = false; |
| 524 | long maxval = isNeg ? Long.MIN_VALUE : -Long.MAX_VALUE; |
| 525 | |
| 526 | for (; i < 22; i++) { |
| 527 | int ch = getChar(); |
| 528 | switch (ch) { |
| 529 | case '0': |
| 530 | case '1': |
| 531 | case '2': |
| 532 | case '3': |
| 533 | case '4': |
| 534 | case '5': |
no test coverage detected