BufferSegment
using System.Buffers;
using System.Runtime.CompilerServices;
namespace System.IO.Pipelines
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal sealed class BufferSegment : ReadOnlySequenceSegment<byte>
{
private IMemoryOwner<byte> _memoryOwner;
private byte[] _array;
private BufferSegment _next;
private int _end;
public int End {
get {
return _end;
}
set {
_end = value;
base.Memory = AvailableMemory.Slice(0, value);
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public BufferSegment NextSegment {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return _next;
}
[System.Runtime.CompilerServices.NullableContext(2)]
set {
base.Next = value;
_next = value;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
internal object MemoryOwner {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return ((object)_memoryOwner) ?? ((object)_array);
}
}
[System.Runtime.CompilerServices.Nullable(0)]
public Memory<byte> AvailableMemory {
[System.Runtime.CompilerServices.NullableContext(0)]
get;
private set;
}
public int Length => End;
public int WritableBytes {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
return AvailableMemory.Length - End;
}
}
public void SetOwnedMemory(IMemoryOwner<byte> memoryOwner)
{
_memoryOwner = memoryOwner;
AvailableMemory = memoryOwner.Memory;
}
public void SetOwnedMemory(byte[] arrayPoolBuffer)
{
_array = arrayPoolBuffer;
AvailableMemory = arrayPoolBuffer;
}
public void Reset()
{
ResetMemory();
base.Next = null;
base.RunningIndex = 0;
_next = null;
}
public void ResetMemory()
{
IMemoryOwner<byte> memoryOwner = _memoryOwner;
if (memoryOwner != null) {
_memoryOwner = null;
memoryOwner.Dispose();
} else {
ArrayPool<byte>.Shared.Return(_array, false);
_array = null;
}
base.Memory = default(ReadOnlyMemory<byte>);
_end = 0;
AvailableMemory = default(Memory<byte>);
}
public void SetNext(BufferSegment segment)
{
NextSegment = segment;
segment = this;
while (segment.Next != null) {
segment.NextSegment.RunningIndex = segment.RunningIndex + segment.Length;
segment = segment.NextSegment;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static long GetLength(BufferSegment startSegment, int startIndex, BufferSegment endSegment, int endIndex)
{
return endSegment.RunningIndex + (uint)endIndex - (startSegment.RunningIndex + (uint)startIndex);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static long GetLength(long startPosition, BufferSegment endSegment, int endIndex)
{
return endSegment.RunningIndex + (uint)endIndex - startPosition;
}
}
}