using System.Collections.Immutable; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace VersionedSerialization; public ref struct Reader(TReader impl, ReaderConfig config = default) where TReader : IReader, allows ref struct { private TReader _impl = impl; public ReaderConfig Config { get; } = config; [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(int length = -1, Encoding? encoding = null) => _impl.ReadString(length, encoding); [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan ReadBytes(long length) => _impl.ReadBytes(length); [MethodImpl(MethodImplOptions.AggressiveInlining)] public T Read() where T : unmanaged { Unsafe.SkipInit(out T value); Read(ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(scoped ref T value) where T : unmanaged => Read(new Span(ref value)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(scoped Span dest) where T : unmanaged => _impl.Read(dest); [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadPrimitive() where T : unmanaged { Unsafe.SkipInit(out T value); ReadPrimitive(ref value); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPrimitive(scoped ref T value) where T : unmanaged => ReadPrimitive(new Span(ref value)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadPrimitive(scoped Span dest) where T : unmanaged => _impl.ReadPrimitive(dest); [MethodImpl(MethodImplOptions.AggressiveInlining)] public ImmutableArray ReadPrimitiveArray(long count) where T : unmanaged { var data = GC.AllocateUninitializedArray((int)count); ReadPrimitive(data); return ImmutableCollectionsMarshal.AsImmutableArray(data); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T ReadVersionedObject(in StructVersion version = default) where T : IReadable, new() { var obj = new T(); ReadVersionedObject(ref obj, version); return obj; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadVersionedObject(scoped ref T dest, in StructVersion version = default) where T : IReadable { dest.Read(ref this, in version); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ReadVersionedObject(scoped Span dest, in StructVersion version = default) where T : IReadable { for (int i = 0; i < dest.Length; i++) { ReadVersionedObject(ref dest[i], version); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ImmutableArray ReadVersionedObjectArray(long count, in StructVersion version = default) where T : IReadable, new() { var array = GC.AllocateUninitializedArray((int)count); ReadVersionedObject(array, in version); return ImmutableCollectionsMarshal.AsImmutableArray(array); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadNativeUInt() => Config.Is32Bit ? ReadPrimitive() : ReadPrimitive(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadNativeInt() => Config.Is32Bit ? ReadPrimitive() : ReadPrimitive(); }