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 |