61 lines
1.8 KiB
C#
61 lines
1.8 KiB
C#
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
|
|||
|
namespace KcpSharp
|
|||
|
{
|
|||
|
internal readonly struct KcpBuffer
|
|||
|
{
|
|||
|
private readonly object? _owner;
|
|||
|
private readonly Memory<byte> _memory;
|
|||
|
private readonly int _length;
|
|||
|
|
|||
|
public ReadOnlyMemory<byte> DataRegion => _memory.Slice(0, _length);
|
|||
|
|
|||
|
public int Length => _length;
|
|||
|
|
|||
|
private KcpBuffer(object? owner, Memory<byte> memory, int length)
|
|||
|
{
|
|||
|
_owner = owner;
|
|||
|
_memory = memory;
|
|||
|
_length = length;
|
|||
|
}
|
|||
|
|
|||
|
public static KcpBuffer CreateFromSpan(KcpRentedBuffer buffer, ReadOnlySpan<byte> dataSource)
|
|||
|
{
|
|||
|
Memory<byte> memory = buffer.Memory;
|
|||
|
if (dataSource.Length > memory.Length)
|
|||
|
{
|
|||
|
ThrowRentedBufferTooSmall();
|
|||
|
}
|
|||
|
dataSource.CopyTo(memory.Span);
|
|||
|
return new KcpBuffer(buffer.Owner, memory, dataSource.Length);
|
|||
|
}
|
|||
|
|
|||
|
public KcpBuffer AppendData(ReadOnlySpan<byte> data)
|
|||
|
{
|
|||
|
if ((_length + data.Length) > _memory.Length)
|
|||
|
{
|
|||
|
ThrowRentedBufferTooSmall();
|
|||
|
}
|
|||
|
data.CopyTo(_memory.Span.Slice(_length));
|
|||
|
return new KcpBuffer(_owner, _memory, _length + data.Length);
|
|||
|
}
|
|||
|
|
|||
|
public KcpBuffer Consume(int length)
|
|||
|
{
|
|||
|
Debug.Assert((uint)length <= (uint)_length);
|
|||
|
return new KcpBuffer(_owner, _memory.Slice(length), _length - length);
|
|||
|
}
|
|||
|
|
|||
|
public void Release()
|
|||
|
{
|
|||
|
new KcpRentedBuffer(_owner, _memory).Dispose();
|
|||
|
}
|
|||
|
|
|||
|
private static void ThrowRentedBufferTooSmall()
|
|||
|
{
|
|||
|
throw new InvalidOperationException("The rented buffer is not large enough to hold the data.");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|