Accept 0x and 0X prefixes
diff --git a/lib/src/int64.dart b/lib/src/int64.dart
index 9c2a88d..a1d65dc 100644
--- a/lib/src/int64.dart
+++ b/lib/src/int64.dart
@@ -114,15 +114,28 @@
static Int64 _tryParse(String s, int radix) {
// A radix-36 digit is 5.17 bits, so 10 digits can fit 52 bits, the
// safe-integer range of a JavaScript Number.
- if (s.length <= 10) _parseViaInt(s, radix);
+ if (s.length <= 10) return _parseViaInt(s, radix);
s = s.trim();
+
+ // Try the fast path again. In the common case where no whitespace is
+ // trimmed, the test serves to guard the `codeUnitAt` references.
+ if (s.length <= 10) return _parseViaInt(s, radix);
+
+ bool negative = false;
+ int start = 0;
+ int ch = s.codeUnitAt(start);
+ negative = ch == 45; /* '-' */
+ if (negative || ch == 43 /* '+' */) start++;
+
if (radix == null) {
- if (s.startsWith('-0x')) return _parseRadix(s, true, 4, 16);
- if (s.startsWith('0x')) return _parseRadix(s, false, 3, 16);
+ if (s.codeUnitAt(start) == 48 /* '0' */ &&
+ s.codeUnitAt(start + 1) | 32 == 120 /* 'x' or 'X' */) {
+ return _parseRadix(s, negative, start + 2, 16);
+ }
radix = 10;
}
- if (s.startsWith('-')) return _parseRadix(s, true, 1, radix);
- return _parseRadix(s, false, 0, radix);
+
+ return _parseRadix(s, negative, start, radix);
}
static Int64 _parseViaInt(String s, int radix) {
diff --git a/test/int64_test.dart b/test/int64_test.dart
index 76693f6..3f3f21f 100644
--- a/test/int64_test.dart
+++ b/test/int64_test.dart
@@ -772,6 +772,78 @@
});
group("parse", () {
+ test("parse", () {
+ checkInt(int x) {
+ expect(Int64.parse('$x'), new Int64(x));
+ expect(Int64.parse('$x', radix: 10), new Int64(x));
+ expect(Int64.tryParse('$x'), new Int64(x));
+ expect(Int64.tryParse('$x', radix: 10), new Int64(x));
+ }
+
+ checkInt(0);
+ checkInt(1);
+ checkInt(-1);
+ checkInt(1000);
+ checkInt(12345678);
+ checkInt(-12345678);
+ checkInt(2147483647);
+ checkInt(2147483648);
+ checkInt(-2147483647);
+ checkInt(-2147483648);
+ checkInt(4294967295);
+ checkInt(4294967296);
+ checkInt(-4294967295);
+ checkInt(-4294967296);
+ checkInt(1000000000000);
+ checkInt(-1000000000000);
+ checkInt(1000000000001);
+ checkInt(-1000000000001);
+ expect(() => Int64.parseRadix('xyzzy', -1), throwsArgumentError);
+ expect(() => Int64.parseRadix('plugh', 10), throwsFormatException);
+
+ expect(() => Int64.parse('plugh', radix: 10), throwsFormatException);
+ expect(Int64.tryParse('plugh', radix: 10), isNull);
+
+ Int64 big = new Int64(1000000000000);
+ expect(Int64.tryParse('1000000000000'), big);
+ expect(Int64.tryParse('1000000000001'), big + 1);
+ expect(Int64.tryParse('+1000000000000'), big);
+ expect(Int64.tryParse('+1000000000001'), big + 1);
+ expect(Int64.tryParse('-1000000000000'), -big);
+ expect(Int64.tryParse('-1000000000001'), -(big + 1));
+
+ expect(Int64.tryParse(' 1000000000000 '), big);
+ expect(Int64.tryParse(' 1000000000001 '), big + 1);
+ expect(Int64.tryParse(' +1000000000000 '), big);
+ expect(Int64.tryParse(' +1000000000001 '), big + 1);
+ expect(Int64.tryParse(' -1000000000000 '), -big);
+ expect(Int64.tryParse(' -1000000000001 '), -(big + 1));
+ expect(Int64.tryParse(' + 1000000000000 '), isNull);
+ expect(Int64.tryParse(' + 1000000000001 '), isNull);
+ expect(Int64.tryParse(' - 1000000000000 '), isNull);
+ expect(Int64.tryParse(' - 1000000000001 '), isNull);
+
+ checkHex(String s, Int64 value) {
+ check(String s, Int64 value) {
+ expect(Int64.tryParse(s), value,
+ reason: '"$s" should parse to $value');
+ }
+
+ check(s.toLowerCase(), value);
+ check(s.toUpperCase(), value);
+ check(' ${s.toUpperCase()} ', value);
+ check(' ${s.toLowerCase()} ', value);
+ }
+
+ Int64 big2 = new Int64(0x1000000000);
+ checkHex('0x1000000000', big2);
+ checkHex('0x1000000001', big2 + 1);
+ checkHex('+0x1000000000', big2);
+ checkHex('+0x1000000001', big2 + 1);
+ checkHex('-0x1000000000', -big2);
+ checkHex('-0x1000000001', -(big2 + 1));
+ });
+
test("parseRadix10", () {
checkInt(int x) {
expect(Int64.parseRadix('$x', 10), new Int64(x));
@@ -795,6 +867,10 @@
checkInt(4294967296);
checkInt(-4294967295);
checkInt(-4294967296);
+ checkInt(1000000000000);
+ checkInt(-1000000000000);
+ checkInt(1000000000001);
+ checkInt(-1000000000001);
expect(() => Int64.parseRadix('xyzzy', -1), throwsArgumentError);
expect(() => Int64.parseRadix('plugh', 10), throwsFormatException);