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 |