/// <inheritdoc /> public override void StartDecode() { // TODO: This is a bit memory hungry, because all data gets read in first, but the implementation is only suited for statistical analysis now and // not for replaying large data sets. Can be improved later. MemoryStream ms = new MemoryStream(); foreach (var fileToRead in _filesToRead) { using (StreamReader sr = File.OpenText(fileToRead)) { string? line = sr.ReadLine(); Encoding raw = new Raw8BitEncoding(); while (line != null) { if (line.Contains("|")) { var splits = line.Split(new char[] { '|' }, StringSplitOptions.None); line = splits[2]; // Raw message } // Pack data into memory stream, from which the parser will get it again byte[] bytes = raw.GetBytes(line + "\r\n"); ms.Write(bytes, 0, bytes.Length); line = sr.ReadLine(); } } } ms.Position = 0; ManualResetEvent ev = new ManualResetEvent(false); var parser = new NmeaParser(InterfaceName, ms, null); parser.SuppressOutdatedMessages = false; // parse all incoming messages, ignoring any timing parser.OnNewSequence += ForwardDecoded; parser.OnParserError += (source, s, error) => { if (error == NmeaError.PortClosed) { ev.Set(); } }; parser.StartDecode(); ev.WaitOne(); // Wait for end of file parser.StopDecode(); ms.Dispose(); }
/// <summary> /// Creates a new instance of the NmeaParser, taking an input and an output stream /// </summary> /// <param name="interfaceName">Friendly name of this interface (used for filtering and eventually logging)</param> /// <param name="dataSource">Data source (may be connected to a serial port, a network interface, or whatever). It is recommended to use a blocking Stream, /// to prevent unnecessary polling</param> /// <param name="dataSink">Optional data sink, to send information. Can be null, and can be identical to the source stream</param> public NmeaParser(String interfaceName, Stream dataSource, Stream?dataSink) : base(interfaceName) { _encoding = new Raw8BitEncoding(); _dataSource = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); _reader = new StreamReader(_dataSource, _encoding); // Nmea sentences are text _dataSink = dataSink; _lock = new object(); _outQueue = new(); _outEvent = new AutoResetEvent(false); ExclusiveTalkerId = TalkerId.Any; _ioExceptionOnSend = null; SuppressOutdatedMessages = true; LastPacketTime = DateTimeOffset.UtcNow; }