using Sick.SafetyScanners.DataStructures; using Sick.SafetyScanners.Helpers; namespace Sick.SafetyScanners.DataProcessing; /// /// Parser for MonitoringCaseData response from COLA2 variable command /// Thread-safe implementation /// public sealed class ParseMonitoringCaseData { /// /// Parses the monitoring case data from a TCP sequence (COLA2 response) /// Matches: ParseMonitoringCaseData::parseTCPSequence in C++ /// public MonitoringCaseData ParseTcpSequence(PacketBuffer buffer) { var span = buffer.GetBufferSpan(); bool valid = IsValid(span); if (!valid) { return new MonitoringCaseData { IsValid = false }; } var indices = new List(8); var fieldsValid = new List(8); for (int i = 0; i < 8; i++) { indices.Add(ReadFieldIndex(span, i)); fieldsValid.Add(ReadFieldValid(span, i)); } return new MonitoringCaseData { IsValid = true, MonitoringCaseNumber = ReadMonitoringCaseNumber(span), FieldIndices = indices, FieldsValid = fieldsValid }; } /// /// Matches: ParseMonitoringCaseData::isValid in C++ /// private bool IsValid(ReadOnlySpan span) { byte byteValue = ReadWriteHelper.ReadUint8(span, 0); return byteValue == 'R' || byteValue == 'Y'; } /// /// Matches: ParseMonitoringCaseData::readMonitoringCaseNumber in C++ /// private ushort ReadMonitoringCaseNumber(ReadOnlySpan span) { return ReadWriteHelper.ReadUint16LittleEndian(span, 6); } /// /// Matches: ParseMonitoringCaseData::readFieldIndex in C++ /// private ushort ReadFieldIndex(ReadOnlySpan span, int index) { return ReadWriteHelper.ReadUint16LittleEndian(span, 158 + (index * 4)); } /// /// Matches: ParseMonitoringCaseData::readFieldValid in C++ /// private bool ReadFieldValid(ReadOnlySpan span, int index) { byte byteValue = ReadWriteHelper.ReadUint8(span, 157 + (index * 4)); return (byteValue & (0x01 << 0)) != 0; } }