Adds EndOfStreamReached event for buffered streams and better handle streams that can't auto-rewind

Fixes #73
This commit is contained in:
Morten Nielsen 2020-07-29 17:09:25 -07:00
parent d8d3c3b119
commit 0bc0c28fba

View file

@ -61,9 +61,20 @@ namespace NmeaParser
var stream = await GetStreamAsync().ConfigureAwait(false);
StreamReader sr = new StreamReader(stream);
m_stream = new BufferedStream(sr, emulationSettings);
m_stream.EndOfStreamReached += OnEndOfStreamReached;
return m_stream;
}
private void OnEndOfStreamReached(object sender, EventArgs e)
{
EndOfStreamReached?.Invoke(this, e);
if (m_stream is BufferedStream stream && !stream.CanRewind && IsOpen)
{
// If we can't rewind the stream, stop
_ = CloseAsync();
}
}
/// <summary>
/// Gets or sets the emulated baud rate. Defaults to 115200
/// </summary>
@ -107,7 +118,11 @@ namespace NmeaParser
/// <inheritdoc />
protected override Task CloseStreamAsync(System.IO.Stream stream)
{
m_stream?.Dispose();
if (m_stream != null)
{
m_stream.EndOfStreamReached -= OnEndOfStreamReached;
m_stream?.Dispose();
}
return Task.FromResult(true);
}
@ -134,6 +149,11 @@ namespace NmeaParser
EmptyLine
}
/// <summary>
/// Raised when the stream has reached the end. If the stream can be revound, it'll start over, unless you stop the device in this thread.
/// </summary>
public event EventHandler? EndOfStreamReached;
// stream that slowly populates a buffer from a StreamReader to simulate nmea messages coming
// in lastLineRead by lastLineRead at a steady stream
private class BufferedStream : Stream
@ -159,6 +179,8 @@ namespace NmeaParser
m_readTask = StartReadLoop(m_tcs.Token);
}
internal bool CanRewind => m_sr.BaseStream.CanSeek;
private async Task StartReadLoop(CancellationToken cancellationToken)
{
await Task.Yield();
@ -230,7 +252,12 @@ namespace NmeaParser
if (m_tcs.IsCancellationRequested)
return null;
if (m_sr.EndOfStream)
{
EndOfStreamReached?.Invoke(this, EventArgs.Empty);
if (m_tcs.IsCancellationRequested)
return null;
m_sr.BaseStream.Seek(0, SeekOrigin.Begin); //start over
}
return m_sr.ReadLine() + '\n';
}
@ -295,6 +322,8 @@ namespace NmeaParser
m_sr.Dispose();
base.Dispose(disposing);
}
internal event EventHandler? EndOfStreamReached;
}
}
}