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.percent.decoder; | 5 library convert.percent.decoder; |
6 | 6 |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 | 8 |
9 import 'package:charcode/ascii.dart'; | 9 import 'package:charcode/ascii.dart'; |
10 import 'package:typed_data/typed_data.dart'; | 10 import 'package:typed_data/typed_data.dart'; |
11 | 11 |
12 import '../utils.dart'; | 12 import '../utils.dart'; |
13 | 13 |
14 /// The canonical instance of [PercentDecoder]. | 14 /// The canonical instance of [PercentDecoder]. |
15 const percentDecoder = const PercentDecoder._(); | 15 const percentDecoder = const PercentDecoder._(); |
16 | 16 |
17 const _lastPercent = -1; | 17 const _lastPercent = -1; |
18 | 18 |
19 /// A converter that decodes percent-encoded strings into byte arrays. | 19 /// A converter that decodes percent-encoded strings into byte arrays. |
20 /// | 20 /// |
21 /// To be maximally flexible, this will decode any percent-encoded byte and | 21 /// To be maximally flexible, this will decode any percent-encoded byte and |
22 /// will allow any non-percent-encoded byte other than `%`. By default, it | 22 /// will allow any non-percent-encoded byte other than `%`. By default, it |
23 /// interprets `+` as `0x2B` rather than `0x20` as emitted by | 23 /// interprets `+` as `0x2B` rather than `0x20` as emitted by |
24 /// [Uri.encodeQueryComponent]. | 24 /// [Uri.encodeQueryComponent]. |
25 /// | 25 /// |
26 /// This will throw a [FormatException] if the input string has an incomplete | 26 /// This will throw a [FormatException] if the input string has an incomplete |
27 /// percent-encoding, or if it contains non-ASCII code units. | 27 /// percent-encoding, or if it contains non-ASCII code units. |
28 class PercentDecoder extends Converter<String, List<int>> { | 28 class PercentDecoder |
| 29 extends ChunkedConverter<String, List<int>, String, List<int>> { |
29 const PercentDecoder._(); | 30 const PercentDecoder._(); |
30 | 31 |
31 List<int> convert(String string) { | 32 List<int> convert(String string) { |
32 var buffer = new Uint8Buffer(); | 33 var buffer = new Uint8Buffer(); |
33 var lastDigit = _decode(string.codeUnits, 0, string.length, buffer); | 34 var lastDigit = _decode(string.codeUnits, 0, string.length, buffer); |
34 | 35 |
35 if (lastDigit != null) { | 36 if (lastDigit != null) { |
36 throw new FormatException( | 37 throw new FormatException( |
37 "Input ended with incomplete encoded byte.", | 38 "Input ended with incomplete encoded byte.", |
38 string, string.length); | 39 string, string.length); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 236 |
236 for (var i = start; i < end; i++) { | 237 for (var i = start; i < end; i++) { |
237 var codeUnit = codeUnits[i]; | 238 var codeUnit = codeUnits[i]; |
238 if (codeUnit >= 0 && codeUnit <= 0x7f) continue; | 239 if (codeUnit >= 0 && codeUnit <= 0x7f) continue; |
239 throw new FormatException( | 240 throw new FormatException( |
240 "Non-ASCII code unit " | 241 "Non-ASCII code unit " |
241 "U+${codeUnit.toRadixString(16).padLeft(4, '0')}", | 242 "U+${codeUnit.toRadixString(16).padLeft(4, '0')}", |
242 codeUnits, i); | 243 codeUnits, i); |
243 } | 244 } |
244 } | 245 } |
OLD | NEW |