// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Buffers; using System.Runtime.CompilerServices; namespace CommunityToolkit.HighPerformance.Streams; /// /// An implementation wrapping a of instance. /// internal readonly struct MemoryManagerOwner : ISpanOwner { /// /// The wrapped instance. /// private readonly MemoryManager memoryManager; /// /// The starting offset within . /// private readonly int offset; /// /// The usable length within . /// private readonly int length; /// /// Initializes a new instance of the struct. /// /// The wrapped instance. /// The starting offset within . /// The usable length within . public MemoryManagerOwner(MemoryManager memoryManager, int offset, int length) { this.memoryManager = memoryManager; this.offset = offset; this.length = length; } /// public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this.length; } /// public Span Span { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { // We can't use the same trick we use for arrays to optimize the creation of // the offset span, as otherwise a bugged MemoryManager instance returning // a span of an incorrect size could cause an access violation. Instead, we just // get the span and then slice it, which will validate both offset and length. return this.memoryManager.GetSpan().Slice(this.offset, this.length); } } }