encompass-cs/encompass-cs/Collections/FixedArray.cs

70 lines
1.5 KiB
C#

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
internal unsafe class FixedArray<T> : IDisposable where T : unmanaged
{
private void* _buffer;
public int Length { get; private set; }
public T this[int i]
{
get { return ReadElement(_buffer, i); }
set { WriteElement(_buffer, i, value); }
}
public unsafe FixedArray(int length, bool clearMemory = false)
{
var bufferSize = Marshal.SizeOf<T>() * length;
_buffer = (void*)Alloc(bufferSize);
if (clearMemory)
{
Memset(_buffer, 0, bufferSize);
}
Length = length;
}
public ref T ByRef(int i)
{
return ref *(T*)((byte*)_buffer + i * sizeof(T));
}
void IDisposable.Dispose()
{
Free((IntPtr)_buffer);
_buffer = null;
Length = 0;
}
private static T ReadElement(void* buffer, int i)
{
return *(T*)((byte*)buffer + i * sizeof(T));
}
private static void WriteElement(void* buffer, int i, T value)
{
*(T*)((byte*)buffer + i * sizeof(T)) = value;
}
private unsafe static IntPtr Alloc(int size)
{
return Marshal.AllocHGlobal(size);
}
public unsafe static void Free(IntPtr ptr)
{
if (ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(ptr);
}
}
private unsafe static void Memset(void* ptr, byte value, int count)
{
Unsafe.InitBlock(ptr, value, (uint)count);
}
}