Move TryGetString to MemoryMarshal, remove TryGetArray and update tests

This commit is contained in:
ahsonkhan 2018-03-01 12:32:54 -08:00 коммит произвёл Jan Kotas
Родитель c26fd152c2
Коммит e31e796208
19 изменённых файлов: 99 добавлений и 192 удалений

Просмотреть файл

@ -4,6 +4,7 @@
using System.Buffers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace System.IO.Pipelines
@ -96,7 +97,7 @@ namespace System.IO.Pipelines
protected override bool TryGetArray(out ArraySegment<byte> arraySegment)
{
_pool.CheckDisposed();
return _ownedMemory.Memory.TryGetArray(out arraySegment);
return MemoryMarshal.TryGetArray(_ownedMemory.Memory, out arraySegment);
}
public override bool IsDisposed

Просмотреть файл

@ -206,7 +206,7 @@ namespace System.IO.Pipes
}
// Issue the asynchronous read.
return await (destination.TryGetArray(out ArraySegment<byte> buffer) ?
return await (MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> buffer) ?
socket.ReceiveAsync(buffer, SocketFlags.None) :
socket.ReceiveAsync(destination.ToArray(), SocketFlags.None)).ConfigureAwait(false);
}

Просмотреть файл

@ -94,7 +94,6 @@ namespace System
public static System.ReadOnlySpan<char> TrimStart(this System.ReadOnlySpan<char> span) { throw null; }
public static System.ReadOnlySpan<char> TrimStart(this System.ReadOnlySpan<char> span, char trimChar) { throw null; }
public static System.ReadOnlySpan<char> TrimStart(this System.ReadOnlySpan<char> span, System.ReadOnlySpan<char> trimChars) { throw null; }
public static bool TryGetString(this System.ReadOnlyMemory<char> readOnlyMemory, out string text, out int start, out int length) { throw null; }
}
public readonly partial struct Memory<T>
{
@ -119,7 +118,6 @@ namespace System
public System.Memory<T> Slice(int start, int length) { throw null; }
public T[] ToArray() { throw null; }
public bool TryCopyTo(System.Memory<T> destination) { throw null; }
public bool TryGetArray(out System.ArraySegment<T> arraySegment) { throw null; }
}
public readonly partial struct ReadOnlyMemory<T>
{
@ -531,6 +529,7 @@ namespace System.Runtime.InteropServices
where TOwner : System.Buffers.OwnedMemory<T> { throw null; }
public static bool TryGetOwnedMemory<T, TOwner>(ReadOnlyMemory<T> readOnlyMemory, out TOwner ownedMemory, out int index, out int length)
where TOwner : System.Buffers.OwnedMemory<T> { throw null; }
public static bool TryGetString(System.ReadOnlyMemory<char> readOnlyMemory, out string text, out int start, out int length) { throw null; }
}
public static partial class SequenceMarshal

Просмотреть файл

@ -132,9 +132,9 @@ namespace System.Buffers
}
else if (typeof(T) == typeof(char))
{
// TODO: MemoryMarshal.TryGetString -- doesn't exist?
// https://github.com/dotnet/corefx/issues/27451
MemoryExtensions.TryGetString(((ReadOnlyMemory<char>)(object)readOnlyMemory), out string text, out int start, out length);
if (!MemoryMarshal.TryGetString(((ReadOnlyMemory<char>)(object)readOnlyMemory), out string text, out int start, out length))
ThrowHelper.ThrowInvalidOperationException();
_sequenceStart = new SequencePosition(text, ReadOnlySequence.StringToSequenceStart(start));
_sequenceEnd = new SequencePosition(text, ReadOnlySequence.StringToSequenceEnd(start + length));
}

Просмотреть файл

@ -353,30 +353,6 @@ namespace System
return new ReadOnlyMemory<char>(text, start, length);
}
/// <summary>Attempts to get the underlying <see cref="string"/> from a <see cref="ReadOnlyMemory{T}"/>.</summary>
/// <param name="readOnlyMemory">The memory that may be wrapping a <see cref="string"/> object.</param>
/// <param name="text">The string.</param>
/// <param name="start">The starting location in <paramref name="text"/>.</param>
/// <param name="length">The number of items in <paramref name="text"/>.</param>
/// <returns></returns>
public static bool TryGetString(this ReadOnlyMemory<char> readOnlyMemory, out string text, out int start, out int length)
{
if (readOnlyMemory.GetObjectStartLength(out int offset, out int count) is string s)
{
text = s;
start = offset;
length = count;
return true;
}
else
{
text = null;
start = 0;
length = 0;
return false;
}
}
internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();
private static IntPtr MeasureStringAdjustment()

