117 lines
3.4 KiB
C#
117 lines
3.4 KiB
C#
namespace Sick.SafetyScanners.DataStructures;
|
|
|
|
/// <summary>
|
|
/// Packet buffer for COLA2 communication
|
|
/// Thread-safe wrapper around byte buffer - matches C++ shared_ptr<vector const> semantics
|
|
/// </summary>
|
|
public sealed class PacketBuffer : IDisposable
|
|
{
|
|
private readonly byte[] _buffer;
|
|
private readonly int _length;
|
|
private bool _disposed;
|
|
|
|
/// <summary>
|
|
/// Maximum size of packet buffer (matches C++ MAXSIZE = 10000)
|
|
/// </summary>
|
|
public const int MaxSize = 10000;
|
|
|
|
/// <summary>
|
|
/// Creates a new packet buffer from byte array
|
|
/// </summary>
|
|
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<vector const>)
|
|
_buffer = new byte[length];
|
|
Array.Copy(buffer, 0, _buffer, 0, length);
|
|
_length = length;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new packet buffer from ReadOnlyMemory
|
|
/// </summary>
|
|
public PacketBuffer(ReadOnlyMemory<byte> memory)
|
|
{
|
|
if (memory.Length > MaxSize)
|
|
throw new ArgumentException($"Length {memory.Length} exceeds MaxSize {MaxSize}", nameof(memory));
|
|
|
|
_buffer = memory.ToArray();
|
|
_length = _buffer.Length;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new packet buffer from ReadOnlySpan
|
|
/// </summary>
|
|
public PacketBuffer(ReadOnlySpan<byte> span)
|
|
{
|
|
if (span.Length > MaxSize)
|
|
throw new ArgumentException($"Length {span.Length} exceeds MaxSize {MaxSize}", nameof(span));
|
|
|
|
_buffer = span.ToArray();
|
|
_length = _buffer.Length;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the buffer as ReadOnlyMemory (zero-copy if possible)
|
|
/// </summary>
|
|
public ReadOnlyMemory<byte> GetBuffer()
|
|
{
|
|
if (_disposed)
|
|
throw new ObjectDisposedException(nameof(PacketBuffer));
|
|
|
|
return new ReadOnlyMemory<byte>(_buffer, 0, _length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the buffer as ReadOnlySpan (zero-copy)
|
|
/// </summary>
|
|
public ReadOnlySpan<byte> GetBufferSpan()
|
|
{
|
|
if (_disposed)
|
|
throw new ObjectDisposedException(nameof(PacketBuffer));
|
|
|
|
return new ReadOnlySpan<byte>(_buffer, 0, _length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the length of the buffer
|
|
/// </summary>
|
|
public int Length
|
|
{
|
|
get
|
|
{
|
|
if (_disposed)
|
|
throw new ObjectDisposedException(nameof(PacketBuffer));
|
|
|
|
return _length;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a copy of the buffer as byte array
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|