using System.Buffers; namespace AyCode.Services.SignalRs; /// /// 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). /// public sealed class SignalData : IDisposable { private byte[]? _buffer; private readonly int _length; private readonly bool _isRented; /// Pooled buffer from ArrayPool (rented, length >= actual data). public SignalData(byte[] rentedBuffer, int length, bool isRented) { _buffer = rentedBuffer; _length = length; _isRented = isRented; } /// Non-pooled byte[] (server send, direct creation). public SignalData(byte[] data) { _buffer = data; _length = data?.Length ?? 0; _isRented = false; } public ReadOnlySpan Span => _buffer.AsSpan(0, _length); public int Length => _length; public bool IsEmpty => _length == 0 || _buffer == null; /// /// Returns a copy as byte[]. Use only when a byte[] is absolutely required. /// Prefer Span for zero-copy access. /// public byte[] ToArray() => Span.ToArray(); public void Dispose() { if (_isRented && _buffer != null) { ArrayPool.Shared.Return(_buffer, clearArray: true); _buffer = null; } } }