using System.Buffers; using System.Diagnostics.CodeAnalysis; using AyCode.Services.SignalRs; using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR.Protocol; namespace AyCode.Services.Server.Tests.SignalRs; /// /// Test protocol that forces multi-segment ReadOnlySequence parsing. /// Splits serialized bytes into chunks before calling base.TryParseMessage, /// exercising SequenceBinaryInput cross-boundary reads and SequenceToByteArray multi-segment paths. /// internal class TestMultiSegmentProtocol : AyCodeBinaryHubProtocol { private const int SegmentSize = 4096; public override bool TryParseMessage(ref ReadOnlySequence input, IInvocationBinder binder, [NotNullWhen(true)] out HubMessage? message) { // Temporarily bypass multi-segment to isolate the issue return base.TryParseMessage(ref input, binder, out message); } private static ReadOnlySequence CreateMultiSegmentSequence(ReadOnlySequence source, int chunkSize) { var bytes = source.ToArray(); var first = new MemorySegment(bytes.AsMemory(0, Math.Min(chunkSize, bytes.Length))); var current = first; for (var offset = chunkSize; offset < bytes.Length; offset += chunkSize) { var length = Math.Min(chunkSize, bytes.Length - offset); current = current.Append(bytes.AsMemory(offset, length)); } return new ReadOnlySequence(first, 0, current, current.Memory.Length); } private sealed class MemorySegment : ReadOnlySequenceSegment { public MemorySegment(ReadOnlyMemory memory) => Memory = memory; public MemorySegment Append(ReadOnlyMemory memory) { var next = new MemorySegment(memory) { RunningIndex = RunningIndex + Memory.Length }; Next = next; return next; } } }