Phase 8A (1/2): de-Span the serial layer, swap JSON to Newtonsoft
Prepares RioJoy.Core for the net40 (Windows XP) target, which has no System.Memory, ValueTask, or System.Text.Json: - IRioTransport and the whole protocol/framing layer now use byte[] + Task (RioPacket.Payload, PacketParser/Builder, RioChecksum, replies, AnalogReport, RioHidReport). At 9600 baud Span bought nothing; the SerialPortTransport bridge copies disappear entirely. - ConfigStore/OverlayTemplateStore switch to Newtonsoft 13 with the same conventions (indented, PascalCase, string enums, null-skipping); verified against the real STJ-written config.json and regions.json (load + round-trip). System.Memory and System.Text.Json packages dropped. 275 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,8 +15,13 @@ public interface IRioTransport : IDisposable
|
||||
/// Read available bytes into <paramref name="buffer"/>. Returns the number of
|
||||
/// bytes read; a return of 0 indicates the transport has closed.
|
||||
/// </summary>
|
||||
ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken);
|
||||
/// <remarks>
|
||||
/// Plain <c>byte[]</c>/<see cref="Task"/> rather than Memory/ValueTask: the
|
||||
/// link runs at 9600 baud, and the net40 (Windows XP) flavor has neither
|
||||
/// System.Memory nor ValueTask (see docs/PLAN.md §Phase 8).
|
||||
/// </remarks>
|
||||
Task<int> ReadAsync(byte[] buffer, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Write all of <paramref name="data"/> to the transport.</summary>
|
||||
ValueTask WriteAsync(ReadOnlyMemory<byte> data, CancellationToken cancellationToken);
|
||||
Task WriteAsync(byte[] data, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public sealed class RioSerialLink
|
||||
}
|
||||
|
||||
/// <summary>Send a pre-built packet (see <see cref="PacketBuilder"/>) to the RIO.</summary>
|
||||
public async Task SendAsync(ReadOnlyMemory<byte> packet, CancellationToken cancellationToken = default)
|
||||
public async Task SendAsync(byte[] packet, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -155,7 +155,7 @@ public sealed class RioSerialLink
|
||||
switch (packet.Command)
|
||||
{
|
||||
case RioCommand.AnalogReply:
|
||||
if (AnalogReport.TryParse(packet.Payload.Span, out AnalogReport report))
|
||||
if (AnalogReport.TryParse(packet.Payload, out AnalogReport report))
|
||||
{
|
||||
_sinceAnalog.Restart();
|
||||
AnalogReceived?.Invoke(report);
|
||||
@@ -163,11 +163,11 @@ public sealed class RioSerialLink
|
||||
break;
|
||||
|
||||
case RioCommand.VersionReply:
|
||||
VersionReceived?.Invoke(VersionInfo.Parse(packet.Payload.Span));
|
||||
VersionReceived?.Invoke(VersionInfo.Parse(packet.Payload));
|
||||
break;
|
||||
|
||||
case RioCommand.CheckReply:
|
||||
CheckReceived?.Invoke(CheckStatus.Parse(packet.Payload.Span));
|
||||
CheckReceived?.Invoke(CheckStatus.Parse(packet.Payload));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,21 +47,11 @@ public sealed class SerialPortTransport : IRioTransport
|
||||
|
||||
public string Description => $"{_port.PortName} @ {BaudRate} 8N1";
|
||||
|
||||
// net48's Stream has no Memory-based ReadAsync/WriteAsync overloads, so bridge
|
||||
// through a pooled array and copy into/out of the caller's Memory<byte>.
|
||||
public async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
byte[] tmp = new byte[buffer.Length];
|
||||
int read = await _stream.ReadAsync(tmp, 0, tmp.Length, cancellationToken).ConfigureAwait(false);
|
||||
new ReadOnlySpan<byte>(tmp, 0, read).CopyTo(buffer.Span);
|
||||
return read;
|
||||
}
|
||||
public Task<int> ReadAsync(byte[] buffer, CancellationToken cancellationToken) =>
|
||||
_stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
|
||||
|
||||
public async ValueTask WriteAsync(ReadOnlyMemory<byte> data, CancellationToken cancellationToken)
|
||||
{
|
||||
byte[] tmp = data.ToArray();
|
||||
await _stream.WriteAsync(tmp, 0, tmp.Length, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
public Task WriteAsync(byte[] data, CancellationToken cancellationToken) =>
|
||||
_stream.WriteAsync(data, 0, data.Length, cancellationToken);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user