blob: 19a85619341c4367c8b2b8db21c854c85d71e032 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.convert;
/// A [ChunkedConversionSink] is used to transmit data more efficiently between
/// two converters during chunked conversions.
///
/// The basic `ChunkedConversionSink` is just a [Sink], and converters should
/// work with a plain `Sink`, but may work more efficiently with certain
/// specialized types of `ChunkedConversionSink`.
///
/// It is recommended that implementations of `ChunkedConversionSink` extend
/// this class, to inherit any further methods that may be added to the class.
abstract class ChunkedConversionSink<T> implements Sink<T> {
ChunkedConversionSink();
factory ChunkedConversionSink.withCallback(
void callback(List<T> accumulated)) = _SimpleCallbackSink<T>;
/// Adds chunked data to this sink.
///
/// This method is also used when converters are used as [StreamTransformer]s.
void add(T chunk);
/// Closes the sink.
///
/// This signals the end of the chunked conversion. This method is called
/// when converters are used as [StreamTransformer]'s.
void close();
}
/// This class accumulates all chunks and invokes a callback with a list of
/// the chunks when the sink is closed.
///
/// This class can be used to terminate a chunked conversion.
class _SimpleCallbackSink<T> extends ChunkedConversionSink<T> {
final void Function(List<T>) _callback;
final List<T> _accumulated = <T>[];
_SimpleCallbackSink(this._callback);
void add(T chunk) {
_accumulated.add(chunk);
}
void close() {
_callback(_accumulated);
}
}
/// This class implements the logic for a chunked conversion as a
/// stream transformer.
///
/// It is used as strategy in the [EventTransformStream].
///
/// It also implements the [ChunkedConversionSink] interface so that it
/// can be used as output sink in a chunked conversion.
class _ConverterStreamEventSink<S, T> implements EventSink<S> {
/// The output sink for the converter.
final EventSink<T> _eventSink;
/// The input sink for new data. All data that is received with
/// [handleData] is added into this sink.
final Sink<S> _chunkedSink;
_ConverterStreamEventSink(Converter<S, T> converter, EventSink<T> sink)
: _eventSink = sink,
_chunkedSink = converter.startChunkedConversion(sink);
void add(S o) {
_chunkedSink.add(o);
}
void addError(Object error, [StackTrace? stackTrace]) {
checkNotNullable(error, "error");
_eventSink.addError(error, stackTrace);
}
void close() {
_chunkedSink.close();
}
}