public async Task BufferingDataPastEndOfStreamCanBeReadAgain()
        {
            var        helloBytes = Encoding.ASCII.GetBytes("Hello World");
            var        stream     = new ThrowAfterZeroByteReadStream(helloBytes);
            PipeReader reader     = PipeReader.Create(stream);


            ReadResult readResult = await reader.ReadAsync();

            ReadOnlySequence <byte> buffer = readResult.Buffer;

            reader.AdvanceTo(buffer.Start, buffer.End);

            // Make sure IsCompleted is true
            readResult = await reader.ReadAsync();

            buffer = readResult.Buffer;
            reader.AdvanceTo(buffer.Start, buffer.End);
            Assert.True(readResult.IsCompleted);

            var value = await ReadFromPipeAsString(reader);

            Assert.Equal("Hello World", value);
            reader.Complete();
        }
        public async Task CompleteReaderWithoutAdvanceDoesNotThrow()
        {
            PipeReader reader = PipeReader.Create(Stream.Null);
            await reader.ReadAsync();

            reader.Complete();
        }
Beispiel #3
0
        public override void Complete(Exception?exception = null)
        {
            _inner.Complete(exception);

            _currentInnerBuffer   = ReadOnlySequence <byte> .Empty;
            _currentDecodedBuffer = ReadOnlySequence <byte> .Empty;
        }
Beispiel #4
0
        private async Task SendLoop()
        {
            Exception exception = null;

            try
            {
                while (true)
                {
                    var result = await reader.ReadAsync().ConfigureAwait(false);

                    if (result.IsCanceled)
                    {
                        break;
                    }

                    var buffer = result.Buffer;

                    await SendAsync(buffer).ConfigureAwait(false);

                    reader.AdvanceTo(buffer.End);

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            reader.Complete(exception);
        }
Beispiel #5
0
        /// <summary>
        /// Read from pipe asynchronously and write to file asynchronously.
        /// </summary>
        /// <returns>
        /// Asynchronous task.
        /// </returns>
        /// <param name="writer">Pipe reader.</param>
        /// <param name="cancellationToken">Token for cancellation.</param>
        private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken = default)
        {
            using (Stream fileStream = new FileStream(TempFilePath, FileMode.Append, FileAccess.Write))
            {
                fileStream.Seek(fileStream.Length, SeekOrigin.Begin);

                while (true)
                {
                    var ReadResult = await reader.ReadAsync(cancellationToken);

                    foreach (var buffer in ReadResult.Buffer)
                    {
                        await fileStream.WriteAsync(buffer, cancellationToken);
                    }

                    reader.AdvanceTo(ReadResult.Buffer.End);

                    if (ReadResult.IsCompleted || ReadResult.IsCanceled)
                    {
                        break;
                    }
                }
            }

            reader.Complete();
        }
Beispiel #6
0
        private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken = default)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var result = await reader.ReadAsync(cancellationToken);

                var buffer = result.Buffer;
                SequencePosition?position;
                do
                {
                    position = buffer.PositionOf((byte)0);

                    if (position != null)
                    {
                        OnMessageReceived(MessageSerializer.DeserializeMessage(buffer.Slice(0, position.Value)));
                        buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
                    }
                } while (position != null);

                reader.AdvanceTo(buffer.Start, buffer.End);

                if (result.IsCompleted)
                {
                    break;
                }
            }

            reader.Complete();
        }
        public async Task DataCanBeReadMultipleTimes()
        {
            var        helloBytes = Encoding.ASCII.GetBytes("Hello World");
            var        sequence   = new ReadOnlySequence <byte>(helloBytes);
            PipeReader reader     = PipeReader.Create(sequence);


            ReadResult readResult = await reader.ReadAsync();

            ReadOnlySequence <byte> buffer = readResult.Buffer;

            reader.AdvanceTo(buffer.Start, buffer.End);

            // Make sure IsCompleted is true
            readResult = await reader.ReadAsync();

            buffer = readResult.Buffer;
            reader.AdvanceTo(buffer.Start, buffer.End);
            Assert.True(readResult.IsCompleted);

            var value = await ReadFromPipeAsString(reader);

            Assert.Equal("Hello World", value);
            reader.Complete();
        }
        public async Task CompletingReturnsUnconsumedMemoryToPool()
        {
            using (var pool = new DisposeTrackingBufferPool())
            {
                var options = new StreamPipeReaderOptions(pool: pool, bufferSize: 4096, minimumReadSize: 1024);
                // 2 full segments
                var        stream = new MemoryStream(new byte[options.BufferSize * 3]);
                PipeReader reader = PipeReader.Create(stream, options);

                while (true)
                {
                    ReadResult readResult = await reader.ReadAsync();

                    reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);

                    if (readResult.IsCompleted)
                    {
                        break;
                    }
                }

                Assert.Equal(4, pool.CurrentlyRentedBlocks);
                reader.Complete();
                Assert.Equal(0, pool.CurrentlyRentedBlocks);
                Assert.Equal(4, pool.DisposedBlocks);
            }
        }
        public async Task CompleteReaderWithoutAdvanceDoesNotThrow()
        {
            PipeReader reader = PipeReader.Create(ReadOnlySequence <byte> .Empty);
            await reader.ReadAsync();

            reader.Complete();
        }
        public async Task ThrowsOnReadAfterCompleteReader()
        {
            PipeReader reader = PipeReader.Create(ReadOnlySequence <byte> .Empty);

            reader.Complete();
            await Assert.ThrowsAsync <InvalidOperationException>(async() => await reader.ReadAsync());
        }
