| Index: sdk/lib/async/stream_pipe.dart
|
| diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
|
| index ca1164dea81bb084211ee36eaff5e128bd744228..a2fc15d5e3adbfe84a89494c940f4dc7f9d96e82 100644
|
| --- a/sdk/lib/async/stream_pipe.dart
|
| +++ b/sdk/lib/async/stream_pipe.dart
|
| @@ -308,20 +308,32 @@ class _HandleErrorStream<T> extends _ForwardingStream<T, T> {
|
|
|
|
|
| class _TakeStream<T> extends _ForwardingStream<T, T> {
|
| - int _remaining;
|
| + final int _count;
|
|
|
| _TakeStream(Stream<T> source, int count)
|
| - : this._remaining = count, super(source) {
|
| + : this._count = count, super(source) {
|
| // This test is done early to avoid handling an async error
|
| // in the _handleData method.
|
| if (count is! int) throw new ArgumentError(count);
|
| }
|
|
|
| + StreamSubscription<T> _createSubscription(
|
| + void onData(T data),
|
| + Function onError,
|
| + void onDone(),
|
| + bool cancelOnError) {
|
| + return new _StateStreamSubscription<T>(
|
| + this, onData, onError, onDone, cancelOnError, _count);
|
| + }
|
| +
|
| void _handleData(T inputEvent, _EventSink<T> sink) {
|
| - if (_remaining > 0) {
|
| + _StateStreamSubscription subscription = sink;
|
| + int count = subscription._count;
|
| + if (count > 0) {
|
| sink._add(inputEvent);
|
| - _remaining -= 1;
|
| - if (_remaining == 0) {
|
| + count -= 1;
|
| + subscription._count = count;
|
| + if (count == 0) {
|
| // Closing also unsubscribes all subscribers, which unsubscribes
|
| // this from source.
|
| sink._close();
|
| @@ -330,6 +342,26 @@ class _TakeStream<T> extends _ForwardingStream<T, T> {
|
| }
|
| }
|
|
|
| +/**
|
| + * A [_ForwardingStreamSubscription] with one extra state field.
|
| + *
|
| + * Use by several different classes, some storing an integer, others a bool.
|
| + */
|
| +class _StateStreamSubscription<T> extends _ForwardingStreamSubscription<T, T> {
|
| + // Raw state field. Typed access provided by getters and setters below.
|
| + var _sharedState;
|
| +
|
| + _StateStreamSubscription(_ForwardingStream stream, void onData(T data),
|
| + Function onError, void onDone(),
|
| + bool cancelOnError, this._sharedState)
|
| + : super(stream, onData, onError, onDone, cancelOnError);
|
| +
|
| + bool get _flag => _sharedState;
|
| + void set _flag(bool flag) { _sharedState = flag; }
|
| + int get _count => _sharedState;
|
| + void set _count(int count) { _sharedState = count; }
|
| +}
|
| +
|
|
|
| class _TakeWhileStream<T> extends _ForwardingStream<T, T> {
|
| final _Predicate<T> _test;
|
| @@ -356,18 +388,29 @@ class _TakeWhileStream<T> extends _ForwardingStream<T, T> {
|
| }
|
|
|
| class _SkipStream<T> extends _ForwardingStream<T, T> {
|
| - int _remaining;
|
| + final int _count;
|
|
|
| _SkipStream(Stream<T> source, int count)
|
| - : this._remaining = count, super(source) {
|
| + : this._count = count, super(source) {
|
| // This test is done early to avoid handling an async error
|
| // in the _handleData method.
|
| if (count is! int || count < 0) throw new ArgumentError(count);
|
| }
|
|
|
| + StreamSubscription<T> _createSubscription(
|
| + void onData(T data),
|
| + Function onError,
|
| + void onDone(),
|
| + bool cancelOnError) {
|
| + return new _StateStreamSubscription<T>(
|
| + this, onData, onError, onDone, cancelOnError, _count);
|
| + }
|
| +
|
| void _handleData(T inputEvent, _EventSink<T> sink) {
|
| - if (_remaining > 0) {
|
| - _remaining--;
|
| + _StateStreamSubscription subscription = sink;
|
| + int count = subscription._count;
|
| + if (count > 0) {
|
| + subscription._count = count - 1;
|
| return;
|
| }
|
| sink._add(inputEvent);
|
| @@ -376,13 +419,23 @@ class _SkipStream<T> extends _ForwardingStream<T, T> {
|
|
|
| class _SkipWhileStream<T> extends _ForwardingStream<T, T> {
|
| final _Predicate<T> _test;
|
| - bool _hasFailed = false;
|
|
|
| _SkipWhileStream(Stream<T> source, bool test(T value))
|
| : this._test = test, super(source);
|
|
|
| + StreamSubscription<T> _createSubscription(
|
| + void onData(T data),
|
| + Function onError,
|
| + void onDone(),
|
| + bool cancelOnError) {
|
| + return new _StateStreamSubscription<T>(
|
| + this, onData, onError, onDone, cancelOnError, false);
|
| + }
|
| +
|
| void _handleData(T inputEvent, _EventSink<T> sink) {
|
| - if (_hasFailed) {
|
| + _StateStreamSubscription subscription = sink;
|
| + bool hasFailed = subscription._flag;
|
| + if (hasFailed) {
|
| sink._add(inputEvent);
|
| return;
|
| }
|
| @@ -392,11 +445,11 @@ class _SkipWhileStream<T> extends _ForwardingStream<T, T> {
|
| } catch (e, s) {
|
| _addErrorWithReplacement(sink, e, s);
|
| // A failure to return a boolean is considered "not matching".
|
| - _hasFailed = true;
|
| + subscription._flag = true;
|
| return;
|
| }
|
| if (!satisfies) {
|
| - _hasFailed = true;
|
| + subscription._flag = true;
|
| sink._add(inputEvent);
|
| }
|
| }
|
|
|