diff --git a/src/System.Memory/ref/System.Memory.cs b/src/System.Memory/ref/System.Memory.cs index c990e3920343..39022a6d6546 100644 --- a/src/System.Memory/ref/System.Memory.cs +++ b/src/System.Memory/ref/System.Memory.cs @@ -507,5 +507,9 @@ public static partial class MemoryMarshal public static ref T GetReference(System.Span span) { throw null; } public static System.Collections.Generic.IEnumerable ToEnumerable(System.ReadOnlyMemory memory) { throw null; } public static bool TryGetArray(System.ReadOnlyMemory readOnlyMemory, out System.ArraySegment arraySegment) { throw null; } + public static bool TryGetOwnedMemory(ReadOnlyMemory readOnlyMemory, out TOwner ownedMemory) + where TOwner : System.Buffers.OwnedMemory { throw null; } + public static bool TryGetOwnedMemory(ReadOnlyMemory readOnlyMemory, out TOwner ownedMemory, out int index, out int length) + where TOwner : System.Buffers.OwnedMemory { throw null; } } } diff --git a/src/System.Memory/tests/MemoryMarshal/TryGetOwnedMemory.cs b/src/System.Memory/tests/MemoryMarshal/TryGetOwnedMemory.cs new file mode 100644 index 000000000000..f90db1042621 --- /dev/null +++ b/src/System.Memory/tests/MemoryMarshal/TryGetOwnedMemory.cs @@ -0,0 +1,93 @@ +// 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.Buffers; +using System.Runtime.InteropServices; +using Xunit; + +namespace System.MemoryTests +{ + public static partial class MemoryMarshalTests + { + [Fact] + public static void TryGetOwnedMemoryFromDefaultMemory() + { + ReadOnlyMemory memory = default; + Assert.False(MemoryMarshal.TryGetOwnedMemory(memory, out OwnedMemory owner)); + Assert.Null(owner); + } + + [Fact] + public static void TryGetOwnedMemory() + { + int[] array = new int[10]; + OwnedMemory orignalOwner = new CustomMemoryForTest(array); + ReadOnlyMemory memory = orignalOwner.Memory; + + Assert.True(MemoryMarshal.TryGetOwnedMemory(memory, out CustomMemoryForTest customOwner)); + Assert.Same(orignalOwner, customOwner); + + Assert.True(MemoryMarshal.TryGetOwnedMemory(memory, out OwnedMemory owner)); + Assert.Same(orignalOwner, owner); + + Assert.False(MemoryMarshal.TryGetOwnedMemory(memory, out OtherMemoryForTest notOwner)); + Assert.Null(notOwner); + } + + [Fact] + public static void TryGetOwnedMemoryFromDefaultMemory_IndexLength() + { + ReadOnlyMemory memory = default; + Assert.False(MemoryMarshal.TryGetOwnedMemory(memory, out OwnedMemory owner, out int index, out int length)); + Assert.Equal(0, index); + Assert.Equal(0, length); + Assert.Null(owner); + } + + [Fact] + public static void TryGetOwnedMemory_IndexLength() + { + int[] array = new int[10]; + OwnedMemory orignalOwner = new CustomMemoryForTest(array); + ReadOnlyMemory memory = orignalOwner.Memory; + + for (int i = 0; i < array.Length; i++) + { + Assert.True(MemoryMarshal.TryGetOwnedMemory(memory.Slice(i), out CustomMemoryForTest customOwner, out int index, out int length)); + Assert.Same(orignalOwner, customOwner); + Assert.Equal(i, index); + Assert.Equal(array.Length - i, length); + } + + for (int i = 0; i < array.Length; i++) + { + Assert.True(MemoryMarshal.TryGetOwnedMemory(memory.Slice(i), out OwnedMemory owner, out int index, out int length)); + Assert.Same(orignalOwner, owner); + Assert.Equal(i, index); + Assert.Equal(array.Length - i, length); + } + + for (int i = 0; i < array.Length; i++) + { + Assert.False(MemoryMarshal.TryGetOwnedMemory(memory.Slice(i), out OtherMemoryForTest notOwner, out int index, out int length)); + Assert.Null(notOwner); + } + } + + internal class OtherMemoryForTest : OwnedMemory + { + public OtherMemoryForTest() { } + + public override int Length => 0; + public override bool IsDisposed => false; + protected override bool IsRetained => false; + public override Span Span => throw new NotImplementedException(); + public override MemoryHandle Pin(int byteOffset = 0) => throw new NotImplementedException(); + protected override bool TryGetArray(out ArraySegment arraySegment) => throw new NotImplementedException(); + protected override void Dispose(bool disposing) => throw new NotImplementedException(); + public override void Retain() => throw new NotImplementedException(); + public override bool Release() => throw new NotImplementedException(); + } + } +} diff --git a/src/System.Memory/tests/System.Memory.Tests.csproj b/src/System.Memory/tests/System.Memory.Tests.csproj index 8da6d9087366..4c273429edc7 100644 --- a/src/System.Memory/tests/System.Memory.Tests.csproj +++ b/src/System.Memory/tests/System.Memory.Tests.csproj @@ -148,6 +148,7 @@ +