I am communicating with a machine that sends/received structured binary data to my netcore service. The machine supplier's new library uses Memory in their library's API.
I have written the following code for Ser/Des which works, but seems verbose. I know I can wrap some of this in methods/helpers, but it feels cumbersome compared to the "old" Streams & BinaryWriter/BinaryReader approach.
Is there a better way to approach this? A better part of the framework or technique I should be using?
Deserialising from Memory:
public void Read(Memory<byte> data)
{
if (data.Length < StaticSize) // StaticSize = 56. Defined by machine's struct.
throw new ArgumentOutOfRangeException($"Span length too small. Minimum: {StaticSize}, Received: {data.Length}.");
var s = data.Span;
MemoryMarshal.TryRead<bool>(s.Slice(0, 1), out _forward);
MemoryMarshal.TryRead<bool>(s.Slice(1, 2), out _reverse);
SomeString = Encoding.UTF8.GetString(s.Slice(2, 22)).Replace("\0", string.Empty);
Dynamics = new TcDynamics(data.Slice(24)); // "TcDynamics" object de-serialized in same manner as this.
}
Serialising to Memory:
public void Write(Memory<byte> data)
{
if (data.Length < StaticSize) // StaticSize = 56. Defined by machine's struct.
throw new ArgumentOutOfRangeException($"Span length too small. Minimum: {StaticSize}, Received: {data.Length}.");
var s = data.Span;
MemoryMarshal.TryWrite<bool>(s.Slice(0, 1), ref _forward);
MemoryMarshal.TryWrite<bool>(s.Slice(1, 2), ref _reverse);
Encoding.UTF8.GetBytes(_someString).CopyTo(s.Slice(2,22)); // Strings are fixed length (21 + termination).
Dynamics.Write(data.Slice(24)); // "TcDynamics" object serialized in same manner as this.
}
SequenceReader
andPipeWriter
1, 2 \$\endgroup\$ – Peter Csala Jul 2 '20 at 9:47myDouble= reader.ReadDouble();
orwriter.Write(myDouble);
writer.Write(myString, lengthInBytes);
I know I can create that myself using Facade pattern to hide away most of the above, but thought there would be a better way somewhere else. I will have a look at your suggestions, thank you. \$\endgroup\$ – Mark Lazz Jul 2 '20 at 14:27Memory
,Span
andReadOnlySpan
were designed to work mainly withbyte
andchar
types. \$\endgroup\$ – Peter Csala Jul 3 '20 at 8:05data
is the same, couldn't you then load aMemoryStream
with the data, and then use a `BinaryReader-/Writer as you did before? \$\endgroup\$ – user73941 Jul 5 '20 at 10:59