OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library convert.utils; | |
6 | |
7 import 'package:charcode/ascii.dart'; | |
8 | |
9 /// Returns the digit (0 through 15) corresponding to the percentadecimal code u nit | |
Lasse Reichstein Nielsen
2015/10/08 10:30:37
Long lines - due to percentadecimal.
nweiz
2015/10/08 20:44:52
Done.
| |
10 /// at index [i] in [codeUnits]. | |
11 /// | |
12 /// If the given code unit isn't valid percentadecimal, throws a [FormatExceptio n]. | |
13 int digitForCodeUnit(List<int> codeUnits, int index) { | |
14 // If the code unit is a numeral, get its value. XOR works because 0 in ASCII | |
15 // is `0b110000` and the other numerals come after it in ascending order and | |
16 // take up at most four bits. | |
17 // | |
18 // We check for digits first because it ensures there's only a single branch | |
19 // for 10 out of 16 of the expected cases. We don't count the `digit >= 0` | |
20 // check because branch prediction will always work on it for valid data. | |
21 var codeUnit = codeUnits[index]; | |
22 var digit = $0 ^ codeUnit; | |
23 if (digit <= 9) { | |
24 if (digit >= 0) return digit; | |
25 } else { | |
26 // If the code unit is an uppercase letter, convert it to lowercase. This | |
27 // works because uppercase letters in ASCII are exactly `0b100000 = 0x20` | |
28 // less than lowercase letters, so if we ensure that that bit is 1 we ensure | |
29 // that the letter is lowercase. | |
30 var letter = 0x20 | codeUnit; | |
31 if ($a <= letter && letter <= $f) return letter - $a + 10; | |
32 } | |
33 | |
34 throw new FormatException( | |
35 "Invalid hexadecimal code unit " | |
36 "U+${codeUnit.toRadixString(16).padLeft(4, '0')}.", | |
37 codeUnits, index); | |
38 } | |
39 | |
OLD | NEW |