@@ -82,6 +82,9 @@ public void ReadByte(in Span<byte> values)
8282 /// <summary>Reads a list of <see cref="byte"/> from buffer into <paramref name="values"/>.</summary>
8383 public void ReadByte ( in List < byte > values ) => ReadByte ( GetListSpan ( in values ) ) ;
8484
85+ /// <inheritdoc cref="ReadByte()"/>
86+ public byte ? ReadNullableByte ( ) => ReadBoolean ( ) ? ReadByte ( ) : null ;
87+
8588 /// <summary>Reads single <see cref="sbyte"/> from buffer.</summary>
8689 public sbyte ReadSByte ( ) => unchecked ( ( sbyte ) buffer [ offset ++ ] ) ;
8790
@@ -91,6 +94,9 @@ public void ReadByte(in Span<byte> values)
9194 /// <summary>Reads a list of <see cref="sbyte"/> from buffer into <paramref name="values"/>.</summary>
9295 public void ReadSByte ( in List < sbyte > values ) => ReadSByte ( GetListSpan ( in values ) ) ;
9396
97+ /// <inheritdoc cref="ReadSByte()"/>
98+ public sbyte ? ReadNullableSByte ( ) => ReadBoolean ( ) ? ReadSByte ( ) : null ;
99+
94100 /// <summary>Reads single <see cref="bool"/> from buffer.</summary>
95101 public bool ReadBoolean ( )
96102 {
@@ -105,6 +111,10 @@ public bool ReadBoolean()
105111 /// <summary>Reads a list of <see cref="bool"/> from buffer into <paramref name="values"/>.</summary>
106112 public void ReadBoolean ( in List < bool > values ) => ReadBoolean ( GetListSpan ( in values ) ) ;
107113
114+
115+ /// <inheritdoc cref="ReadBoolean()"/>
116+ public bool ? ReadNullableBoolean ( ) => ReadBoolean ( ) ? ReadBoolean ( ) : null ;
117+
108118 /// <summary>Reads single <see cref="short"/> from buffer.</summary>
109119 public short ReadInt16 ( ) => ReadNumber < short > ( false ) ;
110120
@@ -119,6 +129,9 @@ public void ReadInt16(in Span<short> values)
119129 /// <summary>Reads a list of <see cref="short"/> from buffer into <paramref name="values"/>.</summary>
120130 public void ReadInt16 ( in List < short > values ) => ReadInt16 ( GetListSpan ( in values ) ) ;
121131
132+ /// <inheritdoc cref="ReadInt16()"/>
133+ public short ? ReadNullableInt16 ( ) => ReadBoolean ( ) ? ReadInt16 ( ) : null ;
134+
122135 /// <summary>Reads single <see cref="ushort"/> from buffer.</summary>
123136 public ushort ReadUInt16 ( ) => ReadNumber < ushort > ( true ) ;
124137
@@ -133,6 +146,9 @@ public void ReadUInt16(in Span<ushort> values)
133146 /// <summary>Reads a list of <see cref="ushort"/> from buffer into <paramref name="values"/>.</summary>
134147 public void ReadUInt16 ( in List < ushort > values ) => ReadUInt16 ( GetListSpan ( in values ) ) ;
135148
149+ /// <inheritdoc cref="ReadUInt16()"/>
150+ public ushort ? ReadNullableUInt16 ( ) => ReadBoolean ( ) ? ReadUInt16 ( ) : null ;
151+
136152 /// <summary>Reads single <see cref="char"/> from buffer.</summary>
137153 public char ReadChar ( ) => ( char ) ReadUInt16 ( ) ;
138154
@@ -150,6 +166,9 @@ public void ReadChar(in Span<char> values)
150166 /// <summary>Reads a list of <see cref="char"/> from buffer into <paramref name="values"/>.</summary>
151167 public void ReadChar ( in List < char > values ) => ReadChar ( GetListSpan ( in values ) ) ;
152168
169+ /// <inheritdoc cref="ReadChar()"/>
170+ public char ? ReadNullableChar ( ) => ReadBoolean ( ) ? ReadChar ( ) : null ;
171+
153172 /// <summary>Reads single <see cref="char"/> from buffer.</summary>
154173 public char ReadUtf8Char ( )
155174 {
@@ -158,6 +177,9 @@ public char ReadUtf8Char()
158177 return result [ 0 ] ;
159178 }
160179
180+ /// <inheritdoc cref="ReadUtf8Char()"/>
181+ public char ? ReadNullableUtf8Char ( ) => ReadBoolean ( ) ? ReadUtf8Char ( ) : null ;
182+
161183 /// <summary>Reads a span of UTF8 <see cref="char"/> from buffer into <paramref name="values"/>.</summary>
162184 public void ReadUtf8String ( in Span < char > values )
163185 {
@@ -183,6 +205,9 @@ public void ReadInt32(in Span<int> values)
183205 /// <summary>Reads a list of <see cref="int"/> from buffer into <paramref name="values"/>.</summary>
184206 public void ReadInt32 ( in List < int > values ) => ReadInt32 ( GetListSpan ( in values ) ) ;
185207
208+ /// <inheritdoc cref="ReadInt32()"/>
209+ public int ? ReadNullableInt32 ( ) => ReadBoolean ( ) ? ReadInt32 ( ) : null ;
210+
186211 /// <summary>Reads single <see cref="uint"/> from buffer.</summary>
187212 public uint ReadUInt32 ( ) => ReadNumber < uint > ( true ) ;
188213
@@ -197,6 +222,9 @@ public void ReadUInt32(in Span<uint> values)
197222 /// <summary>Reads a list of <see cref="uint"/> from buffer into <paramref name="values"/>.</summary>
198223 public void ReadUInt32 ( in List < uint > values ) => ReadUInt32 ( GetListSpan ( in values ) ) ;
199224
225+ /// <inheritdoc cref="ReadUInt32()"/>
226+ public uint ? ReadNullableUInt32 ( ) => ReadBoolean ( ) ? ReadUInt32 ( ) : null ;
227+
200228 /// <summary>Reads single <see cref="long"/> from buffer.</summary>
201229 public long ReadInt64 ( ) => ReadNumber < long > ( false ) ;
202230
@@ -211,6 +239,9 @@ public void ReadInt64(in Span<long> values)
211239 /// <summary>Reads a list of <see cref="long"/> from buffer into <paramref name="values"/>.</summary>
212240 public void ReadInt64 ( in List < long > values ) => ReadInt64 ( GetListSpan ( in values ) ) ;
213241
242+ /// <inheritdoc cref="ReadInt64()"/>
243+ public long ? ReadNullableInt64 ( ) => ReadBoolean ( ) ? ReadInt64 ( ) : null ;
244+
214245 /// <summary>Reads single <see cref="ulong"/> from buffer.</summary>
215246 public ulong ReadUInt64 ( ) => ReadNumber < ulong > ( true ) ;
216247
@@ -225,6 +256,9 @@ public void ReadUInt64(in Span<ulong> values)
225256 /// <summary>Reads a list of <see cref="ulong"/> from buffer into <paramref name="values"/>.</summary>
226257 public void ReadUInt64 ( in List < ulong > values ) => ReadUInt64 ( GetListSpan ( in values ) ) ;
227258
259+ /// <inheritdoc cref="ReadUInt64()"/>
260+ public ulong ? ReadNullableUInt64 ( ) => ReadBoolean ( ) ? ReadUInt64 ( ) : null ;
261+
228262 /// <summary>Reads single <see cref="Int128"/> from buffer.</summary>
229263 public Int128 ReadInt128 ( ) => ReadNumber < Int128 > ( false ) ;
230264
@@ -239,6 +273,9 @@ public void ReadInt128(in Span<Int128> values)
239273 /// <summary>Reads a list of <see cref="Int128"/> from buffer into <paramref name="values"/>.</summary>
240274 public void ReadInt128 ( in List < Int128 > values ) => ReadInt128 ( GetListSpan ( in values ) ) ;
241275
276+ /// <inheritdoc cref="ReadInt128()"/>
277+ public Int128 ? ReadNullableInt128 ( ) => ReadBoolean ( ) ? ReadInt128 ( ) : null ;
278+
242279 /// <summary>Reads single <see cref="UInt128"/> from buffer.</summary>
243280 public UInt128 ReadUInt128 ( ) => ReadNumber < UInt128 > ( true ) ;
244281
@@ -253,6 +290,8 @@ public void ReadUInt128(in Span<UInt128> values)
253290 /// <summary>Reads a list of <see cref="UInt128"/> from buffer into <paramref name="values"/>.</summary>
254291 public void ReadUInt128 ( in List < UInt128 > values ) => ReadUInt128 ( GetListSpan ( in values ) ) ;
255292
293+ /// <inheritdoc cref="ReadUInt128()"/>
294+ public UInt128 ? ReadNullableUInt128 ( ) => ReadBoolean ( ) ? ReadUInt128 ( ) : null ;
256295
257296 /// <summary>Reads single <see cref="Half"/> from buffer.</summary>
258297 public Half ReadHalf ( ) => BitConverter . Int16BitsToHalf ( ReadInt16 ( ) ) ;
@@ -263,12 +302,19 @@ public void ReadUInt128(in Span<UInt128> values)
263302 /// <summary>Reads a list of <see cref="Half"/> from buffer into <paramref name="values"/>.</summary>
264303 public void ReadHalf ( in List < Half > values ) => ReadHalf ( GetListSpan ( in values ) ) ;
265304
305+ /// <inheritdoc cref="ReadHalf()"/>
306+ public Half ? ReadNullableHalf ( ) => ReadBoolean ( ) ? ReadHalf ( ) : null ;
266307
267308 /// <inheritdoc cref="ReadFloat()"/>
268309 /// <seealso cref="ReadFloat()"/>
269310 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
270311 public float ReadSingle ( ) => ReadFloat ( ) ;
271312
313+ /// <inheritdoc cref="ReadNullableFloat()"/>
314+ /// <seealso cref="ReadNullableFloat()"/>
315+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
316+ public float ? ReadNullableSingle ( ) => ReadNullableFloat ( ) ;
317+
272318 /// <summary>Reads float 32 <see cref="float"/> from buffer.</summary>
273319 public float ReadFloat ( ) => BitConverter . Int32BitsToSingle ( ReadInt32 ( ) ) ;
274320
@@ -278,6 +324,8 @@ public void ReadUInt128(in Span<UInt128> values)
278324 /// <summary>Reads a list of <see cref="float"/> from buffer into <paramref name="values"/>.</summary>
279325 public void ReadFloat ( in List < float > values ) => ReadFloat ( GetListSpan ( in values ) ) ;
280326
327+ /// <inheritdoc cref="ReadFloat()"/>
328+ public float ? ReadNullableFloat ( ) => ReadBoolean ( ) ? ReadFloat ( ) : null ;
281329
282330 /// <summary>Reads single <see cref="double"/> from buffer.</summary>
283331 public double ReadDouble ( ) => BitConverter . Int64BitsToDouble ( ReadInt64 ( ) ) ;
@@ -288,6 +336,9 @@ public void ReadUInt128(in Span<UInt128> values)
288336 /// <summary>Reads a list of <see cref="double"/> from buffer into <paramref name="values"/>.</summary>
289337 public void ReadDouble ( in List < double > values ) => ReadDouble ( GetListSpan ( in values ) ) ;
290338
339+ /// <inheritdoc cref="ReadDouble()"/>
340+ public double ? ReadNullableDouble ( ) => ReadBoolean ( ) ? ReadDouble ( ) : null ;
341+
291342 /// <summary>Reads single <see cref="Guid"/> from buffer.</summary>
292343 public Guid ReadGuid ( )
293344 {
@@ -314,6 +365,8 @@ public void ReadGuid(in Span<Guid> values)
314365 /// <summary>Reads a list of <see cref="Guid"/> from buffer into <paramref name="values"/>.</summary>
315366 public void ReadGuid ( in List < Guid > values ) => ReadGuid ( GetListSpan ( in values ) ) ;
316367
368+ /// <inheritdoc cref="ReadGuid()"/>
369+ public Guid ? ReadNullableGuid ( ) => ReadBoolean ( ) ? ReadGuid ( ) : null ;
317370
318371 /// <summary>Reads single <see cref="TimeSpan"/> from buffer.</summary>
319372 public TimeSpan ReadTimeSpan ( ) => new ( ReadInt64 ( ) ) ;
@@ -328,6 +381,8 @@ public void ReadTimeSpan(in Span<TimeSpan> values)
328381 /// <summary>Reads a list of <see cref="TimeSpan"/> from buffer into <paramref name="values"/>.</summary>
329382 public void ReadTimeSpan ( in List < TimeSpan > values ) => ReadTimeSpan ( GetListSpan ( in values ) ) ;
330383
384+ /// <inheritdoc cref="ReadTimeSpan()"/>
385+ public TimeSpan ? ReadNullableTimeSpan ( ) => ReadBoolean ( ) ? ReadTimeSpan ( ) : null ;
331386
332387 /// <summary>Reads single <see cref="TimeOnly"/> from buffer.</summary>
333388 public TimeOnly ReadTimeOnly ( ) => new ( ReadInt64 ( ) ) ;
@@ -342,6 +397,9 @@ public void ReadTimeOnly(in Span<TimeOnly> values)
342397 /// <summary>Reads a list of <see cref="TimeOnly"/> from buffer into <paramref name="values"/>.</summary>
343398 public void ReadTimeOnly ( in List < TimeOnly > values ) => ReadTimeOnly ( GetListSpan ( in values ) ) ;
344399
400+ /// <inheritdoc cref="ReadTimeOnly()"/>
401+ public TimeOnly ? ReadNullableTimeOnly ( ) => ReadBoolean ( ) ? ReadTimeOnly ( ) : null ;
402+
345403 /// <summary>Reads single <see cref="DateTime"/> from buffer.</summary>
346404 public DateTime ReadDateTime ( )
347405 {
@@ -366,6 +424,9 @@ public void ReadDateTime(in Span<DateTime> values)
366424 /// <summary>Reads a list of <see cref="DateTime"/> from buffer into <paramref name="values"/>.</summary>
367425 public void ReadDateTime ( in List < DateTime > values ) => ReadDateTime ( GetListSpan ( in values ) ) ;
368426
427+ /// <inheritdoc cref="ReadDateTime()"/>
428+ public DateTime ? ReadNullableDateTime ( ) => ReadBoolean ( ) ? ReadDateTime ( ) : null ;
429+
369430 /// <summary>Reads single <see cref="DateTimeOffset"/> from buffer.</summary>
370431 public DateTimeOffset ReadDateTimeOffset ( )
371432 {
@@ -390,6 +451,8 @@ public void ReadDateTimeOffset(in Span<DateTimeOffset> values)
390451 /// <summary>Reads a list of <see cref="DateTimeOffset"/> from buffer into <paramref name="values"/>.</summary>
391452 public void ReadDateTimeOffset ( in List < DateTimeOffset > values ) => ReadDateTimeOffset ( GetListSpan ( in values ) ) ;
392453
454+ /// <inheritdoc cref="ReadDateTimeOffset()"/>
455+ public DateTimeOffset ? ReadNullableDateTimeOffset ( ) => ReadBoolean ( ) ? ReadDateTimeOffset ( ) : null ;
393456
394457 /// <summary>Reads single <see cref="DateOnly"/> from buffer.</summary>
395458 public DateOnly ReadDateOnly ( ) => DateOnly . FromDayNumber ( ReadInt32 ( ) ) ;
@@ -404,6 +467,9 @@ public void ReadDateOnly(in Span<DateOnly> values)
404467 /// <summary>Reads a list of <see cref="DateOnly"/> from buffer into <paramref name="values"/>.</summary>
405468 public void ReadDateOnly ( in List < DateOnly > values ) => ReadDateOnly ( GetListSpan ( in values ) ) ;
406469
470+ /// <inheritdoc cref="ReadDateOnly()"/>
471+ public DateOnly ? ReadNullableDateOnly ( ) => ReadBoolean ( ) ? ReadDateOnly ( ) : null ;
472+
407473 /// <summary>Reads an unmanaged struct from buffer.</summary>
408474 public void ReadStruct < T > ( ref T value ) where T : unmanaged
409475 {
@@ -424,36 +490,22 @@ public T ReadStruct<T>() where T : unmanaged
424490 return result ;
425491 }
426492
427- /// <summary>Reads an unmanaged struct list from buffer.</summary>
428- public void ReadStruct < T > ( in List < T > values ) where T : unmanaged =>
429- ReadStruct ( GetListSpan ( in values ) ) ;
430-
431493 /// <summary>Reads an unmanaged struct span from buffer.</summary>
432494 public void ReadStruct < T > ( in Span < T > values ) where T : unmanaged =>
433495 ReadByte ( MemoryMarshal . AsBytes ( values ) ) ;
434496
497+ /// <summary>Reads an unmanaged struct list from buffer.</summary>
498+ public void ReadStruct < T > ( in List < T > values ) where T : unmanaged =>
499+ ReadStruct ( GetListSpan ( in values ) ) ;
500+
435501 /// <summary>Reads an unmanaged struct from buffer.</summary>
436502 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
437503 public void ReadStruct < T > ( in T [ ] values ) where T : unmanaged =>
438504 ReadStruct ( values . AsSpan ( ) ) ;
439505
440- /// <summary>Reads an unmanaged struct from buffer.</summary>
441- public T ReadStructUnsafe < T > ( ) where T : struct
442- {
443- var size = Unsafe . SizeOf < T > ( ) ;
444- if ( size > FreeCapacity ) size = FreeCapacity ;
445- var result = Mem . ReadStruct < T > ( CurrentBuffer [ ..size ] ) ;
446- Advance ( size ) ;
447- return result ;
448- }
449-
450- /// <summary>Reads an unmanaged struct from buffer.</summary>
451- public void ReadStructUnsafe < T > ( in Span < T > values ) where T : struct
452- {
453- ThrowHelpers . ThrowIfTypeIsReferenceOrContainsReferences < T > ( ) ;
454- var valuesBytes = MemoryMarshal . AsBytes ( values ) ;
455- ReadByte ( in valuesBytes ) ;
456- }
506+ /// <inheritdoc cref="ReadStruct{T}()"/>
507+ public T ? ReadNullableStruct < T > ( ) where T : unmanaged =>
508+ ReadBoolean ( ) ? ReadStruct < T > ( ) : null ;
457509
458510 /// <summary>Reads and allocates an <see cref="string"/> from buffer.</summary>
459511 public string ReadString ( int size )
@@ -484,6 +536,14 @@ public T ReadNumber<T>(bool isUnsigned) where T : unmanaged, IBinaryInteger<T>
484536 return result ;
485537 }
486538
539+ /// <inheritdoc cref="ReadNumber{T}()"/>
540+ public T ? ReadNullableNumber < T > ( ) where T : unmanaged, IBinaryInteger < T > , IMinMaxValue < T > =>
541+ ReadBoolean ( ) ? ReadNumber < T > ( ) : null ;
542+
543+ /// <inheritdoc cref="ReadNumber{T}(bool)"/>
544+ public T ? ReadNullableNumber < T > ( bool isUnsigned ) where T : unmanaged, IBinaryInteger < T > =>
545+ ReadBoolean ( ) ? ReadNumber < T > ( isUnsigned ) : null ;
546+
487547 /// <summary>Reads a <see cref="IBinarySerializable"/> <paramref name="value"/> from buffer.</summary>
488548 /// <typeparam name="T">A type that implements <see cref="IBinarySerializable"/>.</typeparam>
489549 public void Read < T > ( ref T value ) where T : IBinarySerializable => value . Deserialize ( in this ) ;
0 commit comments