Flutter Stream相关代码

Stella981
• 阅读 625
  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
  3 // BSD-style license that can be found in the LICENSE file.
  4 
  5 part of dart.async;
  6 
  7 // -------------------------------------------------------------------
  8 // Controller for creating and adding events to a stream.
  9 // -------------------------------------------------------------------
 10 
 11 /**
 12  * Type of a stream controller's `onListen`, `onPause` and `onResume` callbacks.
 13  */
 14 typedef void ControllerCallback();
 15 
 16 /**
 17  * Type of stream controller `onCancel` callbacks.
 18  *
 19  * The callback may return either `void` or a future.
 20  */
 21 typedef ControllerCancelCallback();
 22 
 23 /**
 24  * A controller with the stream it controls.
 25  *
 26  * This controller allows sending data, error and done events on
 27  * its [stream].
 28  * This class can be used to create a simple stream that others
 29  * can listen on, and to push events to that stream.
 30  *
 31  * It's possible to check whether the stream is paused or not, and whether
 32  * it has subscribers or not, as well as getting a callback when either of
 33  * these change.
 34  */
 35 abstract class StreamController<T> implements StreamSink<T> {
 36   /** The stream that this controller is controlling. */
 37   Stream<T> get stream;
 38 
 39   /**
 40    * A controller with a [stream] that supports only one single subscriber.
 41    *
 42    * If [sync] is true, the returned stream controller is a
 43    * [SynchronousStreamController], and must be used with the care
 44    * and attention necessary to not break the [Stream] contract. If in doubt,
 45    * use the non-sync version.
 46    *
 47    * Using an asynchronous controller will never give the wrong
 48    * behavior, but using a synchronous controller incorrectly can cause
 49    * otherwise correct programs to break.
 50    *
 51    * A synchronous controller is only intended for optimizing event
 52    * propagation when one asynchronous event immediately triggers another.
 53    * It should not be used unless the calls to [add] or [addError]
 54    * are guaranteed to occur in places where it won't break `Stream` invariants.
 55    *
 56    * Use synchronous controllers only to forward (potentially transformed)
 57    * events from another stream or a future.
 58    *
 59    * A Stream should be inert until a subscriber starts listening on it (using
 60    * the [onListen] callback to start producing events). Streams should not
 61    * leak resources (like websockets) when no user ever listens on the stream.
 62    *
 63    * The controller buffers all incoming events until a subscriber is
 64    * registered, but this feature should only be used in rare circumstances.
 65    *
 66    * The [onPause] function is called when the stream becomes
 67    * paused. [onResume] is called when the stream resumed.
 68    *
 69    * The [onListen] callback is called when the stream
 70    * receives its listener and [onCancel] when the listener ends
 71    * its subscription. If [onCancel] needs to perform an asynchronous operation,
 72    * [onCancel] should return a future that completes when the cancel operation
 73    * is done.
 74    *
 75    * If the stream is canceled before the controller needs new data the
 76    * [onResume] call might not be executed.
 77    */
 78   factory StreamController(
 79       {void onListen(),
 80       void onPause(),
 81       void onResume(),
 82       onCancel(),
 83       bool sync: false}) {
 84     return sync
 85         ? new _SyncStreamController<T>(onListen, onPause, onResume, onCancel)
 86         : new _AsyncStreamController<T>(onListen, onPause, onResume, onCancel);
 87   }
 88 
 89   /**
 90    * A controller where [stream] can be listened to more than once.
 91    *
 92    * The [Stream] returned by [stream] is a broadcast stream.
 93    * It can be listened to more than once.
 94    *
 95    * A Stream should be inert until a subscriber starts listening on it (using
 96    * the [onListen] callback to start producing events). Streams should not
 97    * leak resources (like websockets) when no user ever listens on the stream.
 98    *
 99    * Broadcast streams do not buffer events when there is no listener.
100    *
101    * The controller distributes any events to all currently subscribed
102    * listeners at the time when [add], [addError] or [close] is called.
103    * It is not allowed to call `add`, `addError`, or `close` before a previous
104    * call has returned. The controller does not have any internal queue of
105    * events, and if there are no listeners at the time the event is added,
106    * it will just be dropped, or, if it is an error, be reported as uncaught.
107    *
108    * Each listener subscription is handled independently,
109    * and if one pauses, only the pausing listener is affected.
110    * A paused listener will buffer events internally until unpaused or canceled.
111    *
112    * If [sync] is true, events may be fired directly by the stream's
113    * subscriptions during an [add], [addError] or [close] call.
114    * The returned stream controller is a [SynchronousStreamController],
115    * and must be used with the care and attention necessary to not break
116    * the [Stream] contract.
117    * See [Completer.sync] for some explanations on when a synchronous
118    * dispatching can be used.
119    * If in doubt, keep the controller non-sync.
120    *
121    * If [sync] is false, the event will always be fired at a later time,
122    * after the code adding the event has completed.
123    * In that case, no guarantees are given with regard to when
124    * multiple listeners get the events, except that each listener will get
125    * all events in the correct order. Each subscription handles the events
126    * individually.
127    * If two events are sent on an async controller with two listeners,
128    * one of the listeners may get both events
129    * before the other listener gets any.
130    * A listener must be subscribed both when the event is initiated
131    * (that is, when [add] is called)
132    * and when the event is later delivered,
133    * in order to receive the event.
134    *
135    * The [onListen] callback is called when the first listener is subscribed,
136    * and the [onCancel] is called when there are no longer any active listeners.
137    * If a listener is added again later, after the [onCancel] was called,
138    * the [onListen] will be called again.
139    */
140   factory StreamController.broadcast(
141       {void onListen(), void onCancel(), bool sync: false}) {
142     return sync
143         ? new _SyncBroadcastStreamController<T>(onListen, onCancel)
144         : new _AsyncBroadcastStreamController<T>(onListen, onCancel);
145   }
146 
147   /**
148    * The callback which is called when the stream is listened to.
149    *
150    * May be set to `null`, in which case no callback will happen.
151    */
152   ControllerCallback get onListen;
153 
154   void set onListen(void onListenHandler());
155 
156   /**
157    * The callback which is called when the stream is paused.
158    *
159    * May be set to `null`, in which case no callback will happen.
160    *
161    * Pause related callbacks are not supported on broadcast stream controllers.
162    */
163   ControllerCallback get onPause;
164 
165   void set onPause(void onPauseHandler());
166 
167   /**
168    * The callback which is called when the stream is resumed.
169    *
170    * May be set to `null`, in which case no callback will happen.
171    *
172    * Pause related callbacks are not supported on broadcast stream controllers.
173    */
174   ControllerCallback get onResume;
175 
176   void set onResume(void onResumeHandler());
177 
178   /**
179    * The callback which is called when the stream is canceled.
180    *
181    * May be set to `null`, in which case no callback will happen.
182    */
183   ControllerCancelCallback get onCancel;
184 
185   void set onCancel(onCancelHandler());
186 
187   /**
188    * Returns a view of this object that only exposes the [StreamSink] interface.
189    */
190   StreamSink<T> get sink;
191 
192   /**
193    * Whether the stream controller is closed for adding more events.
194    *
195    * The controller becomes closed by calling the [close] method.
196    * New events cannot be added, by calling [add] or [addError],
197    * to a closed controller.
198    *
199    * If the controller is closed,
200    * the "done" event might not have been delivered yet,
201    * but it has been scheduled, and it is too late to add more events.
202    */
203   bool get isClosed;
204 
205   /**
206    * Whether the subscription would need to buffer events.
207    *
208    * This is the case if the controller's stream has a listener and it is
209    * paused, or if it has not received a listener yet. In that case, the
210    * controller is considered paused as well.
211    *
212    * A broadcast stream controller is never considered paused. It always
213    * forwards its events to all uncanceled subscriptions, if any,
214    * and let the subscriptions handle their own pausing and buffering.
215    */
216   bool get isPaused;
217 
218   /** Whether there is a subscriber on the [Stream]. */
219   bool get hasListener;
220 
221   /**
222    * Sends a data [event].
223    *
224    * Listeners receive this event in a later microtask.
225    *
226    * Note that a synchronous controller (created by passing true to the `sync`
227    * parameter of the `StreamController` constructor) delivers events
228    * immediately. Since this behavior violates the contract mentioned here,
229    * synchronous controllers should only be used as described in the
230    * documentation to ensure that the delivered events always *appear* as if
231    * they were delivered in a separate microtask.
232    */
233   void add(T event);
234 
235   /**
236    * Sends or enqueues an error event.
237    *
238    * If [error] is `null`, it is replaced by a [NullThrownError].
239    *
240    * Listeners receive this event at a later microtask. This behavior can be
241    * overridden by using `sync` controllers. Note, however, that sync
242    * controllers have to satisfy the preconditions mentioned in the
243    * documentation of the constructors.
244    */
245   void addError(Object error, [StackTrace stackTrace]);
246 
247   /**
248    * Closes the stream.
249    *
250    * Listeners receive the done event at a later microtask. This behavior can be
251    * overridden by using `sync` controllers. Note, however, that sync
252    * controllers have to satisfy the preconditions mentioned in the
253    * documentation of the constructors.
254    */
255   Future close();
256 
257   /**
258    * Receives events from [source] and puts them into this controller's stream.
259    *
260    * Returns a future which completes when the source stream is done.
261    *
262    * Events must not be added directly to this controller using [add],
263    * [addError], [close] or [addStream], until the returned future
264    * is complete.
265    *
266    * Data and error events are forwarded to this controller's stream. A done
267    * event on the source will end the `addStream` operation and complete the
268    * returned future.
269    *
270    * If [cancelOnError] is true, only the first error on [source] is
271    * forwarded to the controller's stream, and the `addStream` ends
272    * after this. If [cancelOnError] is false, all errors are forwarded
273    * and only a done event will end the `addStream`.
274    * If [cancelOnError] is omitted, it defaults to false.
275    */
276   Future addStream(Stream<T> source, {bool cancelOnError});
277 }
278 
279 /**
280  * A stream controller that delivers its events synchronously.
281  *
282  * A synchronous stream controller is intended for cases where
283  * an already asynchronous event triggers an event on a stream.
284  *
285  * Instead of adding the event to the stream in a later microtask,
286  * causing extra latency, the event is instead fired immediately by the
287  * synchronous stream controller, as if the stream event was
288  * the current event or microtask.
289  *
290  * The synchronous stream controller can be used to break the contract
291  * on [Stream], and it must be used carefully to avoid doing so.
292  *
293  * The only advantage to using a [SynchronousStreamController] over a
294  * normal [StreamController] is the improved latency.
295  * Only use the synchronous version if the improvement is significant,
296  * and if its use is safe. Otherwise just use a normal stream controller,
297  * which will always have the correct behavior for a [Stream], and won't
298  * accidentally break other code.
299  *
300  * Adding events to a synchronous controller should only happen as the
301  * very last part of the handling of the original event.
302  * At that point, adding an event to the stream is equivalent to
303  * returning to the event loop and adding the event in the next microtask.
304  *
305  * Each listener callback will be run as if it was a top-level event
306  * or microtask. This means that if it throws, the error will be reported as
307  * uncaught as soon as possible.
308  * This is one reason to add the event as the last thing in the original event
309  * handler - any action done after adding the event will delay the report of
310  * errors in the event listener callbacks.
311  *
312  * If an event is added in a setting that isn't known to be another event,
313  * it may cause the stream's listener to get that event before the listener
314  * is ready to handle it. We promise that after calling [Stream.listen],
315  * you won't get any events until the code doing the listen has completed.
316  * Calling [add] in response to a function call of unknown origin may break
317  * that promise.
318  *
319  * An [onListen] callback from the controller is *not* an asynchronous event,
320  * and adding events to the controller in the `onListen` callback is always
321  * wrong. The events will be delivered before the listener has even received
322  * the subscription yet.
323  *
324  * The synchronous broadcast stream controller also has a restrictions that a
325  * normal stream controller does not:
326  * The [add], [addError], [close] and [addStream] methods *must not* be
327  * called while an event is being delivered.
328  * That is, if a callback on a subscription on the controller's stream causes
329  * a call to any of the functions above, the call will fail.
330  * A broadcast stream may have more than one listener, and if an
331  * event is added synchronously while another is being also in the process
332  * of being added, the latter event might reach some listeners before
333  * the former. To prevent that, an event cannot be added while a previous
334  * event is being fired.
335  * This guarantees that an event is fully delivered when the
336  * first [add], [addError] or [close] returns,
337  * and further events will be delivered in the correct order.
338  *
339  * This still only guarantees that the event is delivered to the subscription.
340  * If the subscription is paused, the actual callback may still happen later,
341  * and the event will instead be buffered by the subscription.
342  * Barring pausing, and the following buffered events that haven't been
343  * delivered yet, callbacks will be called synchronously when an event is added.
344  *
345  * Adding an event to a synchronous non-broadcast stream controller while
346  * another event is in progress may cause the second event to be delayed
347  * and not be delivered synchronously, and until that event is delivered,
348  * the controller will not act synchronously.
349  */
350 abstract class SynchronousStreamController<T> implements StreamController<T> {
351   /**
352    * Adds event to the controller's stream.
353    *
354    * As [StreamController.add], but must not be called while an event is
355    * being added by [add], [addError] or [close].
356    */
357   void add(T data);
358 
359   /**
360    * Adds error to the controller's stream.
361    *
362    * As [StreamController.addError], but must not be called while an event is
363    * being added by [add], [addError] or [close].
364    */
365   void addError(Object error, [StackTrace stackTrace]);
366 
367   /**
368    * Closes the controller's stream.
369    *
370    * As [StreamController.close], but must not be called while an event is
371    * being added by [add], [addError] or [close].
372    */
373   Future close();
374 }
375 
376 abstract class _StreamControllerLifecycle<T> {
377   StreamSubscription<T> _subscribe(
378       void onData(T data), Function onError, void onDone(), bool cancelOnError);
379   void _recordPause(StreamSubscription<T> subscription) {}
380   void _recordResume(StreamSubscription<T> subscription) {}
381   Future _recordCancel(StreamSubscription<T> subscription) => null;
382 }
383 
384 // Base type for implementations of stream controllers.
385 abstract class _StreamControllerBase<T>
386     implements
387         StreamController<T>,
388         _StreamControllerLifecycle<T>,
389         _EventSink<T>,
390         _EventDispatch<T> {}
391 
392 /**
393  * Default implementation of [StreamController].
394  *
395  * Controls a stream that only supports a single controller.
396  */
397 abstract class _StreamController<T> implements _StreamControllerBase<T> {
398   // The states are bit-flags. More than one can be set at a time.
399   //
400   // The "subscription state" goes through the states:
401   //   initial -> subscribed -> canceled.
402   // These are mutually exclusive.
403   // The "closed" state records whether the [close] method has been called
404   // on the controller. This can be done at any time. If done before
405   // subscription, the done event is queued. If done after cancel, the done
406   // event is ignored (just as any other event after a cancel).
407 
408   /** The controller is in its initial state with no subscription. */
409   static const int _STATE_INITIAL = 0;
410   /** The controller has a subscription, but hasn't been closed or canceled. */
411   static const int _STATE_SUBSCRIBED = 1;
412   /** The subscription is canceled. */
413   static const int _STATE_CANCELED = 2;
414   /** Mask for the subscription state. */
415   static const int _STATE_SUBSCRIPTION_MASK = 3;
416 
417   // The following state relate to the controller, not the subscription.
418   // If closed, adding more events is not allowed.
419   // If executing an [addStream], new events are not allowed either, but will
420   // be added by the stream.
421 
422   /**
423    * The controller is closed due to calling [close].
424    *
425    * When the stream is closed, you can neither add new events nor add new
426    * listeners.
427    */
428   static const int _STATE_CLOSED = 4;
429   /**
430    * The controller is in the middle of an [addStream] operation.
431    *
432    * While adding events from a stream, no new events can be added directly
433    * on the controller.
434    */
435   static const int _STATE_ADDSTREAM = 8;
436 
437   /**
438    * Field containing different data depending on the current subscription
439    * state.
440    *
441    * If [_state] is [_STATE_INITIAL], the field may contain a [_PendingEvents]
442    * for events added to the controller before a subscription.
443    *
444    * While [_state] is [_STATE_SUBSCRIBED], the field contains the subscription.
445    *
446    * When [_state] is [_STATE_CANCELED] the field is currently not used.
447    */
448   var _varData;
449 
450   /** Current state of the controller. */
451   int _state = _STATE_INITIAL;
452 
453   /**
454    * Future completed when the stream sends its last event.
455    *
456    * This is also the future returned by [close].
457    */
458   // TODO(lrn): Could this be stored in the varData field too, if it's not
459   // accessed until the call to "close"? Then we need to special case if it's
460   // accessed earlier, or if close is called before subscribing.
461   _Future _doneFuture;
462 
463   ControllerCallback onListen;
464   ControllerCallback onPause;
465   ControllerCallback onResume;
466   ControllerCancelCallback onCancel;
467 
468   _StreamController(this.onListen, this.onPause, this.onResume, this.onCancel);
469 
470   // Return a new stream every time. The streams are equal, but not identical.
471   Stream<T> get stream => new _ControllerStream<T>(this);
472 
473   /**
474    * Returns a view of this object that only exposes the [StreamSink] interface.
475    */
476   StreamSink<T> get sink => new _StreamSinkWrapper<T>(this);
477 
478   /**
479    * Whether a listener has existed and been canceled.
480    *
481    * After this, adding more events will be ignored.
482    */
483   bool get _isCanceled => (_state & _STATE_CANCELED) != 0;
484 
485   /** Whether there is an active listener. */
486   bool get hasListener => (_state & _STATE_SUBSCRIBED) != 0;
487 
488   /** Whether there has not been a listener yet. */
489   bool get _isInitialState =>
490       (_state & _STATE_SUBSCRIPTION_MASK) == _STATE_INITIAL;
491 
492   bool get isClosed => (_state & _STATE_CLOSED) != 0;
493 
494   bool get isPaused =>
495       hasListener ? _subscription._isInputPaused : !_isCanceled;
496 
497   bool get _isAddingStream => (_state & _STATE_ADDSTREAM) != 0;
498 
499   /** New events may not be added after close, or during addStream. */
500   bool get _mayAddEvent => (_state < _STATE_CLOSED);
501 
502   // Returns the pending events.
503   // Pending events are events added before a subscription exists.
504   // They are added to the subscription when it is created.
505   // Pending events, if any, are kept in the _varData field until the
506   // stream is listened to.
507   // While adding a stream, pending events are moved into the
508   // state object to allow the state object to use the _varData field.
509   _PendingEvents<T> get _pendingEvents {
510     assert(_isInitialState);
511     if (!_isAddingStream) {
512       return _varData;
513     }
514     _StreamControllerAddStreamState<T> state = _varData;
515     return state.varData;
516   }
517 
518   // Returns the pending events, and creates the object if necessary.
519   _StreamImplEvents<T> _ensurePendingEvents() {
520     assert(_isInitialState);
521     if (!_isAddingStream) {
522       _varData ??= new _StreamImplEvents<T>();
523       return _varData;
524     }
525     _StreamControllerAddStreamState<T> state = _varData;
526     if (state.varData == null) state.varData = new _StreamImplEvents<T>();
527     return state.varData;
528   }
529 
530   // Get the current subscription.
531   // If we are adding a stream, the subscription is moved into the state
532   // object to allow the state object to use the _varData field.
533   _ControllerSubscription<T> get _subscription {
534     assert(hasListener);
535     if (_isAddingStream) {
536       _StreamControllerAddStreamState<T> addState = _varData;
537       return addState.varData;
538     }
539     return _varData;
540   }
541 
542   /**
543    * Creates an error describing why an event cannot be added.
544    *
545    * The reason, and therefore the error message, depends on the current state.
546    */
547   Error _badEventState() {
548     if (isClosed) {
549       return new StateError("Cannot add event after closing");
550     }
551     assert(_isAddingStream);
552     return new StateError("Cannot add event while adding a stream");
553   }
554 
555   // StreamSink interface.
556   Future addStream(Stream<T> source, {bool cancelOnError}) {
557     if (!_mayAddEvent) throw _badEventState();
558     if (_isCanceled) return new _Future.immediate(null);
559     _StreamControllerAddStreamState<T> addState =
560         new _StreamControllerAddStreamState<T>(
561             this, _varData, source, cancelOnError ?? false);
562     _varData = addState;
563     _state |= _STATE_ADDSTREAM;
564     return addState.addStreamFuture;
565   }
566 
567   /**
568    * Returns a future that is completed when the stream is done
569    * processing events.
570    *
571    * This happens either when the done event has been sent, or if the
572    * subscriber of a single-subscription stream is cancelled.
573    */
574   Future get done => _ensureDoneFuture();
575 
576   Future _ensureDoneFuture() {
577     _doneFuture ??= _isCanceled ? Future._nullFuture : new _Future();
578     return _doneFuture;
579   }
580 
581   /**
582    * Send or enqueue a data event.
583    */
584   void add(T value) {
585     if (!_mayAddEvent) throw _badEventState();
586     _add(value);
587   }
588 
589   /**
590    * Send or enqueue an error event.
591    */
592   void addError(Object error, [StackTrace stackTrace]) {
593     if (!_mayAddEvent) throw _badEventState();
594     error = _nonNullError(error);
595     AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
596     if (replacement != null) {
597       error = _nonNullError(replacement.error);
598       stackTrace = replacement.stackTrace;
599     }
600     _addError(error, stackTrace);
601   }
602 
603   /**
604    * Closes this controller and sends a done event on the stream.
605    *
606    * The first time a controller is closed, a "done" event is added to its
607    * stream.
608    *
609    * You are allowed to close the controller more than once, but only the first
610    * call has any effect.
611    *
612    * After closing, no further events may be added using [add], [addError]
613    * or [addStream].
614    *
615    * The returned future is completed when the done event has been delivered.
616    */
617   Future close() {
618     if (isClosed) {
619       return _ensureDoneFuture();
620     }
621     if (!_mayAddEvent) throw _badEventState();
622     _closeUnchecked();
623     return _ensureDoneFuture();
624   }
625 
626   void _closeUnchecked() {
627     _state |= _STATE_CLOSED;
628     if (hasListener) {
629       _sendDone();
630     } else if (_isInitialState) {
631       _ensurePendingEvents().add(const _DelayedDone());
632     }
633   }
634 
635   // EventSink interface. Used by the [addStream] events.
636 
637   // Add data event, used both by the [addStream] events and by [add].
638   void _add(T value) {
639     if (hasListener) {
640       _sendData(value);
641     } else if (_isInitialState) {
642       _ensurePendingEvents().add(new _DelayedData<T>(value));
643     }
644   }
645 
646   void _addError(Object error, StackTrace stackTrace) {
647     if (hasListener) {
648       _sendError(error, stackTrace);
649     } else if (_isInitialState) {
650       _ensurePendingEvents().add(new _DelayedError(error, stackTrace));
651     }
652   }
653 
654   void _close() {
655     // End of addStream stream.
656     assert(_isAddingStream);
657     _StreamControllerAddStreamState<T> addState = _varData;
658     _varData = addState.varData;
659     _state &= ~_STATE_ADDSTREAM;
660     addState.complete();
661   }
662 
663   // _StreamControllerLifeCycle interface
664 
665   StreamSubscription<T> _subscribe(void onData(T data), Function onError,
666       void onDone(), bool cancelOnError) {
667     if (!_isInitialState) {
668       throw new StateError("Stream has already been listened to.");
669     }
670     _ControllerSubscription<T> subscription = new _ControllerSubscription<T>(
671         this, onData, onError, onDone, cancelOnError);
672 
673     _PendingEvents<T> pendingEvents = _pendingEvents;
674     _state |= _STATE_SUBSCRIBED;
675     if (_isAddingStream) {
676       _StreamControllerAddStreamState<T> addState = _varData;
677       addState.varData = subscription;
678       addState.resume();
679     } else {
680       _varData = subscription;
681     }
682     subscription._setPendingEvents(pendingEvents);
683     subscription._guardCallback(() {
684       _runGuarded(onListen);
685     });
686 
687     return subscription;
688   }
689 
690   Future _recordCancel(StreamSubscription<T> subscription) {
691     // When we cancel, we first cancel any stream being added,
692     // Then we call `onCancel`, and finally the _doneFuture is completed.
693     // If either of addStream's cancel or `onCancel` returns a future,
694     // we wait for it before continuing.
695     // Any error during this process ends up in the returned future.
696     // If more errors happen, we act as if it happens inside nested try/finallys
697     // or whenComplete calls, and only the last error ends up in the
698     // returned future.
699     Future result;
700     if (_isAddingStream) {
701       _StreamControllerAddStreamState<T> addState = _varData;
702       result = addState.cancel();
703     }
704     _varData = null;
705     _state =
706         (_state & ~(_STATE_SUBSCRIBED | _STATE_ADDSTREAM)) | _STATE_CANCELED;
707 
708     if (onCancel != null) {
709       if (result == null) {
710         // Only introduce a future if one is needed.
711         // If _onCancel returns null, no future is needed.
712         try {
713           result = onCancel();
714         } catch (e, s) {
715           // Return the error in the returned future.
716           // Complete it asynchronously, so there is time for a listener
717           // to handle the error.
718           result = new _Future().._asyncCompleteError(e, s);
719         }
720       } else {
721         // Simpler case when we already know that we will return a future.
722         result = result.whenComplete(onCancel);
723       }
724     }
725 
726     void complete() {
727       if (_doneFuture != null && _doneFuture._mayComplete) {
728         _doneFuture._asyncComplete(null);
729       }
730     }
731 
732     if (result != null) {
733       result = result.whenComplete(complete);
734     } else {
735       complete();
736     }
737 
738     return result;
739   }
740 
741   void _recordPause(StreamSubscription<T> subscription) {
742     if (_isAddingStream) {
743       _StreamControllerAddStreamState<T> addState = _varData;
744       addState.pause();
745     }
746     _runGuarded(onPause);
747   }
748 
749   void _recordResume(StreamSubscription<T> subscription) {
750     if (_isAddingStream) {
751       _StreamControllerAddStreamState<T> addState = _varData;
752       addState.resume();
753     }
754     _runGuarded(onResume);
755   }
756 }
757 
758 abstract class _SyncStreamControllerDispatch<T>
759     implements _StreamController<T>, SynchronousStreamController<T> {
760   int get _state;
761   void set _state(int state);
762 
763   void _sendData(T data) {
764     _subscription._add(data);
765   }
766 
767   void _sendError(Object error, StackTrace stackTrace) {
768     _subscription._addError(error, stackTrace);
769   }
770 
771   void _sendDone() {
772     _subscription._close();
773   }
774 }
775 
776 abstract class _AsyncStreamControllerDispatch<T>
777     implements _StreamController<T> {
778   void _sendData(T data) {
779     _subscription._addPending(new _DelayedData<T>(data));
780   }
781 
782   void _sendError(Object error, StackTrace stackTrace) {
783     _subscription._addPending(new _DelayedError(error, stackTrace));
784   }
785 
786   void _sendDone() {
787     _subscription._addPending(const _DelayedDone());
788   }
789 }
790 
791 // TODO(lrn): Use common superclass for callback-controllers when VM supports
792 // constructors in mixin superclasses.
793 
794 class _AsyncStreamController<T> = _StreamController<T>
795     with _AsyncStreamControllerDispatch<T>;
796 
797 class _SyncStreamController<T> = _StreamController<T>
798     with _SyncStreamControllerDispatch<T>;
799 
800 typedef _NotificationHandler();
801 
802 void _runGuarded(_NotificationHandler notificationHandler) {
803   if (notificationHandler == null) return;
804   try {
805     notificationHandler();
806   } catch (e, s) {
807     Zone.current.handleUncaughtError(e, s);
808   }
809 }
810 
811 class _ControllerStream<T> extends _StreamImpl<T> {
812   _StreamControllerLifecycle<T> _controller;
813 
814   _ControllerStream(this._controller);
815 
816   StreamSubscription<T> _createSubscription(void onData(T data),
817           Function onError, void onDone(), bool cancelOnError) =>
818       _controller._subscribe(onData, onError, onDone, cancelOnError);
819 
820   // Override == and hashCode so that new streams returned by the same
821   // controller are considered equal. The controller returns a new stream
822   // each time it's queried, but doesn't have to cache the result.
823 
824   int get hashCode => _controller.hashCode ^ 0x35323532;
825 
826   bool operator ==(Object other) {
827     if (identical(this, other)) return true;
828     return other is _ControllerStream &&
829         identical(other._controller, this._controller);
830   }
831 }
832 
833 class _ControllerSubscription<T> extends _BufferingStreamSubscription<T> {
834   final _StreamControllerLifecycle<T> _controller;
835 
836   _ControllerSubscription(this._controller, void onData(T data),
837       Function onError, void onDone(), bool cancelOnError)
838       : super(onData, onError, onDone, cancelOnError);
839 
840   Future _onCancel() {
841     return _controller._recordCancel(this);
842   }
843 
844   void _onPause() {
845     _controller._recordPause(this);
846   }
847 
848   void _onResume() {
849     _controller._recordResume(this);
850   }
851 }
852 
853 /** A class that exposes only the [StreamSink] interface of an object. */
854 class _StreamSinkWrapper<T> implements StreamSink<T> {
855   final StreamController _target;
856   _StreamSinkWrapper(this._target);
857   void add(T data) {
858     _target.add(data);
859   }
860 
861   void addError(Object error, [StackTrace stackTrace]) {
862     _target.addError(error, stackTrace);
863   }
864 
865   Future close() => _target.close();
866 
867   Future addStream(Stream<T> source) => _target.addStream(source);
868 
869   Future get done => _target.done;
870 }
871 
872 /**
873  * Object containing the state used to handle [StreamController.addStream].
874  */
875 class _AddStreamState<T> {
876   // [_Future] returned by call to addStream.
877   final _Future addStreamFuture;
878 
879   // Subscription on stream argument to addStream.
880   final StreamSubscription addSubscription;
881 
882   _AddStreamState(
883       _EventSink<T> controller, Stream<T> source, bool cancelOnError)
884       : addStreamFuture = new _Future(),
885         addSubscription = source.listen(controller._add,
886             onError: cancelOnError
887                 ? makeErrorHandler(controller)
888                 : controller._addError,
889             onDone: controller._close,
890             cancelOnError: cancelOnError);
891 
892   static makeErrorHandler(_EventSink controller) => (e, StackTrace s) {
893         controller._addError(e, s);
894         controller._close();
895       };
896 
897   void pause() {
898     addSubscription.pause();
899   }
900 
901   void resume() {
902     addSubscription.resume();
903   }
904 
905   /**
906    * Stop adding the stream.
907    *
908    * Complete the future returned by `StreamController.addStream` when
909    * the cancel is complete.
910    *
911    * Return a future if the cancel takes time, otherwise return `null`.
912    */
913   Future cancel() {
914     var cancel = addSubscription.cancel();
915     if (cancel == null) {
916       addStreamFuture._asyncComplete(null);
917       return null;
918     }
919     return cancel.whenComplete(() {
920       addStreamFuture._asyncComplete(null);
921     });
922   }
923 
924   void complete() {
925     addStreamFuture._asyncComplete(null);
926   }
927 }
928 
929 class _StreamControllerAddStreamState<T> extends _AddStreamState<T> {
930   // The subscription or pending data of a _StreamController.
931   // Stored here because we reuse the `_varData` field  in the _StreamController
932   // to store this state object.
933   var varData;
934 
935   _StreamControllerAddStreamState(_StreamController<T> controller, this.varData,
936       Stream<T> source, bool cancelOnError)
937       : super(controller, source, cancelOnError) {
938     if (controller.isPaused) {
939       addSubscription.pause();
940     }
941   }
942 }

   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
   3 // BSD-style license that can be found in the LICENSE file.
   4 
   5 part of dart.async;
   6 
   7 // -------------------------------------------------------------------
   8 // Core Stream types
   9 // -------------------------------------------------------------------
  10 
  11 typedef void _TimerCallback();
  12 
  13 /**
  14  * A source of asynchronous data events.
  15  *
  16  * A Stream provides a way to receive a sequence of events.
  17  * Each event is either a data event, also called an *element* of the stream,
  18  * or an error event, which is a notification that something has failed.
  19  * When a stream has emitted all its event,
  20  * a single "done" event will notify the listener that the end has been reached.
  21  *
  22  * You [listen] on a stream to make it start generating events,
  23  * and to set up listeners that receive the events.
  24  * When you listen, you receive a [StreamSubscription] object
  25  * which is the active object providing the events,
  26  * and which can be used to stop listening again,
  27  * or to temporarily pause events from the subscription.
  28  *
  29  * There are two kinds of streams: "Single-subscription" streams and
  30  * "broadcast" streams.
  31  *
  32  * *A single-subscription stream* allows only a single listener during the whole
  33  * lifetime of the stream.
  34  * It doesn't start generating events until it has a listener,
  35  * and it stops sending events when the listener is unsubscribed,
  36  * even if the source of events could still provide more.
  37  *
  38  * Listening twice on a single-subscription stream is not allowed, even after
  39  * the first subscription has been canceled.
  40  *
  41  * Single-subscription streams are generally used for streaming chunks of
  42  * larger contiguous data like file I/O.
  43  *
  44  * *A broadcast stream* allows any number of listeners, and it fires
  45  * its events when they are ready, whether there are listeners or not.
  46  *
  47  * Broadcast streams are used for independent events/observers.
  48  *
  49  * If several listeners want to listen to a single subscription stream,
  50  * use [asBroadcastStream] to create a broadcast stream on top of the
  51  * non-broadcast stream.
  52  *
  53  * On either kind of stream, stream transformations, such as [where] and
  54  * [skip], return the same type of stream as the one the method was called on,
  55  * unless otherwise noted.
  56  *
  57  * When an event is fired, the listener(s) at that time will receive the event.
  58  * If a listener is added to a broadcast stream while an event is being fired,
  59  * that listener will not receive the event currently being fired.
  60  * If a listener is canceled, it immediately stops receiving events.
  61  * Listening on a broadcast stream can be treated as listening on a new stream
  62  * containing only the events that have not yet been emitted when the [listen]
  63  * call occurs.
  64  * For example, the [first] getter listens to the stream, then returns the first
  65  * event that listener receives.
  66  * This is not necessarily the first even emitted by the stream, but the first
  67  * of the *remaining* events of the broadcast stream.
  68  *
  69  * When the "done" event is fired, subscribers are unsubscribed before
  70  * receiving the event. After the event has been sent, the stream has no
  71  * subscribers. Adding new subscribers to a broadcast stream after this point
  72  * is allowed, but they will just receive a new "done" event as soon
  73  * as possible.
  74  *
  75  * Stream subscriptions always respect "pause" requests. If necessary they need
  76  * to buffer their input, but often, and preferably, they can simply request
  77  * their input to pause too.
  78  *
  79  * The default implementation of [isBroadcast] returns false.
  80  * A broadcast stream inheriting from [Stream] must override [isBroadcast]
  81  * to return `true`.
  82  */
  83 abstract class Stream<T> {
  84   Stream();
  85 
  86   /**
  87    * Internal use only. We do not want to promise that Stream stays const.
  88    *
  89    * If mixins become compatible with const constructors, we may use a
  90    * stream mixin instead of extending Stream from a const class.
  91    */
  92   const Stream._internal();
  93 
  94   /**
  95    * Creates an empty broadcast stream.
  96    *
  97    * This is a stream which does nothing except sending a done event
  98    * when it's listened to.
  99    */
 100   const factory Stream.empty() = _EmptyStream<T>;
 101 
 102   /**
 103    * Creates a new single-subscription stream from the future.
 104    *
 105    * When the future completes, the stream will fire one event, either
 106    * data or error, and then close with a done-event.
 107    */
 108   factory Stream.fromFuture(Future<T> future) {
 109     // Use the controller's buffering to fill in the value even before
 110     // the stream has a listener. For a single value, it's not worth it
 111     // to wait for a listener before doing the `then` on the future.
 112     _StreamController<T> controller = new StreamController<T>(sync: true);
 113     future.then((value) {
 114       controller._add(value);
 115       controller._closeUnchecked();
 116     }, onError: (error, stackTrace) {
 117       controller._addError(error, stackTrace);
 118       controller._closeUnchecked();
 119     });
 120     return controller.stream;
 121   }
 122 
 123   /**
 124    * Create a stream from a group of futures.
 125    *
 126    * The stream reports the results of the futures on the stream in the order
 127    * in which the futures complete.
 128    * Each future provides either a data event or an error event,
 129    * depending on how the future completes.
 130    *
 131    * If some futures have already completed when `Stream.fromFutures` is called,
 132    * their results will be emitted in some unspecified order.
 133    *
 134    * When all futures have completed, the stream is closed.
 135    *
 136    * If [futures] is empty, the stream closes as soon as possible.
 137    */
 138   factory Stream.fromFutures(Iterable<Future<T>> futures) {
 139     _StreamController<T> controller = new StreamController<T>(sync: true);
 140     int count = 0;
 141     // Declare these as variables holding closures instead of as
 142     // function declarations.
 143     // This avoids creating a new closure from the functions for each future.
 144     var onValue = (T value) {
 145       if (!controller.isClosed) {
 146         controller._add(value);
 147         if (--count == 0) controller._closeUnchecked();
 148       }
 149     };
 150     var onError = (error, StackTrace stack) {
 151       if (!controller.isClosed) {
 152         controller._addError(error, stack);
 153         if (--count == 0) controller._closeUnchecked();
 154       }
 155     };
 156     // The futures are already running, so start listening to them immediately
 157     // (instead of waiting for the stream to be listened on).
 158     // If we wait, we might not catch errors in the futures in time.
 159     for (var future in futures) {
 160       count++;
 161       future.then(onValue, onError: onError);
 162     }
 163     // Use schedule microtask since controller is sync.
 164     if (count == 0) scheduleMicrotask(controller.close);
 165     return controller.stream;
 166   }
 167 
 168   /**
 169    * Creates a single-subscription stream that gets its data from [elements].
 170    *
 171    * The iterable is iterated when the stream receives a listener, and stops
 172    * iterating if the listener cancels the subscription, or if the
 173    * [Iterator.moveNext] method returns `false` or throws.
 174    * Iteration is suspended while the stream subscription is paused.
 175    *
 176    * If calling [Iterator.moveNext] on `elements.iterator` throws,
 177    * the stream emits that error and then it closes.
 178    * If reading [Iterator.current] on `elements.iterator` throws,
 179    * the stream emits that error, but keeps iterating.
 180    */
 181   factory Stream.fromIterable(Iterable<T> elements) {
 182     return new _GeneratedStreamImpl<T>(
 183         () => new _IterablePendingEvents<T>(elements));
 184   }
 185 
 186   /**
 187    * Creates a stream that repeatedly emits events at [period] intervals.
 188    *
 189    * The event values are computed by invoking [computation]. The argument to
 190    * this callback is an integer that starts with 0 and is incremented for
 191    * every event.
 192    *
 193    * If [computation] is omitted the event values will all be `null`.
 194    */
 195   factory Stream.periodic(Duration period,
 196       [T computation(int computationCount)]) {
 197     Timer timer;
 198     int computationCount = 0;
 199     StreamController<T> controller;
 200     // Counts the time that the Stream was running (and not paused).
 201     Stopwatch watch = new Stopwatch();
 202 
 203     void sendEvent() {
 204       watch.reset();
 205       T data;
 206       if (computation != null) {
 207         try {
 208           data = computation(computationCount++);
 209         } catch (e, s) {
 210           controller.addError(e, s);
 211           return;
 212         }
 213       }
 214       controller.add(data);
 215     }
 216 
 217     void startPeriodicTimer() {
 218       assert(timer == null);
 219       timer = new Timer.periodic(period, (Timer timer) {
 220         sendEvent();
 221       });
 222     }
 223 
 224     controller = new StreamController<T>(
 225         sync: true,
 226         onListen: () {
 227           watch.start();
 228           startPeriodicTimer();
 229         },
 230         onPause: () {
 231           timer.cancel();
 232           timer = null;
 233           watch.stop();
 234         },
 235         onResume: () {
 236           assert(timer == null);
 237           Duration elapsed = watch.elapsed;
 238           watch.start();
 239           timer = new Timer(period - elapsed, () {
 240             timer = null;
 241             startPeriodicTimer();
 242             sendEvent();
 243           });
 244         },
 245         onCancel: () {
 246           if (timer != null) timer.cancel();
 247           timer = null;
 248           return Future._nullFuture;
 249         });
 250     return controller.stream;
 251   }
 252 
 253   /**
 254    * Creates a stream where all events of an existing stream are piped through
 255    * a sink-transformation.
 256    *
 257    * The given [mapSink] closure is invoked when the returned stream is
 258    * listened to. All events from the [source] are added into the event sink
 259    * that is returned from the invocation. The transformation puts all
 260    * transformed events into the sink the [mapSink] closure received during
 261    * its invocation. Conceptually the [mapSink] creates a transformation pipe
 262    * with the input sink being the returned [EventSink] and the output sink
 263    * being the sink it received.
 264    *
 265    * This constructor is frequently used to build transformers.
 266    *
 267    * Example use for a duplicating transformer:
 268    *
 269    *     class DuplicationSink implements EventSink<String> {
 270    *       final EventSink<String> _outputSink;
 271    *       DuplicationSink(this._outputSink);
 272    *
 273    *       void add(String data) {
 274    *         _outputSink.add(data);
 275    *         _outputSink.add(data);
 276    *       }
 277    *
 278    *       void addError(e, [st]) { _outputSink.addError(e, st); }
 279    *       void close() { _outputSink.close(); }
 280    *     }
 281    *
 282    *     class DuplicationTransformer extends StreamTransformerBase<String, String> {
 283    *       // Some generic types omitted for brevity.
 284    *       Stream bind(Stream stream) => new Stream<String>.eventTransformed(
 285    *           stream,
 286    *           (EventSink sink) => new DuplicationSink(sink));
 287    *     }
 288    *
 289    *     stringStream.transform(new DuplicationTransformer());
 290    *
 291    * The resulting stream is a broadcast stream if [source] is.
 292    */
 293   factory Stream.eventTransformed(
 294       Stream source, EventSink mapSink(EventSink<T> sink)) {
 295     return new _BoundSinkStream(source, mapSink);
 296   }
 297 
 298   /**
 299    * Adapts [source] to be a `Stream<T>`.
 300    *
 301    * This allows [source] to be used at the new type, but at run-time it
 302    * must satisfy the requirements of both the new type and its original type.
 303    *
 304    * Data events created by the source stream must also be instances of [T].
 305    */
 306   static Stream<T> castFrom<S, T>(Stream<S> source) =>
 307       new CastStream<S, T>(source);
 308 
 309   /**
 310    * Whether this stream is a broadcast stream.
 311    */
 312   bool get isBroadcast => false;
 313 
 314   /**
 315    * Returns a multi-subscription stream that produces the same events as this.
 316    *
 317    * The returned stream will subscribe to this stream when its first
 318    * subscriber is added, and will stay subscribed until this stream ends,
 319    * or a callback cancels the subscription.
 320    *
 321    * If [onListen] is provided, it is called with a subscription-like object
 322    * that represents the underlying subscription to this stream. It is
 323    * possible to pause, resume or cancel the subscription during the call
 324    * to [onListen]. It is not possible to change the event handlers, including
 325    * using [StreamSubscription.asFuture].
 326    *
 327    * If [onCancel] is provided, it is called in a similar way to [onListen]
 328    * when the returned stream stops having listener. If it later gets
 329    * a new listener, the [onListen] function is called again.
 330    *
 331    * Use the callbacks, for example, for pausing the underlying subscription
 332    * while having no subscribers to prevent losing events, or canceling the
 333    * subscription when there are no listeners.
 334    */
 335   Stream<T> asBroadcastStream(
 336       {void onListen(StreamSubscription<T> subscription),
 337       void onCancel(StreamSubscription<T> subscription)}) {
 338     return new _AsBroadcastStream<T>(this, onListen, onCancel);
 339   }
 340 
 341   /**
 342    * Adds a subscription to this stream.
 343    *
 344    * Returns a [StreamSubscription] which handles events from this stream using
 345    * the provided [onData], [onError] and [onDone] handlers.
 346    * The handlers can be changed on the subscription, but they start out
 347    * as the provided functions.
 348    *
 349    * On each data event from this stream, the subscriber's [onData] handler
 350    * is called. If [onData] is `null`, nothing happens.
 351    *
 352    * On errors from this stream, the [onError] handler is called with the
 353    * error object and possibly a stack trace.
 354    *
 355    * The [onError] callback must be of type `void onError(error)` or
 356    * `void onError(error, StackTrace stackTrace)`. If [onError] accepts
 357    * two arguments it is called with the error object and the stack trace
 358    * (which could be `null` if this stream itself received an error without
 359    * stack trace).
 360    * Otherwise it is called with just the error object.
 361    * If [onError] is omitted, any errors on this stream are considered unhandled,
 362    * and will be passed to the current [Zone]'s error handler.
 363    * By default unhandled async errors are treated
 364    * as if they were uncaught top-level errors.
 365    *
 366    * If this stream closes and sends a done event, the [onDone] handler is
 367    * called. If [onDone] is `null`, nothing happens.
 368    *
 369    * If [cancelOnError] is true, the subscription is automatically canceled
 370    * when the first error event is delivered. The default is `false`.
 371    *
 372    * While a subscription is paused, or when it has been canceled,
 373    * the subscription doesn't receive events and none of the
 374    * event handler functions are called.
 375    */
 376   StreamSubscription<T> listen(void onData(T event),
 377       {Function onError, void onDone(), bool cancelOnError});
 378 
 379   /**
 380    * Creates a new stream from this stream that discards some elements.
 381    *
 382    * The new stream sends the same error and done events as this stream,
 383    * but it only sends the data events that satisfy the [test].
 384    *
 385    * If the [test] function throws, the data event is dropped and the
 386    * error is emitted on the returned stream instead.
 387    *
 388    * The returned stream is a broadcast stream if this stream is.
 389    * If a broadcast stream is listened to more than once, each subscription
 390    * will individually perform the `test`.
 391    */
 392   Stream<T> where(bool test(T event)) {
 393     return new _WhereStream<T>(this, test);
 394   }
 395 
 396   /**
 397    * Transforms each element of this stream into a new stream event.
 398    *
 399    * Creates a new stream that converts each element of this stream
 400    * to a new value using the [convert] function, and emits the result.
 401    *
 402    * For each data event, `o`, in this stream, the returned stream
 403    * provides a data event with the value `convert(o)`.
 404    * If [convert] throws, the returned stream reports it as an error
 405    * event instead.
 406    *
 407    * Error and done events are passed through unchanged to the returned stream.
 408    *
 409    * The returned stream is a broadcast stream if this stream is.
 410    * The [convert] function is called once per data event per listener.
 411    * If a broadcast stream is listened to more than once, each subscription
 412    * will individually call [convert] on each data event.
 413    *
 414    * Unlike [transform], this method does not treat the stream as
 415    * chunks of a single value. Instead each event is converted independently
 416    * of the previous and following events, which may not always be correct.
 417    * For example, UTF-8 encoding, or decoding, will give wrong results
 418    * if a surrogate pair, or a multibyte UTF-8 encoding, is split into
 419    * separate events, and those events are attempted encoded or decoded
 420    * independently.
 421    */
 422   Stream<S> map<S>(S convert(T event)) {
 423     return new _MapStream<T, S>(this, convert);
 424   }
 425 
 426   /**
 427    * Creates a new stream with each data event of this stream asynchronously
 428    * mapped to a new event.
 429    *
 430    * This acts like [map], except that [convert] may return a [Future],
 431    * and in that case, this stream waits for that future to complete before
 432    * continuing with its result.
 433    *
 434    * The returned stream is a broadcast stream if this stream is.
 435    */
 436   Stream<E> asyncMap<E>(FutureOr<E> convert(T event)) {
 437     _StreamControllerBase<E> controller;
 438     StreamSubscription<T> subscription;
 439 
 440     void onListen() {
 441       final add = controller.add;
 442       assert(controller is _StreamController<E> ||
 443           controller is _BroadcastStreamController);
 444       final addError = controller._addError;
 445       subscription = this.listen((T event) {
 446         FutureOr<E> newValue;
 447         try {
 448           newValue = convert(event);
 449         } catch (e, s) {
 450           controller.addError(e, s);
 451           return;
 452         }
 453         if (newValue is Future<E>) {
 454           subscription.pause();
 455           newValue
 456               .then(add, onError: addError)
 457               .whenComplete(subscription.resume);
 458         } else {
 459           controller.add(newValue);
 460         }
 461       }, onError: addError, onDone: controller.close);
 462     }
 463 
 464     if (this.isBroadcast) {
 465       controller = new StreamController<E>.broadcast(
 466           onListen: onListen,
 467           onCancel: () {
 468             subscription.cancel();
 469           },
 470           sync: true);
 471     } else {
 472       controller = new StreamController<E>(
 473           onListen: onListen,
 474           onPause: () {
 475             subscription.pause();
 476           },
 477           onResume: () {
 478             subscription.resume();
 479           },
 480           onCancel: () => subscription.cancel(),
 481           sync: true);
 482     }
 483     return controller.stream;
 484   }
 485 
 486   /**
 487    * Transforms each element into a sequence of asynchronous events.
 488    *
 489    * Returns a new stream and for each event of this stream, do the following:
 490    *
 491    * * If the event is an error event or a done event, it is emitted directly
 492    * by the returned stream.
 493    * * Otherwise it is an element. Then the [convert] function is called
 494    * with the element as argument to produce a convert-stream for the element.
 495    * * If that call throws, the error is emitted on the returned stream.
 496    * * If the call returns `null`, no further action is taken for the elements.
 497    * * Otherwise, this stream is paused and convert-stream is listened to.
 498    * Every data and error event of the convert-stream is emitted on the returned
 499    * stream in the order it is produced.
 500    * When the convert-stream ends, this stream is resumed.
 501    *
 502    * The returned stream is a broadcast stream if this stream is.
 503    */
 504   Stream<E> asyncExpand<E>(Stream<E> convert(T event)) {
 505     _StreamControllerBase<E> controller;
 506     StreamSubscription<T> subscription;
 507     void onListen() {
 508       assert(controller is _StreamController ||
 509           controller is _BroadcastStreamController);
 510       subscription = this.listen((T event) {
 511         Stream<E> newStream;
 512         try {
 513           newStream = convert(event);
 514         } catch (e, s) {
 515           controller.addError(e, s);
 516           return;
 517         }
 518         if (newStream != null) {
 519           subscription.pause();
 520           controller.addStream(newStream).whenComplete(subscription.resume);
 521         }
 522       },
 523           onError: controller._addError, // Avoid Zone error replacement.
 524           onDone: controller.close);
 525     }
 526 
 527     if (this.isBroadcast) {
 528       controller = new StreamController<E>.broadcast(
 529           onListen: onListen,
 530           onCancel: () {
 531             subscription.cancel();
 532           },
 533           sync: true);
 534     } else {
 535       controller = new StreamController<E>(
 536           onListen: onListen,
 537           onPause: () {
 538             subscription.pause();
 539           },
 540           onResume: () {
 541             subscription.resume();
 542           },
 543           onCancel: () => subscription.cancel(),
 544           sync: true);
 545     }
 546     return controller.stream;
 547   }
 548 
 549   /**
 550    * Creates a wrapper Stream that intercepts some errors from this stream.
 551    *
 552    * If this stream sends an error that matches [test], then it is intercepted
 553    * by the [onError] function.
 554    *
 555    * The [onError] callback must be of type `void onError(error)` or
 556    * `void onError(error, StackTrace stackTrace)`.
 557    * The function type determines whether [onError] is invoked with a stack
 558    * trace argument.
 559    * The stack trace argument may be `null` if this stream received an error
 560    * without a stack trace.
 561    *
 562    * An asynchronous error `error` is matched by a test function if
 563    *`test(error)` returns true. If [test] is omitted, every error is considered
 564    * matching.
 565    *
 566    * If the error is intercepted, the [onError] function can decide what to do
 567    * with it. It can throw if it wants to raise a new (or the same) error,
 568    * or simply return to make this stream forget the error.
 569    * If the received `error` value is thrown again by the [onError] function,
 570    * it acts like a `rethrow` and it is emitted along with its original
 571    * stack trace, not the stack trace of the `throw` inside [onError].
 572    *
 573    * If you need to transform an error into a data event, use the more generic
 574    * [Stream.transform] to handle the event by writing a data event to
 575    * the output sink.
 576    *
 577    * The returned stream is a broadcast stream if this stream is.
 578    * If a broadcast stream is listened to more than once, each subscription
 579    * will individually perform the `test` and handle the error.
 580    */
 581   Stream<T> handleError(Function onError, {bool test(error)}) {
 582     return new _HandleErrorStream<T>(this, onError, test);
 583   }
 584 
 585   /**
 586    * Transforms each element of this stream into a sequence of elements.
 587    *
 588    * Returns a new stream where each element of this stream is replaced
 589    * by zero or more data events.
 590    * The event values are provided as an [Iterable] by a call to [convert]
 591    * with the element as argument, and the elements of that iterable is
 592    * emitted in iteration order.
 593    * If calling [convert] throws, or if the iteration of the returned values
 594    * throws, the error is emitted on the returned stream and iteration ends
 595    * for that element of this stream.
 596    *
 597    * Error events and the done event of this stream are forwarded directly
 598    * to the returned stream.
 599    *
 600    * The returned stream is a broadcast stream if this stream is.
 601    * If a broadcast stream is listened to more than once, each subscription
 602    * will individually call `convert` and expand the events.
 603    */
 604   Stream<S> expand<S>(Iterable<S> convert(T element)) {
 605     return new _ExpandStream<T, S>(this, convert);
 606   }
 607 
 608   /**
 609    * Pipes the events of this stream into [streamConsumer].
 610    *
 611    * All events of this stream are added to `streamConsumer` using
 612    * [StreamConsumer.addStream].
 613    * The `streamConsumer` is closed when this stream has been successfully added
 614    * to it - when the future returned by `addStream` completes without an error.
 615    *
 616    * Returns a future which completes when this stream has been consumed
 617    * and the consumer has been closed.
 618    *
 619    * The returned future completes with the same result as the future returned
 620    * by [StreamConsumer.close].
 621    * If the call to [StreamConsumer.addStream] fails in some way, this
 622    * method fails in the same way.
 623    */
 624   Future pipe(StreamConsumer<T> streamConsumer) {
 625     return streamConsumer.addStream(this).then((_) => streamConsumer.close());
 626   }
 627 
 628   /**
 629    * Applies  [streamTransformer] to this stream.
 630    *
 631    * Returns the transformed stream,
 632    * that is, the result of `streamTransformer.bind(this)`.
 633    * This method simply allows writing the call to `streamTransformer.bind`
 634    * in a chained fashion, like
 635    * ```
 636    * stream.map(mapping).transform(transformation).toList()
 637    * ```
 638    * which can be more convenient than calling `bind` directly.
 639    *
 640    * The [streamTransformer] can return any stream.
 641    * Whether the returned stream is a broadcast stream or not,
 642    * and which elements it will contain,
 643    * is entirely up to the transformation.
 644    *
 645    * This method should always be used for transformations which treat
 646    * the entire stream as representing a single value
 647    * which has perhaps been split into several parts for transport,
 648    * like a file being read from disk or being fetched over a network.
 649    * The transformation will then produce a new stream which
 650    * transforms the stream's value incrementally (perhaps using
 651    * [Converter.startChunkedConversion]). The resulting stream
 652    * may again be chunks of the result, but does not have to
 653    * correspond to specific events from the source string.
 654    */
 655   Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer) {
 656     return streamTransformer.bind(this);
 657   }
 658 
 659   /**
 660    * Combines a sequence of values by repeatedly applying [combine].
 661    *
 662    * Similar to [Iterable.reduce], this function maintains a value,
 663    * starting with the first element of this stream
 664    * and updated for each further element of this stream.
 665    * For each element after the first,
 666    * the value is updated to the result of calling [combine]
 667    * with the previous value and the element.
 668    *
 669    * When this stream is done, the returned future is completed with
 670    * the value at that time.
 671    *
 672    * If this stream is empty, the returned future is completed with
 673    * an error.
 674    * If this stream emits an error, or the call to [combine] throws,
 675    * the returned future is completed with that error,
 676    * and processing is stopped.
 677    */
 678   Future<T> reduce(T combine(T previous, T element)) {
 679     _Future<T> result = new _Future<T>();
 680     bool seenFirst = false;
 681     T value;
 682     StreamSubscription subscription;
 683     subscription = this.listen(
 684         (T element) {
 685           if (seenFirst) {
 686             _runUserCode(() => combine(value, element), (T newValue) {
 687               value = newValue;
 688             }, _cancelAndErrorClosure(subscription, result));
 689           } else {
 690             value = element;
 691             seenFirst = true;
 692           }
 693         },
 694         onError: result._completeError,
 695         onDone: () {
 696           if (!seenFirst) {
 697             try {
 698               // Throw and recatch, instead of just doing
 699               //  _completeWithErrorCallback, e, theError, StackTrace.current),
 700               // to ensure that the stackTrace is set on the error.
 701               throw IterableElementError.noElement();
 702             } catch (e, s) {
 703               _completeWithErrorCallback(result, e, s);
 704             }
 705           } else {
 706             result._complete(value);
 707           }
 708         },
 709         cancelOnError: true);
 710     return result;
 711   }
 712 
 713   /**
 714    * Combines a sequence of values by repeatedly applying [combine].
 715    *
 716    * Similar to [Iterable.fold], this function maintains a value,
 717    * starting with [initialValue] and updated for each element of
 718    * this stream.
 719    * For each element, the value is updated to the result of calling
 720    * [combine] with the previous value and the element.
 721    *
 722    * When this stream is done, the returned future is completed with
 723    * the value at that time.
 724    * For an empty stream, the future is completed with [initialValue].
 725    *
 726    * If this stream emits an error, or the call to [combine] throws,
 727    * the returned future is completed with that error,
 728    * and processing is stopped.
 729    */
 730   Future<S> fold<S>(S initialValue, S combine(S previous, T element)) {
 731     _Future<S> result = new _Future<S>();
 732     S value = initialValue;
 733     StreamSubscription subscription;
 734     subscription = this.listen(
 735         (T element) {
 736           _runUserCode(() => combine(value, element), (S newValue) {
 737             value = newValue;
 738           }, _cancelAndErrorClosure(subscription, result));
 739         },
 740         onError: result._completeError,
 741         onDone: () {
 742           result._complete(value);
 743         },
 744         cancelOnError: true);
 745     return result;
 746   }
 747 
 748   /**
 749    * Combines the string representation of elements into a single string.
 750    *
 751    * Each element is converted to a string using its [Object.toString] method.
 752    * If [separator] is provided, it is inserted between element string
 753    * representations.
 754    *
 755    * The returned future is completed with the combined string when this stream
 756    * is done.
 757    *
 758    * If this stream emits an error, or the call to [Object.toString] throws,
 759    * the returned future is completed with that error,
 760    * and processing stops.
 761    */
 762   Future<String> join([String separator = ""]) {
 763     _Future<String> result = new _Future<String>();
 764     StringBuffer buffer = new StringBuffer();
 765     StreamSubscription subscription;
 766     bool first = true;
 767     subscription = this.listen(
 768         (T element) {
 769           if (!first) {
 770             buffer.write(separator);
 771           }
 772           first = false;
 773           try {
 774             buffer.write(element);
 775           } catch (e, s) {
 776             _cancelAndErrorWithReplacement(subscription, result, e, s);
 777           }
 778         },
 779         onError: result._completeError,
 780         onDone: () {
 781           result._complete(buffer.toString());
 782         },
 783         cancelOnError: true);
 784     return result;
 785   }
 786 
 787   /**
 788    * Returns whether [needle] occurs in the elements provided by this stream.
 789    *
 790    * Compares each element of this stream to [needle] using [Object.==].
 791    * If an equal element is found, the returned future is completed with `true`.
 792    * If this stream ends without finding a match, the future is completed with
 793    * `false`.
 794    *
 795    * If this stream emits an error, or the call to [Object.==] throws,
 796    * the returned future is completed with that error,
 797    * and processing stops.
 798    */
 799   Future<bool> contains(Object needle) {
 800     _Future<bool> future = new _Future<bool>();
 801     StreamSubscription subscription;
 802     subscription = this.listen(
 803         (T element) {
 804           _runUserCode(() => (element == needle), (bool isMatch) {
 805             if (isMatch) {
 806               _cancelAndValue(subscription, future, true);
 807             }
 808           }, _cancelAndErrorClosure(subscription, future));
 809         },
 810         onError: future._completeError,
 811         onDone: () {
 812           future._complete(false);
 813         },
 814         cancelOnError: true);
 815     return future;
 816   }
 817 
 818   /**
 819    * Executes [action] on each element of this stream.
 820    *
 821    * Completes the returned [Future] when all elements of this stream
 822    * have been processed.
 823    *
 824    * If this stream emits an error, or if the call to [action] throws,
 825    * the returned future completes with that error,
 826    * and processing stops.
 827    */
 828   Future forEach(void action(T element)) {
 829     _Future future = new _Future();
 830     StreamSubscription subscription;
 831     subscription = this.listen(
 832         (T element) {
 833           // TODO(floitsch): the type should be 'void' and inferred.
 834           _runUserCode<dynamic>(() => action(element), (_) {},
 835               _cancelAndErrorClosure(subscription, future));
 836         },
 837         onError: future._completeError,
 838         onDone: () {
 839           future._complete(null);
 840         },
 841         cancelOnError: true);
 842     return future;
 843   }
 844 
 845   /**
 846    * Checks whether [test] accepts all elements provided by this stream.
 847    *
 848    * Calls [test] on each element of this stream.
 849    * If the call returns `false`, the returned future is completed with `false`
 850    * and processing stops.
 851    *
 852    * If this stream ends without finding an element that [test] rejects,
 853    * the returned future is completed with `true`.
 854    *
 855    * If this stream emits an error, or if the call to [test] throws,
 856    * the returned future is completed with that error,
 857    * and processing stops.
 858    */
 859   Future<bool> every(bool test(T element)) {
 860     _Future<bool> future = new _Future<bool>();
 861     StreamSubscription subscription;
 862     subscription = this.listen(
 863         (T element) {
 864           _runUserCode(() => test(element), (bool isMatch) {
 865             if (!isMatch) {
 866               _cancelAndValue(subscription, future, false);
 867             }
 868           }, _cancelAndErrorClosure(subscription, future));
 869         },
 870         onError: future._completeError,
 871         onDone: () {
 872           future._complete(true);
 873         },
 874         cancelOnError: true);
 875     return future;
 876   }
 877 
 878   /**
 879    * Checks whether [test] accepts any element provided by this stream.
 880    *
 881    * Calls [test] on each element of this stream.
 882    * If the call returns `true`, the returned future is completed with `true`
 883    * and processing stops.
 884    *
 885    * If this stream ends without finding an element that [test] accepts,
 886    * the returned future is completed with `false`.
 887    *
 888    * If this stream emits an error, or if the call to [test] throws,
 889    * the returned future is completed with that error,
 890    * and processing stops.
 891    */
 892   Future<bool> any(bool test(T element)) {
 893     _Future<bool> future = new _Future<bool>();
 894     StreamSubscription subscription;
 895     subscription = this.listen(
 896         (T element) {
 897           _runUserCode(() => test(element), (bool isMatch) {
 898             if (isMatch) {
 899               _cancelAndValue(subscription, future, true);
 900             }
 901           }, _cancelAndErrorClosure(subscription, future));
 902         },
 903         onError: future._completeError,
 904         onDone: () {
 905           future._complete(false);
 906         },
 907         cancelOnError: true);
 908     return future;
 909   }
 910 
 911   /**
 912    * The number of elements in this stream.
 913    *
 914    * Waits for all elements of this stream. When this stream ends,
 915    * the returned future is completed with the number of elements.
 916    *
 917    * If this stream emits an error,
 918    * the returned future is completed with that error,
 919    * and processing stops.
 920    *
 921    * This operation listens to this stream, and a non-broadcast stream cannot
 922    * be reused after finding its length.
 923    */
 924   Future<int> get length {
 925     _Future<int> future = new _Future<int>();
 926     int count = 0;
 927     this.listen(
 928         (_) {
 929           count++;
 930         },
 931         onError: future._completeError,
 932         onDone: () {
 933           future._complete(count);
 934         },
 935         cancelOnError: true);
 936     return future;
 937   }
 938 
 939   /**
 940    * Whether this stream contains any elements.
 941    *
 942    * Waits for the first element of this stream, then completes the returned
 943    * future with `true`.
 944    * If this stream ends without emitting any elements, the returned future is
 945    * completed with `false`.
 946    *
 947    * If the first event is an error, the returned future is completed with that
 948    * error.
 949    *
 950    * This operation listens to this stream, and a non-broadcast stream cannot
 951    * be reused after checking whether it is empty.
 952    */
 953   Future<bool> get isEmpty {
 954     _Future<bool> future = new _Future<bool>();
 955     StreamSubscription subscription;
 956     subscription = this.listen(
 957         (_) {
 958           _cancelAndValue(subscription, future, false);
 959         },
 960         onError: future._completeError,
 961         onDone: () {
 962           future._complete(true);
 963         },
 964         cancelOnError: true);
 965     return future;
 966   }
 967 
 968   /**
 969    * Adapt this stream to be a `Stream<R>`.
 970    *
 971    * This stream is wrapped as a `Stream<R>` which checks at run-time that
 972    * each data event emitted by this stream is also an instance of [R].
 973    */
 974   Stream<R> cast<R>() => Stream.castFrom<T, R>(this);
 975   /**
 976    * Collects all elements of this stream in a [List].
 977    *
 978    * Creates a `List<T>` and adds all elements of this stream to the list
 979    * in the order they arrive.
 980    * When this stream ends, the returned future is completed with that list.
 981    *
 982    * If this stream emits an error,
 983    * the returned future is completed with that error,
 984    * and processing stops.
 985    */
 986   Future<List<T>> toList() {
 987     List<T> result = <T>[];
 988     _Future<List<T>> future = new _Future<List<T>>();
 989     this.listen(
 990         (T data) {
 991           result.add(data);
 992         },
 993         onError: future._completeError,
 994         onDone: () {
 995           future._complete(result);
 996         },
 997         cancelOnError: true);
 998     return future;
 999   }
