convert method
Adds input
to the sequence of converted bytes and finishes converting
all bytes.
If expectedMac
is non-null, then the method will throw
SecretBoxAuthenticationError if the computed MAC does match.
If possibleBuffer
is non-null, the method is allowed (but not required)
to write the output to it. The buffer can be the same as input
.
Otherwise the method will allocate memory for the output.
Implementation
@override
Future<List<int>> convert(
List<int> input, {
Uint8List? possibleBuffer,
Mac? expectedMac,
int? chunkSize,
}) async {
if (!_isInitialized) {
throw StateError('Not initialized');
}
final outputChunks = <List<int>>[];
chunkSize ??= defaultChunkSize;
if (chunkSize < 0) {
//
// Do not split the input
//
final outputChunk = convertChunkSync(
input,
possibleBuffer: possibleBuffer,
);
outputChunks.add(outputChunk);
} else {
//
// Split the input
//
if (chunkSize < 64) {
throw ArgumentError.value(chunkSize, 'chunkSize');
}
if (input is! Uint8List) {
input = Uint8List.fromList(input);
possibleBuffer = input;
}
for (var i = 0; i < input.length; i += chunkSize) {
// Pause to avoid blocking the event loop.
if (i > 0) {
await Future.delayed(const Duration(milliseconds: 1));
}
final thisChunkSize = min(chunkSize, input.length - i);
final inputChunk = input.buffer.asUint8List(
input.offsetInBytes + i,
thisChunkSize,
);
final outputChunk = convertChunkSync(
inputChunk,
possibleBuffer: possibleBuffer,
);
outputChunks.add(outputChunk);
}
}
final suffix = beforeClose();
if (suffix.isNotEmpty) {
macSink.add(suffix);
outputChunks.add(suffix);
}
macSink.close();
final mac = await macSink.mac();
_mac = mac;
if (expectedMac != null && mac != expectedMac) {
throw SecretBoxAuthenticationError();
}
return _concatenate(outputChunks);
}