// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
namespace SixLabors.PolygonClipper {
///
/// An disposable buffer that is backed by an array pool.
///
/// The type of buffer element.
internal ref struct Buffer
where T : unmanaged
{
private int length;
private readonly byte[] buffer;
private readonly Span span;
private bool isDisposed;
public Buffer(int length)
{
Guard.MustBeGreaterThanOrEqualTo(length, 0, nameof(length));
int itemSizeBytes = Unsafe.SizeOf();
int bufferSizeInBytes = length * itemSizeBytes;
this.buffer = ArrayPool.Shared.Rent(bufferSizeInBytes);
this.length = length;
using ByteMemoryManager manager = new(this.buffer);
this.Memory = manager.Memory[..this.length];
this.span = this.Memory.Span;
this.isDisposed = false;
}
public Memory Memory { get; }
public readonly Span GetSpan()
{
if (this.buffer is null)
{
ThrowObjectDisposedException();
}
return this.span;
}
public void Dispose()
{
if (this.isDisposed)
{
return;
}
ArrayPool.Shared.Return(this.buffer);
this.length = 0;
this.isDisposed = true;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void ThrowObjectDisposedException() => throw new ObjectDisposedException("Buffer");
}
}