diff --git a/src/NmeaParser.Shared/BufferedStreamDevice.cs b/src/NmeaParser.Shared/BufferedStreamDevice.cs index b230f26..aa103d2 100644 --- a/src/NmeaParser.Shared/BufferedStreamDevice.cs +++ b/src/NmeaParser.Shared/BufferedStreamDevice.cs @@ -34,13 +34,13 @@ namespace NmeaParser /// /// Initializes a new instance of the class. /// - protected BufferedStreamDevice() : this(200) + protected BufferedStreamDevice() : this(1000) { } /// /// Initializes a new instance of the class. /// - /// The time to wait between each line being read in milliseconds + /// The time to wait between each group of lines being read in milliseconds protected BufferedStreamDevice(int readSpeed) { m_readSpeed = readSpeed; @@ -77,30 +77,50 @@ namespace NmeaParser } // stream that slowly populates a buffer from a StreamReader to simulate nmea messages coming - // in line by line at a steady stream + // in lastLineRead by lastLineRead at a steady stream private class BufferedStream : Stream { - StreamReader m_sr; - byte[] m_buffer = new byte[0]; - System.Threading.Timer m_timer; - object lockObj = new object(); + private StreamReader m_sr; + private byte[] m_buffer = new byte[0]; + private System.Threading.Timer m_timer; + private object lockObj = new object(); + private string groupToken = null; + private string lastLineRead = null; /// /// Initializes a new instance of the class. /// /// The stream. - /// The read speed. + /// The read speed in milliseconds. public BufferedStream(StreamReader stream, int readSpeed) { m_sr = stream; - m_timer = new System.Threading.Timer(OnRead, null, 0, readSpeed); //add a new line to buffer every 100 ms + m_timer = new System.Threading.Timer(OnRead, null, 0, readSpeed); //read a group of lines every 'readSpeed' milliseconds } private void OnRead(object state) { - if (m_sr.EndOfStream) - m_sr.BaseStream.Seek(0, SeekOrigin.Begin); //start over - - //populate the buffer with a line - string line = m_sr.ReadLine() + '\n'; + if (lastLineRead != null) + AppendToBuffer(lastLineRead); + //Get the group token if we don't have one + while (groupToken == null && (lastLineRead == null || !lastLineRead.StartsWith("$", StringComparison.Ordinal))) + { + lastLineRead = ReadLine(); //seek forward to first nmea token + AppendToBuffer(lastLineRead); + } + if(groupToken == null) + { + var values = lastLineRead.Trim().Split(new char[] { ',' }); + if (values.Length > 0) + groupToken = values[0]; + } + lastLineRead = ReadLine(); + while (!lastLineRead.StartsWith(groupToken, StringComparison.Ordinal)) //keep reading until messages start repeating again + { + AppendToBuffer(lastLineRead); + lastLineRead = ReadLine(); + } + } + private void AppendToBuffer(string line) + { var bytes = Encoding.UTF8.GetBytes(line); lock (lockObj) { @@ -110,6 +130,12 @@ namespace NmeaParser m_buffer = newBuffer; } } + private string ReadLine() + { + if (m_sr.EndOfStream) + m_sr.BaseStream.Seek(0, SeekOrigin.Begin); //start over + return m_sr.ReadLine() + '\n'; + } /// /// Gets a value indicating whether this instance can read. /// diff --git a/src/NmeaParser.Shared/NmeaDevice.cs b/src/NmeaParser.Shared/NmeaDevice.cs index 5e8c119..10ae92d 100644 --- a/src/NmeaParser.Shared/NmeaDevice.cs +++ b/src/NmeaParser.Shared/NmeaDevice.cs @@ -81,7 +81,7 @@ namespace NmeaParser { OnData(buffer.Take(readCount).ToArray()); } - await Task.Delay(10, token); + await Task.Delay(50, token); } if (closeTask != null) closeTask.SetResult(true); @@ -123,19 +123,22 @@ namespace NmeaParser private void OnData(byte[] data) { var nmea = System.Text.Encoding.UTF8.GetString(data, 0, data.Length); - string line = null; + List lines = new List(); lock (m_lockObject) { m_message += nmea; var lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal); - if (lineEnd > -1) + while (lineEnd > -1) { - line = m_message.Substring(0, lineEnd).Trim(); + string line = m_message.Substring(0, lineEnd).Trim(); m_message = m_message.Substring(lineEnd + 1); + if (!string.IsNullOrEmpty(line)) + lines.Add(line); + lineEnd = m_message.IndexOf("\n", StringComparison.Ordinal); } } - if (!string.IsNullOrEmpty(line)) + foreach(var line in lines) ProcessMessage(line); } diff --git a/src/NmeaParser.Shared/NmeaFileDevice.cs b/src/NmeaParser.Shared/NmeaFileDevice.cs index 77195ae..12ab88a 100644 --- a/src/NmeaParser.Shared/NmeaFileDevice.cs +++ b/src/NmeaParser.Shared/NmeaFileDevice.cs @@ -39,9 +39,9 @@ namespace NmeaParser /// /// #if NETFX_CORE - public NmeaFileDevice(Windows.Storage.IStorageFile fileName) : this(fileName, 200) + public NmeaFileDevice(Windows.Storage.IStorageFile fileName) : this(fileName, 1000) #else - public NmeaFileDevice(string fileName) : this(fileName, 200) + public NmeaFileDevice(string fileName) : this(fileName, 1000) #endif { m_filename = fileName; @@ -50,7 +50,7 @@ namespace NmeaParser /// Initializes a new instance of the class. /// /// - /// The time to wait between each line being read in milliseconds + /// The time to wait between each group of lines being read in milliseconds #if NETFX_CORE public NmeaFileDevice(Windows.Storage.IStorageFile fileName, int readSpeed) : base(readSpeed) @@ -62,7 +62,6 @@ namespace NmeaParser } #if !NETFX_CORE - /// /// Gets the name of the nmea file this device is using. ///