using System;
using System.Runtime.InteropServices;
namespace VIVE.OpenXR
{
public static class MemoryTools
{
///
/// Convert the enum array to IntPtr. Should call after use.
///
///
///
///
public static IntPtr ToIntPtr(T[] array) where T : Enum
{
int size = Marshal.SizeOf(typeof(T)) * array.Length;
IntPtr ptr = Marshal.AllocHGlobal(size);
int[] intArray = new int[array.Length];
for (int i = 0; i < array.Length; i++)
intArray[i] = (int)(object)array[i];
Marshal.Copy(intArray, 0, ptr, array.Length);
return ptr;
}
///
/// Make the same size raw buffer from input array.
///
/// Data type could be primitive type or struct. Should call after use.
/// The data array
/// The memory handle. Should release by
public static IntPtr MakeRawMemory(T[] refArray)
{
int size = Marshal.SizeOf(typeof(T)) * refArray.Length;
return Marshal.AllocHGlobal(size);
}
///
/// Copy the raw memory to the array. You should make sure the array has the same size as the raw memory.
///
/// Convert the memory to this type array.
/// The output array.
/// The data source in raw memory form.
/// Specify the copy count. Count should be less than array length.
public static void CopyFromRawMemory(T[] array, IntPtr raw, int count = 0)
{
int N = array.Length;
if (count > 0 && count < array.Length)
N = count;
int step = Marshal.SizeOf(typeof(T));
for (int i = 0; i < N; i++)
{
array[i] = Marshal.PtrToStructure(IntPtr.Add(raw, i * step));
}
}
///
/// Make the same size raw buffer from input array. Make sure the raw has enough size.
///
/// Convert this type array to raw memory.
/// The output data in raw memory form
/// The data source
public static void CopyToRawMemory(IntPtr raw, T[] array)
{
int step = Marshal.SizeOf(typeof(T));
for (int i = 0; i < array.Length; i++)
{
Marshal.StructureToPtr(array[i], IntPtr.Add(raw, i * step), false);
}
}
///
/// Release the raw memory handle which is created by
///
///
public static void ReleaseRawMemory(IntPtr ptr)
{
Marshal.FreeHGlobal(ptr);
}
}
}