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

Side by Side Diff: sdk/lib/utf/utf_stream.dart

Issue 14696012: Make web-socket pass AutobanhTestSuite. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes Created 7 years, 7 months 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 | « sdk/lib/io/websocket_impl.dart ('k') | 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) 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.utf; 5 part of dart.utf;
6 6
7 class _HelperStreamController<T> extends StreamController<T> { 7 class _HelperStreamController<T> extends StreamController<T> {
8 final Function onPauseChanged; 8 final Function onPauseChanged;
9 9
10 _HelperStreamController(this.onPauseChanged); 10 _HelperStreamController(this.onPauseChanged);
11 11
12 void onPauseStateChange() { 12 void onPauseStateChange() {
13 onPauseChanged(); 13 onPauseChanged();
14 } 14 }
15 } 15 }
16 16
17 abstract class _StringDecoder 17 abstract class _StringDecoder
18 extends StreamEventTransformer<List<int>, String> { 18 extends StreamEventTransformer<List<int>, String> {
19 List<int> _carry; 19 List<int> _carry;
20 List<int> _buffer; 20 List<int> _buffer;
21 int _replacementChar; 21 int _replacementChar;
22 22
23 _StringDecoder(int this._replacementChar); 23 _StringDecoder(int this._replacementChar);
24 24
25 void handleData(List<int> bytes, EventSink<String> sink) { 25 void handleData(List<int> bytes, EventSink<String> sink) {
26 _buffer = <int>[]; 26 try {
27 List<int> carry = _carry; 27 _buffer = <int>[];
28 _carry = null; 28 List<int> carry = _carry;
29 int pos = 0; 29 _carry = null;
30 int available = bytes.length; 30 int pos = 0;
31 // If we have carry-over data, start from negative index, indicating carry 31 int available = bytes.length;
32 // index. 32 // If we have carry-over data, start from negative index, indicating carry
33 int goodChars = 0; 33 // index.
34 if (carry != null) pos = -carry.length; 34 int goodChars = 0;
35 while (pos < available) { 35 if (carry != null) pos = -carry.length;
36 int currentPos = pos; 36 while (pos < available) {
37 int getNext() { 37 int currentPos = pos;
38 if (pos < 0) { 38 int getNext() {
39 return carry[pos++ + carry.length]; 39 if (pos < 0) {
40 } else if (pos < available) { 40 return carry[pos++ + carry.length];
41 return bytes[pos++]; 41 } else if (pos < available) {
42 return bytes[pos++];
43 }
44 return null;
42 } 45 }
43 return null; 46 int consumed = _processBytes(getNext);
47 if (consumed > 0) {
48 goodChars = _buffer.length;
49 } else if (consumed == 0) {
50 _buffer.length = goodChars;
51 if (currentPos < 0) {
52 _carry = [];
53 _carry.addAll(carry);
54 _carry.addAll(bytes);
55 } else {
56 _carry = bytes.sublist(currentPos);
57 }
58 break;
59 } else {
60 // Invalid byte at position pos - 1
61 _buffer.length = goodChars;
62 _addChar(-1);
63 goodChars = _buffer.length;
64 }
44 } 65 }
45 int consumed = _processBytes(getNext); 66 if (_buffer.length > 0) {
46 if (consumed > 0) { 67 // Limit to 'goodChars', if lower than actual charCodes in the buffer.
47 goodChars = _buffer.length; 68 sink.add(new String.fromCharCodes(_buffer));
48 } else if (consumed == 0) {
49 _buffer.length = goodChars;
50 if (currentPos < 0) {
51 _carry = [];
52 _carry.addAll(carry);
53 _carry.addAll(bytes);
54 } else {
55 _carry = bytes.sublist(currentPos);
56 }
57 break;
58 } else {
59 // Invalid byte at position pos - 1
60 _buffer.length = goodChars;
61 _addChar(-1);
62 goodChars = _buffer.length;
63 } 69 }
70 _buffer = null;
71 } catch (e) {
72 sink.addError(e);
64 } 73 }
65 if (_buffer.length > 0) {
66 // Limit to 'goodChars', if lower than actual charCodes in the buffer.
67 sink.add(new String.fromCharCodes(_buffer));
68 }
69 _buffer = null;
70 } 74 }
71 75
72 void handleDone(EventSink<String> sink) { 76 void handleDone(EventSink<String> sink) {
73 if (_carry != null) { 77 if (_carry != null) {
74 sink.add(new String.fromCharCodes( 78 if (_replacementChar != null) {
75 new List.filled(_carry.length, _replacementChar))); 79 sink.add(new String.fromCharCodes(
80 new List.filled(_carry.length, _replacementChar)));
81 } else {
82 throw new ArgumentError('Invalid codepoint');
83 }
76 } 84 }
77 sink.close(); 85 sink.close();
78 } 86 }
79 87
80 int _processBytes(int getNext()); 88 int _processBytes(int getNext());
81 89
82 void _addChar(int char) { 90 void _addChar(int char) {
83 if (char > 0x10FFFF || char < 0) char = _replacementChar; 91 void error() {
92 if (_replacementChar != null) {
93 char = _replacementChar;
94 } else {
95 throw new ArgumentError('Invalid codepoint');
96 }
97 }
98 if (char < 0) error();
99 if (char >= 0xD800 && char <= 0xDFFF) error();
100 if (char > 0x10FFFF) error();
84 _buffer.add(char); 101 _buffer.add(char);
85 } 102 }
86 } 103 }
87 104
88 /** 105 /**
89 * StringTransformer that decodes a stream of UTF-8 encoded bytes. 106 * StringTransformer that decodes a stream of UTF-8 encoded bytes.
90 */ 107 */
91 class Utf8DecoderTransformer extends _StringDecoder { 108 class Utf8DecoderTransformer extends _StringDecoder {
92 Utf8DecoderTransformer( 109 Utf8DecoderTransformer(
93 [int replacementChar = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) 110 [int replacementChar = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT])
(...skipping 26 matching lines...) Expand all
120 additionalBytes = 5; 137 additionalBytes = 5;
121 min = 0x4000000; 138 min = 0x4000000;
122 } else { 139 } else {
123 return -1; 140 return -1;
124 } 141 }
125 for (int i = 0; i < additionalBytes; i++) { 142 for (int i = 0; i < additionalBytes; i++) {
126 int next = getNext(); 143 int next = getNext();
127 if (next == null) return 0; // Not enough chars, reset. 144 if (next == null) return 0; // Not enough chars, reset.
128 if ((next & 0xc0) != 0x80 || (next & 0xff) != next) return -1; 145 if ((next & 0xc0) != 0x80 || (next & 0xff) != next) return -1;
129 value = value << 6 | (next & 0x3f); 146 value = value << 6 | (next & 0x3f);
147 if (additionalBytes >= 3 && i == 0 && value << 12 > 0x10FFFF) {
148 _addChar(-1);
149 }
130 } 150 }
131 // Invalid charCode if less then minimum expected. 151 // Invalid charCode if less then minimum expected.
132 if (value < min) value = -1; 152 if (value < min) value = -1;
133 _addChar(value); 153 _addChar(value);
134 return 1 + additionalBytes; 154 return 1 + additionalBytes;
135 } 155 }
136 _addChar(value); 156 _addChar(value);
137 return 1; 157 return 1;
138 } 158 }
139 } 159 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 199 }
180 for (int i = additionalBytes; i > 0; i--) { 200 for (int i = additionalBytes; i > 0; i--) {
181 // 10xxxxxx (xxxxxx is next 6 bits from the top). 201 // 10xxxxxx (xxxxxx is next 6 bits from the top).
182 bytes.add(((charCode >> (6 * (i - 1))) & 0x3F) | 0x80); 202 bytes.add(((charCode >> (6 * (i - 1))) & 0x3F) | 0x80);
183 } 203 }
184 pos += additionalBytes + 1; 204 pos += additionalBytes + 1;
185 } 205 }
186 return bytes; 206 return bytes;
187 } 207 }
188 } 208 }
OLDNEW
« no previous file with comments | « sdk/lib/io/websocket_impl.dart ('k') | tests/standalone/io/string_decoder_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698