ImageSharp/SixLabors.Fonts/Buffer{T}.cs
2026-08-03 22:31:27 +02:00

74 lines
1.9 KiB
C#

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