Skip to content

Commit 5a6cffa

Browse files
committed
nullable IBinarySerializer support
1 parent 7e7aafd commit 5a6cffa

File tree

5 files changed

+60
-3
lines changed

5 files changed

+60
-3
lines changed

samples/SpaceWar.Shared/Logic/Ship.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void Serialize(ref readonly BinaryBufferWriter writer)
3333
writer.Write(in Invincible);
3434
writer.Write(in Score);
3535
writer.Write(in Thrust);
36-
writer.Write(in Missile);
36+
writer.Write(Missile);
3737

3838
// Caution: WriteStruct not normalize endianness
3939
writer.WriteStruct(in Bullets);

src/Backdash/Serialization/BinaryBufferReader.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,33 @@ public void ReadNumber<T>(ref T? value, bool isUnsigned) where T : unmanaged, IB
337337
public T? ReadNullableNumber<T>(bool isUnsigned) where T : unmanaged, IBinaryInteger<T> =>
338338
ReadBoolean() ? ReadNumber<T>(isUnsigned) : null;
339339

340+
/// <summary>Reads a <see cref="IBinarySerializable"/> <typeparamref name="T"/> from buffer.</summary>
341+
/// <typeparam name="T">A value type that implements <see cref="IBinarySerializable"/>.</typeparam>
342+
public T? ReadNullable<T>() where T : struct, IBinarySerializable
343+
{
344+
T? value = new();
345+
Read(ref value);
346+
return value;
347+
}
340348

341349
/// <summary>Reads a <see cref="IBinarySerializable"/> <paramref name="value"/> from buffer.</summary>
342350
/// <typeparam name="T">A value type that implements <see cref="IBinarySerializable"/>.</typeparam>
343351
public void Read<T>(ref T value) where T : struct, IBinarySerializable => value.Deserialize(in this);
344352

353+
/// <summary>Reads a <see cref="IBinarySerializable"/> <typeparamref name="T"/> from buffer.</summary>
354+
/// <typeparam name="T">A value type that implements <see cref="IBinarySerializable"/>.</typeparam>
355+
public T Read<T>() where T : struct, IBinarySerializable
356+
{
357+
T value = new();
358+
value.Deserialize(in this);
359+
return value;
360+
}
361+
362+
/// <summary>Reads a <see cref="IBinarySerializable"/> <paramref name="value"/> from buffer.</summary>
363+
/// <typeparam name="T">A value type that implements <see cref="IBinarySerializable"/>.</typeparam>
364+
public void Read<T>(ref T? value) where T : struct, IBinarySerializable =>
365+
value = ReadBoolean() ? Read<T>() : null;
366+
345367
/// <summary>Reads a span of <see cref="IBinarySerializable"/> <paramref name="values"/> into buffer.</summary>
346368
/// <typeparam name="T">A list of a value type that implements <see cref="IBinarySerializable"/>.</typeparam>
347369
public void Read<T>(in Span<T> values) where T : unmanaged, IBinarySerializable

src/Backdash/Serialization/BinaryBufferWriter.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,24 @@ public void Write(in ReadOnlySpan<DateTimeOffset> values)
481481
/// <summary>Writes a list of bytes of <see cref="DateOnly"/> <paramref name="values"/> into buffer.</summary>
482482
public void Write(in List<DateOnly> values) => Write(GetListSpan(in values));
483483

484+
/// <summary>Writes a <see cref="IBinarySerializable"/> <paramref name="value"/> into buffer.</summary>
485+
/// <typeparam name="T">A type that implements <see cref="IBinarySerializable"/>.</typeparam>
486+
// ReSharper disable once PossiblyImpureMethodCallOnReadonlyVariable
487+
public void Write<T>(ref readonly T value) where T : struct, IBinarySerializable => value.Serialize(in this);
488+
489+
/// <summary>Writes a <see cref="IBinarySerializable"/> <paramref name="value"/> into buffer.</summary>
490+
/// <typeparam name="T">A type that implements <see cref="IBinarySerializable"/>.</typeparam>
491+
public void Write<T>(ref readonly T? value) where T : struct, IBinarySerializable
492+
{
493+
Write(value.HasValue);
494+
// ReSharper disable once PossiblyImpureMethodCallOnReadonlyVariable
495+
if (value.HasValue)
496+
Nullable.GetValueRefOrDefaultRef(in value).Serialize(in this);
497+
}
484498

485499
/// <summary>Writes a <see cref="IBinarySerializable"/> <paramref name="value"/> into buffer.</summary>
486500
/// <typeparam name="T">A type that implements <see cref="IBinarySerializable"/>.</typeparam>
487-
public void Write<T>(in T value) where T : IBinarySerializable => value.Serialize(in this);
501+
public void Write<T>(T value) where T : class, IBinarySerializable => value.Serialize(in this);
488502

489503
/// <summary>Writes span of <see cref="IBinarySerializable"/> <paramref name="values"/> into buffer.</summary>
490504
/// <typeparam name="T">A type that implements <see cref="IBinarySerializable"/>.</typeparam>

tests/Backdash.Tests/Specs/Unit/Serialization/BinaryBufferReadWriteNullableValues.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,27 @@ public bool UnmanagedStruct(SimpleStructData? value, Endianness endianness)
306306
return value == read;
307307
}
308308

309+
[PropertyTest]
310+
public bool SerializableValueType(SimpleStructData? value, SimpleStructData? result, Endianness endianness)
311+
{
312+
var size = Setup(value, endianness, out var writer);
313+
314+
writer.Write(in value);
315+
writer.WrittenCount.Should().Be(size);
316+
317+
var reader = GetReader(writer);
318+
reader.Read(ref result);
319+
reader.ReadCount.Should().Be(size);
320+
321+
ResetRead();
322+
var otherRead = reader.ReadNullable<SimpleStructData>();
323+
reader.ReadCount.Should().Be(size);
324+
otherRead.Should().Be(result);
325+
326+
return value == result;
327+
}
328+
329+
309330
[Collection(SerialCollectionDefinition.Name)]
310331
public class BinaryIntegerTests
311332
{

tests/Backdash.Tests/Specs/Unit/Serialization/BinaryBufferReadWriteValueTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ public bool SerializableObject(SimpleRefData value, SimpleRefData result, Endian
380380
{
381381
var size = Setup<SimpleStructData>(endianness, out var writer);
382382

383-
writer.Write(in value);
383+
writer.Write(value);
384384
writer.WrittenCount.Should().Be(size);
385385

386386
var reader = GetReader(writer);

0 commit comments

Comments
 (0)