Index: lib/src/hex/decoder.dart |
diff --git a/lib/src/hex/decoder.dart b/lib/src/hex/decoder.dart |
index 2ba169af364e84f036bfd2668619843ae103818e..5b959d70307f81e3137f078dd5745a1375ee39a2 100644 |
--- a/lib/src/hex/decoder.dart |
+++ b/lib/src/hex/decoder.dart |
@@ -7,7 +7,7 @@ library convert.hex.decoder; |
import 'dart:convert'; |
import 'dart:typed_data'; |
-import 'package:charcode/ascii.dart'; |
+import '../utils.dart'; |
/// The canonical instance of [HexDecoder]. |
const hexDecoder = const HexDecoder._(); |
@@ -66,7 +66,7 @@ class _HexDecoderSink extends StringConversionSinkBase { |
} else { |
var hexPairs = (end - start - 1) ~/ 2; |
bytes = new Uint8List(1 + hexPairs); |
- bytes[0] = _lastDigit + _digitForCodeUnit(codeUnits, start); |
+ bytes[0] = _lastDigit + digitForCodeUnit(codeUnits, start); |
start++; |
bytesStart = 1; |
} |
@@ -121,7 +121,7 @@ class _HexDecoderByteSink extends ByteConversionSinkBase { |
} else { |
var hexPairs = (end - start - 1) ~/ 2; |
bytes = new Uint8List(1 + hexPairs); |
- bytes[0] = _lastDigit + _digitForCodeUnit(chunk, start); |
+ bytes[0] = _lastDigit + digitForCodeUnit(chunk, start); |
start++; |
bytesStart = 1; |
} |
@@ -152,42 +152,11 @@ int _decode(List<int> codeUnits, int sourceStart, int sourceEnd, |
List<int> destination, int destinationStart) { |
var destinationIndex = destinationStart; |
for (var i = sourceStart; i < sourceEnd - 1; i += 2) { |
- var firstDigit = _digitForCodeUnit(codeUnits, i); |
- var secondDigit = _digitForCodeUnit(codeUnits, i + 1); |
+ var firstDigit = digitForCodeUnit(codeUnits, i); |
+ var secondDigit = digitForCodeUnit(codeUnits, i + 1); |
destination[destinationIndex++] = 16 * firstDigit + secondDigit; |
} |
if ((sourceEnd - sourceStart).isEven) return null; |
- return 16 * _digitForCodeUnit(codeUnits, sourceEnd - 1); |
-} |
- |
-/// Returns the digit (0 through 15) corresponding to the hexadecimal code unit |
-/// at index [i] in [codeUnits]. |
-/// |
-/// If the given code unit isn't valid hexadecimal, throws a [FormatException]. |
-int _digitForCodeUnit(List<int> codeUnits, int index) { |
- // If the code unit is a numeral, get its value. XOR works because 0 in ASCII |
- // is `0b110000` and the other numerals come after it in ascending order and |
- // take up at most four bits. |
- // |
- // We check for digits first because it ensures there's only a single branch |
- // for 10 out of 16 of the expected cases. We don't count the `digit >= 0` |
- // check because branch prediction will always work on it for valid data. |
- var codeUnit = codeUnits[index]; |
- var digit = $0 ^ codeUnit; |
- if (digit <= 9) { |
- if (digit >= 0) return digit; |
- } else { |
- // If the code unit is an uppercase letter, convert it to lowercase. This |
- // works because uppercase letters in ASCII are exactly `0b100000 = 0x20` |
- // less than lowercase letters, so if we ensure that that bit is 1 we ensure |
- // that the letter is lowercase. |
- var letter = 0x20 | codeUnit; |
- if ($a <= letter && letter <= $f) return letter - $a + 10; |
- } |
- |
- throw new FormatException( |
- "Invalid hexadecimal code unit " |
- "U+${codeUnit.toRadixString(16).padLeft(4, '0')}.", |
- codeUnits, index); |
+ return 16 * digitForCodeUnit(codeUnits, sourceEnd - 1); |
} |