Chromium Code Reviews| Index: runtime/lib/convert_patch.dart |
| diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart |
| index 93da46140cb3fac8b3477af430d4d278bd61a3d0..c3e14c757e80e45452a6693cca779df41bc1216b 100644 |
| --- a/runtime/lib/convert_patch.dart |
| +++ b/runtime/lib/convert_patch.dart |
| @@ -391,21 +391,26 @@ class _JsonParser { |
| // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' |
| // Initial position is right after first '"'. |
| int start = position; |
| - int char; |
| - do { |
| - if (position == source.length) { |
| - fail(start - 1, "Unterminated string"); |
| - } |
| - char = source.codeUnitAt(position); |
| - if (char == QUOTE) { |
| - listener.handleString(source.substring(start, position)); |
| - return position + 1; |
| - } |
| - if (char < SPACE) { |
| - fail(position, "Control character in string"); |
| + while (position < source.length) { |
| + int char = source.codeUnitAt(position); |
| + if (char <= BACKSLASH) { // BACKSLASH is larger than QUOTE. |
|
Søren Gjesse
2014/03/24 08:33:57
and SPACE :-)
Lasse Reichstein Nielsen
2014/03/24 12:13:49
SPACE is *obviously* smaller than anything :)
But
|
| + if (char == BACKSLASH) { |
| + return parseStringWithEscapes(start, position); |
| + } |
| + if (char == QUOTE) { |
| + listener.handleString(source.substring(start, position)); |
| + return position + 1; |
| + } |
| + if (char < SPACE) { |
| + fail(position, "Control character in string"); |
| + } |
| } |
| position++; |
| - } while (char != BACKSLASH); |
| + } |
| + fail(start - 1, "Unterminated string"); |
| + } |
| + |
| + int parseStringWithEscapes(string, position) { |
|
Lasse Reichstein Nielsen
2014/03/07 10:40:27
string -> start.
Lasse Reichstein Nielsen
2014/03/24 08:30:54
string -> source even.
|
| // Backslash escape detected. Collect character codes for rest of string. |
| int firstEscape = position - 1; |
| List<int> chars = <int>[]; |
| @@ -472,74 +477,84 @@ class _JsonParser { |
| } |
| } |
| - int _handleLiteral(start, position, isDouble) { |
| - String literal = source.substring(start, position); |
| - // This correctly creates -0 for doubles. |
| - num value = (isDouble ? double.parse(literal) : int.parse(literal)); |
| - listener.handleNumber(value); |
| - return position; |
| - } |
| - |
| int parseNumber(int char, int position) { |
| // Format: |
| // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)? |
| int start = position; |
| int length = source.length; |
| + int intValue = 0; // Collect int value while parsing. |
| + int intSign = 1; |
| bool isDouble = false; |
| - if (char == MINUS) { |
| - position++; |
| - if (position == length) fail(position, "Missing expected digit"); |
| - char = source.codeUnitAt(position); |
| - } |
| - if (char < CHAR_0 || char > CHAR_9) { |
| - fail(position, "Missing expected digit"); |
| - } |
| - if (char == CHAR_0) { |
| - position++; |
| - if (position == length) return _handleLiteral(start, position, false); |
| - char = source.codeUnitAt(position); |
| - if (CHAR_0 <= char && char <= CHAR_9) { |
| - fail(position); |
| - } |
| - } else { |
| - do { |
| + // Break this block when the end of the number literal is reached. |
| + // At that time, position points to the next character, and isDouble |
| + // is set if the literal contains a decimal point or an exponential. |
| + parsing: { |
| + if (char == MINUS) { |
| + intSign = -1; |
| position++; |
| - if (position == length) return _handleLiteral(start, position, false); |
| + if (position == length) fail(position, "Missing expected digit"); |
| char = source.codeUnitAt(position); |
| - } while (CHAR_0 <= char && char <= CHAR_9); |
| - } |
| - if (char == DECIMALPOINT) { |
| - isDouble = true; |
| - position++; |
| - if (position == length) fail(position, "Missing expected digit"); |
| - char = source.codeUnitAt(position); |
| - if (char < CHAR_0 || char > CHAR_9) fail(position); |
| - do { |
| + } |
| + if (char < CHAR_0 || char > CHAR_9) { |
| + fail(position, "Missing expected digit"); |
| + } |
| + if (char == CHAR_0) { |
| position++; |
| - if (position == length) return _handleLiteral(start, position, true); |
| + if (position == length) break parsing; |
| char = source.codeUnitAt(position); |
| - } while (CHAR_0 <= char && char <= CHAR_9); |
| - } |
| - if (char == CHAR_e || char == CHAR_E) { |
| - isDouble = true; |
| - position++; |
| - if (position == length) fail(position, "Missing expected digit"); |
| - char = source.codeUnitAt(position); |
| - if (char == PLUS || char == MINUS) { |
| + if (CHAR_0 <= char && char <= CHAR_9) { |
| + fail(position); |
| + } |
| + } else { |
| + do { |
| + intValue = intValue * 10 + (char - CHAR_0); |
| + position++; |
| + if (position == length) break parsing; |
| + char = source.codeUnitAt(position); |
| + } while (CHAR_0 <= char && char <= CHAR_9); |
| + } |
| + if (char == DECIMALPOINT) { |
| + isDouble = true; |
| position++; |
| if (position == length) fail(position, "Missing expected digit"); |
| char = source.codeUnitAt(position); |
| + if (char < CHAR_0 || char > CHAR_9) fail(position); |
| + do { |
| + position++; |
| + if (position == length) break parsing; |
| + char = source.codeUnitAt(position); |
| + } while (CHAR_0 <= char && char <= CHAR_9); |
| } |
| - if (char < CHAR_0 || char > CHAR_9) { |
| - fail(position, "Missing expected digit"); |
| - } |
| - do { |
| + if (char == CHAR_e || char == CHAR_E) { |
| + isDouble = true; |
| position++; |
| - if (position == length) return _handleLiteral(start, position, true); |
| + if (position == length) fail(position, "Missing expected digit"); |
| char = source.codeUnitAt(position); |
| - } while (CHAR_0 <= char && char <= CHAR_9); |
| + if (char == PLUS || char == MINUS) { |
| + position++; |
| + if (position == length) fail(position, "Missing expected digit"); |
| + char = source.codeUnitAt(position); |
| + } |
| + if (char < CHAR_0 || char > CHAR_9) { |
| + fail(position, "Missing expected digit"); |
| + } |
| + do { |
| + position++; |
| + if (position == length) break parsing; |
| + char = source.codeUnitAt(position); |
| + } while (CHAR_0 <= char && char <= CHAR_9); |
| + } |
| } |
| - return _handleLiteral(start, position, isDouble); |
| + if (!isDouble) { |
| + listener.handleNumber(intSign * intValue); |
| + return position; |
| + } |
| + // Consider whether we can have an int/double.parse that works on part of |
| + // a string, to avoid creating the substring. |
| + String literal = source.substring(start, position); |
| + // This correctly creates -0.0 for doubles. |
| + listener.handleNumber(double.parse(literal)); |
|
Søren Gjesse
2014/03/24 08:33:57
There is no simpler way to create the double now y
Lasse Reichstein Nielsen
2014/03/24 12:13:49
In simple cases, there probably is.
Parsing a doub
|
| + return position; |
| } |
| void fail(int position, [String message]) { |