Просмотреть файл

@ -1,84 +0,0 @@
// 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 Xunit;
namespace System.MemoryTests
{
public static partial class MemoryTests
{
[Fact]
public static void MemoryTryGetArray()
{
int[] array = new int[10];
Memory<int> memory = array;
Assert.True(memory.TryGetArray(out ArraySegment<int> segment));
Assert.Equal(array.Length, segment.Count);
for (int i = segment.Offset; i < segment.Count + segment.Offset; i++)
{
Assert.Equal(array[i], segment.Array[i]);
}
}
[Fact]
public static void TryGetArrayFromDefaultMemory()
{
Memory<int> memory = default;
Assert.True(memory.TryGetArray(out ArraySegment<int> segment));
Assert.Equal(0, segment.Array.Length);
}
[Fact]
public static void OwnedMemoryTryGetArray()
{
int[] array = new int[10];
OwnedMemory<int> owner = new CustomMemoryForTest<int>(array);
Memory<int> memory = owner.Memory;
Assert.True(memory.TryGetArray(out ArraySegment<int> segment));
Assert.Equal(array.Length, segment.Count);
for (int i = segment.Offset; i < segment.Count + segment.Offset; i++)
{
Assert.Equal(array[i], segment.Array[i]);
}
}
[Fact]
public static void TryGetArrayFromEmptyMemory()
{
int[] array = new int[0];
Memory<int> memory = array;
Assert.True(memory.TryGetArray(out ArraySegment<int> segment));
Assert.Same(array, segment.Array);
Assert.Equal(0, segment.Array.Length);
Assert.True(Memory<byte>.Empty.TryGetArray(out ArraySegment<byte> byteSegment));
Assert.Equal(0, byteSegment.Array.Length);
}
[Fact]
public static void TryGetArrayFromEmptyOwnedMemory()
{
int[] array = new int[0];
OwnedMemory<int> owner = new CustomMemoryForTest<int>(array);
Assert.True(owner.Memory.TryGetArray(out ArraySegment<int> segment));
Assert.Same(array, segment.Array);
Assert.Equal(0, segment.Array.Length);
}
[Fact]
public static void TryGetArrayFromEmptyNonRetrievableOwnedMemory()
{
using (var owner = new NativeOwnedMemory(0))
{
Assert.True(owner.Memory.TryGetArray(out ArraySegment<byte> segment));
Assert.Equal(0, segment.Array.Length);
}
}
}
}

Просмотреть файл

@ -55,14 +55,14 @@ namespace System.MemoryTests
ReadOnlyMemory<char> readOnlyClone = memory;
// TryGetString
bool gotString1 = readOnlyMemory.TryGetString(out string text1, out int start1, out int length1);
Assert.Equal(gotString1, readOnlyClone.TryGetString(out string text2, out int start2, out int length2));
bool gotString1 = MemoryMarshal.TryGetString(readOnlyMemory, out string text1, out int start1, out int length1);
Assert.Equal(gotString1, MemoryMarshal.TryGetString(readOnlyClone, out string text2, out int start2, out int length2));
Assert.Same(text1, text2);
Assert.Equal(start1, start2);
Assert.Equal(length1, length2);
if (gotString1)
{
Assert.False(memory.TryGetArray(out ArraySegment<char> array));
Assert.False(MemoryMarshal.TryGetArray(memory, out ArraySegment<char> array));
}
}
@ -81,7 +81,8 @@ namespace System.MemoryTests
Assert.True(readOnlyMemory.Span == memory.Span);
// TryGetArray
Assert.True(MemoryMarshal.TryGetArray(readOnlyMemory, out ArraySegment<T> array1) == memory.TryGetArray(out ArraySegment<T> array2));
Assert.True(MemoryMarshal.TryGetArray(readOnlyMemory, out ArraySegment<T> array1)
== MemoryMarshal.TryGetArray(memory, out ArraySegment<T> array2));
Assert.Same(array1.Array, array2.Array);
Assert.Equal(array1.Offset, array2.Offset);
Assert.Equal(array1.Count, array2.Count);

