namespace Common.Hardware.SIRT { using System.Collections.Generic; public sealed class SIRTStream { private readonly SIRTPort sirtPort; public SIRTStream(string portName) => this.sirtPort = new SIRTPort(portName); public bool IsOpen => this.sirtPort.IsOpen; public string PortName => this.sirtPort.PortName; public void Close() => this.sirtPort.Close(); public void Open() => this.sirtPort.Open(); public IEnumerable Read() { var buffer = new List(); var bufferLength = default(int); var startIndex = default(int); var lengthIndex = default(int); var length = default(int); var endIndex = default(int); var messageLength = default(int); var message = default(byte[]); foreach (var bytes in this.sirtPort.Read()) { buffer.AddRange(bytes); bufferLength = buffer.Count; // until can parse messages from the buffer while (bufferLength >= 12) { // reset the start index if needed if (startIndex < 0) { startIndex = 0; } startIndex = buffer.IndexOf(SIRTConstants.SIRT_PC, startIndex); // when no start byte found clear and break if (startIndex < 0) { SIRTLogger.LogState($"Message start not found startIndex: {startIndex} < 0"); buffer.Clear(); break; } lengthIndex = startIndex + SIRTConstants.LEN_IX; // when not enough bytes to the length index just break if (lengthIndex >= bufferLength) { SIRTLogger.LogState($"Message not complete lengthIndex: {lengthIndex} >= {bufferLength} :bufferLength"); break; } length = buffer[lengthIndex]; endIndex = lengthIndex + length + 3; // when not enough bytes to the end of the message just break if (endIndex >= bufferLength) { SIRTLogger.LogState($"Message not complete endIndex: {endIndex} >= {bufferLength} :bufferLength"); break; } // when message dose not ends with 0x16 try again with next start index if (buffer[endIndex] != SIRTConstants.MSG_END) { SIRTLogger.LogState($"Message end {buffer[endIndex]} is not valid"); startIndex++; continue; } messageLength = endIndex - startIndex + 1; message = new byte[messageLength]; buffer.CopyTo(startIndex, message, 0, messageLength); buffer.RemoveRange(0, endIndex); yield return message; // in case there are more messages in the buffer bufferLength = buffer.Count; startIndex = 0; } } } public void Write(params byte[] bytes) => this.sirtPort.Write(bytes); } }