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 : import 'dart:convert'; 7 : 8 : import 'package:async/async.dart'; 9 : 10 : import '../stream_channel.dart'; 11 : 12 : /// A [StreamChannelTransformer] transforms the events being passed to and 13 : /// emitted by a [StreamChannel]. 14 : /// 15 : /// This works on the same principle as [StreamTransformer] and 16 : /// [StreamSinkTransformer]. Each transformer defines a [bind] method that takes 17 : /// in the original [StreamChannel] and returns the transformed version. 18 : /// 19 : /// Transformers must be able to have [bind] called multiple times. If a 20 : /// subclass implements [bind] explicitly, it should be sure that the returned 21 : /// stream follows the second stream channel guarantee: closing the sink causes 22 : /// the stream to close before it emits any more events. This guarantee is 23 : /// invalidated when an asynchronous gap is added between the original stream's 24 : /// event dispatch and the returned stream's, for example by transforming it 25 : /// with a [StreamTransformer]. The guarantee can be easily preserved using 26 : /// [StreamChannel.withCloseGuarantee]. 27 : class StreamChannelTransformer<S, T> { 28 : /// The transformer to use on the channel's stream. 29 : final StreamTransformer<T, S> _streamTransformer; 30 : 31 : /// The transformer to use on the channel's sink. 32 : final StreamSinkTransformer<S, T> _sinkTransformer; 33 : 34 : /// Creates a [StreamChannelTransformer] from existing stream and sink 35 : /// transformers. 36 0 : const StreamChannelTransformer( 37 : this._streamTransformer, this._sinkTransformer); 38 : 39 : /// Creates a [StreamChannelTransformer] from a codec's encoder and decoder. 40 : /// 41 : /// All input to the inner channel's sink is encoded using [Codec.encoder], 42 : /// and all output from its stream is decoded using [Codec.decoder]. 43 0 : StreamChannelTransformer.fromCodec(Codec<S, T> codec) 44 0 : : this(codec.decoder, 45 0 : StreamSinkTransformer.fromStreamTransformer(codec.encoder)); 46 : 47 : /// Transforms the events sent to and emitted by [channel]. 48 : /// 49 : /// Creates a new channel. When events are passed to the returned channel's 50 : /// sink, the transformer will transform them and pass the transformed 51 : /// versions to `channel.sink`. When events are emitted from the 52 : /// `channel.straem`, the transformer will transform them and pass the 53 : /// transformed versions to the returned channel's stream. 54 0 : StreamChannel<S> bind(StreamChannel<T> channel) => 55 0 : StreamChannel<S>.withCloseGuarantee( 56 0 : channel.stream.transform(_streamTransformer), 57 0 : _sinkTransformer.bind(channel.sink)); 58 : }