Просмотреть файл

@ -0,0 +1,73 @@
// 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 Xunit;
using System.Runtime.InteropServices;
namespace System.MemoryTests
{
public static partial class MemoryMarshalTests
{
[Fact]
public static void ReadOnlyMemory_TryGetString_Roundtrips()
{
string input = "0123456789";
ReadOnlyMemory<char> m = input.AsMemory();
Assert.False(m.IsEmpty);
Assert.True(MemoryMarshal.TryGetString(m, out string text, out int start, out int length));
Assert.Same(input, text);
Assert.Equal(0, start);
Assert.Equal(input.Length, length);
m = m.Slice(1);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(1, start);
Assert.Equal(input.Length - 1, length);
m = m.Slice(1);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(2, start);
Assert.Equal(input.Length - 2, length);
m = m.Slice(3, 2);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(5, start);
Assert.Equal(2, length);
m = m.Slice(m.Length);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
m = m.Slice(0);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
m = m.Slice(0, 0);
Assert.True(MemoryMarshal.TryGetString(m, out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
Assert.True(m.IsEmpty);
}
[Fact]
public static void Array_TryGetString_ReturnsFalse()
{
ReadOnlyMemory<char> m = new char[10];
Assert.False(MemoryMarshal.TryGetString(m, out string text, out int start, out int length));
Assert.Null(text);
Assert.Equal(0, start);
Assert.Equal(0, length);
}
}
}

Просмотреть файл

@ -213,7 +213,7 @@ namespace System.MemoryTests
using (OwnedMemory<int> block = MemoryPool<int>.Shared.Rent(42))
{
Memory<int> memory = block.Memory;
bool success = memory.TryGetArray(out ArraySegment<int> arraySegment);
bool success = MemoryMarshal.TryGetArray(memory, out ArraySegment<int> arraySegment);
Assert.True(success);
Assert.Equal(block.Length, arraySegment.Count);
unsafe
@ -307,7 +307,7 @@ namespace System.MemoryTests
OwnedMemory<int> block = MemoryPool<int>.Shared.Rent(42);
Memory<int> memory = block.Memory;
block.Dispose();
Assert.Throws<ObjectDisposedException>(() => memory.TryGetArray(out ArraySegment<int> arraySegment));
Assert.Throws<ObjectDisposedException>(() => MemoryMarshal.TryGetArray(memory, out ArraySegment<int> arraySegment));
}
}
}

Просмотреть файл

@ -83,67 +83,6 @@ namespace System.MemoryTests
Assert.Throws<ArgumentOutOfRangeException>(() => str.AsMemory(-1, -1));
}
[Fact]
public static void AsReadOnlyMemory_TryGetString_Roundtrips()
{
string input = "0123456789";
ReadOnlyMemory<char> m = input.AsMemory();
Assert.False(m.IsEmpty);
Assert.True(m.TryGetString(out string text, out int start, out int length));
Assert.Same(input, text);
Assert.Equal(0, start);
Assert.Equal(input.Length, length);
m = m.Slice(1);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(1, start);
Assert.Equal(input.Length - 1, length);
m = m.Slice(1);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(2, start);
Assert.Equal(input.Length - 2, length);
m = m.Slice(3, 2);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(5, start);
Assert.Equal(2, length);
m = m.Slice(m.Length);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
m = m.Slice(0);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
m = m.Slice(0, 0);
Assert.True(m.TryGetString(out text, out start, out length));
Assert.Same(input, text);
Assert.Equal(7, start);
Assert.Equal(0, length);
Assert.True(m.IsEmpty);
}
[Fact]
public static void Array_TryGetString_ReturnsFalse()
{
ReadOnlyMemory<char> m = new char[10];
Assert.False(m.TryGetString(out string text, out int start, out int length));
Assert.Null(text);
Assert.Equal(0, start);
Assert.Equal(0, length);
}
[Fact]
public static void AsReadOnlyMemory_TryGetArray_ReturnsFalse()
{

Просмотреть файл

@ -149,7 +149,6 @@
<Compile Include="Memory\Span.cs" />
<Compile Include="Memory\Strings.cs" />
<Compile Include="Memory\ToArray.cs" />
<Compile Include="Memory\TryGetArray.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="MemoryMarshal\AsMemory.cs" />
@ -158,6 +157,7 @@
<Compile Include="MemoryMarshal\GetReference.cs" />
<Compile Include="MemoryMarshal\TryGetArray.cs" />
<Compile Include="MemoryMarshal\TryGetOwnedMemory.cs" />
<Compile Include="MemoryMarshal\TryGetString.cs" />
<Compile Include="MemoryMarshal\ToEnumerable.cs" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -5,6 +5,7 @@
using System.Diagnostics.Tracing;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Net
{
@ -106,7 +107,7 @@ namespace System.Net
}
buffer = buffer.Slice(offset, Math.Min(count, MaxDumpSize));
byte[] slice = buffer.TryGetArray(out ArraySegment<byte> arraySegment) && arraySegment.Offset == 0 && arraySegment.Count == buffer.Length ?
byte[] slice = MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> arraySegment) && arraySegment.Offset == 0 && arraySegment.Count == buffer.Length ?
arraySegment.Array :
buffer.ToArray();

