Files
YMhut-box-C-/src/YMhut.Box.Core/Tools/SerialTerminalModels.cs
T

101 lines
2.6 KiB
C#

using System.Globalization;
using System.Text;
namespace YMhut.Box.Core.Tools;
public enum SerialParityMode
{
None,
Odd,
Even,
Mark,
Space
}
public enum SerialStopBitsMode
{
One,
OnePointFive,
Two
}
public sealed record SerialConnectionOptions(
string PortName,
int BaudRate,
int DataBits = 8,
SerialParityMode Parity = SerialParityMode.None,
SerialStopBitsMode StopBits = SerialStopBitsMode.One);
public sealed class SerialDataReceivedEventArgs(ReadOnlyMemory<byte> data) : EventArgs
{
public ReadOnlyMemory<byte> Data { get; } = data;
}
public interface ISerialPortTransport : IDisposable
{
bool IsOpen { get; }
event EventHandler<SerialDataReceivedEventArgs>? DataReceived;
IReadOnlyList<string> GetPortNames();
Task OpenAsync(SerialConnectionOptions options, CancellationToken cancellationToken = default);
Task WriteAsync(ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default);
Task CloseAsync(CancellationToken cancellationToken = default);
}
public static class SerialPayloadCodec
{
public static byte[] Parse(string value, bool hexadecimal)
{
if (!hexadecimal)
{
return Encoding.UTF8.GetBytes(value ?? string.Empty);
}
var input = value ?? string.Empty;
foreach (var character in input)
{
if (!char.IsAsciiHexDigit(character) &&
!char.IsWhiteSpace(character) &&
character is not (',' or ';' or ':' or '-'))
{
throw new FormatException("Hexadecimal input contains an invalid character.");
}
}
var compact = new string(input.Where(char.IsAsciiHexDigit).ToArray());
if (compact.Length == 0)
{
return [];
}
if (compact.Length % 2 != 0)
{
throw new FormatException("Hexadecimal input must contain complete byte pairs.");
}
var bytes = new byte[compact.Length / 2];
for (var index = 0; index < bytes.Length; index++)
{
if (!byte.TryParse(compact.AsSpan(index * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out bytes[index]))
{
throw new FormatException("Hexadecimal input contains an invalid byte.");
}
}
return bytes;
}
public static string Format(ReadOnlySpan<byte> data, bool hexadecimal)
{
if (!hexadecimal)
{
return Encoding.UTF8.GetString(data);
}
var encoded = Convert.ToHexString(data);
return string.Join(' ', encoded.Chunk(2).Select(chars => new string(chars)));
}
}