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:
Cyd
2026-07-11 20:36:19 -05:00
co-authored by Claude Fable 5
parent 02abfa8a14
commit 3b2af7b79a
21 changed files with 104 additions and 93 deletions
+10 -7
View File
@@ -92,15 +92,17 @@ public sealed class PacketParser
}
/// <summary>
/// Feed a chunk of received bytes, invoking <paramref name="onEvent"/> for
/// each event produced, in order.
/// Feed the first <paramref name="count"/> received bytes of
/// <paramref name="data"/>, invoking <paramref name="onEvent"/> for each
/// event produced, in order.
/// </summary>
public void Feed(ReadOnlySpan<byte> data, Action<RioRxEvent> onEvent)
public void Feed(byte[] data, int count, Action<RioRxEvent> onEvent)
{
if (data is null) throw new ArgumentNullException(nameof(data));
if (onEvent is null) throw new ArgumentNullException(nameof(onEvent));
foreach (byte ch in data)
for (int i = 0; i < count; i++)
{
if (Feed(ch, out RioRxEvent ev))
if (Feed(data[i], out RioRxEvent ev))
onEvent(ev);
}
}
@@ -110,11 +112,12 @@ public sealed class PacketParser
// _buffer = [command][payload…][checksum]; _count includes all of them.
int bodyLen = _count - 1; // command + payload (exclude checksum)
byte receivedChecksum = _buffer[bodyLen];
byte computed = RioChecksum.Compute(_buffer.AsSpan(0, bodyLen));
byte computed = RioChecksum.Compute(_buffer, 0, bodyLen);
bool checksumValid = computed == receivedChecksum;
var command = (RioCommand)_buffer[0];
var payload = _buffer.AsSpan(1, bodyLen - 1).ToArray(); // copy out; buffer is reused
var payload = new byte[bodyLen - 1]; // copy out; buffer is reused
Array.Copy(_buffer, 1, payload, 0, payload.Length);
var packet = new RioPacket(command, payload);
Reset();