read method

Stream<Uint8List> read(
  1. String path, {
  2. int start = 0,
  3. int? end,
})

Decrypts [start, end) of the plaintext, touching only the chunks that overlap it.

Implementation

Stream<Uint8List> read(String path, {int start = 0, int? end}) async* {
  final UVaultHeader header = await readHeader(path);
  final UAead aead = await openFile(header);
  final int fileLength = await _backend.length(path) ?? header.length;
  final int plain = header.plainLength(fileLength);
  final int stop = end == null || end > plain ? plain : end;
  if (start >= stop) return;
  final int body = fileLength - header.length;
  final int chunkCount = body <= 0 ? 0 : (body + header.sealedChunkSize - 1) ~/ header.sealedChunkSize;
  for (int index = start ~/ header.chunkSize; index < chunkCount; index++) {
    final int plainStart = index * header.chunkSize;
    if (plainStart >= stop) break;
    final int sealedStart = header.length + index * header.sealedChunkSize;
    final int sealedEnd = min(sealedStart + header.sealedChunkSize, fileLength);
    final BytesBuilder sealed = BytesBuilder(copy: false);
    await for (final Uint8List bytes in _backend.read(path, start: sealedStart, end: sealedEnd)) {
      sealed.add(bytes);
    }
    final Uint8List chunk = await aead.open(header.nonce(index, last: index == chunkCount - 1), sealed.takeBytes());
    final int from = max(0, start - plainStart);
    final int to = min(chunk.length, stop - plainStart);
    if (to > from) yield Uint8List.sublistView(chunk, from, to);
  }
}