// something other than an array and this is a MemoryStream-derived type that doesn't override Read(Span<byte>) will
// it then fall back to doing the ArrayPool/copy behavior.
return new ValueTask<int>(
- destination.TryGetArray(out ArraySegment<byte> destinationArray) ?
+ MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> destinationArray) ?
Read(destinationArray.Array, destinationArray.Offset, destinationArray.Count) :
Read(destination.Span));
}
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Buffers;
namespace System.IO
}
public virtual ValueTask<int> ReadAsync(Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) =>
- new ValueTask<int>(buffer.TryGetArray(out ArraySegment<char> array) ?
+ new ValueTask<int>(MemoryMarshal.TryGetArray(buffer, out ArraySegment<char> array) ?
ReadAsync(array.Array, array.Offset, array.Count) :
Task<int>.Factory.StartNew(state =>
{
}
public virtual ValueTask<int> ReadBlockAsync(Memory<char> buffer, CancellationToken cancellationToken = default(CancellationToken)) =>
- new ValueTask<int>(buffer.TryGetArray(out ArraySegment<char> array) ?
+ new ValueTask<int>(MemoryMarshal.TryGetArray(buffer, out ArraySegment<char> array) ?
ReadBlockAsync(array.Array, array.Offset, array.Count) :
Task<int>.Factory.StartNew(state =>
{
// something other than an array and this is an UnmanagedMemoryStream-derived type that doesn't override Read(Span<byte>) will
// it then fall back to doing the ArrayPool/copy behavior.
return new ValueTask<int>(
- destination.TryGetArray(out ArraySegment<byte> destinationArray) ?
+ MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> destinationArray) ?
Read(destinationArray.Array, destinationArray.Offset, destinationArray.Count) :
Read(destination.Span));
}
}
/// <summary>
- /// Get an array segment from the underlying memory.
- /// If unable to get the array segment, return false with a default array segment.
- /// </summary>
- public bool TryGetArray(out ArraySegment<T> arraySegment)
- {
- if (_index < 0)
- {
- if (((OwnedMemory<T>)_object).TryGetArray(out var segment))
- {
- arraySegment = new ArraySegment<T>(segment.Array, segment.Offset + (_index & RemoveOwnedFlagBitMask), _length);
- return true;
- }
- }
- else if (_object is T[] arr)
- {
- arraySegment = new ArraySegment<T>(arr, _index, _length);
- return true;
- }
-
- if (_length == 0)
- {
-#if FEATURE_PORTABLE_SPAN
- arraySegment = new ArraySegment<T>(SpanHelpers.PerTypeValues<T>.EmptyArray);
-#else
- arraySegment = ArraySegment<T>.Empty;
-#endif // FEATURE_PORTABLE_SPAN
- return true;
- }
-
- arraySegment = default(ArraySegment<T>);
- return false;
- }
-
- /// <summary>
/// Copies the contents from the memory into a new array. This heap
/// allocates, so should generally be avoided, however it is sometimes
/// necessary to bridge the gap with APIs written in terms of arrays.
}
if (typeof(T) == typeof(char) &&
- ((ReadOnlyMemory<char>)(object)_memory).TryGetString(out string text, out int start, out int length))
+ MemoryMarshal.TryGetString((ReadOnlyMemory<char>)(object)_memory, out string text, out int start, out int length))
{
return (T[])(object)text.Substring(start, length).ToCharArray();
}
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;
- }
- }
}
}
for (int i = 0; i < memory.Length; i++)
yield return memory.Span[i];
}
+
+ /// <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(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;
+ }
+ }
}
}
public virtual ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default(CancellationToken))
{
- if (destination.TryGetArray(out ArraySegment<byte> array))
+ if (MemoryMarshal.TryGetArray(destination, out ArraySegment<byte> array))
{
return new ValueTask<int>(ReadAsync(array.Array, array.Offset, array.Count, cancellationToken));
}