Beispiel #11
0
        private async Task ReadPipeAsync(PipeReader reader, CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var result = await reader.ReadAsync(cancellationToken);


                ReadOnlySequence <byte> buffer = result.Buffer;
                bool canParse = false;
                do
                {
                    canParse = _parser.CanParse(buffer);
                    if (canParse)
                    {
                        ParseResult messageParsed = await _parser.ParseAsync(buffer);

                        _whenMessageParsed.OnNext(messageParsed.CleanMessage);
                        buffer = buffer.Slice(buffer.GetPosition(1, messageParsed.EndPosition));
                    }
                }while (canParse);
                reader.AdvanceTo(buffer.Start, buffer.End);

                if (result.IsCompleted)
                {
                    break;
                }
            }
            reader.Complete();
        }
Beispiel #12
0
        public async Task ReadPipeAsync(PipeReader reader, IParserRequestHandler handler)
        {
            while (true)
            {
                var result = await reader.ReadAsync();

                var buffer = result.Buffer;
                SequencePosition?position = null;
                do
                {
                    position = buffer.PositionOf((byte)'\n');
                    if (position != null)
                    {
                        var sequence = buffer.Slice(0, position.Value);
                        Logger.Debug("Parsing request...");
                        Parser.ParseRequestLine(handler, sequence, out var consumed, out var examined);
                        buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
                    }
                }while (position != null);
                reader.AdvanceTo(buffer.Start, buffer.End);
                if (result.IsCompleted)
                {
                    break;
                }
            }
            reader.Complete();
        }
        public static async Task Echo(PipeReader input, PipeWriter output, ConnectionContext connection)
        {
            try
            {
                while (true)
                {
                    var result = await input.ReadAsync();

                    var request = result.Buffer;

                    if (request.IsEmpty && result.IsCompleted)
                    {
                        input.AdvanceTo(request.End);
                        break;
                    }

                    foreach (var memory in request)
                    {
                        output.Write(memory.Span);
                    }
                    await output.FlushAsync();

                    input.AdvanceTo(request.End);
                }
            }
            catch
            { }
            finally
            {
                input.Complete();
                output.Complete();
            }
        }
Beispiel #14
0
        static async Task ReadFromPipe(PipeReader reader, Action <ReadOnlySequence <byte> > operation)
        {
            while (true)
            {
                var readResult = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer   = readResult.Buffer;
                SequencePosition?       position = null;
                do
                {
                    position = buffer.PositionOf((byte)'\n');
                    if (position != null)
                    {
                        var line = buffer.Slice(0, position.Value);
                        operation?.Invoke(line);
                        var next = buffer.GetPosition(1, position.Value); //等价于popstion+1因为需要包含'\n';
                        buffer = buffer.Slice(next);                      //跳过已经读取的数据;
                    }
                }while (position != null);
                //指示PipeReader已经消费了多少数据
                reader.AdvanceTo(buffer.Start, buffer.End);
                if (readResult.IsCompleted)
                {
                    break;
                }
            }
            reader.Complete();
        }
