Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: sdk/lib/io/string_stream.dart

Issue 11473018: Improve streaming UTF-8 decoder (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/standalone/io/string_decoder_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // Interface for decoders decoding binary data into string data. The 5 // Interface for decoders decoding binary data into string data. The
6 // decoder keeps track of line breaks during decoding. 6 // decoder keeps track of line breaks during decoding.
7 abstract class _StringDecoder { 7 abstract class _StringDecoder {
8 // Add more binary data to be decoded. The ownership of the buffer 8 // Add more binary data to be decoded. The ownership of the buffer
9 // is transfered to the decoder and the caller most not modify it any more. 9 // is transfered to the decoder and the caller most not modify it any more.
10 int write(List<int> buffer); 10 int write(List<int> buffer);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 Function onError; 168 Function onError;
169 169
170 final int LF = 10; 170 final int LF = 10;
171 final int CR = 13; 171 final int CR = 13;
172 } 172 }
173 173
174 174
175 // Utility class for decoding UTF-8 from data delivered as a stream of 175 // Utility class for decoding UTF-8 from data delivered as a stream of
176 // bytes. 176 // bytes.
177 class _UTF8Decoder extends _StringDecoderBase { 177 class _UTF8Decoder extends _StringDecoderBase {
178 static const kMaxCodePoint = 0x10FFFF;
179 static const kReplacementCodePoint = 0x3f;
180
181 void _reportError(error) {
182 if (onError != null) {
183 onError(error);
184 return false;
185 } else {
186 throw error;
187 }
188 }
189
178 // Process the next UTF-8 encoded character. 190 // Process the next UTF-8 encoded character.
179 bool _processNext() { 191 bool _processNext() {
180 // Peek the next byte to calculate the number of bytes required for 192 // Peek the next byte to calculate the number of bytes required for
181 // the next character. 193 // the next character.
182 int value = _bufferList.peek() & 0xFF; 194 int value = _bufferList.peek() & 0xFF;
183 if ((value & 0x80) == 0x80) { 195 if ((value & 0x80) == 0x80) {
184 int additionalBytes; 196 int additionalBytes;
185 if ((value & 0xe0) == 0xc0) { // 110xxxxx 197 if ((value & 0xe0) == 0xc0) { // 110xxxxx
186 value = value & 0x1F; 198 value = value & 0x1F;
187 additionalBytes = 1; 199 additionalBytes = 1;
188 } else if ((value & 0xf0) == 0xe0) { // 1110xxxx 200 } else if ((value & 0xf0) == 0xe0) { // 1110xxxx
189 value = value & 0x0F; 201 value = value & 0x0F;
190 additionalBytes = 2; 202 additionalBytes = 2;
191 } else { // 11110xxx 203 } else if ((value & 0xf8) == 0xf0) { // 11110xxx
192 value = value & 0x07; 204 value = value & 0x07;
193 additionalBytes = 3; 205 additionalBytes = 3;
206 } else if ((value & 0xfc) == 0xf8) { // 111110xx
207 value = value & 0x03;
208 additionalBytes = 4;
209 } else if ((value & 0xfe) == 0xfc) { // 1111110x
210 value = value & 0x01;
211 additionalBytes = 5;
212 } else {
213 _reportError(new DecoderException("Illegal UTF-8"));
194 } 214 }
195 // Check if there are enough bytes to decode the character. Otherwise 215 // Check if there are enough bytes to decode the character. Otherwise
196 // return false. 216 // return false.
197 if (_bufferList.length < additionalBytes + 1) { 217 if (_bufferList.length < additionalBytes + 1) {
198 return false; 218 return false;
199 } 219 }
200 // Remove the value peeked from the buffer list. 220 // Remove the value peeked from the buffer list.
201 _bufferList.next(); 221 _bufferList.next();
202 for (int i = 0; i < additionalBytes; i++) { 222 for (int i = 0; i < additionalBytes; i++) {
203 int byte = _bufferList.next(); 223 int byte = _bufferList.next();
224 if ((byte & 0xc0) != 0x80) {
225 _reportError(new DecoderException("Illegal UTF-8"));
226 }
204 value = value << 6 | (byte & 0x3F); 227 value = value << 6 | (byte & 0x3F);
205 } 228 }
206 } else { 229 } else {
207 // Remove the value peeked from the buffer list. 230 // Remove the value peeked from the buffer list.
208 _bufferList.next(); 231 _bufferList.next();
209 } 232 }
210 addChar(value); 233 print(value.toRadixString(16));
Mads Ager (google) 2012/12/07 11:43:21 hovsa. ;-)
234 if (value > kMaxCodePoint) {
235 addChar(kReplacementCodePoint);
236 } else {
237 addChar(value);
238 }
211 return true; 239 return true;
212 } 240 }
213 } 241 }
214 242
215 243
216 // Utility class for decoding ascii data delivered as a stream of 244 // Utility class for decoding ascii data delivered as a stream of
217 // bytes. 245 // bytes.
218 class _AsciiDecoder extends _StringDecoderBase { 246 class _AsciiDecoder extends _StringDecoderBase {
219 // Process the next ascii encoded character. 247 // Process the next ascii encoded character.
220 bool _processNext() { 248 bool _processNext() {
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 bool _inputClosed = false; // Is the underlying input stream closed? 536 bool _inputClosed = false; // Is the underlying input stream closed?
509 bool _closed = false; // Is this stream closed. 537 bool _closed = false; // Is this stream closed.
510 bool _eof = false; // Has all data been read from the decoder? 538 bool _eof = false; // Has all data been read from the decoder?
511 Timer _scheduledDataCallback; 539 Timer _scheduledDataCallback;
512 Timer _scheduledLineCallback; 540 Timer _scheduledLineCallback;
513 Timer _scheduledCloseCallback; 541 Timer _scheduledCloseCallback;
514 Function _clientDataHandler; 542 Function _clientDataHandler;
515 Function _clientLineHandler; 543 Function _clientLineHandler;
516 Function _clientCloseHandler; 544 Function _clientCloseHandler;
517 } 545 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/io/string_decoder_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698