LCOV - code coverage report
Current view: top level - async-1.13.3/lib/src - stream_zip.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 0 34 0.0 %
Date: 2017-10-10 20:17:03 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2016, 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             : import "dart:async";
       6             : 
       7             : /// A stream that combines the values of other streams.
       8             : ///
       9             : /// This emits lists of collected values from each input stream. The first list
      10             : /// contains the first value emitted by each stream, the second contains the
      11             : /// second value, and so on. The lists have the same ordering as the iterable
      12             : /// passed to [new StreamZip].
      13             : ///
      14             : /// Any errors from any of the streams are forwarded directly to this stream.
      15             : class StreamZip<T> extends Stream<List<T>> {
      16             :   final Iterable<Stream<T>> _streams;
      17             : 
      18           0 :   StreamZip(Iterable<Stream<T>> streams) : _streams = streams;
      19             : 
      20             :   StreamSubscription<List<T>> listen(void onData(List<T> data),
      21             :       {Function onError, void onDone(), bool cancelOnError}) {
      22             :     cancelOnError = identical(true, cancelOnError);
      23           0 :     var subscriptions = <StreamSubscription<T>>[];
      24             :     StreamController<List<T>> controller;
      25             :     List<T> current;
      26             :     int dataCount = 0;
      27             : 
      28             :     /// Called for each data from a subscription in [subscriptions].
      29             :     void handleData(int index, T data) {
      30           0 :       current[index] = data;
      31           0 :       dataCount++;
      32           0 :       if (dataCount == subscriptions.length) {
      33             :         var data = current;
      34           0 :         current = new List(subscriptions.length);
      35             :         dataCount = 0;
      36           0 :         for (int i = 0; i < subscriptions.length; i++) {
      37           0 :           if (i != index) subscriptions[i].resume();
      38             :         }
      39           0 :         controller.add(data);
      40             :       } else {
      41           0 :         subscriptions[index].pause();
      42             :       }
      43             :     }
      44             : 
      45             :     /// Called for each error from a subscription in [subscriptions].
      46             :     /// Except if [cancelOnError] is true, in which case the function below
      47             :     /// is used instead.
      48             :     void handleError(Object error, StackTrace stackTrace) {
      49           0 :       controller.addError(error, stackTrace);
      50             :     }
      51             : 
      52             :     /// Called when a subscription has an error and [cancelOnError] is true.
      53             :     ///
      54             :     /// Prematurely cancels all subscriptions since we know that we won't
      55             :     /// be needing any more values.
      56             :     void handleErrorCancel(Object error, StackTrace stackTrace) {
      57           0 :       for (int i = 0; i < subscriptions.length; i++) {
      58           0 :         subscriptions[i].cancel();
      59             :       }
      60           0 :       controller.addError(error, stackTrace);
      61             :     }
      62             : 
      63             :     void handleDone() {
      64           0 :       for (int i = 0; i < subscriptions.length; i++) {
      65           0 :         subscriptions[i].cancel();
      66             :       }
      67           0 :       controller.close();
      68             :     }
      69             : 
      70             :     try {
      71           0 :       for (var stream in _streams) {
      72           0 :         int index = subscriptions.length;
      73           0 :         subscriptions.add(stream.listen((data) {
      74           0 :           handleData(index, data);
      75             :         },
      76             :             onError: cancelOnError ? handleError : handleErrorCancel,
      77             :             onDone: handleDone,
      78             :             cancelOnError: cancelOnError));
      79             :       }
      80             :     } catch (e) {
      81           0 :       for (int i = subscriptions.length - 1; i >= 0; i--) {
      82           0 :         subscriptions[i].cancel();
      83             :       }
      84             :       rethrow;
      85             :     }
      86             : 
      87           0 :     current = new List(subscriptions.length);
      88             : 
      89           0 :     controller = new StreamController<List<T>>(onPause: () {
      90           0 :       for (int i = 0; i < subscriptions.length; i++) {
      91             :         // This may pause some subscriptions more than once.
      92             :         // These will not be resumed by onResume below, but must wait for the
      93             :         // next round.
      94           0 :         subscriptions[i].pause();
      95             :       }
      96             :     }, onResume: () {
      97           0 :       for (int i = 0; i < subscriptions.length; i++) {
      98           0 :         subscriptions[i].resume();
      99             :       }
     100             :     }, onCancel: () {
     101           0 :       for (int i = 0; i < subscriptions.length; i++) {
     102             :         // Canceling more than once is safe.
     103           0 :         subscriptions[i].cancel();
     104             :       }
     105             :     });
     106             : 
     107           0 :     if (subscriptions.isEmpty) {
     108           0 :       controller.close();
     109             :     }
     110           0 :     return controller.stream.listen(onData,
     111             :         onError: onError, onDone: onDone, cancelOnError: cancelOnError);
     112             :   }
     113             : }

Generated by: LCOV version 1.13