Beispiel #15
0
        protected async Task ReadPipeAsync(PipeReader reader)
        {
            while (true)
            {
                var result = await reader.ReadAsync();

                var buffer = result.Buffer;

                SequencePosition consumed = buffer.Start;
                SequencePosition examined = buffer.End;

                try
                {
                    if (result.IsCompleted)
                    {
                        break;
                    }

                    ReaderBuffer(result, out consumed, out examined);
                }
                finally
                {
                    reader.AdvanceTo(consumed, examined);
                }
            }

            reader.Complete();
        }
        public async Task ConsumePartialBufferWorks()
        {
            // We're using the pipe here as a way to pump bytes into the reader asynchronously
            var        pipe   = new Pipe();
            PipeReader reader = PipeReader.Create(pipe.Reader.AsStream());

            pipe.Writer.WriteEmpty(10);
            await pipe.Writer.FlushAsync();

            ReadResult readResult = await reader.ReadAsync();

            Assert.Equal(10, readResult.Buffer.Length);
            reader.AdvanceTo(readResult.Buffer.GetPosition(4), readResult.Buffer.End);

            pipe.Writer.WriteEmpty(2);
            await pipe.Writer.FlushAsync();

            readResult = await reader.ReadAsync();

            // 6 bytes left over plus 2 newly written bytes
            Assert.Equal(8, readResult.Buffer.Length);
            reader.AdvanceTo(readResult.Buffer.End);

            reader.Complete();

            pipe.Writer.Complete();
            pipe.Reader.Complete();
        }
Beispiel #17
0
        private async Task ReadPipeAsync(Socket socket, PipeReader reader)
        {
            while (true)
            {
                ReadResult result = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer   = result.Buffer;
                SequencePosition        consumed = buffer.Start;
                SequencePosition        examined = buffer.End;
                if (result.IsCanceled)
                {
                    break;
                }

                var completed = result.IsCompleted;

                var pos = ProcessRead(buffer, out consumed, out examined);
                if (completed)
                {
                    break;
                }

                reader.AdvanceTo(consumed, examined);
            }

            reader.Complete();
        }
Beispiel #18
0
        private async Task ExecuteAsync()
        {
            Exception sendError = null;

            try
            {
                // Spawn send and receive logic
                var receiveTask = DoReceive();
                var sendTask    = DoSend();

                if (await Task.WhenAny(receiveTask, sendTask).ConfigureAwait(false) == sendTask)
                {
                    // Tell the reader it's being aborted
                    _socket.Dispose();
                }

                // Now wait for both to complete
                await receiveTask;
                sendError = await sendTask;

                // Dispose the socket(should noop if already called)
                _socket.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Unexpected exception in {nameof(SocketConnection)}.{nameof(StartAsync)}: " + ex);
            }
            finally
            {
                // Complete the output after disposing the socket
                _reader.Complete(sendError);
            }
        }
Beispiel #19
0
 public void Dispose()
 {
     _reader.Complete();
     _outStream.Dispose();
     _stream.Dispose();
     _cancelTokenSource.Dispose();
 }
