177 lines
5.4 KiB
C#
177 lines
5.4 KiB
C#
using Sick.SafetyScanners.DataStructures;
|
|
using Sick.SafetyScanners.Helpers;
|
|
using System.Text;
|
|
|
|
namespace Sick.SafetyScanners.DataProcessing;
|
|
|
|
/// <summary>
|
|
/// Parser for FieldHeaderData response from COLA2 variable command
|
|
/// Thread-safe implementation
|
|
/// </summary>
|
|
public sealed class ParseFieldHeaderData
|
|
{
|
|
/// <summary>
|
|
/// Parses the field header data from a TCP sequence (COLA2 response)
|
|
/// Matches: ParseFieldHeaderData::parseTCPSequence in C++
|
|
/// </summary>
|
|
public FieldData ParseTcpSequence(PacketBuffer buffer)
|
|
{
|
|
var span = buffer.GetBufferSpan();
|
|
bool valid = IsValid(span);
|
|
|
|
if (!valid)
|
|
{
|
|
return new FieldData
|
|
{
|
|
IsValid = false
|
|
};
|
|
}
|
|
|
|
SetFieldType(span, out bool isWarningField, out bool isProtectiveField);
|
|
ushort setIndex = ReadSetIndex(span);
|
|
uint nameLength = ReadNameLength(span);
|
|
|
|
return new FieldData
|
|
{
|
|
IsValid = true,
|
|
VersionCVersion = ReadVersionIndicator(span),
|
|
VersionMajorVersionNumber = ReadMajorNumber(span),
|
|
VersionMinorVersionNumber = ReadMinorNumber(span),
|
|
VersionReleaseNumber = ReadReleaseNumber(span),
|
|
IsDefined = ReadIsDefined(span),
|
|
EvalMethod = ReadEvalMethod(span),
|
|
MultiSampling = ReadMultiSampling(span),
|
|
ObjectResolution = ReadObjectResolution(span),
|
|
FieldSetIndex = setIndex,
|
|
NameLength = nameLength,
|
|
FieldName = ReadFieldName(span, nameLength),
|
|
IsWarningField = isWarningField,
|
|
IsProtectiveField = isProtectiveField
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::isValid in C++
|
|
/// </summary>
|
|
private bool IsValid(ReadOnlySpan<byte> span)
|
|
{
|
|
byte byteValue = ReadWriteHelper.ReadUint8(span, 0);
|
|
return byteValue == 'R' || byteValue == 'Y';
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::setFieldType in C++
|
|
/// </summary>
|
|
private void SetFieldType(ReadOnlySpan<byte> span, out bool isWarningField, out bool isProtectiveField)
|
|
{
|
|
byte fieldType = ReadEvalMethod(span);
|
|
isWarningField = false;
|
|
isProtectiveField = false;
|
|
if (fieldType == 4 || fieldType == 14)
|
|
{
|
|
isProtectiveField = true;
|
|
}
|
|
else if (fieldType == 5 || fieldType == 15)
|
|
{
|
|
isWarningField = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readVersionIndicator in C++
|
|
/// </summary>
|
|
private string ReadVersionIndicator(ReadOnlySpan<byte> span)
|
|
{
|
|
byte ch = ReadWriteHelper.ReadUint8(span, 0);
|
|
return ((char)ch).ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readMajorNumber in C++
|
|
/// </summary>
|
|
private byte ReadMajorNumber(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint8(span, 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readMinorNumber in C++
|
|
/// </summary>
|
|
private byte ReadMinorNumber(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint8(span, 2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readReleaseNumber in C++
|
|
/// </summary>
|
|
private byte ReadReleaseNumber(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint8(span, 3);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readIsDefined in C++
|
|
/// </summary>
|
|
private bool ReadIsDefined(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint8(span, 72) != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readEvalMethod in C++
|
|
/// </summary>
|
|
private byte ReadEvalMethod(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint8(span, 73);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readMultiSampling in C++
|
|
/// </summary>
|
|
private ushort ReadMultiSampling(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint16LittleEndian(span, 74);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readObjectResolution in C++
|
|
/// </summary>
|
|
private ushort ReadObjectResolution(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint16LittleEndian(span, 78);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readSetIndex in C++
|
|
/// </summary>
|
|
private ushort ReadSetIndex(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint16LittleEndian(span, 82);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readNameLength in C++
|
|
/// </summary>
|
|
private uint ReadNameLength(ReadOnlySpan<byte> span)
|
|
{
|
|
return ReadWriteHelper.ReadUint32LittleEndian(span, 84);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Matches: ParseFieldHeaderData::readFieldName in C++
|
|
/// </summary>
|
|
private string ReadFieldName(ReadOnlySpan<byte> span, uint nameLength)
|
|
{
|
|
var nameBuilder = new StringBuilder((int)nameLength);
|
|
for (uint i = 0; i < nameLength; i++)
|
|
{
|
|
byte ch = ReadWriteHelper.ReadUint8(span, 88 + (int)i);
|
|
nameBuilder.Append((char)ch);
|
|
}
|
|
|
|
return nameBuilder.ToString();
|
|
}
|
|
}
|
|
|