Example #1
0
        public override Task WriteAsync(ReadOnlyMemory <byte> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled(cancellationToken));
            }

            try
            {
                // See corresponding comment in ReadAsync for why we don't just always use Write(ReadOnlySpan<byte>).
                // Unlike ReadAsync, we could delegate to WriteAsync(byte[], ...) here, but we don't for consistency.
                if (source.DangerousTryGetArray(out ArraySegment <byte> sourceArray))
                {
                    Write(sourceArray.Array, sourceArray.Offset, sourceArray.Count);
                }
                else
                {
                    Write(source.Span);
                }
                return(Task.CompletedTask);
            }
            catch (OperationCanceledException oce)
            {
                return(Task.FromCancellation <VoidTaskResult>(oce));
            }
            catch (Exception exception)
            {
                return(Task.FromException(exception));
            }
        }
Example #2
0
        public virtual Task WriteAsync(ReadOnlyMemory <byte> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (source.DangerousTryGetArray(out ArraySegment <byte> array))
            {
                return(WriteAsync(array.Array, array.Offset, array.Count, cancellationToken));
            }
            else
            {
                byte[] buffer = ArrayPool <byte> .Shared.Rent(source.Length);

                source.Span.CopyTo(buffer);
                return(FinishWriteAsync(WriteAsync(buffer, 0, source.Length, cancellationToken), buffer));

                async Task FinishWriteAsync(Task writeTask, byte[] localBuffer)
                {
                    try
                    {
                        await writeTask.ConfigureAwait(false);
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(localBuffer);
                    }
                }
            }
        }
Example #3
0
        private static unsafe void AsMemory_Roundtrips_Core <T>(ReadOnlyMemory <T> readOnlyMemory)
        {
            Memory <T>         memory        = MemoryMarshal.AsMemory(readOnlyMemory);
            ReadOnlyMemory <T> readOnlyClone = memory;

            // Equals
            Assert.True(readOnlyMemory.Equals(readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)memory));

            // Span
            Assert.True(readOnlyMemory.Span == readOnlyClone.Span);
            Assert.True(readOnlyMemory.Span == memory.Span);

            // TryGetArray
            Assert.True(readOnlyMemory.DangerousTryGetArray(out ArraySegment <T> array1) == memory.TryGetArray(out ArraySegment <T> array2));
            Assert.Same(array1.Array, array2.Array);
            Assert.Equal(array1.Offset, array2.Offset);
            Assert.Equal(array1.Count, array2.Count);

            // Retain
            using (MemoryHandle readOnlyMemoryHandle = readOnlyMemory.Retain())
                using (MemoryHandle readOnlyCloneHandle = readOnlyMemory.Retain())
                    using (MemoryHandle memoryHandle = readOnlyMemory.Retain())
                    {
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)readOnlyCloneHandle.Pointer);
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)memoryHandle.Pointer);
                    }
        }
Example #4
0
 public virtual Task WriteLineAsync(ReadOnlyMemory <char> source, CancellationToken cancellationToken = default(CancellationToken)) =>
 source.DangerousTryGetArray(out ArraySegment <char> array) ?
 WriteLineAsync(array.Array, array.Offset, array.Count) :
 Task.Factory.StartNew(state =>
 {
     var t = (Tuple <TextWriter, ReadOnlyMemory <char> >)state;
     t.Item1.WriteLine(t.Item2.Span);
 }, Tuple.Create(this, source), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
Example #5
0
        public static void AsReadOnlyMemory_TryGetArray_ReturnsFalse()
        {
            ReadOnlyMemory <char> m = "0123456789".AsReadOnlyMemory();

            Assert.False(m.DangerousTryGetArray(out ArraySegment <char> array));
            Assert.Null(array.Array);
            Assert.Equal(0, array.Offset);
            Assert.Equal(0, array.Count);
        }
Example #6
0
 public ReadOnlyMemoryContent(ReadOnlyMemory <byte> content)
 {
     _content = content;
     if (content.DangerousTryGetArray(out ArraySegment <byte> array))
     {
         // If we have an array, allow HttpClient to take optimized paths by just
         // giving it the array content to use as its already buffered data.
         SetBuffer(array.Array, array.Offset, array.Count);
     }
 }
        public static void MemoryDangerousTryGetArray()
        {
            int[] array = new int[10];
            ReadOnlyMemory <int> memory = array;

            Assert.True(memory.DangerousTryGetArray(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]);
            }
        }
        public static void OwnedMemoryTryGetArray()
        {
            int[]                array  = new int[10];
            OwnedMemory <int>    owner  = new CustomMemoryForTest <int>(array);
            ReadOnlyMemory <int> memory = owner.AsMemory;

            Assert.True(memory.DangerousTryGetArray(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]);
            }
        }
