| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.convert; | 5 part of dart.convert; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * An instance of the default implementation of the [Latin1Codec]. | 8 * An instance of the default implementation of the [Latin1Codec]. |
| 9 * | 9 * |
| 10 * This instance provides a convenient access to the most common ISO Latin 1 | 10 * This instance provides a convenient access to the most common ISO Latin 1 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 /** | 43 /** |
| 44 * Decodes the Latin-1 [bytes] (a list of unsigned 8-bit integers) to the | 44 * Decodes the Latin-1 [bytes] (a list of unsigned 8-bit integers) to the |
| 45 * corresponding string. | 45 * corresponding string. |
| 46 * | 46 * |
| 47 * If [bytes] contains values that are not in the range 0 .. 255, the decoder | 47 * If [bytes] contains values that are not in the range 0 .. 255, the decoder |
| 48 * will eventually throw a [FormatException]. | 48 * will eventually throw a [FormatException]. |
| 49 * | 49 * |
| 50 * If [allowInvalid] is not provided, it defaults to the value used to create | 50 * If [allowInvalid] is not provided, it defaults to the value used to create |
| 51 * this [Latin1Codec]. | 51 * this [Latin1Codec]. |
| 52 */ | 52 */ |
| 53 String decode(List<int> bytes, { bool allowInvalid }) { | 53 String decode(List<int> bytes, {bool allowInvalid}) { |
| 54 if (allowInvalid == null) allowInvalid = _allowInvalid; | 54 if (allowInvalid == null) allowInvalid = _allowInvalid; |
| 55 if (allowInvalid) { | 55 if (allowInvalid) { |
| 56 return const Latin1Decoder(allowInvalid: true).convert(bytes); | 56 return const Latin1Decoder(allowInvalid: true).convert(bytes); |
| 57 } else { | 57 } else { |
| 58 return const Latin1Decoder(allowInvalid: false).convert(bytes); | 58 return const Latin1Decoder(allowInvalid: false).convert(bytes); |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 Latin1Encoder get encoder => const Latin1Encoder(); | 62 Latin1Encoder get encoder => const Latin1Encoder(); |
| 63 | 63 |
| 64 Latin1Decoder get decoder => | 64 Latin1Decoder get decoder => _allowInvalid |
| 65 _allowInvalid ? const Latin1Decoder(allowInvalid: true) | 65 ? const Latin1Decoder(allowInvalid: true) |
| 66 : const Latin1Decoder(allowInvalid: false); | 66 : const Latin1Decoder(allowInvalid: false); |
| 67 } | 67 } |
| 68 | 68 |
| 69 /** | 69 /** |
| 70 * This class converts strings of only ISO Latin-1 characters to bytes. | 70 * This class converts strings of only ISO Latin-1 characters to bytes. |
| 71 */ | 71 */ |
| 72 class Latin1Encoder extends _UnicodeSubsetEncoder { | 72 class Latin1Encoder extends _UnicodeSubsetEncoder { |
| 73 const Latin1Encoder() : super(_LATIN1_MASK); | 73 const Latin1Encoder() : super(_LATIN1_MASK); |
| 74 } | 74 } |
| 75 | 75 |
| 76 /** | 76 /** |
| 77 * This class converts Latin-1 bytes (lists of unsigned 8-bit integers) | 77 * This class converts Latin-1 bytes (lists of unsigned 8-bit integers) |
| 78 * to a string. | 78 * to a string. |
| 79 */ | 79 */ |
| 80 class Latin1Decoder extends _UnicodeSubsetDecoder { | 80 class Latin1Decoder extends _UnicodeSubsetDecoder { |
| 81 /** | 81 /** |
| 82 * Instantiates a new [Latin1Decoder]. | 82 * Instantiates a new [Latin1Decoder]. |
| 83 * | 83 * |
| 84 * The optional [allowInvalid] argument defines how [convert] deals | 84 * The optional [allowInvalid] argument defines how [convert] deals |
| 85 * with invalid bytes. | 85 * with invalid bytes. |
| 86 * | 86 * |
| 87 * If it is `true`, [convert] replaces invalid bytes with the Unicode | 87 * If it is `true`, [convert] replaces invalid bytes with the Unicode |
| 88 * Replacement character `U+FFFD` (�). | 88 * Replacement character `U+FFFD` (�). |
| 89 * Otherwise it throws a [FormatException]. | 89 * Otherwise it throws a [FormatException]. |
| 90 */ | 90 */ |
| 91 const Latin1Decoder({ bool allowInvalid: false }) | 91 const Latin1Decoder({bool allowInvalid: false}) |
| 92 : super(allowInvalid, _LATIN1_MASK); | 92 : super(allowInvalid, _LATIN1_MASK); |
| 93 | 93 |
| 94 /** | 94 /** |
| 95 * Starts a chunked conversion. | 95 * Starts a chunked conversion. |
| 96 * | 96 * |
| 97 * The converter works more efficiently if the given [sink] is a | 97 * The converter works more efficiently if the given [sink] is a |
| 98 * [StringConversionSink]. | 98 * [StringConversionSink]. |
| 99 */ | 99 */ |
| 100 ByteConversionSink startChunkedConversion(Sink<String> sink) { | 100 ByteConversionSink startChunkedConversion(Sink<String> sink) { |
| 101 StringConversionSink stringSink; | 101 StringConversionSink stringSink; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } | 145 } |
| 146 | 146 |
| 147 static void _checkValidLatin1(List<int> source, int start, int end) { | 147 static void _checkValidLatin1(List<int> source, int start, int end) { |
| 148 int mask = 0; | 148 int mask = 0; |
| 149 for (int i = start; i < end; i++) { | 149 for (int i = start; i < end; i++) { |
| 150 mask |= source[i]; | 150 mask |= source[i]; |
| 151 } | 151 } |
| 152 if (mask >= 0 && mask <= _LATIN1_MASK) { | 152 if (mask >= 0 && mask <= _LATIN1_MASK) { |
| 153 return; | 153 return; |
| 154 } | 154 } |
| 155 _reportInvalidLatin1(source, start, end); // Always throws. | 155 _reportInvalidLatin1(source, start, end); // Always throws. |
| 156 } | 156 } |
| 157 | 157 |
| 158 | |
| 159 static void _reportInvalidLatin1(List<int> source, int start, int end) { | 158 static void _reportInvalidLatin1(List<int> source, int start, int end) { |
| 160 // Find the index of the first non-Latin-1 character code. | 159 // Find the index of the first non-Latin-1 character code. |
| 161 for (int i = start; i < end; i++) { | 160 for (int i = start; i < end; i++) { |
| 162 int char = source[i]; | 161 int char = source[i]; |
| 163 if (char < 0 || char > _LATIN1_MASK) { | 162 if (char < 0 || char > _LATIN1_MASK) { |
| 164 throw new FormatException("Source contains non-Latin-1 characters.", | 163 throw new FormatException( |
| 165 source, i); | 164 "Source contains non-Latin-1 characters.", source, i); |
| 166 } | 165 } |
| 167 } | 166 } |
| 168 // Unreachable - we only call the function if the loop above throws. | 167 // Unreachable - we only call the function if the loop above throws. |
| 169 assert(false); | 168 assert(false); |
| 170 } | 169 } |
| 171 } | 170 } |
| 172 | 171 |
| 173 class _Latin1AllowInvalidDecoderSink extends _Latin1DecoderSink { | 172 class _Latin1AllowInvalidDecoderSink extends _Latin1DecoderSink { |
| 174 _Latin1AllowInvalidDecoderSink(StringConversionSink sink): super(sink); | 173 _Latin1AllowInvalidDecoderSink(StringConversionSink sink) : super(sink); |
| 175 | 174 |
| 176 void addSlice(List<int> source, int start, int end, bool isLast) { | 175 void addSlice(List<int> source, int start, int end, bool isLast) { |
| 177 RangeError.checkValidRange(start, end, source.length); | 176 RangeError.checkValidRange(start, end, source.length); |
| 178 for (int i = start; i < end; i++) { | 177 for (int i = start; i < end; i++) { |
| 179 int char = source[i]; | 178 int char = source[i]; |
| 180 if (char > _LATIN1_MASK || char < 0) { | 179 if (char > _LATIN1_MASK || char < 0) { |
| 181 if (i > start) _addSliceToSink(source, start, i, false); | 180 if (i > start) _addSliceToSink(source, start, i, false); |
| 182 // Add UTF-8 encoding of U+FFFD. | 181 // Add UTF-8 encoding of U+FFFD. |
| 183 _addSliceToSink(const[0xFFFD], 0, 1, false); | 182 _addSliceToSink(const [0xFFFD], 0, 1, false); |
| 184 start = i + 1; | 183 start = i + 1; |
| 185 } | 184 } |
| 186 } | 185 } |
| 187 if (start < end) { | 186 if (start < end) { |
| 188 _addSliceToSink(source, start, end, isLast); | 187 _addSliceToSink(source, start, end, isLast); |
| 189 } | 188 } |
| 190 if (isLast) { | 189 if (isLast) { |
| 191 close(); | 190 close(); |
| 192 } | 191 } |
| 193 } | 192 } |
| 194 } | 193 } |
| OLD | NEW |