using Sick.SafetyScanners.DataStructures; using Sick.SafetyScanners.Helpers; using System.Text; namespace Sick.SafetyScanners.DataProcessing; /// /// Parser for FieldSetsData response from COLA2 variable command /// Thread-safe implementation /// public sealed class ParseFieldSetsData { /// /// Parses the field sets data from a TCP sequence (COLA2 response) /// Matches: ParseFieldSetsData::parseTCPSequence in C++ /// public FieldSets ParseTcpSequence(PacketBuffer buffer) { var span = buffer.GetBufferSpan(); uint arrayLength = ReadArrayLength(span); var nameLengths = new List((int)arrayLength); var fieldNames = new List((int)arrayLength); var isDefined = new List((int)arrayLength); for (uint i = 0; i < arrayLength; i++) { uint nameLength = ReadWriteHelper.ReadUint32LittleEndian(span, 8 + (int)(i * 104)); nameLengths.Add(nameLength); var nameBuilder = new StringBuilder((int)nameLength); for (uint j = 0; j < nameLength; j++) { byte ch = ReadWriteHelper.ReadUint8(span, 12 + (int)(i * 104) + (int)j); nameBuilder.Append((char)ch); } fieldNames.Add(nameBuilder.ToString()); byte byteValue = ReadWriteHelper.ReadUint8(span, 44 + (int)(i * 104)); isDefined.Add((byteValue & (0x01 << 0)) != 0); } return new FieldSets { VersionCVersion = ReadVersionIndicator(span), VersionMajorVersionNumber = ReadMajorNumber(span), VersionMinorVersionNumber = ReadMinorNumber(span), VersionReleaseNumber = ReadReleaseNumber(span), NameLengths = nameLengths, FieldNames = fieldNames, IsDefined = isDefined }; } /// /// Matches: ParseFieldSetsData::readVersionIndicator in C++ /// private string ReadVersionIndicator(ReadOnlySpan span) { byte ch = ReadWriteHelper.ReadUint8(span, 0); return ((char)ch).ToString(); } /// /// Matches: ParseFieldSetsData::readMajorNumber in C++ /// private byte ReadMajorNumber(ReadOnlySpan span) { return ReadWriteHelper.ReadUint8(span, 1); } /// /// Matches: ParseFieldSetsData::readMinorNumber in C++ /// private byte ReadMinorNumber(ReadOnlySpan span) { return ReadWriteHelper.ReadUint8(span, 2); } /// /// Matches: ParseFieldSetsData::readReleaseNumber in C++ /// private byte ReadReleaseNumber(ReadOnlySpan span) { return ReadWriteHelper.ReadUint8(span, 3); } private uint ReadArrayLength(ReadOnlySpan span) { return ReadWriteHelper.ReadUint32LittleEndian(span, 4); } }