Example #9
0
        public override async Task WriteAsync(ReadOnlyMemory <byte> source, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            // See corresponding comment in ReadAsync for why we don't just always use Write(ReadOnlySpan<byte>).
            // Unlike ReadAsync, we could delegate to WriteAsync(byte[], ...) here, but we don't for consistency.
            if (source.DangerousTryGetArray(out ArraySegment <byte> sourceArray))
            {
                Write(sourceArray.Array, sourceArray.Offset, sourceArray.Count);
            }
            else
            {
                Write(source.Span);
            }
        }
Example #10
0
        private async Task WriteAsyncCore(ReadOnlyMemory <byte> source, CancellationToken cancellationToken)
        {
            Debug.Assert(this is NamedPipeClientStream || this is NamedPipeServerStream, $"Expected a named pipe, got a {GetType()}");
            try
            {
                // TODO #22608: Remove this terribly inefficient special-case once Socket.SendAsync
                // accepts a Memory<T> in the near future.
                byte[] buffer;
                int    offset, count;
                if (source.DangerousTryGetArray(out ArraySegment <byte> segment))
                {
                    buffer = segment.Array;
                    offset = segment.Offset;
                    count  = segment.Count;
                }
                else
                {
                    buffer = source.ToArray();
                    offset = 0;
                    count  = buffer.Length;
                }

                while (count > 0)
                {
                    // cancellationToken is (mostly) ignored.  We could institute a polling loop like we do for reads if
                    // cancellationToken.CanBeCanceled, but that adds costs regardless of whether the operation will be canceled, and
                    // most writes will complete immediately as they simply store data into the socket's buffer.  The only time we end
                    // up using it in a meaningful way is if a write completes partially, we'll check it on each individual write operation.
                    cancellationToken.ThrowIfCancellationRequested();

                    int bytesWritten = await _handle.NamedPipeSocket.SendAsync(new ArraySegment <byte>(buffer, offset, count), SocketFlags.None).ConfigureAwait(false);

                    Debug.Assert(bytesWritten <= count);

                    count  -= bytesWritten;
                    offset += bytesWritten;
                }
            }
            catch (SocketException e)
            {
                throw GetIOExceptionForSocketException(e);
            }
        }
Example #11
0
        /// <summary>Implements Task-returning SendAsync on top of Begin/EndSend.</summary>
        private Task <int> SendAsyncApm(ReadOnlyMemory <byte> buffer, SocketFlags socketFlags)
        {
            if (buffer.DangerousTryGetArray(out ArraySegment <byte> bufferArray))
            {
                var tcs = new TaskCompletionSource <int>(this);
                BeginSend(bufferArray.Array, bufferArray.Offset, bufferArray.Count, socketFlags, iar =>
                {
                    var innerTcs = (TaskCompletionSource <int>)iar.AsyncState;
                    try { innerTcs.TrySetResult(((Socket)innerTcs.Task.AsyncState).EndSend(iar)); }
                    catch (Exception e) { innerTcs.TrySetException(e); }
                }, tcs);
                return(tcs.Task);
            }
            else
            {
                // We weren't able to extract an underlying byte[] from the Memory<byte>.
                // Instead read into an ArrayPool array, then copy from that into the memory.
                byte[] poolArray = ArrayPool <byte> .Shared.Rent(buffer.Length);

                buffer.Span.CopyTo(poolArray);
                var tcs = new TaskCompletionSource <int>(this);
                BeginSend(poolArray, 0, buffer.Length, socketFlags, iar =>
                {
                    var state = (Tuple <TaskCompletionSource <int>, byte[]>)iar.AsyncState;
                    try
                    {
                        state.Item1.TrySetResult(((Socket)state.Item1.Task.AsyncState).EndSend(iar));
                    }
                    catch (Exception e)
                    {
                        state.Item1.TrySetException(e);
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(state.Item2);
                    }
                }, Tuple.Create(tcs, poolArray));
                return(tcs.Task);
            }
        }
Example #12
0
        public static void TryGetArrayFromDefaultMemory()
        {
            ReadOnlyMemory <int> memory = default;

            Assert.False(memory.DangerousTryGetArray(out ArraySegment <int> segment));
            Assert.True(segment.Equals(default));
Example #13
0
            private MemoryHandle _handle; // mutable struct; do not make this readonly

            internal MemoryFileStreamCompletionSource(FileStream stream, int numBufferedBytes, ReadOnlyMemory <byte> memory) :
                base(stream, numBufferedBytes, bytes: null) // this type handles the pinning, so null is passed for bytes
            {
                Debug.Assert(!memory.DangerousTryGetArray(out ArraySegment <byte> array), "The base should be used directly if we can get the array.");
                _handle = memory.Retain(pin: true);
            }
Example #14
0
 public virtual Task SendAsync(ReadOnlyMemory <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
 buffer.DangerousTryGetArray(out ArraySegment <byte> arraySegment) ?
 SendAsync(arraySegment, messageType, endOfMessage, cancellationToken) :
 SendWithArrayPoolAsync(buffer, messageType, endOfMessage, cancellationToken);