AyCode.Core/AyCode.Services/SignalRs/SignalData.cs

53 lines
1.6 KiB
C#

using System.Buffers;
namespace AyCode.Services.SignalRs;
/// <summary>
/// Wrapper for byte[] response data with optional ArrayPool lifecycle.
/// Created by AyCodeBinaryHubProtocol for pooled buffers,
/// or directly from byte[] for non-pooled data (server send path).
/// Consumer must Dispose() to return rented buffer.
/// Supports future AsyncEnumerable streaming (per-chunk lifecycle).
/// </summary>
public sealed class SignalData : IDisposable
{
private byte[]? _buffer;
private readonly int _length;
private readonly bool _isRented;
/// <summary>Pooled buffer from ArrayPool (rented, length >= actual data).</summary>
public SignalData(byte[] rentedBuffer, int length, bool isRented)
{
_buffer = rentedBuffer;
_length = length;
_isRented = isRented;
}
/// <summary>Non-pooled byte[] (server send, direct creation).</summary>
public SignalData(byte[] data)
{
_buffer = data;
_length = data?.Length ?? 0;
_isRented = false;
}
public ReadOnlySpan<byte> Span => _buffer.AsSpan(0, _length);
public int Length => _length;
public bool IsEmpty => _length == 0 || _buffer == null;
/// <summary>
/// Returns a copy as byte[]. Use only when a byte[] is absolutely required.
/// Prefer Span for zero-copy access.
/// </summary>
public byte[] ToArray() => Span.ToArray();
public void Dispose()
{
if (_isRented && _buffer != null)
{
ArrayPool<byte>.Shared.Return(_buffer, clearArray: true);
_buffer = null;
}
}
}