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);