using System;
using System.Buffers;
using System.Runtime.InteropServices;
using SixLabors.Memory;
namespace SixLabors.ImageSharp.Tests.Memory
{
internal class TestMemoryAllocator : MemoryAllocator
{
public TestMemoryAllocator(byte dirtyValue = 42)
{
this.DirtyValue = dirtyValue;
}
///
/// The value to initilazie the result buffer with, with non-clean options ()
///
public byte DirtyValue { get; }
public override IMemoryOwner Allocate(int length, AllocationOptions options = AllocationOptions.None)
{
T[] array = this.AllocateArray(length, options);
return new BasicArrayBuffer(array, length);
}
public override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options = AllocationOptions.None)
{
byte[] array = this.AllocateArray(length, options);
return new ManagedByteBuffer(array);
}
private T[] AllocateArray(int length, AllocationOptions options)
where T : struct
{
var array = new T[length + 42];
if (options == AllocationOptions.None)
{
Span data = MemoryMarshal.Cast(array.AsSpan());
data.Fill(this.DirtyValue);
}
return array;
}
///
/// Wraps an array as an instance.
///
private class BasicArrayBuffer : MemoryManager
where T : struct
{
private GCHandle pinHandle;
///
/// Initializes a new instance of the class
///
/// The array
/// The length of the buffer
public BasicArrayBuffer(T[] array, int length)
{
DebugGuard.MustBeLessThanOrEqualTo(length, array.Length, nameof(length));
this.Array = array;
this.Length = length;
}
///
/// Initializes a new instance of the class
///
/// The array
public BasicArrayBuffer(T[] array)
: this(array, array.Length)
{
}
///
/// Gets the array
///
public T[] Array { get; }
///
/// Gets the length
///
public int Length { get; }
///
public override Span GetSpan() => this.Array.AsSpan(0, this.Length);
public override unsafe MemoryHandle Pin(int elementIndex = 0)
{
if (!this.pinHandle.IsAllocated)
{
this.pinHandle = GCHandle.Alloc(this.Array, GCHandleType.Pinned);
}
void* ptr = (void*)this.pinHandle.AddrOfPinnedObject();
return new MemoryHandle(ptr, this.pinHandle);
}
public override void Unpin()
{
throw new NotImplementedException();
}
///
protected override void Dispose(bool disposing)
{
}
}
private class ManagedByteBuffer : BasicArrayBuffer, IManagedByteBuffer
{
public ManagedByteBuffer(byte[] array)
: base(array)
{
}
}
}
}