using Sick.SafetyScanners.DataStructures;
using Sick.SafetyScanners.Helpers;
using System.Text;
namespace Sick.SafetyScanners.DataProcessing;
///
/// Parser for UserName response from COLA2 variable command
/// Thread-safe implementation
///
public sealed class ParseUserName
{
///
/// Parses the user name from a TCP sequence (COLA2 response)
/// Matches: ParseUserNameData::parseTCPSequence in C++
///
public UserName ParseTcpSequence(PacketBuffer buffer)
{
var span = buffer.GetBufferSpan();
return new UserName
{
VersionCVersion = ReadVersionIndicator(span),
VersionMajorVersionNumber = ReadMajorNumber(span),
VersionMinorVersionNumber = ReadMinorNumber(span),
VersionReleaseNumber = ReadReleaseNumber(span),
NameLength = ReadNameLength(span),
Name = ReadUserName(span)
};
}
///
/// Matches: ParseUserNameData::readVersionIndicator in C++
///
private string ReadVersionIndicator(ReadOnlySpan span)
{
byte ch = ReadWriteHelper.ReadUint8(span, 0);
return ((char)ch).ToString();
}
///
/// Matches: ParseUserNameData::readMajorNumber in C++
///
private byte ReadMajorNumber(ReadOnlySpan span)
{
return ReadWriteHelper.ReadUint8(span, 1);
}
///
/// Matches: ParseUserNameData::readMinorNumber in C++
///
private byte ReadMinorNumber(ReadOnlySpan span)
{
return ReadWriteHelper.ReadUint8(span, 2);
}
///
/// Matches: ParseUserNameData::readReleaseNumber in C++
///
private byte ReadReleaseNumber(ReadOnlySpan span)
{
return ReadWriteHelper.ReadUint8(span, 3);
}
///
/// Matches: ParseUserNameData::readNameLength in C++
///
private uint ReadNameLength(ReadOnlySpan span)
{
return ReadWriteHelper.ReadUint32LittleEndian(span, 4);
}
///
/// Matches: ParseUserNameData::readUserName in C++
///
private string ReadUserName(ReadOnlySpan span)
{
uint nameLength = ReadWriteHelper.ReadUint32LittleEndian(span, 4);
var nameBuilder = new StringBuilder((int)nameLength);
for (uint i = 0; i < nameLength; i++)
{
byte ch = ReadWriteHelper.ReadUint8(span, 8 + (int)i);
nameBuilder.Append((char)ch);
}
return nameBuilder.ToString();
}
}