| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // Dart core library. | 4 // Dart core library. |
| 5 | 5 |
| 6 // VM implementation of int. | 6 // VM implementation of int. |
| 7 | 7 |
| 8 patch class int { | 8 patch class int { |
| 9 | 9 |
| 10 static bool _isWhitespace(int codePoint) { | |
| 11 return | |
| 12 (codePoint == 32) || // Space. | |
| 13 ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc. | |
| 14 } | |
| 15 | |
| 16 static bool is64Bit() => 1 << 32 is _Smi; | 10 static bool is64Bit() => 1 << 32 is _Smi; |
| 17 | 11 |
| 18 static int _tryParseSmi(String str) { | 12 static int _tryParseSmi(String str, int first, int last) { |
| 19 if (str.isEmpty) return null; | 13 assert(first <= last); |
| 20 var ix = 0; | 14 var ix = first; |
| 21 var endIx = str.length - 1; | 15 var sign = 1; |
| 22 // Find first and last non-whitespace. | |
| 23 while (ix <= endIx) { | |
| 24 if (!_isWhitespace(str.codeUnitAt(ix))) break; | |
| 25 ix++; | |
| 26 } | |
| 27 if (endIx < ix) { | |
| 28 return null; // Empty. | |
| 29 } | |
| 30 while (endIx > ix) { | |
| 31 if (!_isWhitespace(str.codeUnitAt(endIx))) break; | |
| 32 endIx--; | |
| 33 } | |
| 34 | |
| 35 var isNegative = false; | |
| 36 var c = str.codeUnitAt(ix); | 16 var c = str.codeUnitAt(ix); |
| 37 // Check for leading '+' or '-'. | 17 // Check for leading '+' or '-'. |
| 38 if ((c == 0x2b) || (c == 0x2d)) { | 18 if ((c == 0x2b) || (c == 0x2d)) { |
| 39 ix++; | 19 ix++; |
| 40 isNegative = (c == 0x2d); | 20 sign = 0x2c - c; // -1 for '-', +1 for '+'. |
| 41 if (ix > endIx) { | 21 if (ix > last) { |
| 42 return null; // Empty. | 22 return null; // Empty. |
| 43 } | 23 } |
| 44 } | 24 } |
| 45 int smiLimit = is64Bit() ? 18 : 9; | 25 int smiLimit = is64Bit() ? 18 : 9; |
| 46 if ((endIx - ix) >= smiLimit) { | 26 if ((last - ix) >= smiLimit) { |
| 47 return null; // May not fit into a Smi. | 27 return null; // May not fit into a Smi. |
| 48 } | 28 } |
| 49 var result = 0; | 29 var result = 0; |
| 50 for (int i = ix; i <= endIx; i++) { | 30 for (int i = ix; i <= last; i++) { |
| 51 var c = str.codeUnitAt(i) - 0x30; | 31 var c = str.codeUnitAt(i) - 0x30; |
| 52 if ((c > 9) || (c < 0)) { | 32 if ((c > 9) || (c < 0)) { |
| 53 return null; | 33 return null; |
| 54 } | 34 } |
| 55 result = result * 10 + c; | 35 result = result * 10 + c; |
| 56 } | 36 } |
| 57 return isNegative ? -result : result; | 37 return sign * result; |
| 38 } |
| 39 |
| 40 static int _tryParseSmiWhitespace(String str) { |
| 41 int first = str._firstNonWhitespace(); |
| 42 if (first < str.length) { |
| 43 int last = str._lastNonWhitespace(); |
| 44 int res = _tryParseSmi(str, first, last); |
| 45 if (res != null) return res; |
| 46 } |
| 47 return _native_parse(str); |
| 58 } | 48 } |
| 59 | 49 |
| 60 static int _parse(String str) { | 50 static int _parse(String str) { |
| 61 int res = _tryParseSmi(str); | 51 int res = _tryParseSmi(str, 0, str.length - 1); |
| 62 if (res == null) { | 52 if (res != null) return res; |
| 63 res = _native_parse(str); | 53 return _tryParseSmiWhitespace(str); |
| 64 } | |
| 65 return res; | |
| 66 } | 54 } |
| 67 | 55 |
| 68 static int _native_parse(String str) native "Integer_parse"; | 56 static int _native_parse(String str) native "Integer_parse"; |
| 69 | 57 |
| 70 static int _throwFormatException(String source, int position) { | 58 static int _throwFormatException(String source, int position) { |
| 71 throw new FormatException("", source, position); | 59 throw new FormatException("", source, position); |
| 72 } | 60 } |
| 73 | 61 |
| 74 /* patch */ static int parse(String source, | 62 /* patch */ static int parse(String source, |
| 75 { int radix, | 63 { int radix, |
| 76 int onError(String str) }) { | 64 int onError(String str) }) { |
| 77 if (radix == null) { | 65 if (radix == null) { |
| 78 int result = _parse(source); | 66 int result; |
| 67 if (source.isNotEmpty) result = _parse(source); |
| 79 if (result == null) { | 68 if (result == null) { |
| 80 if (onError == null) { | 69 if (onError == null) { |
| 81 throw new FormatException("", source); | 70 throw new FormatException("", source); |
| 82 } | 71 } |
| 83 return onError(source); | 72 return onError(source); |
| 84 } | 73 } |
| 85 return result; | 74 return result; |
| 86 } | 75 } |
| 87 return _slowParse(source, radix, onError); | 76 return _slowParse(source, radix, onError); |
| 88 } | 77 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 int digit = digits[code - 0x30]; | 121 int digit = digits[code - 0x30]; |
| 133 if (digit >= radix) return onError(source); | 122 if (digit >= radix) return onError(source); |
| 134 result = result * radix + digit; | 123 result = result * radix + digit; |
| 135 i++; | 124 i++; |
| 136 if (i == end) break; | 125 if (i == end) break; |
| 137 code = source.codeUnitAt(i); | 126 code = source.codeUnitAt(i); |
| 138 } while (true); | 127 } while (true); |
| 139 return negative ? -result : result; | 128 return negative ? -result : result; |
| 140 } | 129 } |
| 141 } | 130 } |
| OLD | NEW |