writeAt method

  1. @override
Future<int> writeAt(
  1. int offset,
  2. Uint8List src, {
  3. int start = 0,
  4. int? end,
})

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;
  });
}