mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 05:36:49 +00:00
f6ac970290
This is a reland of commit608934e330
Can be landed when Flutter with https://github.com/flutter/flutter/pull/123211 has been rolled into internal repository. Original change's description: > Reland "Add class modifiers to `dart:convert`." > > This is a reland of commitb2f4cf3e01
> > Commented out deprecation for now. > > Original change's description: > > Add class modifiers to `dart:convert`. > > > > The usual approach: > > Pure interfaces marked `interface`. > > Pure implementation classes marked `final`. > > Base classes marked `base` or nothing, and `mixin class` if reasonable. > > Combined X/XBase/XMixin where possible. > > > > CoreLibraryReviewExempt: Aske is away > > Change-Id: I927f9bd488fb385ff9c17c8fc94920a1f5076347 > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289200 > > Reviewed-by: Stephen Adams <sra@google.com> > > Reviewed-by: Slava Egorov <vegorov@google.com> > > Reviewed-by: Nate Bosch <nbosch@google.com> > > Commit-Queue: Lasse Nielsen <lrn@google.com> > > CoreLibraryReviewExempt: Approved in original. > Change-Id: I1bc14f99b742567e2634dcfcbc52f332dbcc5364 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290521 > Reviewed-by: Nate Bosch <nbosch@google.com> > Commit-Queue: Lasse Nielsen <lrn@google.com> CoreLibraryReviewExempt: Approved in original. Change-Id: If157e1ef2339d7a06e99a1e402f2f8ac93550b83 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290960 Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com>
101 lines
3 KiB
Dart
101 lines
3 KiB
Dart
// 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;
|
|
|
|
/// The [ByteConversionSink] provides an interface for converters to
|
|
/// efficiently transmit byte data.
|
|
///
|
|
/// Instead of limiting the interface to one non-chunked list of bytes it
|
|
/// accepts its input in chunks (themselves being lists of bytes).
|
|
abstract mixin class ByteConversionSink
|
|
implements ChunkedConversionSink<List<int>> {
|
|
const ByteConversionSink();
|
|
|
|
factory ByteConversionSink.withCallback(
|
|
void callback(List<int> accumulated)) = _ByteCallbackSink;
|
|
factory ByteConversionSink.from(Sink<List<int>> sink) = _ByteAdapterSink;
|
|
|
|
/// Adds the next [chunk] to `this`.
|
|
///
|
|
/// Adds the bytes defined by [start] and [end]-exclusive to `this`.
|
|
///
|
|
/// If [isLast] is `true` closes `this`.
|
|
///
|
|
/// Contrary to `add` the given [chunk] must not be held onto.
|
|
/// Once the method returns, it is safe to overwrite the data in it.
|
|
void addSlice(List<int> chunk, int start, int end, bool isLast) {
|
|
add(chunk.sublist(start, end));
|
|
if (isLast) close();
|
|
}
|
|
}
|
|
|
|
/// This class provides a base-class for converters that need to accept byte
|
|
/// inputs.
|
|
// TODO(lrn): @Deprecated("Use ByteConversionSink instead")
|
|
typedef ByteConversionSinkBase = ByteConversionSink;
|
|
|
|
/// This class adapts a simple [Sink] to a [ByteConversionSink].
|
|
///
|
|
/// All additional methods of the [ByteConversionSink] (compared to the
|
|
/// ChunkedConversionSink) are redirected to the `add` method.
|
|
class _ByteAdapterSink extends ByteConversionSink {
|
|
final Sink<List<int>> _sink;
|
|
|
|
_ByteAdapterSink(this._sink);
|
|
|
|
void add(List<int> chunk) {
|
|
_sink.add(chunk);
|
|
}
|
|
|
|
void close() {
|
|
_sink.close();
|
|
}
|
|
}
|
|
|
|
/// This class accumulates all chunks into one list of bytes
|
|
/// and invokes a callback when the sink is closed.
|
|
///
|
|
/// This class can be used to terminate a chunked conversion.
|
|
class _ByteCallbackSink extends ByteConversionSink {
|
|
static const _INITIAL_BUFFER_SIZE = 1024;
|
|
|
|
final void Function(List<int>) _callback;
|
|
List<int> _buffer = Uint8List(_INITIAL_BUFFER_SIZE);
|
|
int _bufferIndex = 0;
|
|
|
|
_ByteCallbackSink(void callback(List<int> accumulated))
|
|
: _callback = callback;
|
|
|
|
void add(Iterable<int> chunk) {
|
|
var freeCount = _buffer.length - _bufferIndex;
|
|
if (chunk.length > freeCount) {
|
|
// Grow the buffer.
|
|
var oldLength = _buffer.length;
|
|
var newLength = _roundToPowerOf2(chunk.length + oldLength) * 2;
|
|
var grown = Uint8List(newLength);
|
|
grown.setRange(0, _buffer.length, _buffer);
|
|
_buffer = grown;
|
|
}
|
|
_buffer.setRange(_bufferIndex, _bufferIndex + chunk.length, chunk);
|
|
_bufferIndex += chunk.length;
|
|
}
|
|
|
|
static int _roundToPowerOf2(int v) {
|
|
assert(v > 0);
|
|
v--;
|
|
v |= v >> 1;
|
|
v |= v >> 2;
|
|
v |= v >> 4;
|
|
v |= v >> 8;
|
|
v |= v >> 16;
|
|
v++;
|
|
return v;
|
|
}
|
|
|
|
void close() {
|
|
_callback(_buffer.sublist(0, _bufferIndex));
|
|
}
|
|
}
|