writeAt method
Writes src[start..end) at offset. Returns bytes written.
Implementation
@override
Future<int> writeAt(
int offset,
Uint8List src, {
int start = 0,
int? end,
}) async {
final e = end ?? src.length;
RangeError.checkValidRange(start, e, src.length);
if (offset < 0) throw RangeError.value(offset, 'offset');
if (start == e) return 0;
_checkWritable();
return _serialize(() async {
final length = e - start;
final newEnd = offset + length;
if (newEnd > kMaxLogicalLength) {
throw RangeError.value(newEnd, 'offset', 'web offset exceeds 2^53');
}
if (newEnd > _length) _length = newEnd;
final first = offset ~/ chunkSize;
final last = (newEnd - 1) ~/ chunkSize;
final partial = <int>[];
for (var index = first; index <= last; index++) {
final chunkStart = index * chunkSize;
final covers = offset <= chunkStart && newEnd >= chunkStart + chunkSize;
if (!covers) partial.add(index);
}
if (partial.isNotEmpty) {
await _loadChunks(partial, readOnly: false);
}
final dirty = <int, Uint8List>{};
var done = 0;
while (done < length) {
final absolute = offset + done;
final index = absolute ~/ chunkSize;
final inChunk = absolute % chunkSize;
final take = math.min(length - done, chunkSize - inChunk);
final chunk = dirty[index] ?? _cachedChunk(index);
chunk.setRange(inChunk, inChunk + take, src, start + done);
dirty[index] = chunk;
done += take;
}
await _store.putMany({
for (final entry in dirty.entries)
idbChunkKey(path, entry.key): entry.value,
});
for (final entry in dirty.entries) {
_putCache(entry.key, entry.value);
}
_metaDirty = true;
return length;
});
}