using Ryujinx.Horizon.Sdk.Sf.Cmif; using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Memory; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Horizon.Sdk.Sf { static class CommandSerialization { public static ReadOnlySpan GetReadOnlySpan(PointerAndSize bufferRange) { return HorizonStatic.AddressSpace.GetSpan(bufferRange.Address, checked((int)bufferRange.Size)); } public static WritableRegion GetWritableRegion(PointerAndSize bufferRange) { return HorizonStatic.AddressSpace.GetWritableRegion(bufferRange.Address, checked((int)bufferRange.Size)); } public static ref T GetRef(PointerAndSize bufferRange) where T : unmanaged { var writableRegion = GetWritableRegion(bufferRange); return ref MemoryMarshal.Cast(writableRegion.Memory.Span)[0]; } public static object DeserializeArg(ref ServiceDispatchContext context, ReadOnlySpan inRawData, int offset) where T : unmanaged { return MemoryMarshal.Cast(inRawData.Slice(offset, Unsafe.SizeOf()))[0]; } public static T DeserializeArg(ReadOnlySpan inRawData, int offset) where T : unmanaged { return MemoryMarshal.Cast(inRawData.Slice(offset, Unsafe.SizeOf()))[0]; } public static ulong DeserializeClientProcessId(ref ServiceDispatchContext context) { return context.Request.Pid; } public static int DeserializeCopyHandle(ref ServiceDispatchContext context, int index) { return context.Request.Data.CopyHandles[index]; } public static int DeserializeMoveHandle(ref ServiceDispatchContext context, int index) { return context.Request.Data.MoveHandles[index]; } public static void SerializeArg(Span outRawData, int offset, T value) where T : unmanaged { MemoryMarshal.Cast(outRawData.Slice(offset, Unsafe.SizeOf()))[0] = value; } public static void SerializeCopyHandle(HipcMessageData response, int index, int value) { response.CopyHandles[index] = value; } public static void SerializeMoveHandle(HipcMessageData response, int index, int value) { response.MoveHandles[index] = value; } } }