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;
}
}