/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Shared/Buffers/BufferSegment.cs
127 строк
4 KB
Pranav K
Use file scoped namespaces (#38076)
06 ноя 2021, 03:52
Не верифицирован
06 ноя 2021, 03:52
a450cb6
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; namespace System.IO.Pipelines; // Copied from https://github.com/dotnet/corefx/blob/de3902bb56f1254ec1af4bf7d092fc2c048734cc/src/System.IO.Pipelines/src/System/IO/Pipelines/BufferSegment.cs internal sealed class BufferSegment : ReadOnlySequenceSegment<byte> { private object? _memoryOwner; private BufferSegment? _next; private int _end; /// <summary> /// The End represents the offset into AvailableMemory where the range of "active" bytes ends. At the point when the block is leased /// the End is guaranteed to be equal to Start. The value of Start may be assigned anywhere between 0 and /// Buffer.Length, and must be equal to or less than End. /// </summary> public int End { get => _end; set { Debug.Assert(value <= AvailableMemory.Length); _end = value; Memory = AvailableMemory.Slice(0, value); } } /// <summary> /// Reference to the next block of data when the overall "active" bytes spans multiple blocks. At the point when the block is /// leased Next is guaranteed to be null. Start, End, and Next are used together in order to create a linked-list of discontiguous /// working memory. The "active" memory is grown when bytes are copied in, End is increased, and Next is assigned. The "active" /// memory is shrunk when bytes are consumed, Start is increased, and blocks are returned to the pool. /// </summary> public BufferSegment? NextSegment { get => _next; set { Next = value; _next = value; } } public void SetOwnedMemory(IMemoryOwner<byte> memoryOwner) { _memoryOwner = memoryOwner; AvailableMemory = memoryOwner.Memory; } public void SetOwnedMemory(byte[] arrayPoolBuffer) { _memoryOwner = arrayPoolBuffer; AvailableMemory = arrayPoolBuffer; } public void ResetMemory() { Debug.Assert(_memoryOwner != null); if (_memoryOwner is IMemoryOwner<byte> owner) { owner.Dispose(); } else { byte[] poolArray = (byte[])_memoryOwner; ArrayPool<byte>.Shared.Return(poolArray); } // Order of below field clears is significant as it clears in a sequential order // https://github.com/dotnet/corefx/pull/35256#issuecomment-462800477 Next = null; RunningIndex = 0; Memory = default; _memoryOwner = null; _next = null; _end = 0; AvailableMemory = default; } // Exposed for testing internal object? MemoryOwner => _memoryOwner; public Memory<byte> AvailableMemory { get; private set; } public int Length => End; public int WritableBytes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => AvailableMemory.Length - End; } public void SetNext(BufferSegment segment) { Debug.Assert(segment != null); Debug.Assert(Next == null); 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; } }