Просмотреть файл

@ -214,7 +214,7 @@ namespace System.Net.Sockets
/// <summary>Implements Task-returning ReceiveAsync on top of Begin/EndReceive.</summary>
private Task<int> ReceiveAsyncApm(Memory<byte> buffer, SocketFlags socketFlags)
{
if (buffer.TryGetArray(out ArraySegment<byte> bufferArray))
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> bufferArray))
{
// We were able to extract the underlying byte[] from the Memory<byte>. Use it.
var tcs = new TaskCompletionSource<int>(this);

Просмотреть файл

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace System.Net.Sockets
@ -106,7 +107,7 @@ namespace System.Net.Sockets
{
if (_bufferIsExplicitArray)
{
bool success = _buffer.TryGetArray(out ArraySegment<byte> arraySegment);
bool success = MemoryMarshal.TryGetArray(_buffer, out ArraySegment<byte> arraySegment);
Debug.Assert(success);
return arraySegment.Array;
}

Просмотреть файл

@ -4,6 +4,7 @@
using System.Buffers;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Xunit;
namespace System.Net.Sockets.Tests
@ -48,7 +49,7 @@ namespace System.Net.Sockets.Tests
byte[] array = new byte[42];
saea.SetBuffer(array, 0, array.Length);
Assert.True(saea.MemoryBuffer.TryGetArray(out ArraySegment<byte> result));
Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out ArraySegment<byte> result));
Assert.Same(array, result.Array);
Assert.Same(saea.Buffer, array);
Assert.Equal(0, result.Offset);
@ -59,7 +60,7 @@ namespace System.Net.Sockets.Tests
Assert.Equal(1, saea.Offset);
Assert.Equal(2, saea.Count);
Assert.True(saea.MemoryBuffer.TryGetArray(out result));
Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out result));
Assert.Same(array, result.Array);
Assert.Equal(0, result.Offset);
Assert.Equal(array.Length, result.Count);

Просмотреть файл

@ -25,7 +25,7 @@ namespace System.Net.WebSockets
internal static ValueTask<int> ReadAsync(this Stream stream, Memory<byte> destination, CancellationToken cancellationToken = default)
{
if (destination.TryGetArray(out ArraySegment<byte> array))
if (MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> array))
{
return new ValueTask<int>(stream.ReadAsync(array.Array, array.Offset, array.Count, cancellationToken));
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace System.Net.WebSockets
public virtual async ValueTask<ValueWebSocketReceiveResult> ReceiveAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
if (buffer.TryGetArray(out ArraySegment<byte> arraySegment))
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> arraySegment))
{
WebSocketReceiveResult r = await ReceiveAsync(arraySegment, cancellationToken).ConfigureAwait(false);
return new ValueWebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage);

Просмотреть файл

@ -138,7 +138,7 @@ namespace System.IO
n = buffer.Length;
}
_s.AsReadOnlySpan().Slice(_pos, n).CopyTo(buffer);
_s.AsSpan().Slice(_pos, n).CopyTo(buffer);
_pos += n;
}

Просмотреть файл

@ -1705,7 +1705,6 @@ namespace System
public System.Memory<T> Slice(int start, int length) { throw null; }
public T[] ToArray() { throw null; }
public bool TryCopyTo(System.Memory<T> destination) { throw null; }
public bool TryGetArray(out System.ArraySegment<T> arraySegment) { throw null; }
}
public partial class MethodAccessException : System.MemberAccessException
{