Beispiel #20
0
        private async Task ReadPipeAsync(WebSocket socket, PipeReader reader, CancellationToken token)
        {
            while (true)
            {
                ReadResult result = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer = result.Buffer;
                do
                {
                    var line = buffer.Slice(0, myBufferSize);
                    await ProcessLine(socket, line, token);

                    buffer = buffer.Slice(myBufferSize);
                }while (buffer.Length >= myBufferSize);

                //We sliced the buffer until no more data could be processed
                //Tell the PipeReader how much we consumed and how much we left to process
                reader.AdvanceTo(buffer.Start, buffer.End);

                if (result.IsCompleted)
                {
                    break;
                }
            }

            reader.Complete();
        }
        static async Task SendToClientAsync(PipeReader reader, TcpClient client)
        {
            Stream tcpStream = client.GetStream();

            while (true)
            {
                ReadResult readResult = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer = readResult.Buffer;

                if (buffer.IsEmpty && readResult.IsCompleted)
                {
                    break;
                }

                foreach (ReadOnlyMemory <byte> segment in buffer)
                {
                    await tcpStream.WriteAsync(segment);
                }

                reader.AdvanceTo(buffer.End);

                if (readResult.IsCompleted)
                {
                    break;
                }
            }

            await tcpStream.FlushAsync();

            tcpStream.Dispose();
            reader.Complete();
        }
        private async Task PipeProcessorAsync(PipeReader reader, CancellationToken cancelationToken = default)
        {
            while (!cancelationToken.IsCancellationRequested)
            {
                var result = await reader.ReadAsync(cancelationToken).ConfigureAwait(false);

                var buffer = result.Buffer;
                SequencePosition?position;

                do
                {
                    position = buffer.PositionOf((byte)'\n');

                    if (position != null)
                    {
                        var notif = msgProc.PushMessage(buffer.Slice(0, position.Value).ToArray());
                        if (notif.HasValue)
                        {
                            dispatcher.Invoke(notif.Value);
                        }

                        // +2 = skipping \n\r
                        buffer = buffer.Slice(buffer.GetPosition(2, position.Value));
                    }
                } while (position != null);

                reader.AdvanceTo(buffer.Start, buffer.End);
                if (result.IsCompleted || result.IsCanceled)
                {
                    break;
                }
            }

            reader.Complete();
        }
        private static async Task ReadPipeAsync(Socket socket, PipeReader reader)
        {
            ReadOnlySequence <byte> buffer = new ReadOnlySequence <byte>();

            try
            {
                while (true)
                {
                    ReadResult result = await reader.ReadAsync();

                    buffer = result.Buffer;
                    while (buffer.Length >= BufferSize)
                    {
                        var line = buffer.Slice(0, BufferSize);
                        ProcessLine(socket, line);
                        buffer = buffer.Slice(BufferSize);
                    }

                    //We sliced the buffer until no more data could be processed
                    //Tell the PipeReader how much we consumed and how much we left to process
                    reader.AdvanceTo(buffer.Start, buffer.End);

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine("Buffer Length: {0}", buffer.Length);
                Console.WriteLine(exc);
            }
            reader.Complete();
        }
Beispiel #24
0
        protected virtual Task OnCloseAsync(Exception?exception, CancellationToken cancellationToken)
        {
            // Tell the PipeReader that there's no more data coming
            _reader.Complete(_exception);

            return(Task.CompletedTask);
        }
        public async Task ThrowsOnReadAfterCompleteReader()
        {
            PipeReader reader = PipeReader.Create(Stream.Null);

            reader.Complete();
            await Assert.ThrowsAsync <InvalidOperationException>(async() => await reader.ReadAsync());
        }
Beispiel #26
0
        static async Task ReadPipeAsync(IReadOnlyDictionary <ushort, IChannel> handlers, PipeReader reader)
        {
            while (true)
            {
                ReadResult result = await reader.ReadAsync();

                ReadOnlySequence <byte> buffer = result.Buffer;

                while (buffer.TryReadFrame(out Frame frame))
                {
                    //TODO: proper memory management instead of copy
                    var slice = buffer.Slice(Constants.HeaderSize, frame.ContentLength);

                    await handlers[frame.Channel].Handle(frame, ref slice);

                    var nextPart = buffer.GetPosition(frame.TotalLength);
                    buffer = buffer.Slice(nextPart);
                }
                ;

                reader.AdvanceTo(buffer.Start, buffer.End);

                if (result.IsCompleted)
                {
                    break;
                }
            }
            reader.Complete();
        }
Beispiel #27
0
        public Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            _input?.Complete();
            _output?.Complete();

            return(Task.CompletedTask);
        }
Beispiel #28
0
            public async Task Execute(PipeReader reader, PipeWriter writer)
            {
                List <MemoryHandle> handles = new List <MemoryHandle>();

                while (true)
                {
                    var result = await reader.ReadAsync();

                    var inputBuffer = result.Buffer;

                    if (inputBuffer.IsEmpty)
                    {
                        if (result.IsCompleted)
                        {
                            break;
                        }

                        reader.AdvanceTo(inputBuffer.End);
                        continue;
                    }

                    var writerBuffer = writer;
                    var buffer       = inputBuffer.First;
                    if (buffer.Length > 0)
                    {
                        unsafe
                        {
                            var handle = buffer.Pin();
                            handles.Add(handle);
                            _inflater.SetInput((IntPtr)handle.Pointer, buffer.Length);

                            var wbuffer = writerBuffer.GetMemory();
                            handle = wbuffer.Pin();
                            handles.Add(handle);
                            int written = _inflater.Inflate((IntPtr)handle.Pointer, wbuffer.Length);
                            writerBuffer.Advance(written);

                            var consumed = buffer.Length - _inflater.AvailableInput;

                            inputBuffer = inputBuffer.Slice(0, consumed);
                        }
                    }

                    reader.AdvanceTo(inputBuffer.End);

                    await writerBuffer.FlushAsync();
                }

                reader.Complete();

                writer.Complete();

                _inflater.Dispose();

                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
            }
        public override async Task Stop()
        {
            if (!started)
            {
                return;
            }

            cancellationTokenSource.Cancel();

            await readerTask;

            pipeReader.Complete();
            pipeWriter.Complete();
            pipe.Reset();

            started = false;
        }
        private async Task WriteOutputAsync(LibuvOutputConsumer consumer, PipeReader outputReader, Http1Connection http1Connection)
        {
            // This WriteOutputAsync() calling code is equivalent to that in LibuvConnection.
            try
            {
                // Ensure that outputReader.Complete() runs on the LibuvThread.
                // Without ConfigureAwait(false), xunit will dispatch.
                await consumer.WriteOutputAsync().ConfigureAwait(false);

                http1Connection.Abort(error: null);
                outputReader.Complete();
            }
            catch (UvException ex)
            {
                http1Connection.Abort(ex);
                outputReader.Complete(ex);
            }
        }