namespace Sick.SafetyScanners.DataStructures; /// /// Packet buffer for COLA2 communication /// Thread-safe wrapper around byte buffer - matches C++ shared_ptr semantics /// public sealed class PacketBuffer : IDisposable { private readonly byte[] _buffer; private readonly int _length; private bool _disposed; /// /// Maximum size of packet buffer (matches C++ MAXSIZE = 10000) /// public const int MaxSize = 10000; /// /// Creates a new packet buffer from byte array /// public PacketBuffer(byte[] buffer, int length) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); if (length < 0 || length > buffer.Length) throw new ArgumentOutOfRangeException(nameof(length)); if (length > MaxSize) throw new ArgumentException($"Length {length} exceeds MaxSize {MaxSize}", nameof(length)); // Copy buffer to ensure immutability (like C++ shared_ptr) _buffer = new byte[length]; Array.Copy(buffer, 0, _buffer, 0, length); _length = length; } /// /// Creates a new packet buffer from ReadOnlyMemory /// public PacketBuffer(ReadOnlyMemory memory) { if (memory.Length > MaxSize) throw new ArgumentException($"Length {memory.Length} exceeds MaxSize {MaxSize}", nameof(memory)); _buffer = memory.ToArray(); _length = _buffer.Length; } /// /// Creates a new packet buffer from ReadOnlySpan /// public PacketBuffer(ReadOnlySpan span) { if (span.Length > MaxSize) throw new ArgumentException($"Length {span.Length} exceeds MaxSize {MaxSize}", nameof(span)); _buffer = span.ToArray(); _length = _buffer.Length; } /// /// Gets the buffer as ReadOnlyMemory (zero-copy if possible) /// public ReadOnlyMemory GetBuffer() { if (_disposed) throw new ObjectDisposedException(nameof(PacketBuffer)); return new ReadOnlyMemory(_buffer, 0, _length); } /// /// Gets the buffer as ReadOnlySpan (zero-copy) /// public ReadOnlySpan GetBufferSpan() { if (_disposed) throw new ObjectDisposedException(nameof(PacketBuffer)); return new ReadOnlySpan(_buffer, 0, _length); } /// /// Gets the length of the buffer /// public int Length { get { if (_disposed) throw new ObjectDisposedException(nameof(PacketBuffer)); return _length; } } /// /// Gets a copy of the buffer as byte array /// public byte[] ToArray() { if (_disposed) throw new ObjectDisposedException(nameof(PacketBuffer)); var result = new byte[_length]; Array.Copy(_buffer, 0, result, 0, _length); return result; } public void Dispose() { _disposed = true; } }