1000 
1001   /**
1002    * Collects the data of this stream in a [Set].
1003    *
1004    * Creates a `Set<T>` and adds all elements of this stream to the set.
1005    * in the order they arrive.
1006    * When this stream ends, the returned future is completed with that set.
1007    *
1008    * The returned set is the same type as returned by `new Set<T>()`.
1009    * If another type of set is needed, either use [forEach] to add each
1010    * element to the set, or use
1011    * `toList().then((list) => new SomeOtherSet.from(list))`
1012    * to create the set.
1013    *
1014    * If this stream emits an error,
1015    * the returned future is completed with that error,
1016    * and processing stops.
1017    */
1018   Future<Set<T>> toSet() {
1019     Set<T> result = new Set<T>();
1020     _Future<Set<T>> future = new _Future<Set<T>>();
1021     this.listen(
1022         (T data) {
1023           result.add(data);
1024         },
1025         onError: future._completeError,
1026         onDone: () {
1027           future._complete(result);
1028         },
1029         cancelOnError: true);
1030     return future;
1031   }
1032 
1033   /**
1034    * Discards all data on this stream, but signals when it is done or an error
1035    * occurred.
1036    *
1037    * When subscribing using [drain], cancelOnError will be true. This means
1038    * that the future will complete with the first error on this stream and then
1039    * cancel the subscription.
1040    * If this stream emits an error, or the call to [combine] throws,
1041    * the returned future is completed with that error,
1042    * and processing is stopped.
1043    *
1044    * In case of a `done` event the future completes with the given
1045    * [futureValue].
1046    */
1047   Future<E> drain<E>([E futureValue]) =>
1048       listen(null, cancelOnError: true).asFuture<E>(futureValue);
1049 
1050   /**
1051    * Provides at most the first [count] data events of this stream.
1052    *
1053    * Returns a stream that emits the same events that this stream would
1054    * if listened to at the same time,
1055    * until either this stream ends or it has emitted [count] data events,
1056    * at which point the returned stream is done.
1057    *
1058    * If this stream produces fewer than [count] data events before it's done,
1059    * so will the returned stream.
1060    *
1061    * Starts listening to this stream when the returned stream is listened to
1062    * and stops listening when the first [count] data events have been received.
1063    *
1064    * This means that if this is a single-subscription (non-broadcast) streams
1065    * it cannot be reused after the returned stream has been listened to.
1066    *
1067    * If this is a broadcast stream, the returned stream is a broadcast stream.
1068    * In that case, the events are only counted from the time
1069    * the returned stream is listened to.
1070    */
1071   Stream<T> take(int count) {
1072     return new _TakeStream<T>(this, count);
1073   }
1074 
1075   /**
1076    * Forwards data events while [test] is successful.
1077    *
1078    * Returns a stream that provides the same events as this stream
1079    * until [test] fails for a data event.
1080    * The returned stream is done when either this stream is done,
1081    * or when this stream first emits a data event that fails [test].
1082    *
1083    * The `test` call is considered failing if it returns a non-`true` value
1084    * or if it throws. If the `test` call throws, the error is emitted as the
1085    * last event on the returned streams.
1086    *
1087    * Stops listening to this stream after the accepted elements.
1088    *
1089    * Internally the method cancels its subscription after these elements. This
1090    * means that single-subscription (non-broadcast) streams are closed and
1091    * cannot be reused after a call to this method.
1092    *
1093    * The returned stream is a broadcast stream if this stream is.
1094    * For a broadcast stream, the events are only tested from the time
1095    * the returned stream is listened to.
1096    */
1097   Stream<T> takeWhile(bool test(T element)) {
1098     return new _TakeWhileStream<T>(this, test);
1099   }
1100 
1101   /**
1102    * Skips the first [count] data events from this stream.
1103    *
1104    * Returns a stream that emits the same events as this stream would
1105    * if listened to at the same time, except that the first [count]
1106    * data events are not emitted.
1107    * The returned stream is done when this stream is.
1108    *
1109    * If this stream emits fewer than [count] data events
1110    * before being done, the returned stream emits no data events.
1111    *
1112    * The returned stream is a broadcast stream if this stream is.
1113    * For a broadcast stream, the events are only counted from the time
1114    * the returned stream is listened to.
1115    */
1116   Stream<T> skip(int count) {
1117     return new _SkipStream<T>(this, count);
1118   }
1119 
1120   /**
1121    * Skip data events from this stream while they are matched by [test].
1122    *
1123    * Returns a stream that emits the same events as this stream,
1124    * except that data events are not emitted until a data event fails `test`.
1125    * The test fails when called with a data event
1126    * if it returns a non-`true` value or if the call to `test` throws.
1127    * If the call throws, the error is emitted as an error event
1128    * on the returned stream instead of the data event,
1129    * otherwise the event that made `test` return non-true is emitted as the
1130    * first data event.
1131    *
1132    * Error and done events are provided by the returned stream unmodified.
1133    *
1134    * The returned stream is a broadcast stream if this stream is.
1135    * For a broadcast stream, the events are only tested from the time
1136    * the returned stream is listened to.
1137    */
1138   Stream<T> skipWhile(bool test(T element)) {
1139     return new _SkipWhileStream<T>(this, test);
1140   }
1141 
1142   /**
1143    * Skips data events if they are equal to the previous data event.
1144    *
1145    * The returned stream provides the same events as this stream, except
1146    * that it never provides two consecutive data events that are equal.
1147    * That is, errors are passed through to the returned stream, and
1148    * data events are passed through if they are distinct from the most
1149    * recently emitted data event.
1150    *
1151    * Equality is determined by the provided [equals] method. If that is
1152    * omitted, the '==' operator on the last provided data element is used.
1153    *
1154    * If [equals] throws, the data event is replaced by an error event
1155    * containing the thrown error. The behavior is equivalent to the
1156    * original stream emitting the error event, and it doesn't change
1157    * the what the most recently emitted data event is.
1158    *
1159    * The returned stream is a broadcast stream if this stream is.
1160    * If a broadcast stream is listened to more than once, each subscription
1161    * will individually perform the `equals` test.
1162    */
1163   Stream<T> distinct([bool equals(T previous, T next)]) {
1164     return new _DistinctStream<T>(this, equals);
1165   }
1166 
1167   /**
1168    * The first element of this stream.
1169    *
1170    * Stops listening to this stream after the first element has been received.
1171    *
1172    * Internally the method cancels its subscription after the first element.
1173    * This means that single-subscription (non-broadcast) streams are closed
1174    * and cannot be reused after a call to this getter.
1175    *
1176    * If an error event occurs before the first data event, the returned future
1177    * is completed with that error.
1178    *
1179    * If this stream is empty (a done event occurs before the first data event),
1180    * the returned future completes with an error.
1181    *
1182    * Except for the type of the error, this method is equivalent to
1183    * `this.elementAt(0)`.
1184    */
1185   Future<T> get first {
1186     _Future<T> future = new _Future<T>();
1187     StreamSubscription subscription;
1188     subscription = this.listen(
1189         (T value) {
1190           _cancelAndValue(subscription, future, value);
1191         },
1192         onError: future._completeError,
1193         onDone: () {
1194           try {
1195             throw IterableElementError.noElement();
1196           } catch (e, s) {
1197             _completeWithErrorCallback(future, e, s);
1198           }
1199         },
1200         cancelOnError: true);
1201     return future;
1202   }
1203 
1204   /**
1205    * The last element of this stream.
1206    *
1207    * If this stream emits an error event,
1208    * the returned future is completed with that error
1209    * and processing stops.
1210    *
1211    * If this stream is empty (the done event is the first event),
1212    * the returned future completes with an error.
1213    */
1214   Future<T> get last {
1215     _Future<T> future = new _Future<T>();
1216     T result;
1217     bool foundResult = false;
1218     listen(
1219         (T value) {
1220           foundResult = true;
1221           result = value;
1222         },
1223         onError: future._completeError,
1224         onDone: () {
1225           if (foundResult) {
1226             future._complete(result);
1227             return;
1228           }
1229           try {
1230             throw IterableElementError.noElement();
1231           } catch (e, s) {
1232             _completeWithErrorCallback(future, e, s);
1233           }
1234         },
1235         cancelOnError: true);
1236     return future;
1237   }
1238 
1239   /**
1240    * The single element of this stream.
1241    *
1242    * If this stream emits an error event,
1243    * the returned future is completed with that error
1244    * and processing stops.
1245    *
1246    * If [this] is empty or has more than one element,
1247    * the returned future completes with an error.
1248    */
1249   Future<T> get single {
1250     _Future<T> future = new _Future<T>();
1251     T result;
1252     bool foundResult = false;
1253     StreamSubscription subscription;
1254     subscription = this.listen(
1255         (T value) {
1256           if (foundResult) {
1257             // This is the second element we get.
1258             try {
1259               throw IterableElementError.tooMany();
1260             } catch (e, s) {
1261               _cancelAndErrorWithReplacement(subscription, future, e, s);
1262             }
1263             return;
1264           }
1265           foundResult = true;
1266           result = value;
1267         },
1268         onError: future._completeError,
1269         onDone: () {
1270           if (foundResult) {
1271             future._complete(result);
1272             return;
1273           }
1274           try {
1275             throw IterableElementError.noElement();
1276           } catch (e, s) {
1277             _completeWithErrorCallback(future, e, s);
1278           }
1279         },
1280         cancelOnError: true);
1281     return future;
1282   }
1283 
1284   /**
1285    * Finds the first element of this stream matching [test].
1286    *
1287    * Returns a future that is completed with the first element of this stream
1288    * that [test] returns `true` for.
1289    *
1290    * If no such element is found before this stream is done, and a
1291    * [orElse] function is provided, the result of calling [orElse]
1292    * becomes the value of the future. If [orElse] throws, the returned
1293    * future is completed with that error.
1294    *
1295    * If this stream emits an error before the first matching element,
1296    * the returned future is completed with that error, and processing stops.
1297    *
1298    * Stops listening to this stream after the first matching element or error
1299    * has been received.
1300    *
1301    * Internally the method cancels its subscription after the first element that
1302    * matches the predicate. This means that single-subscription (non-broadcast)
1303    * streams are closed and cannot be reused after a call to this method.
1304    *
1305    * If an error occurs, or if this stream ends without finding a match and
1306    * with no [orElse] function provided,
1307    * the returned future is completed with an error.
1308    */
1309   Future<T> firstWhere(bool test(T element), {T orElse()}) {
1310     _Future<T> future = new _Future();
1311     StreamSubscription subscription;
1312     subscription = this.listen(
1313         (T value) {
1314           _runUserCode(() => test(value), (bool isMatch) {
1315             if (isMatch) {
1316               _cancelAndValue(subscription, future, value);
1317             }
1318           }, _cancelAndErrorClosure(subscription, future));
1319         },
1320         onError: future._completeError,
1321         onDone: () {
1322           if (orElse != null) {
1323             _runUserCode(orElse, future._complete, future._completeError);
1324             return;
1325           }
1326           try {
1327             throw IterableElementError.noElement();
1328           } catch (e, s) {
1329             _completeWithErrorCallback(future, e, s);
1330           }
1331         },
1332         cancelOnError: true);
1333     return future;
1334   }
1335 
1336   /**
1337    * Finds the last element in this stream matching [test].
1338    *
1339    * If this stream emits an error, the returned future is completed with that
1340    * error, and processing stops.
1341    *
1342    * Otherwise as [firstWhere], except that the last matching element is found
1343    * instead of the first.
1344    * That means that a non-error result cannot be provided before this stream
1345    * is done.
1346    */
1347   Future<T> lastWhere(bool test(T element), {T orElse()}) {
1348     _Future<T> future = new _Future();
1349     T result;
1350     bool foundResult = false;
1351     StreamSubscription subscription;
1352     subscription = this.listen(
1353         (T value) {
1354           _runUserCode(() => true == test(value), (bool isMatch) {
1355             if (isMatch) {
1356               foundResult = true;
1357               result = value;
1358             }
1359           }, _cancelAndErrorClosure(subscription, future));
1360         },
1361         onError: future._completeError,
1362         onDone: () {
1363           if (foundResult) {
1364             future._complete(result);
1365             return;
1366           }
1367           if (orElse != null) {
1368             _runUserCode(orElse, future._complete, future._completeError);
1369             return;
1370           }
1371           try {
1372             throw IterableElementError.noElement();
1373           } catch (e, s) {
1374             _completeWithErrorCallback(future, e, s);
1375           }
1376         },
1377         cancelOnError: true);
1378     return future;
1379   }
1380 
1381   /**
1382    * Finds the single element in this stream matching [test].
1383    *
1384    * Like [lastWhere], except that it is an error if more than one
1385    * matching element occurs in this stream.
1386    */
1387   Future<T> singleWhere(bool test(T element), {T orElse()}) {
1388     _Future<T> future = new _Future<T>();
1389     T result;
1390     bool foundResult = false;
1391     StreamSubscription subscription;
1392     subscription = this.listen(
1393         (T value) {
1394           _runUserCode(() => true == test(value), (bool isMatch) {
1395             if (isMatch) {
1396               if (foundResult) {
1397                 try {
1398                   throw IterableElementError.tooMany();
1399                 } catch (e, s) {
1400                   _cancelAndErrorWithReplacement(subscription, future, e, s);
1401                 }
1402                 return;
1403               }
1404               foundResult = true;
1405               result = value;
1406             }
1407           }, _cancelAndErrorClosure(subscription, future));
1408         },
1409         onError: future._completeError,
1410         onDone: () {
1411           if (foundResult) {
1412             future._complete(result);
1413             return;
1414           }
1415           try {
1416             if (orElse != null) {
1417               _runUserCode(orElse, future._complete, future._completeError);
1418               return;
1419             }
1420             throw IterableElementError.noElement();
1421           } catch (e, s) {
1422             _completeWithErrorCallback(future, e, s);
1423           }
1424         },
1425         cancelOnError: true);
1426     return future;
1427   }
1428 
1429   /**
1430    * Returns the value of the [index]th data event of this stream.
1431    *
1432    * Stops listening to this stream after the [index]th data event has been
1433    * received.
1434    *
1435    * Internally the method cancels its subscription after these elements. This
1436    * means that single-subscription (non-broadcast) streams are closed and
1437    * cannot be reused after a call to this method.
1438    *
1439    * If an error event occurs before the value is found, the future completes
1440    * with this error.
1441    *
1442    * If a done event occurs before the value is found, the future completes
1443    * with a [RangeError].
1444    */
1445   Future<T> elementAt(int index) {
1446     ArgumentError.checkNotNull(index, "index");
1447     RangeError.checkNotNegative(index, "index");
1448     _Future<T> future = new _Future<T>();
1449     StreamSubscription subscription;
1450     int elementIndex = 0;
1451     subscription = this.listen(
1452         (T value) {
1453           if (index == elementIndex) {
1454             _cancelAndValue(subscription, future, value);
1455             return;
1456           }
1457           elementIndex += 1;
1458         },
1459         onError: future._completeError,
1460         onDone: () {
1461           future._completeError(
1462               new RangeError.index(index, this, "index", null, elementIndex));
1463         },
1464         cancelOnError: true);
1465     return future;
1466   }
1467 
1468   /**
1469    * Creates a new stream with the same events as this stream.
1470    *
1471    * Whenever more than [timeLimit] passes between two events from this stream,
1472    * the [onTimeout] function is called, which can emit further events on
1473    * the returned stream.
1474    *
1475    * The countdown doesn't start until the returned stream is listened to.
1476    * The countdown is reset every time an event is forwarded from this stream,
1477    * or when this stream is paused and resumed.
1478    *
1479    * The [onTimeout] function is called with one argument: an
1480    * [EventSink] that allows putting events into the returned stream.
1481    * This `EventSink` is only valid during the call to [onTimeout].
1482    * Calling [EventSink.close] on the sink passed to [onTimeout] closes the
1483    * returned stream, and no further events are processed.
1484    *
1485    * If [onTimeout] is omitted, a timeout will just put a [TimeoutException]
1486    * into the error channel of the returned stream.
1487    * If the call to [onTimeout] throws, the error is emitted on the returned
1488    * stream.
1489    *
1490    * The returned stream is a broadcast stream if this stream is.
1491    * If a broadcast stream is listened to more than once, each subscription
1492    * will have its individually timer that starts counting on listen,
1493    * and the subscriptions' timers can be paused individually.
1494    */
1495   Stream<T> timeout(Duration timeLimit, {void onTimeout(EventSink<T> sink)}) {
1496     _StreamControllerBase<T> controller;
1497     // The following variables are set on listen.
1498     StreamSubscription<T> subscription;
1499     Timer timer;
1500     Zone zone;
1501     _TimerCallback timeout;
1502 
1503     void onData(T event) {
1504       timer.cancel();
1505       controller.add(event);
1506       timer = zone.createTimer(timeLimit, timeout);
1507     }
1508 
1509     void onError(error, StackTrace stackTrace) {
1510       timer.cancel();
1511       assert(controller is _StreamController ||
1512           controller is _BroadcastStreamController);
1513       controller._addError(error, stackTrace); // Avoid Zone error replacement.
1514       timer = zone.createTimer(timeLimit, timeout);
1515     }
1516 
1517     void onDone() {
1518       timer.cancel();
1519       controller.close();
1520     }
1521 
1522     void onListen() {
1523       // This is the onListen callback for of controller.
1524       // It runs in the same zone that the subscription was created in.
1525       // Use that zone for creating timers and running the onTimeout
1526       // callback.
1527       zone = Zone.current;
1528       if (onTimeout == null) {
1529         timeout = () {
1530           controller.addError(
1531               new TimeoutException("No stream event", timeLimit), null);
1532         };
1533       } else {
1534         // TODO(floitsch): the return type should be 'void', and the type
1535         // should be inferred.
1536         var registeredOnTimeout =
1537             zone.registerUnaryCallback<dynamic, EventSink<T>>(onTimeout);
1538         var wrapper = new _ControllerEventSinkWrapper<T>(null);
1539         timeout = () {
1540           wrapper._sink = controller; // Only valid during call.
1541           zone.runUnaryGuarded(registeredOnTimeout, wrapper);
1542           wrapper._sink = null;
1543         };
1544       }
1545 
1546       subscription = this.listen(onData, onError: onError, onDone: onDone);
1547       timer = zone.createTimer(timeLimit, timeout);
1548     }
1549 
1550     Future onCancel() {
1551       timer.cancel();
1552       Future result = subscription.cancel();
1553       subscription = null;
1554       return result;
1555     }
1556 
1557     controller = isBroadcast
1558         ? new _SyncBroadcastStreamController<T>(onListen, onCancel)
1559         : new _SyncStreamController<T>(onListen, () {
1560             // Don't null the timer, onCancel may call cancel again.
1561             timer.cancel();
1562             subscription.pause();
1563           }, () {
1564             subscription.resume();
1565             timer = zone.createTimer(timeLimit, timeout);
1566           }, onCancel);
1567     return controller.stream;
1568   }
1569 }
1570 
1571 /**
1572  * A subscription on events from a [Stream].
1573  *
1574  * When you listen on a [Stream] using [Stream.listen],
1575  * a [StreamSubscription] object is returned.
1576  *
1577  * The subscription provides events to the listener,
1578  * and holds the callbacks used to handle the events.
1579  * The subscription can also be used to unsubscribe from the events,
1580  * or to temporarily pause the events from the stream.
1581  */
1582 abstract class StreamSubscription<T> {
1583   /**
1584    * Cancels this subscription.
1585    *
1586    * After this call, the subscription no longer receives events.
1587    *
1588    * The stream may need to shut down the source of events and clean up after
1589    * the subscription is canceled.
1590    *
1591    * Returns a future that is completed once the stream has finished
1592    * its cleanup.
1593    *
1594    * For historical reasons, may also return `null` if no cleanup was necessary.
1595    * Returning `null` is deprecated and should be avoided.
1596    *
1597    * Typically, futures are returned when the stream needs to release resources.
1598    * For example, a stream might need to close an open file (as an asynchronous
1599    * operation). If the listener wants to delete the file after having
1600    * canceled the subscription, it must wait for the cleanup future to complete.
1601    *
1602    * A returned future completes with a `null` value.
1603    * If the cleanup throws, which it really shouldn't, the returned future
1604    * completes with that error.
1605    */
1606   Future cancel();
1607 
1608   /**
1609    * Replaces the data event handler of this subscription.
1610    *
1611    * The [handleData] function is called for each element of the stream
1612    * after this function is called.
1613    * If [handleData] is `null`, further elements are ignored.
1614    *
1615    * This method replaces the current handler set by the invocation of
1616    * [Stream.listen] or by a previous call to [onData].
1617    */
1618   void onData(void handleData(T data));
1619 
1620   /**
1621    * Replaces the error event handler of this subscription.
1622    *
1623    * The [handleError] function must be able to be called with either
1624    * one positional argument, or with two positional arguments
1625    * where the seconds is always a [StackTrace].
1626    *
1627    * The [handleError] argument may be `null`, in which case further
1628    * error events are considered unhandled, and will be reported to
1629    * [Zone.handleUncaughtError].
1630    *
1631    * The provided function is called for all error events from the
1632    * stream subscription.
1633    *
1634    * This method replaces the current handler set by the invocation of
1635    * [Stream.listen], by calling [asFuture], or by a previous call to [onError].
1636    */
1637   void onError(Function handleError);
1638 
1639   /**
1640    * Replaces the done event handler of this subscription.
1641    *
1642    * The [handleDone] function is called when the stream closes.
1643    * The value may be `null`, in which case no function is called.
1644    *
1645    * This method replaces the current handler set by the invocation of
1646    * [Stream.listen], by calling [asFuture], or by a previous call to [onDone].
1647    */
1648   void onDone(void handleDone());
1649 
1650   /**
1651    * Request that the stream pauses events until further notice.
1652    *
1653    * While paused, the subscription will not fire any events.
1654    * If it receives events from its source, they will be buffered until
1655    * the subscription is resumed.
1656    * For non-broadcast streams, the underlying source is usually informed
1657    * about the pause,
1658    * so it can stop generating events until the subscription is resumed.
1659    *
1660    * To avoid buffering events on a broadcast stream, it is better to
1661    * cancel this subscription, and start to listen again when events
1662    * are needed, if the intermediate events are not important.
1663    *
1664    * If [resumeSignal] is provided, the stream subscription will undo the pause
1665    * when the future completes, as if by a call to [resume].
1666    * If the future completes with an error,
1667    * the stream will still resume, but the error will be considered unhandled
1668    * and is passed to [Zone.handleUncaughtError].
1669    *
1670    * A call to [resume] will also undo a pause.
1671    *
1672    * If the subscription is paused more than once, an equal number
1673    * of resumes must be performed to resume the stream.
1674    * Calls to [resume] and the completion of a [resumeSignal] are
1675    * interchangeable - the [pause] which was passed a [resumeSignal] may be
1676    * ended by a call to [resume], and completing the [resumeSignal] may end a
1677    * different [pause].
1678    *
1679    * It is safe to [resume] or complete a [resumeSignal] even when the
1680    * subscription is not paused, and the resume will have no effect.
1681    *
1682    * Currently DOM streams silently drop events when the stream is paused. This
1683    * is a bug and will be fixed.
1684    */
1685   void pause([Future resumeSignal]);
1686 
1687   /**
1688    * Resume after a pause.
1689    *
1690    * This undoes one previous call to [pause].
1691    * When all previously calls to [pause] have been matched by a calls to
1692    * [resume], possibly through a `resumeSignal` passed to [pause],
1693    * the stream subscription may emit events again.
1694    *
1695    * It is safe to [resume] even when the subscription is not paused, and the
1696    * resume will have no effect.
1697    */
1698   void resume();
1699 
1700   /**
1701    * Whether the [StreamSubscription] is currently paused.
1702    *
1703    * If there have been more calls to [pause] than to [resume] on this
1704    * stream subscription, the subscription is paused, and this getter
1705    * returns `true`.
1706    *
1707    * Returns `false` if the stream can currently emit events, or if
1708    * the subscription has completed or been cancelled.
1709    */
1710   bool get isPaused;
1711 
1712   /**
1713    * Returns a future that handles the [onDone] and [onError] callbacks.
1714    *
1715    * This method *overwrites* the existing [onDone] and [onError] callbacks
1716    * with new ones that complete the returned future.
1717    *
1718    * In case of an error the subscription will automatically cancel (even
1719    * when it was listening with `cancelOnError` set to `false`).
1720    *
1721    * In case of a `done` event the future completes with the given
1722    * [futureValue].
1723    */
1724   Future<E> asFuture<E>([E futureValue]);
1725 }
1726 
1727 /**
1728  * A [Sink] that supports adding errors.
1729  *
1730  * This makes it suitable for capturing the results of asynchronous
1731  * computations, which can complete with a value or an error.
1732  *
1733  * The [EventSink] has been designed to handle asynchronous events from
1734  * [Stream]s. See, for example, [Stream.eventTransformed] which uses
1735  * `EventSink`s to transform events.
1736  */
1737 abstract class EventSink<T> implements Sink<T> {
1738   /**
1739    * Adds a data [event] to the sink.
1740    *
1741    * Must not be called on a closed sink.
1742    */
1743   void add(T event);
1744 
1745   /**
1746    * Adds an [error] to the sink.
1747    *
1748    * Must not be called on a closed sink.
1749    */
1750   void addError(Object error, [StackTrace stackTrace]);
1751 
1752   /**
1753    * Closes the sink.
1754    *
1755    * Calling this method more than once is allowed, but does nothing.
1756    *
1757    * Neither [add] nor [addError] must be called after this method.
1758    */
1759   void close();
1760 }
1761 
1762 /** [Stream] wrapper that only exposes the [Stream] interface. */
1763 class StreamView<T> extends Stream<T> {
1764   final Stream<T> _stream;
1765 
1766   const StreamView(Stream<T> stream)
1767       : _stream = stream,
1768         super._internal();
1769 
1770   bool get isBroadcast => _stream.isBroadcast;
1771 
1772   Stream<T> asBroadcastStream(
1773           {void onListen(StreamSubscription<T> subscription),
1774           void onCancel(StreamSubscription<T> subscription)}) =>
1775       _stream.asBroadcastStream(onListen: onListen, onCancel: onCancel);
1776 
1777   StreamSubscription<T> listen(void onData(T value),
1778       {Function onError, void onDone(), bool cancelOnError}) {
1779     return _stream.listen(onData,
1780         onError: onError, onDone: onDone, cancelOnError: cancelOnError);
1781   }
1782 }
1783 
1784 /**
1785  * Abstract interface for a "sink" accepting multiple entire streams.
1786  *
1787  * A consumer can accept a number of consecutive streams using [addStream],
1788  * and when no further data need to be added, the [close] method tells the
1789  * consumer to complete its work and shut down.
1790  *
1791  * The [Stream.pipe] accepts a `StreamConsumer` and will pass the stream
1792  * to the consumer's [addStream] method. When that completes, it will
1793  * call [close] and then complete its own returned future.
1794  */
1795 abstract class StreamConsumer<S> {
1796   /**
1797    * Consumes the elements of [stream].
1798    *
1799    * Listens on [stream] and does something for each event.
1800    *
1801    * Returns a future which is completed when the stream is done being added,
1802    * and the consumer is ready to accept a new stream.
1803    * No further calls to [addStream] or [close] should happen before the
1804    * returned future has completed.
1805    *
1806    * The consumer may stop listening to the stream after an error,
1807    * it may consume all the errors and only stop at a done event,
1808    * or it may be canceled early if the receiver don't want any further events.
1809    *
1810    * If the consumer stops listening because of some error preventing it
1811    * from continuing, it may report this error in the returned future,
1812    * otherwise it will just complete the future with `null`.
1813    */
1814   Future addStream(Stream<S> stream);
1815 
1816   /**
1817    * Tells the consumer that no further streams will be added.
1818    *
1819    * This allows the consumer to complete any remaining work and release
1820    * resources that are no longer needed
1821    *
1822    * Returns a future which is completed when the consumer has shut down.
1823    * If cleaning up can fail, the error may be reported in the returned future,
1824    * otherwise it completes with `null`.
1825    */
1826   Future close();
1827 }
1828 
1829 /**
1830  * A object that accepts stream events both synchronously and asynchronously.
1831  *
1832  * A [StreamSink] combines the methods from [StreamConsumer] and [EventSink].
1833  *
1834  * The [EventSink] methods can't be used while the [addStream] is called.
1835  * As soon as the [addStream]'s [Future] completes with a value, the
1836  * [EventSink] methods can be used again.
1837  *
1838  * If [addStream] is called after any of the [EventSink] methods, it'll
1839  * be delayed until the underlying system has consumed the data added by the
1840  * [EventSink] methods.
1841  *
1842  * When [EventSink] methods are used, the [done] [Future] can be used to
1843  * catch any errors.
1844  *
1845  * When [close] is called, it will return the [done] [Future].
1846  */
1847 abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
1848   /**
1849    * Tells the stream sink that no further streams will be added.
1850    *
1851    * This allows the stream sink to complete any remaining work and release
1852    * resources that are no longer needed
1853    *
1854    * Returns a future which is completed when the stream sink has shut down.
1855    * If cleaning up can fail, the error may be reported in the returned future,
1856    * otherwise it completes with `null`.
1857    *
1858    * Returns the same future as [done].
1859    *
1860    * The stream sink may close before the [close] method is called, either due
1861    * to an error or because it is itself providing events to someone who has
1862    * stopped listening. In that case, the [done] future is completed first,
1863    * and the `close` method will return the `done` future when called.
1864    *
1865    * Unifies [StreamConsumer.close] and [EventSink.close] which both mark their
1866    * object as not expecting any further events.
1867    */
1868   Future close();
1869 
1870   /**
1871    * Return a future which is completed when the [StreamSink] is finished.
1872    *
1873    * If the `StreamSink` fails with an error,
1874    * perhaps in response to adding events using [add], [addError] or [close],
1875    * the [done] future will complete with that error.
1876    *
1877    * Otherwise, the returned future will complete when either:
1878    *
1879    * * all events have been processed and the sink has been closed, or
1880    * * the sink has otherwise been stopped from handling more events
1881    *   (for example by canceling a stream subscription).
1882    */
1883   Future get done;
1884 }
1885 
1886 /**
1887  * Transforms a Stream.
1888  *
1889  * When a stream's [Stream.transform] method is invoked with a
1890  * [StreamTransformer], the stream calls the [bind] method on the provided
1891  * transformer. The resulting stream is then returned from the
1892  * [Stream.transform] method.
1893  *
1894  * Conceptually, a transformer is simply a function from [Stream] to [Stream]
1895  * that is encapsulated into a class.
1896  *
1897  * It is good practice to write transformers that can be used multiple times.
1898  *
1899  * All other transforming methods on [Stream], such as [Stream.map],
1900  * [Stream.where] or [Stream.expand] can be implemented using
1901  * [Stream.transform]. A [StreamTransformer] is thus very powerful but often
1902  * also a bit more complicated to use.
1903  */
1904 abstract class StreamTransformer<S, T> {
1905   /**
1906    * Creates a [StreamTransformer] based on the given [onListen] callback.
1907    *
1908    * The returned stream transformer uses the provided [onListen] callback
1909    * when a transformed stream is listened to. At that time, the callback
1910    * receives the input stream (the one passed to [bind]) and a
1911    * boolean flag `cancelOnError` to create a [StreamSubscription].
1912    *
1913    * If the transformed stream is a broadcast stream, so is the stream
1914    * returned by the [StreamTransformer.bind] method by this transformer.
1915    *
1916    * If the transformed stream is listened to multiple times, the [onListen]
1917    * callback is called again for each new [Stream.listen] call.
1918    * This happens whether the stream is a broadcast stream or not,
1919    * but the call will usually fail for non-broadcast streams.
1920    *
1921    * The [onListen] callback does *not* receive the handlers that were passed
1922    * to [Stream.listen]. These are automatically set after the call to the
1923    * [onListen] callback (using [StreamSubscription.onData],
1924    * [StreamSubscription.onError] and [StreamSubscription.onDone]).
1925    *
1926    * Most commonly, an [onListen] callback will first call [Stream.listen] on
1927    * the provided stream (with the corresponding `cancelOnError` flag), and then
1928    * return a new [StreamSubscription].
1929    *
1930    * There are two common ways to create a StreamSubscription:
1931    *
1932    * 1. by allocating a [StreamController] and to return the result of
1933    *    listening to its stream. It's important to forward pause, resume and
1934    *    cancel events (unless the transformer intentionally wants to change
1935    *    this behavior).
1936    * 2. by creating a new class that implements [StreamSubscription].
1937    *    Note that the subscription should run callbacks in the [Zone] the
1938    *    stream was listened to (see [Zone] and [Zone.bindCallback]).
1939    *
1940    * Example:
1941    *
1942    * ```
1943    * /// Starts listening to [input] and duplicates all non-error events.
1944    * StreamSubscription<int> _onListen(Stream<int> input, bool cancelOnError) {
1945    *   StreamSubscription<String> subscription;
1946    *   // Create controller that forwards pause, resume and cancel events.
1947    *   var controller = new StreamController<String>(
1948    *       onPause: () {
1949    *         subscription.pause();
1950    *       },
1951    *       onResume: () {
1952    *         subscription.resume();
1953    *       },
1954    *       onCancel: () => subscription.cancel(),
1955    *       sync: true); // "sync" is correct here, since events are forwarded.
1956    *
1957    *   // Listen to the provided stream using `cancelOnError`.
1958    *   subscription = input.listen((data) {
1959    *     // Duplicate the data.
1960    *     controller.add(data);
1961    *     controller.add(data);
1962    *   },
1963    *       onError: controller.addError,
1964    *       onDone: controller.close,
1965    *       cancelOnError: cancelOnError);
1966    *
1967    *   // Return a new [StreamSubscription] by listening to the controller's
1968    *   // stream.
1969    *   return controller.stream.listen(null);
1970    * }
1971    *
1972    * // Instantiate a transformer:
1973    * var duplicator = const StreamTransformer<int, int>(_onListen);
1974    *
1975    * // Use as follows:
1976    * intStream.transform(duplicator);
1977    * ```
1978    */
1979   const factory StreamTransformer(
1980           StreamSubscription<T> onListen(
1981               Stream<S> stream, bool cancelOnError)) =
1982       _StreamSubscriptionTransformer<S, T>;
1983 
1984   /**
1985    * Creates a [StreamTransformer] that delegates events to the given functions.
1986    *
1987    * Example use of a duplicating transformer:
1988    *
1989    * ```
1990    * stringStream.transform(new StreamTransformer<String, String>.fromHandlers(
1991    *     handleData: (String value, EventSink<String> sink) {
1992    *       sink.add(value);
1993    *       sink.add(value);  // Duplicate the incoming events.
1994    *     }));
1995    * ```
1996    *
1997    * Transformers that are constructed this way cannot use captured state if
1998    * they are used in streams that can be listened to multiple times.
1999    * ```
2000    * StreamController<String> controller;
2001    * controller = new StreamController.broadcast(onListen: () {
2002    *   scheduleMicrotask(() {
2003    *     controller.addError("Bad");
2004    *     controller.addError("Worse");
2005    *     controller.addError("Worst");
2006    *   });
2007    * });
2008    * var sharedState = 0;
2009    * var transformedStream = controller.stream.transform(
2010    *     new StreamTransformer<String>.fromHandlers(
2011    *         handleError: (error, stackTrace, sink) {
2012    *   sharedState++; // Increment shared error-counter.
2013    *   sink.add("Error $sharedState: $error");
2014    * }));
2015    *
2016    * transformedStream.listen(print);
2017    * transformedStream.listen(print); // Listen twice.
2018    * // Listening twice to the same stream makes the transformer share the same
2019    * // state. Instead of having "Error 1: Bad", "Error 2: Worse",
2020    * // "Error 3: Worst" as output (each twice for the separate subscriptions),
2021    * // this program emits:
2022    * // Error 1: Bad
2023    * // Error 2: Bad
2024    * // Error 3: Worse
2025    * // Error 4: Worse
2026    * // Error 5: Worst
2027    * // Error 6: Worst
2028    * ```
2029    */
2030   factory StreamTransformer.fromHandlers(
2031       {void handleData(S data, EventSink<T> sink),
2032       void handleError(Object error, StackTrace stackTrace, EventSink<T> sink),
2033       void handleDone(EventSink<T> sink)}) = _StreamHandlerTransformer<S, T>;
2034 
2035   /**
2036    * Creates a [StreamTransformer] based on a [bind] callback.
2037    *
2038    * The returned stream transformer uses the [bind] argument to implement the
2039    * [StreamTransformer.bind] API and can be used when the transformation is
2040    * available as a stream-to-stream function.
2041    *
2042    * ```dart
2043    * final splitDecoded = StreamTransformer<List<int>, String>.fromBind(
2044    *     (stream) => stream.transform(utf8.decoder).transform(LineSplitter()));
2045    * ```
2046    */
2047   @Since("2.1")
2048   factory StreamTransformer.fromBind(Stream<T> Function(Stream<S>) bind) =
2049       _StreamBindTransformer<S, T>;
2050 
2051   /**
2052    * Adapts [source] to be a `StreamTransformer<TS, TT>`.
2053    *
2054    * This allows [source] to be used at the new type, but at run-time it
2055    * must satisfy the requirements of both the new type and its original type.
2056    *
2057    * Data events passed into the returned transformer must also be instances
2058    * of [SS], and data events produced by [source] for those events must
2059    * also be instances of [TT].
2060    */
2061   static StreamTransformer<TS, TT> castFrom<SS, ST, TS, TT>(
2062       StreamTransformer<SS, ST> source) {
2063     return new CastStreamTransformer<SS, ST, TS, TT>(source);
2064   }
2065 
2066   /**
2067    * Transforms the provided [stream].
2068    *
2069    * Returns a new stream with events that are computed from events of the
2070    * provided [stream].
2071    *
2072    * The [StreamTransformer] interface is completely generic,
2073    * so it cannot say what subclasses do.
2074    * Each [StreamTransformer] should document clearly how it transforms the
2075    * stream (on the class or variable used to access the transformer),
2076    * as well as any differences from the following typical behavior:
2077    *
2078    * * When the returned stream is listened to, it starts listening to the
2079    *   input [stream].
2080    * * Subscriptions of the returned stream forward (in a reasonable time)
2081    *   a [StreamSubscription.pause] call to the subscription of the input
2082    *   [stream].
2083    * * Similarly, canceling a subscription of the returned stream eventually
2084    *   (in reasonable time) cancels the subscription of the input [stream].
2085    *
2086    * "Reasonable time" depends on the transformer and stream. Some transformers,
2087    * like a "timeout" transformer, might make these operations depend on a
2088    * duration. Others might not delay them at all, or just by a microtask.
2089    *
2090    * Transformers are free to handle errors in any way.
2091    * A transformer implementation may choose to propagate errors,
2092    * or convert them to other events, or ignore them completely,
2093    * but if errors are ignored, it should be documented explicitly.
2094    */
2095   Stream<T> bind(Stream<S> stream);
2096 
2097   /**
2098    * Provides a `StreamTransformer<RS, RT>` view of this stream transformer.
2099    *
2100    * The resulting transformer will check at run-time that all data events
2101    * of the stream it transforms are actually instances of [S],
2102    * and it will check that all data events produced by this transformer
2103    * are actually instances of [RT].
2104    */
2105   StreamTransformer<RS, RT> cast<RS, RT>();
2106 }
2107 
2108 /**
2109  * Base class for implementing [StreamTransformer].
2110  *
2111  * Contains default implementations of every method except [bind].
2112  */
2113 abstract class StreamTransformerBase<S, T> implements StreamTransformer<S, T> {
2114   const StreamTransformerBase();
2115 
2116   StreamTransformer<RS, RT> cast<RS, RT>() =>
2117       StreamTransformer.castFrom<S, T, RS, RT>(this);
2118 }
2119 
2120 /**
2121  * An [Iterator] like interface for the values of a [Stream].
2122  *
2123  * This wraps a [Stream] and a subscription on the stream. It listens
2124  * on the stream, and completes the future returned by [moveNext] when the
2125  * next value becomes available.
2126  *
2127  * The stream may be paused between calls to [moveNext].
2128  */
2129 abstract class StreamIterator<T> {
2130   /** Create a [StreamIterator] on [stream]. */
2131   factory StreamIterator(Stream<T> stream)
2132       // TODO(lrn): use redirecting factory constructor when type
2133       // arguments are supported.
2134       =>
2135       new _StreamIterator<T>(stream);
2136 
2137   /**
2138    * Wait for the next stream value to be available.
2139    *
2140    * Returns a future which will complete with either `true` or `false`.
2141    * Completing with `true` means that another event has been received and
2142    * can be read as [current].
2143    * Completing with `false` means that the stream iteration is done and
2144    * no further events will ever be available.
2145    * The future may complete with an error, if the stream produces an error,
2146    * which also ends iteration.
2147    *
2148    * The function must not be called again until the future returned by a
2149    * previous call is completed.
2150    */
2151   Future<bool> moveNext();
2152 
2153   /**
2154    * The current value of the stream.
2155    *
2156    * Is `null` before the first call to [moveNext] and after a call to
2157    * `moveNext` completes with a `false` result or an error.
2158    *
2159    * When a `moveNext` call completes with `true`, the `current` field holds
2160    * the most recent event of the stream, and it stays like that until the next
2161    * call to `moveNext`.
2162    * Between a call to `moveNext` and when its returned future completes,
2163    * the value is unspecified.
2164    */
2165   T get current;
2166 
2167   /**
2168    * Cancels the stream iterator (and the underlying stream subscription) early.
2169    *
2170    * The stream iterator is automatically canceled if the [moveNext] future
2171    * completes with either `false` or an error.
2172    *
2173    * If you need to stop listening for values before the stream iterator is
2174    * automatically closed, you must call [cancel] to ensure that the stream
2175    * is properly closed.
2176    *
2177    * If [moveNext] has been called when the iterator is canceled,
2178    * its returned future will complete with `false` as value,
2179    * as will all further calls to [moveNext].
2180    *
2181    * Returns a future if the cancel-operation is not completed synchronously.
2182    * Otherwise returns `null`.
2183    */
2184   Future cancel();
2185 }
2186 
2187 /**
2188  * Wraps an [_EventSink] so it exposes only the [EventSink] interface.
2189  */
2190 class _ControllerEventSinkWrapper<T> implements EventSink<T> {
2191   EventSink _sink;
2192   _ControllerEventSinkWrapper(this._sink);
2193 
2194   void add(T data) {
2195     _sink.add(data);
2196   }
2197 
2198   void addError(error, [StackTrace stackTrace]) {
2199     _sink.addError(error, stackTrace);
2200   }
2201 
2202   void close() {
2203     _sink.close();
2204   }
2205 }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Wesley13 Wesley13
3年前
RAC环境单实例启动数据库收到ORA
     在RAC环境中,如果你在没有启动节点的集群服务的情况下单实例启动数据库,将收到类似如下的报错:\oracle@rhel1u01\$sqlSQL\Plus:Release10.2.0.5.0ProductiononTueApr215:00:272013Copyright(
Wesley13 Wesley13
3年前
CSS 奇思妙想:超级酷炫的边框动画
点上方蓝字关注公众号「前端从进阶到入院」精选原创好文助你进入大厂文章转载自公众号「iCSS前端趣闻」今天逛博客网站shoptalkshow\1\,看到这样一个界面,非常有意思:!(https://oscimg.oschina.net/oscnet/9655b35af5a045999ff55c144a3f7c
Wesley13 Wesley13
3年前
IJCAI2020 图相关论文集
↑公众号关注“GraphAI”专注于图机器学习IJCAI2020图相关论文集!(https://oscimg.oschina.net/oscnet/538c1eb7d78b304723ca074c35b6cc896f2.png)
Stella981 Stella981
3年前
Js使用面向对象和面向过程的方法实现拖拽物体的效果
1.面向过程的拖拽实现代码:!(https://oscimg.oschina.net/oscnet/d680c759957babef2fec0902676eaa35ad9.gif)<!DOCTYPEhtml<html<head<titledragDiv</title
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo