readBytes method
Reads a list of bytes of nrBytesToRead
bytes from the stream, if
possible, or null otherwise (e.g. the stream doesn't contain
nrBytesToRead
bytes).
Implementation
Future<List<int>?> readBytes(int nrBytesToRead) async {
// If we don't want to read anything, stop immediately.
if (nrBytesToRead == 0) {
return null;
}
// Try to get enough data in the cache.
var cachedBytes = await _ensureEnoughBytesInCache(nrBytesToRead);
// If we still don't have enough bytes, stop.
if (cachedBytes < nrBytesToRead) {
return null;
}
// Have enough bytes -> return them.
final result = List<int>.filled(nrBytesToRead, 0);
_bytesRead += nrBytesToRead;
do {
final firstList = _cachedLists.first;
// Determine how many items we can take from the first list.
final nrBytesFromFirstList =
min(nrBytesToRead, firstList.length - _positionInFrontList);
// Get those items to the result.
final srcRange = firstList.getRange(
_positionInFrontList, _positionInFrontList + nrBytesFromFirstList);
// We need to start setting bytes to result after the ones we've already
// set in previous loops.
final targetPos = result.length - nrBytesToRead;
result.setRange(targetPos, targetPos + nrBytesFromFirstList, srcRange);
// Remove the first list if it's fully consumed.
_positionInFrontList += nrBytesFromFirstList;
if (_positionInFrontList == firstList.length) {
_cachedLists.removeFirst();
_positionInFrontList = 0;
}
// Calculate how many bytes we still need to read.
nrBytesToRead -= nrBytesFromFirstList;
// Continue until we've read all we needed to.
} while (nrBytesToRead != 0);
return result;
}