diff options
Diffstat (limited to 'src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs')
| -rw-r--r-- | src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs new file mode 100644 index 00000000..5bad376a --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs @@ -0,0 +1,63 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Horizon.Sdk.Ngc.Detail +{ + ref struct BinaryReader + { + private readonly ReadOnlySpan<byte> _data; + private int _offset; + + public BinaryReader(ReadOnlySpan<byte> data) + { + _data = data; + } + + public bool Read<T>(out T value) where T : unmanaged + { + int byteLength = Unsafe.SizeOf<T>(); + + if ((uint)(_offset + byteLength) <= (uint)_data.Length) + { + value = MemoryMarshal.Cast<byte, T>(_data[_offset..])[0]; + _offset += byteLength; + + return true; + } + + value = default; + + return false; + } + + public int AllocateAndReadArray<T>(ref T[] array, int length, int maxLengthExclusive) where T : unmanaged + { + return AllocateAndReadArray(ref array, Math.Min(length, maxLengthExclusive)); + } + + public int AllocateAndReadArray<T>(ref T[] array, int length) where T : unmanaged + { + array = new T[length]; + + return ReadArray(array); + } + + public int ReadArray<T>(T[] array) where T : unmanaged + { + if (array != null) + { + int byteLength = array.Length * Unsafe.SizeOf<T>(); + byteLength = Math.Min(byteLength, _data.Length - _offset); + + MemoryMarshal.Cast<byte, T>(_data.Slice(_offset, byteLength)).CopyTo(array); + + _offset += byteLength; + + return byteLength / Unsafe.SizeOf<T>(); + } + + return 0; + } + } +} |
