aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs')
-rw-r--r--src/Ryujinx.Horizon/Sdk/Ngc/Detail/BinaryReader.cs63
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;
+ }
+ }
+}