OLD | NEW |
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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 _input.onError = callback; | 417 _input.onError = callback; |
418 _decoder.onError = (e) { | 418 _decoder.onError = (e) { |
419 _clientCloseHandler = null; | 419 _clientCloseHandler = null; |
420 _input.close(); | 420 _input.close(); |
421 callback(e); | 421 callback(e); |
422 }; | 422 }; |
423 } | 423 } |
424 | 424 |
425 void _onData() { | 425 void _onData() { |
426 _readData(); | 426 _readData(); |
427 if (!_decoder.isEmpty && _clientDataHandler !== null) { | 427 if (!_decoder.isEmpty && _clientDataHandler != null) { |
428 _clientDataHandler(); | 428 _clientDataHandler(); |
429 } | 429 } |
430 if (_decoder.lineBreaks > 0 && _clientLineHandler !== null) { | 430 if (_decoder.lineBreaks > 0 && _clientLineHandler != null) { |
431 _clientLineHandler(); | 431 _clientLineHandler(); |
432 } | 432 } |
433 _checkScheduleCallback(); | 433 _checkScheduleCallback(); |
434 _checkInstallDataHandler(); | 434 _checkInstallDataHandler(); |
435 } | 435 } |
436 | 436 |
437 void _onClosed() { | 437 void _onClosed() { |
438 _inputClosed = true; | 438 _inputClosed = true; |
439 if (_decoder.isEmpty && _clientCloseHandler != null) { | 439 if (_decoder.isEmpty && _clientCloseHandler != null) { |
440 _clientCloseHandler(); | 440 _clientCloseHandler(); |
441 } else { | 441 } else { |
442 _checkScheduleCallback(); | 442 _checkScheduleCallback(); |
443 } | 443 } |
444 } | 444 } |
445 | 445 |
446 void _readData() { | 446 void _readData() { |
447 List<int> data = _input.read(); | 447 List<int> data = _input.read(); |
448 if (data !== null) { | 448 if (data != null) { |
449 _decoder.write(data); | 449 _decoder.write(data); |
450 } | 450 } |
451 } | 451 } |
452 | 452 |
453 void _checkInstallDataHandler() { | 453 void _checkInstallDataHandler() { |
454 if (_inputClosed || | 454 if (_inputClosed || |
455 (_clientDataHandler === null && _clientLineHandler === null)) { | 455 (_clientDataHandler == null && _clientLineHandler == null)) { |
456 _input.onData = null; | 456 _input.onData = null; |
457 } else if (_clientDataHandler !== null) { | 457 } else if (_clientDataHandler != null) { |
458 if (_decoder.isEmpty) { | 458 if (_decoder.isEmpty) { |
459 _input.onData = _onData; | 459 _input.onData = _onData; |
460 } else { | 460 } else { |
461 _input.onData = null; | 461 _input.onData = null; |
462 } | 462 } |
463 } else { | 463 } else { |
464 assert(_clientLineHandler !== null); | 464 assert(_clientLineHandler != null); |
465 if (_decoder.lineBreaks == 0) { | 465 if (_decoder.lineBreaks == 0) { |
466 _input.onData = _onData; | 466 _input.onData = _onData; |
467 } else { | 467 } else { |
468 _input.onData = null; | 468 _input.onData = null; |
469 } | 469 } |
470 } | 470 } |
471 } | 471 } |
472 | 472 |
473 // TODO(sgjesse): Find a better way of scheduling callbacks from | 473 // TODO(sgjesse): Find a better way of scheduling callbacks from |
474 // the event loop. | 474 // the event loop. |
475 void _checkScheduleCallback() { | 475 void _checkScheduleCallback() { |
476 void issueDataCallback(Timer timer) { | 476 void issueDataCallback(Timer timer) { |
477 _scheduledDataCallback = null; | 477 _scheduledDataCallback = null; |
478 if (_clientDataHandler !== null) { | 478 if (_clientDataHandler != null) { |
479 _clientDataHandler(); | 479 _clientDataHandler(); |
480 _checkScheduleCallback(); | 480 _checkScheduleCallback(); |
481 } | 481 } |
482 } | 482 } |
483 | 483 |
484 void issueLineCallback(Timer timer) { | 484 void issueLineCallback(Timer timer) { |
485 _scheduledLineCallback = null; | 485 _scheduledLineCallback = null; |
486 if (_clientLineHandler !== null) { | 486 if (_clientLineHandler != null) { |
487 _clientLineHandler(); | 487 _clientLineHandler(); |
488 _checkScheduleCallback(); | 488 _checkScheduleCallback(); |
489 } | 489 } |
490 } | 490 } |
491 | 491 |
492 void issueCloseCallback(Timer timer) { | 492 void issueCloseCallback(Timer timer) { |
493 _scheduledCloseCallback = null; | 493 _scheduledCloseCallback = null; |
494 if (!_closed) { | 494 if (!_closed) { |
495 if (_clientCloseHandler !== null) _clientCloseHandler(); | 495 if (_clientCloseHandler != null) _clientCloseHandler(); |
496 _closed = true; | 496 _closed = true; |
497 } | 497 } |
498 } | 498 } |
499 | 499 |
500 if (!_closed) { | 500 if (!_closed) { |
501 // Schedule data callback if string data available. | 501 // Schedule data callback if string data available. |
502 if (_clientDataHandler != null && | 502 if (_clientDataHandler != null && |
503 !_decoder.isEmpty && | 503 !_decoder.isEmpty && |
504 _scheduledDataCallback == null) { | 504 _scheduledDataCallback == null) { |
505 if (_scheduledLineCallback != null) { | 505 if (_scheduledLineCallback != null) { |
(...skipping 27 matching lines...) Expand all Loading... |
533 bool _inputClosed = false; // Is the underlying input stream closed? | 533 bool _inputClosed = false; // Is the underlying input stream closed? |
534 bool _closed = false; // Is this stream closed. | 534 bool _closed = false; // Is this stream closed. |
535 bool _eof = false; // Has all data been read from the decoder? | 535 bool _eof = false; // Has all data been read from the decoder? |
536 Timer _scheduledDataCallback; | 536 Timer _scheduledDataCallback; |
537 Timer _scheduledLineCallback; | 537 Timer _scheduledLineCallback; |
538 Timer _scheduledCloseCallback; | 538 Timer _scheduledCloseCallback; |
539 Function _clientDataHandler; | 539 Function _clientDataHandler; |
540 Function _clientLineHandler; | 540 Function _clientLineHandler; |
541 Function _clientCloseHandler; | 541 Function _clientCloseHandler; |
542 } | 542 } |
OLD | NEW |