read method
Overwrites the contents of view
with data read from sourceStream
.
Optionally a non-null streamSizeBytesHint
may be provided to
indicate how large the stream is, but see caveats in
StreamReaderState.remainingStreamBytesHint on its use.
Throws ReadonlyContainerException if view
.isReadonly, as the contents
of a readonly view cannot be overwritten.
Throws NotEmptyContainerException if view
.isNotEmpty, as the contents
of an already existing view cannot be overwritten (since there may be
other views that depend on it).
Throws InvalidSignatureException if the stream contains an invalid
signature at either Persistence level or Persister level.
Throws NewerVersionException if the stream contains a newer version at
either Persistence level or Persister level.
Implementation
Future<void> read(GpsPointsView view, Stream<List<int>> sourceStream,
[int? streamSizeBytesHint]) async {
if (view.isReadonly) {
throw ReadonlyContainerException();
}
if (view.isNotEmpty) {
throw NotEmptyContainerException();
}
final state = StreamReaderState(sourceStream, streamSizeBytesHint);
// Read the header signature and stop if it's unrecognized.
await _readValidateSignature(state, _signatureAndVersion.signature);
// Read the streaming method version and stop if it's newer than what
// we support internally.
await _readValidateVersion(state, _signatureAndVersion.version, 'stream');
final persister = getPersister(view);
// Read the persister signature and validate against the persister that's
// supposed to read the specified view.
await _readValidateSignature(state, persister.signature);
// Read the persister version number and stop if it's newer than what the
// persister writes natively.
final loadedPersisterVersion = await _readValidateVersion(
state, persister.version, 'persister ${persister.runtimeType}');
// Read the metadata.
final metadataLength = await state.readUint8();
if (metadataLength == null || metadataLength > maxMetadataLength) {
throw (InvalidMetadataException(
'Expected to read metadata with max length $maxMetadataLength, '
'but found length $metadataLength.'));
}
// Always read entire metadata because it's fixed-length, will trim it
// afterwards to reflect the actual length read above.
final metadataList = await state.readBytes(maxMetadataLength);
if (metadataList == null) {
throw (InvalidMetadataException(
'Failed reading metadata, probably the stream is corrupted '
'(too short)'));
}
final metadata = ByteData(metadataLength);
metadata.buffer.asUint8List().setRange(0, metadataLength, metadataList);
// Have the persister read and interpret the actual data.
return persister.readViewFromStream(
view, state, loadedPersisterVersion, metadata);
}