<PackageReference Include="System.Drawing.Common" Version="10.0.0-rc.2.25502.107" />

BinaryReaderExtensions

static class BinaryReaderExtensions
using System.Buffers.Binary; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; namespace System.IO { internal static class BinaryReaderExtensions { [NullableContext(1)] internal static DateTime ReadDateTime(this BinaryReader reader) { return CreateDateTimeFromData(reader.ReadInt64()); } internal static DateTime CreateDateTimeFromData(long data) { try { new DateTime(data & 4611686018427387903); } catch (ArgumentException ex) { throw new SerializationException(ex.Message, ex); } return Unsafe.As<long, DateTime>(ref data); } [NullableContext(1)] internal static long Remaining(this BinaryReader reader) { Stream baseStream = reader.BaseStream; return baseStream.Length - baseStream.Position; } [return: Nullable(new byte[] { 1, 0 })] internal unsafe static T[] ReadPrimitiveArray<[IsUnmanaged] T>([Nullable(1)] this BinaryReader reader, int count) where T : struct { ArgumentOutOfRangeException.ThrowIfNegative(count, "count"); checked { if (typeof(T) == typeof(decimal) || typeof(T) == typeof(DateTime) || typeof(T) == typeof(TimeSpan)) { if (count == 0) return Array.Empty<T>(); if (count > 0 && reader.Remaining() < count * ((typeof(T) == typeof(decimal)) ? 2 : sizeof(T))) throw new SerializationException("Not enough data to fill array."); return <ReadPrimitiveArray>g__ReadNonBlittableTypes|3_0<T>(reader, count); } if (typeof(T) != typeof(bool) && typeof(T) != typeof(byte) && typeof(T) != typeof(sbyte) && typeof(T) != typeof(char) && typeof(T) != typeof(short) && typeof(T) != typeof(ushort) && typeof(T) != typeof(int) && typeof(T) != typeof(uint) && typeof(T) != typeof(long) && typeof(T) != typeof(ulong) && typeof(T) != typeof(float) && typeof(T) != typeof(double)) throw new ArgumentException("Cannot read primitives of " + typeof(T).Name + ".", "T"); if (count > 0 && reader.Remaining() < count * ((typeof(T) == typeof(char)) ? 1 : sizeof(T))) throw new SerializationException("Not enough data to fill array."); if (count == 0) return Array.Empty<T>(); } if (typeof(T) == typeof(char)) return (T[])reader.ReadChars(count); T[] array = new T[count]; fixed (T* pointer = array) { Span<byte> span = new Span<byte>((void*)pointer, array.Length * sizeof(T)); if (reader.Read(span) != span.Length) throw new SerializationException("Not enough data to fill array."); if (sizeof(T) != 1 && !BitConverter.IsLittleEndian) { if (sizeof(T) == 2) { Span<ushort> span2 = MemoryMarshal.Cast<byte, ushort>(span); BinaryPrimitives.ReverseEndianness(span2, span2); } else if (sizeof(T) == 4) { Span<int> span3 = MemoryMarshal.Cast<byte, int>(span); BinaryPrimitives.ReverseEndianness(span3, span3); } else { if (sizeof(T) != 8) throw new InvalidOperationException("Cannot read primitives of " + typeof(T).Name + "."); Span<long> span4 = MemoryMarshal.Cast<byte, long>(span); BinaryPrimitives.ReverseEndianness(span4, span4); } } } return array; } internal unsafe static void WritePrimitives<[IsUnmanaged] T>([Nullable(1)] this BinaryWriter writer, [Nullable(new byte[] { 1, 0 })] IReadOnlyList<T> values) where T : struct { if (((IReadOnlyCollection<T>)values).Count != 0) { if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(decimal) || typeof(T) == typeof(TimeSpan)) <WritePrimitives>g__WritePrimitiveCollection|4_0(writer, values); else { if (typeof(T) != typeof(bool) && typeof(T) != typeof(byte) && typeof(T) != typeof(sbyte) && typeof(T) != typeof(char) && typeof(T) != typeof(short) && typeof(T) != typeof(ushort) && typeof(T) != typeof(int) && typeof(T) != typeof(uint) && typeof(T) != typeof(long) && typeof(T) != typeof(ulong) && typeof(T) != typeof(float) && typeof(T) != typeof(double)) throw new ArgumentException("Cannot write primitives of " + typeof(T).Name + ".", "T"); T[] array = values as T[]; ReadOnlySpan<T> span; if (array != null) span = array; else if (values is ArraySegment<T>) { ArraySegment<T> segment = (ArraySegment<T>)values; span = segment; } else { List<T> list = values as List<T>; if (list == null) { <WritePrimitives>g__WritePrimitiveCollection|4_0(writer, values); return; } span = CollectionsMarshal.AsSpan(list); } if (typeof(T) == typeof(char)) writer.Write(MemoryMarshal.Cast<T, char>(span)); else if (sizeof(T) == 1 || BitConverter.IsLittleEndian) { writer.Write(MemoryMarshal.Cast<T, byte>(span)); } else { <WritePrimitives>g__WritePrimitiveCollection|4_0(writer, values); } } } } } }