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

Side by Side Diff: runtime/bin/string_stream.dart

Issue 8477026: Change the handling of the close event in the StringInputStream (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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/src/StringStreamTest.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 // Utility class which can deliver bytes one by one from a number of 5 // Utility class which can deliver bytes one by one from a number of
6 // buffers added. 6 // buffers added.
7 class _BufferList { 7 class _BufferList {
8 _BufferList() : _index = 0, _length = 0, _buffers = new Queue(); 8 _BufferList() : _index = 0, _length = 0, _buffers = new Queue();
9 9
10 void add(List<int> buffer) { 10 void add(List<int> buffer) {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 // If there is buffered data return that first. 191 // If there is buffered data return that first.
192 var decodedString = _decoder.decoded; 192 var decodedString = _decoder.decoded;
193 if (_buffer !== null) { 193 if (_buffer !== null) {
194 var result = _buffer; 194 var result = _buffer;
195 _resetBuffer(); 195 _resetBuffer();
196 if (decodedString !== null) result += decodedString; 196 if (decodedString !== null) result += decodedString;
197 return result; 197 return result;
198 } else { 198 } else {
199 if (decodedString !== null) { 199 if (decodedString !== null) {
200 return decodedString; 200 return decodedString;
201 } else if (_inputClosed) {
202 _streamClosed();
203 return null;
201 } else { 204 } else {
202 _readData(); 205 _readData();
203 return _decoder.decoded; 206 return _decoder.decoded;
204 } 207 }
205 } 208 }
206 } 209 }
207 210
208 String readLine() { 211 String readLine() {
212 if (_closed) return null;
209 // Get line from the buffer if possible. 213 // Get line from the buffer if possible.
210 if (_buffer !== null) { 214 if (_buffer !== null) {
211 var result = _readLineFromBuffer(); 215 var result = _readLineFromBuffer();
212 if (result !== null) return result; 216 if (result !== null) return result;
213 } 217 }
214 // Try to fill more data into the buffer and read a line. 218 // Try to fill more data into the buffer and read a line.
215 if (_fillBuffer()) { 219 if (_fillBuffer()) {
216 if (_eof && _buffer === null) return null; 220 if (_eof && _buffer === null) {
221 _streamClosed();
222 return null;
223 }
217 return _readLineFromBuffer(); 224 return _readLineFromBuffer();
218 } 225 }
219 return null; 226 return null;
220 } 227 }
221 228
222 String get encoding() => _encoding; 229 String get encoding() => _encoding;
223 230
224 bool get closed() => _closed; 231 bool get closed() => _closed;
225 232
226 void set dataHandler(void callback()) { 233 void set dataHandler(void callback()) {
227 _clientDataHandler = callback; 234 _clientDataHandler = callback;
228 } 235 }
229 236
230 void set closeHandler(void callback()) { 237 void set closeHandler(void callback()) {
231 _clientCloseHandler = callback; 238 _clientCloseHandler = callback;
232 } 239 }
233 240
234 void _dataHandler() { 241 void _dataHandler() {
235 _readData(); 242 _readData();
236 if (!_decoder.isEmpty() && _clientDataHandler !== null) { 243 if (!_decoder.isEmpty() && _clientDataHandler !== null) {
237 _clientDataHandler(); 244 _clientDataHandler();
238 } 245 }
239 } 246 }
240 247
241 void _closeHandler() { 248 void _closeHandler() {
242 _closed = true; 249 _inputClosed = true;
243 if (_clientDataHandler !== null) _clientDataHandler(); 250 if (_buffer !== null || !_decoder.isEmpty()) {
244 if (_clientCloseHandler !== null) _clientCloseHandler(); 251 // If there is still data buffered in either the buffer or the
252 // decoder call the data handler.
253 if (_clientDataHandler !== null) _clientDataHandler();
254 } else {
255 closed_ = true;
256 if (_clientCloseHandler !== null) _clientCloseHandler();
257 }
245 } 258 }
246 259
247 void _readData() { 260 void _readData() {
248 List<int> data = _input.read(); 261 List<int> data = _input.read();
249 if (data !== null) { 262 if (data !== null) {
250 _decoder.write(data); 263 _decoder.write(data);
251 } 264 }
252 } 265 }
253 266
254 String _readLineFromBuffer() { 267 String _readLineFromBuffer() {
255 // Both \n or \r indicates a new line. If \r is followed by \n the 268 // Both \n or \r indicates a new line. If \r is followed by \n the
256 // \n is part of the line breaking character. 269 // \n is part of the line breaking character.
257 for (int i = _bufferLineStart; i < _buffer.length; i++) { 270 for (int i = _bufferLineStart; i < _buffer.length; i++) {
258 String char = _buffer[i]; 271 String char = _buffer[i];
259 if (char == '\r') { 272 if (char == '\r') {
260 if (i == _buffer.length - 1) { 273 if (i == _buffer.length - 1) {
261 if (_eof) { 274 if (_eof) {
262 var result = _buffer.substring(_bufferLineStart, i); 275 var result = _buffer.substring(_bufferLineStart, i);
263 _resetBuffer(); 276 _resetBuffer();
277 _streamClosed();
264 return result; 278 return result;
265 } else { 279 } else {
266 return null; 280 return null;
267 } 281 }
268 } 282 }
269 var result = _buffer.substring(_bufferLineStart, i); 283 var result = _buffer.substring(_bufferLineStart, i);
270 _bufferLineStart = i + 1; 284 _bufferLineStart = i + 1;
271 if (_buffer[_bufferLineStart] == '\n') _bufferLineStart++; 285 if (_buffer[_bufferLineStart] == '\n') _bufferLineStart++;
286 if (_bufferLineStart == _buffer.length) _resetBuffer();
272 return result; 287 return result;
273 } else if (char == '\n') { 288 } else if (char == '\n') {
274 var result = _buffer.substring(_bufferLineStart, i); 289 var result = _buffer.substring(_bufferLineStart, i);
275 _bufferLineStart = i + 1; 290 _bufferLineStart = i + 1;
291 if (_bufferLineStart == _buffer.length) _resetBuffer();
276 return result; 292 return result;
277 } 293 }
278 } 294 }
279 if (_eof) { 295 if (_eof) {
280 var result = _buffer; 296 var result = _buffer;
281 _resetBuffer(); 297 _resetBuffer();
298 _streamClosed();
282 return result; 299 return result;
283 } 300 }
284 return null; 301 return null;
285 } 302 }
286 303
287 void _resetBuffer() { 304 void _resetBuffer() {
288 _buffer = null; 305 _buffer = null;
289 _bufferLineStart = null; 306 _bufferLineStart = null;
290 } 307 }
291 308
292 // Fill decoded data into the buffer. Returns true if more data was 309 // Fill decoded data into the buffer. Returns true if more data was
293 // added or end of file was reached. 310 // added or end of file was reached.
294 bool _fillBuffer() { 311 bool _fillBuffer() {
295 if (_eof) return false; 312 if (_eof) return false;
296 if (_buffer !== null && _bufferLineStart == _buffer.length) { 313 if (!_inputClosed) _readData();
297 _buffer = null;
298 _bufferLineStart = null;
299 }
300 _readData();
301 var decodedString = _decoder.decoded; 314 var decodedString = _decoder.decoded;
302 if (decodedString === null && _closed) { 315 if (decodedString === null && _inputClosed) {
303 _eof = true; 316 _eof = true;
304 return true; 317 return true;
305 } 318 }
306 if (_buffer === null) { 319 if (_buffer === null) {
307 _buffer = decodedString; 320 _buffer = decodedString;
308 if (_buffer !== null) { 321 if (_buffer !== null) {
309 _bufferLineStart = 0; 322 _bufferLineStart = 0;
310 return true; 323 return true;
311 } 324 }
312 } else if (decodedString !== null) { 325 } else if (decodedString !== null) {
313 _buffer = _buffer.substring(_bufferLineStart) + decodedString; 326 _buffer = _buffer.substring(_bufferLineStart) + decodedString;
314 _bufferLineStart = 0; 327 _bufferLineStart = 0;
315 return true; 328 return true;
316 } 329 }
317 return false; 330 return false;
318 } 331 }
319 332
333 void _streamClosed() {
334 _closed = true;
335
336 // TODO(sgjesse): Find a better way of scheduling callbacks from
337 // the event loop.
338 void issueCloseCallback(Timer timer) {
339 if (_clientCloseHandler !== null) _clientCloseHandler();
340 }
341 new Timer(issueCloseCallback, 0, false);
342 }
343
320 InputStream _input; 344 InputStream _input;
321 String _encoding; 345 String _encoding;
322 _Decoder _decoder; 346 _Decoder _decoder;
323 String _buffer; // String can be buffered here if readLine is used. 347 String _buffer; // String can be buffered here if readLine is used.
324 int _bufferLineStart; // Current offset into _buffer if any. 348 int _bufferLineStart; // Current offset into _buffer if any.
325 bool _closed = false; 349 bool _inputClosed = false; // Is the underlying input stream closed?
350 bool _closed = false; // Is this stream closed.
326 bool _eof = false; // Has all data been read from the decoder? 351 bool _eof = false; // Has all data been read from the decoder?
327 var _clientDataHandler; 352 var _clientDataHandler;
328 var _clientCloseHandler; 353 var _clientCloseHandler;
329 } 354 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/src/StringStreamTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698