OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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 | 4 |
5 library convert.hex.decoder; | 5 library convert.hex.decoder; |
6 | 6 |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 import 'dart:typed_data'; | 8 import 'dart:typed_data'; |
9 | 9 |
10 import '../utils.dart'; | 10 import '../utils.dart'; |
11 | 11 |
12 /// The canonical instance of [HexDecoder]. | 12 /// The canonical instance of [HexDecoder]. |
13 const hexDecoder = const HexDecoder._(); | 13 const hexDecoder = const HexDecoder._(); |
14 | 14 |
15 /// A converter that decodes hexadecimal strings into byte arrays. | 15 /// A converter that decodes hexadecimal strings into byte arrays. |
16 /// | 16 /// |
17 /// Because two hexadecimal digits correspond to a single byte, this will throw | 17 /// Because two hexadecimal digits correspond to a single byte, this will throw |
18 /// a [FormatException] if given an odd-length string. It will also throw a | 18 /// a [FormatException] if given an odd-length string. It will also throw a |
19 /// [FormatException] if given a string containing non-hexadecimal code units. | 19 /// [FormatException] if given a string containing non-hexadecimal code units. |
20 class HexDecoder extends Converter<String, List<int>> { | 20 class HexDecoder |
| 21 extends ChunkedConverter<String, List<int>, String, List<int>> { |
21 const HexDecoder._(); | 22 const HexDecoder._(); |
22 | 23 |
23 List<int> convert(String string) { | 24 List<int> convert(String string) { |
24 if (!string.length.isEven) { | 25 if (!string.length.isEven) { |
25 throw new FormatException("Invalid input length, must be even.", | 26 throw new FormatException("Invalid input length, must be even.", |
26 string, string.length); | 27 string, string.length); |
27 } | 28 } |
28 | 29 |
29 var bytes = new Uint8List(string.length ~/ 2); | 30 var bytes = new Uint8List(string.length ~/ 2); |
30 _decode(string.codeUnits, 0, string.length, bytes, 0); | 31 _decode(string.codeUnits, 0, string.length, bytes, 0); |
(...skipping 20 matching lines...) Expand all Loading... |
51 | 52 |
52 void addSlice(String string, int start, int end, bool isLast) { | 53 void addSlice(String string, int start, int end, bool isLast) { |
53 RangeError.checkValidRange(start, end, string.length); | 54 RangeError.checkValidRange(start, end, string.length); |
54 | 55 |
55 if (start == end) { | 56 if (start == end) { |
56 if (isLast) _close(string, end); | 57 if (isLast) _close(string, end); |
57 return; | 58 return; |
58 } | 59 } |
59 | 60 |
60 var codeUnits = string.codeUnits; | 61 var codeUnits = string.codeUnits; |
61 var bytes; | 62 Uint8List bytes; |
62 var bytesStart; | 63 int bytesStart; |
63 if (_lastDigit == null) { | 64 if (_lastDigit == null) { |
64 bytes = new Uint8List((end - start) ~/ 2); | 65 bytes = new Uint8List((end - start) ~/ 2); |
65 bytesStart = 0; | 66 bytesStart = 0; |
66 } else { | 67 } else { |
67 var hexPairs = (end - start - 1) ~/ 2; | 68 var hexPairs = (end - start - 1) ~/ 2; |
68 bytes = new Uint8List(1 + hexPairs); | 69 bytes = new Uint8List(1 + hexPairs); |
69 bytes[0] = _lastDigit + digitForCodeUnit(codeUnits, start); | 70 bytes[0] = _lastDigit + digitForCodeUnit(codeUnits, start); |
70 start++; | 71 start++; |
71 bytesStart = 1; | 72 bytesStart = 1; |
72 } | 73 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 void add(List<int> chunk) => addSlice(chunk, 0, chunk.length, false); | 112 void add(List<int> chunk) => addSlice(chunk, 0, chunk.length, false); |
112 | 113 |
113 void addSlice(List<int> chunk, int start, int end, bool isLast) { | 114 void addSlice(List<int> chunk, int start, int end, bool isLast) { |
114 RangeError.checkValidRange(start, end, chunk.length); | 115 RangeError.checkValidRange(start, end, chunk.length); |
115 | 116 |
116 if (start == end) { | 117 if (start == end) { |
117 if (isLast) _close(chunk, end); | 118 if (isLast) _close(chunk, end); |
118 return; | 119 return; |
119 } | 120 } |
120 | 121 |
121 var bytes; | 122 Uint8List bytes; |
122 var bytesStart; | 123 int bytesStart; |
123 if (_lastDigit == null) { | 124 if (_lastDigit == null) { |
124 bytes = new Uint8List((end - start) ~/ 2); | 125 bytes = new Uint8List((end - start) ~/ 2); |
125 bytesStart = 0; | 126 bytesStart = 0; |
126 } else { | 127 } else { |
127 var hexPairs = (end - start - 1) ~/ 2; | 128 var hexPairs = (end - start - 1) ~/ 2; |
128 bytes = new Uint8List(1 + hexPairs); | 129 bytes = new Uint8List(1 + hexPairs); |
129 bytes[0] = _lastDigit + digitForCodeUnit(chunk, start); | 130 bytes[0] = _lastDigit + digitForCodeUnit(chunk, start); |
130 start++; | 131 start++; |
131 bytesStart = 1; | 132 bytesStart = 1; |
132 } | 133 } |
(...skipping 30 matching lines...) Expand all Loading... |
163 var destinationIndex = destinationStart; | 164 var destinationIndex = destinationStart; |
164 for (var i = sourceStart; i < sourceEnd - 1; i += 2) { | 165 for (var i = sourceStart; i < sourceEnd - 1; i += 2) { |
165 var firstDigit = digitForCodeUnit(codeUnits, i); | 166 var firstDigit = digitForCodeUnit(codeUnits, i); |
166 var secondDigit = digitForCodeUnit(codeUnits, i + 1); | 167 var secondDigit = digitForCodeUnit(codeUnits, i + 1); |
167 destination[destinationIndex++] = 16 * firstDigit + secondDigit; | 168 destination[destinationIndex++] = 16 * firstDigit + secondDigit; |
168 } | 169 } |
169 | 170 |
170 if ((sourceEnd - sourceStart).isEven) return null; | 171 if ((sourceEnd - sourceStart).isEven) return null; |
171 return 16 * digitForCodeUnit(codeUnits, sourceEnd - 1); | 172 return 16 * digitForCodeUnit(codeUnits, sourceEnd - 1); |
172 } | 173 } |
OLD | NEW |