public static int Write <T>(
            this PipeWriter writer,
            T writable)
            where T : IWritable
        {
            int size   = writable.Size;
            var buffer = writer.GetSpan(size);

            writable.WriteTo(buffer);
            writer.Advance(size);
            return(size);
        }
Beispiel #2
0
        protected virtual async Task FillPipeAsync(PipeWriter writer)
        {
            var options = Options;
            var cts     = _cts;

            while (!cts.IsCancellationRequested)
            {
                try
                {
                    var bufferSize       = options.ReceiveBufferSize;
                    var maxPackageLength = options.MaxPackageLength;

                    if (bufferSize <= 0)
                    {
                        bufferSize = 1024 * 4; //4k
                    }
                    var memory = writer.GetMemory(bufferSize);

                    var bytesRead = await FillPipeWithDataAsync(memory, cts.Token);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    LastActiveTime = DateTimeOffset.Now;

                    // Tell the PipeWriter how much was read
                    writer.Advance(bytesRead);
                }
                catch (Exception e)
                {
                    if (!IsIgnorableException(e))
                    {
                        OnError("Exception happened in ReceiveAsync", e);
                    }

                    break;
                }

                // Make the data available to the PipeReader
                var result = await writer.FlushAsync();

                if (result.IsCompleted)
                {
                    break;
                }
            }

            // Signal to the reader that we're done writing
            writer.Complete();
            Out.Writer.Complete();// TODO: should complete the output right now?
        }
Beispiel #3
0
        private async Task FillPipeAsync(PipeWriter writer)
        {
            while (!IsClosed)
            {
                try
                {
                    var bufferSize       = options.ReceiveBufferSize;
                    var maxPackageLength = options.MaxPackageLength;
                    if (maxPackageLength > 0)
                    {
                        bufferSize = Math.Min(bufferSize, maxPackageLength);
                    }

                    var memory = writer.GetMemory(bufferSize);

                    var read = await ReceiveAsync(memory);

                    if (read == 0)
                    {
                        //continue;
                        break;
                    }
                    writer.Advance(read);
                }
                catch (SocketException socketException)
                {
                    if (socketException.ErrorCode == 10054 || socketException.ErrorCode == 995)
                    {
                        logger.LogDebug("channel close");
                    }
                    else
                    {
                        logger.LogError(socketException, "Exception happened in ReceiveAsync");
                    }
                    break;
                }
                catch (Exception e)
                {
                    logger.LogError(e, "Exception happened in ReceiveAsync");
                    break;
                }

                var result = await writer.FlushAsync();

                if (result.IsCompleted)
                {
                    logger.LogWarning($"completed:{result.IsCompleted}");
                    break;
                }
            }
            writer.Complete();
            output.Writer.Complete();
        }
Beispiel #4
0
        private static void WriteHeader(PipeWriter pipeWriter, int length, bool compress)
        {
            var headerData = pipeWriter.GetSpan(HeaderSize);

            // Compression flag
            headerData[0] = compress ? (byte)1 : (byte)0;

            // Message length
            EncodeMessageLength(length, headerData.Slice(1));

            pipeWriter.Advance(HeaderSize);
        }
Beispiel #5
0
        /// <summary>
        /// Write to the PipeWriter
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="frame"></param>
        /// <returns></returns>
        protected override ValueTask <FlushResult> Write(PipeWriter writer, TFrame frame)
        {
            var headerLen  = GetHeaderLength(frame);
            var headerSpan = writer.GetSpan(headerLen);

            WriteHeader(headerSpan, frame);
            writer.Advance(headerLen);

            var payload = frame.Payload;

            return(payload.Memory.IsEmpty ? writer.FlushAsync() : writer.WriteAsync(payload.Memory));
        }
Beispiel #6
0
        public static async Task CopyToUntilCanceledOrCompletedAsync(this PipeReader reader, PipeWriter writer, CancellationToken cancel)
        {
            using var cancelRegistration = cancel.Register(delegate
            {
                // If we get canceled, indicate operation cancellation on both pipes to break out of the loop.
                // The purpose of this here is to avoid throwing exceptions for cancellation, instead using the graceful signal.
                // Just because exceptions cost extra CPU time that we want to avoid when handling load spikes (such as mass disconnects).
                reader.CancelPendingRead();
                writer.CancelPendingFlush();
            });

            // We copy until we encounter either a read cancellation (upstream reached end of stream) or a write
            // completion (downstream reached end of stream) or a write cancellation (downstream requested graceful stop).

            while (true)
            {
                var readResult = await reader.ReadAsync(CancellationToken.None);

                if (readResult.IsCanceled)
                {
                    break;
                }

                try
                {
                    if (!readResult.Buffer.IsEmpty)
                    {
                        foreach (var segment in readResult.Buffer)
                        {
                            var memory = writer.GetMemory(segment.Length);
                            segment.CopyTo(memory);
                            writer.Advance(segment.Length);
                        }

                        var flushResult = await writer.FlushAsync(CancellationToken.None);

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

                    if (readResult.IsCompleted)
                    {
                        break;
                    }
                }
                finally
                {
                    reader.AdvanceTo(readResult.Buffer.End);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Copies a sequence of bytes to a <see cref="PipeWriter"/>.
        /// </summary>
        /// <param name="writer">The writer to use.</param>
        /// <param name="sequence">The sequence to read.</param>
        private static void Write(this PipeWriter writer, ReadOnlySequence <byte> sequence)
        {
            Requires.NotNull(writer, nameof(writer));

            foreach (ReadOnlyMemory <byte> sourceMemory in sequence)
            {
                var sourceSpan = sourceMemory.Span;
                var targetSpan = writer.GetSpan(sourceSpan.Length);
                sourceSpan.CopyTo(targetSpan);
                writer.Advance(sourceSpan.Length);
            }
        }
Beispiel #8
0
        private async Task FillPipeAsync(PipeWriter writer, CancellationToken token)
        {
            const int minimumBufferSize = 1024 * 4;

            try
            {
                while (!token.IsCancellationRequested)
                {
                    token.ThrowIfCancellationRequested();
                    var memory = writer.GetMemory(minimumBufferSize);
                    try
                    {
                        var receiveResult = await _userSocket.ReceiveAsync(memory, token).ConfigureAwait(false);

                        if (_userSocket.CloseStatus.HasValue)
                        {
                            break;
                        }

                        writer.Advance(receiveResult.Count);

                        if (receiveResult.EndOfMessage)
                        {
                            var result = await writer.FlushAsync(token).ConfigureAwait(false);

                            if (result.IsCompleted)
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Failed to get data stream");
                        await _userSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Internal server error, contact administrator", _cancellationTokenSource.Token).ConfigureAwait(false);

                        break;
                    }
                }

                await _userSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Socket was closed", _cancellationTokenSource.Token).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Internal sever error");
                await _userSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Internal server error, contact administrator", _cancellationTokenSource.Token).ConfigureAwait(false);
            }
            finally
            {
                writer.Complete();
            }
        }
Beispiel #9
0
        public void NothingWrittenToStreamUnlessFlushed()
        {
            byte[]     bytes  = Encoding.ASCII.GetBytes("Hello World");
            var        stream = new MemoryStream();
            PipeWriter writer = PipeWriter.Create(stream);

            bytes.AsSpan().CopyTo(writer.GetSpan(bytes.Length));
            writer.Advance(bytes.Length);

            Assert.Equal(0, stream.Length);

            writer.Complete();
        }
        private static async Task WriteUrlAsync(PipeWriter pipeWriter, InputModel model, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                throw new InvalidOperationException("Cannot write message after request is complete.");
            }

            var bytesWritten = BuildUrl(pipeWriter.GetMemory().Span, model);

            pipeWriter.Advance(bytesWritten);

            await pipeWriter.FlushAsync(cancellationToken);
        }
Beispiel #11
0
    // Reverted.  Recommend formatting for table   --------------------------------------
    #region snippet
    async Task WriteHelloAsync(PipeWriter writer, CancellationToken cancellationToken = default)
    {
        // Request at least 5 bytes from the PipeWriter.
        Memory <byte> memory = writer.GetMemory(5);

        // Write directly into the buffer.
        int written = Encoding.ASCII.GetBytes("Hello".AsSpan(), memory.Span);

        // Tell the writer how many bytes were written.
        writer.Advance(written);

        await writer.FlushAsync(cancellationToken);
    }
Beispiel #12
0
        public static int Write <T, Options>(
            this PipeWriter writer,
            T writable,
            Options options)
            where T : IWritable <Options>
        {
            int size   = writable.Size(options);
            var buffer = writer.GetSpan(size);

            writable.WriteTo(buffer, options);
            writer.Advance(size);
            return(size);
        }
        private async Task WriteMessageDelimiterAsync(
            CancellationToken cancellationToken)
        {
            Memory <byte> memory = _writer.GetMemory(1);

            memory.Span[0] = Subscription._delimiter;

            _writer.Advance(1);

            await _writer
            .FlushAsync(cancellationToken)
            .ConfigureAwait(false);
        }
        public async Task ReceiveAsync(
            PipeWriter writer,
            CancellationToken cancellationToken = default)
        {
            if (IsClosed)
            {
                return;
            }

            try
            {
                WebSocketReceiveResult?socketResult = null;
                do
                {
                    Memory <byte> memory = writer.GetMemory(_maxMessageSize);
                    if (MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> buffer))
                    {
                        try
                        {
                            socketResult = await _socketClient.Socket
                                           .ReceiveAsync(buffer, cancellationToken)
                                           .ConfigureAwait(false);

                            if (socketResult.Count == 0)
                            {
                                break;
                            }

                            writer.Advance(socketResult.Count);
                        }
                        catch
                        {
                            break;
                        }

                        FlushResult result = await writer
                                             .FlushAsync(cancellationToken)
                                             .ConfigureAwait(false);

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                } while (socketResult == null || !socketResult.EndOfMessage);
            }
            catch (ObjectDisposedException)
            {
                // we will just stop receiving
            }
        }
        private async void FillPipeAsync(Stream stream, PipeWriter writer, CancellationToken token)
        {
            const int bufferSize = 512;

#if NETSTANDARD2_0
            var buffer = ArrayPool <byte> .Shared.Rent(bufferSize);
#endif
            try
            {
                while (true)
                {
#if NETSTANDARD2_0
                    int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    var result = await writer.WriteAsync(new ReadOnlyMemory <byte>(buffer, 0, bytesRead), token).ConfigureAwait(false);
#else
                    var buffer    = writer.GetMemory(bufferSize);
                    int bytesRead = await stream.ReadAsync(buffer, token).ConfigureAwait(false);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    writer.Advance(bytesRead);
                    var result = await writer.FlushAsync(token).ConfigureAwait(false);
#endif
                    if (result.IsCompleted)
                    {
                        break;
                    }
                }

                writer.Complete();
            }
            catch (Exception ex)
            {
                writer.Complete(ex);
            }
#if NETSTANDARD2_0
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }
#endif
        }
        public async Task ReceiveAsync(
            PipeWriter writer,
            CancellationToken cancellationToken)
        {
            WebSocket?webSocket = _webSocket;

            if (_disposed || webSocket == null)
            {
                return;
            }

            try
            {
                WebSocketReceiveResult?socketResult = null;
                do
                {
                    Memory <byte> memory  = writer.GetMemory(_maxMessageSize);
                    bool          success = MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> buffer);

                    if (success)
                    {
                        try
                        {
                            socketResult = await webSocket.ReceiveAsync(buffer, cancellationToken);

                            if (socketResult.Count == 0)
                            {
                                break;
                            }

                            writer.Advance(socketResult.Count);
                        }
                        catch
                        {
                            break;
                        }

                        FlushResult result = await writer.FlushAsync(cancellationToken);

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                } while (socketResult == null || !socketResult.EndOfMessage);
            }
            catch (ObjectDisposedException)
            {
                // we will just stop receiving
            }
        }
        protected virtual async Task FillPipeAsync(PipeWriter writer)
        {
            var options = Options;

            while (true)
            {
                try
                {
                    var bufferSize       = options.ReceiveBufferSize;
                    var maxPackageLength = options.MaxPackageLength;

                    if (maxPackageLength > 0)
                    {
                        bufferSize = Math.Min(bufferSize, maxPackageLength);
                    }

                    var memory = writer.GetMemory(bufferSize);

                    var bytesRead = await FillPipeWithDataAsync(memory);

                    if (bytesRead == 0)
                    {
                        break;
                    }

                    // Tell the PipeWriter how much was read
                    writer.Advance(bytesRead);
                }
                catch (Exception e)
                {
                    if (!IsIgnorableException(e))
                    {
                        Logger.LogError(e, "Exception happened in ReceiveAsync");
                    }

                    break;
                }

                // Make the data available to the PipeReader
                var result = await writer.FlushAsync();

                if (result.IsCompleted)
                {
                    break;
                }
            }

            // Signal to the reader that we're done writing
            writer.Complete();
            Out.Writer.Complete();// TODO: should complete the output right now?
        }
        private int EncodeFragment(PipeWriter writer, OpCode opCode, int expectedHeadLength, ReadOnlySpan <char> text, bool isFinal)
        {
            var head = writer.GetSpan(expectedHeadLength);

            var opCodeFlag = (byte)opCode;

            if (isFinal)
            {
                opCodeFlag = (byte)(opCodeFlag | 0x80);
            }

            head[0] = opCodeFlag;

            writer.Advance(expectedHeadLength);

            var encoder    = _textEncoding.GetEncoder();
            var completed  = false;
            var totalBytes = 0;

            while (!completed)
            {
                var span = writer.GetSpan();

                encoder.Convert(text, span, false, out int charsUsed, out int bytesUsed, out completed);

                if (charsUsed > 0)
                {
                    text = text.Slice(charsUsed);
                }

                totalBytes += bytesUsed;
                writer.Advance(bytesUsed);
            }

            WriteLength(ref head, totalBytes);
            writer.FlushAsync().GetAwaiter().GetResult();
            return(totalBytes + expectedHeadLength);
        }
Beispiel #19
0
        private static async Task WriteMessageDelimiterAsync(
            this PipeWriter writer,
            CancellationToken cancellationToken)
        {
            Memory <byte> memory = writer.GetMemory(1);

            memory.Span[0] = MessageProcessor.Delimiter;

            writer.Advance(1);

            await writer
            .FlushAsync(cancellationToken)
            .ConfigureAwait(false);
        }
Beispiel #20
0
        async ValueTask WriteSomeDataAsync(PipeWriter writer)
        {
            // use an oversized size guess
            Memory <byte> workspace = writer.GetMemory(20);
            // write the data to the workspace
            int bytes = Encoding.ASCII.GetBytes(
                "hello, world!", workspace.Span);

            // tell the pipe how much of the workspace
            // we actually want to commit
            writer.Advance(bytes);
            // this is **not** the same as Stream.Flush!
            await writer.FlushAsync();
        }
Beispiel #21
0
        /// <inheritdoc/>
        protected override void EncodeObject(PipeWriter writer)
        {
            var size   = GetSizeInBytes();
            var buffer = writer.GetSpan(size).Slice(0, size);

            buffer[0] = (byte)'i';
            buffer    = buffer.Slice(1);

            Encoding.ASCII.GetBytes(Value.ToString().AsSpan(), buffer);

            buffer[buffer.Length - 1] = (byte)'e';

            writer.Advance(size);
        }
Beispiel #22
0
        private async Task WriteToConnection(
            PipeWriter output,
            CancellationToken token)
        {
            try
            {
                var reader = _writeChannel.Reader;
                while (true)
                {
                    if (!await reader.WaitToReadAsync(token))
                    {
                        break;
                    }

                    if (!reader.TryRead(out var message))
                    {
                        continue;
                    }

                    var count = WriteOperationMessage(message, output);
                    output.Advance(count);

                    // apply back-pressure etc
                    var flush = await output.FlushAsync(token);

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

                // Manifest any errors in the completion task
                await reader.Completion;
            }
            catch (Exception ex)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                output.Complete(ex);
                throw;
            }
            finally
            {
                // This will safely no-op if the catch block above ran.
                output.Complete();
            }
        }
Beispiel #23
0
        private async Task FillPipeAsync(Stream stream, PipeWriter writer, CancellationToken cancellationToken = default)
        {
            const Int32 minimumBufferSize = 512;

            while (true)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    _exitReason = ExitReason.CancellationRequested;
                    break;
                }

                try
                {
                    // Allocate at least 512 bytes from the PipeWriter. NOTE: NMEA sentences must be less than 80 bytes.
                    var memory = writer.GetMemory(minimumBufferSize);

                    var bytesRead = await stream.ReadAsync(memory, cancellationToken).ConfigureAwait(false);

                    BytesReceived += bytesRead;
                    if (bytesRead == 0)
                    {
                        _logger.LogTrace("FillPipeAsync: Stream Ended");
                        _exitReason = ExitReason.StreamEnded;
                        break;
                    }

                    // Tell the PipeWriter how much was read from the Stream
                    writer.Advance(bytesRead);

                    // Make the data available to the PipeReader
                    var result = await writer.FlushAsync(cancellationToken).ConfigureAwait(false);

                    if (result.IsCompleted)
                    {
                        _logger.LogTrace("FillPipeAsync: Reader is Completed");
                        break;
                    }
                }
                catch (OperationCanceledException)
                {
                    _exitReason = ExitReason.CancellationRequested;
                    break;
                }
            }

            // Tell the PipeReader that there's no more data coming
            writer.Complete();
        }
Beispiel #24
0
        private async Task FillPipeAsync(PipeWriter writer, CancellationToken cancellationToken)
        {
            const int minimumBufferSize = 512;

            while (true)
            {
                // 从PipeWriter至少分配512字节
                var memory = writer.GetMemory(minimumBufferSize);
                try
                {
                    var reads = await Socket.ReceiveAsync(memory, SocketFlags.None, cancellationToken);

                    if (reads == 0)
                    {
                        break;
                    }

                    Actived = DateTimeOffset.Now;
                    // 告诉PipeWriter从套接字读取了多少
                    writer.Advance(reads);
                }
                catch (SocketException exception)
                {
                    LogError("[{2}] 套接字读取出现错误:{1}({0})", exception.Message, exception.SocketErrorCode, Name);
                    if (!Socket.Connected)
                    {
                        await CloseAsync();

                        return;
                    }
                }
                catch (Exception ex)
                {
                    LogError("[{0}] {1}", Name, ex.Message);
                    break;
                }

                // 标记数据可用,让PipeReader读取
                var result = await writer.FlushAsync(cancellationToken);

                if (result.IsCompleted)
                {
                    break;
                }
            }

            // 告诉PipeReader没有更多的数据
            await writer.CompleteAsync();
        }
Beispiel #25
0
            internal async ValueTask OnContentAsync(FrameHeader header, ReadOnlySequence <byte> payload, CancellationToken cancellationToken)
            {
                PipeWriter writer = this.GetReceivedMessagePipeWriter();

                foreach (var segment in payload)
                {
                    try
                    {
                        var memory = writer.GetMemory(segment.Length);
                        segment.CopyTo(memory);
                        writer.Advance(segment.Length);
                    }
                    catch (InvalidOperationException)
                    {
                        // Someone completed the writer.
                        return;
                    }
                }

                if (!payload.IsEmpty && this.MultiplexingStream.TraceSource.Switch.ShouldTrace(TraceEventType.Verbose))
                {
                    this.MultiplexingStream.TraceSource.TraceData(TraceEventType.Verbose, (int)TraceEventId.FrameReceivedPayload, payload);
                }

                ValueTask <FlushResult> flushResult = writer.FlushAsync(cancellationToken);

                if (this.BackpressureSupportEnabled)
                {
                    if (!flushResult.IsCompleted)
                    {
                        // The incoming data has overrun the size of the write buffer inside the PipeWriter.
                        // This should never happen if we created the Pipe because we specify the Pause threshold to exceed the window size.
                        // If it happens, it should be because someone specified an ExistingPipe with an inappropriately sized buffer in its PipeWriter.
                        Assumes.True(this.existingPipeGiven == true); // Make sure this isn't an internal error
                        this.Fault(new InvalidOperationException(Strings.ExistingPipeOutputHasPauseThresholdSetTooLow));
                    }
                }
                else
                {
                    await flushResult.ConfigureAwait(false);
                }

                if (flushResult.IsCanceled)
                {
                    // This happens when the channel is disposed (while or before flushing).
                    Assumes.True(this.IsDisposed);
                    writer.Complete();
                }
            }
Beispiel #26
0
        private async Task FillBuffer(PipeWriter writer, CancellationToken cancellationToken)
        {
            long offset = 0;

            while (offset < File.Size)
            {
                var pipeBuffer  = writer.GetMemory(_maxSegmentSize);
                var segmentSize = (int)Math.Min(_maxSegmentSize, File.Size - offset);

                try
                {
                    using var readSegmentCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                    readSegmentCts.CancelAfter(_segmentFetchTimeout);

                    var bytes = await _jsRuntime.InvokeAsync <byte[]>(
                        InputFileInterop.ReadFileData,
                        readSegmentCts.Token,
                        _inputFileElement,
                        File.Id,
                        offset,
                        segmentSize);

                    if (bytes is null || bytes.Length != segmentSize)
                    {
                        throw new InvalidOperationException(
                                  $"A segment with size {bytes?.Length ?? 0} bytes was received, but {segmentSize} bytes were expected.");
                    }

                    bytes.CopyTo(pipeBuffer);
                    writer.Advance(segmentSize);
                    offset += segmentSize;

                    var result = await writer.FlushAsync(cancellationToken);

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
                catch (Exception e)
                {
                    await writer.CompleteAsync(e);

                    return;
                }
            }

            await writer.CompleteAsync();
        }
        /* https://tools.ietf.org/html/rfc7540#section-4.1
         +-----------------------------------------------+
         |                 Length (24)                   |
         +---------------+---------------+---------------+
         |   Type (8)    |   Flags (8)   |
         +-+-------------+---------------+-------------------------------+
         |R|                 Stream Identifier (31)                      |
         +=+=============================================================+
         |                   Frame Payload (0...)                      ...
         +---------------------------------------------------------------+
         */
        internal static void WriteHeader(Http2Frame frame, PipeWriter output)
        {
            var buffer = output.GetSpan(Http2FrameReader.HeaderLength);

            Bitshifter.WriteUInt24BigEndian(buffer, (uint)frame.PayloadLength);
            buffer = buffer.Slice(3);

            buffer[0] = (byte)frame.Type;
            buffer[1] = frame.Flags;
            buffer    = buffer.Slice(2);

            Bitshifter.WriteUInt31BigEndian(buffer, (uint)frame.StreamId);

            output.Advance(Http2FrameReader.HeaderLength);
        }
        public async Task DataWrittenOnFlushAsync()
        {
            byte[]     bytes  = Encoding.ASCII.GetBytes("Hello World");
            var        stream = new MemoryStream();
            PipeWriter writer = PipeWriter.Create(stream);

            bytes.AsSpan().CopyTo(writer.GetSpan(bytes.Length));
            writer.Advance(bytes.Length);
            await writer.FlushAsync();

            Assert.Equal(bytes.Length, stream.Length);
            Assert.Equal("Hello World", Encoding.ASCII.GetString(stream.ToArray()));

            writer.Complete();
        }
Beispiel #29
0
        private static void WriteHeader(PipeWriter pipeWriter, int length, bool compress)
        {
            const int MessageDelimiterSize = 4;                        // how many bytes it takes to encode "Message-Length"
            const int HeaderSize           = MessageDelimiterSize + 1; // message length + compression flag

            var headerData = pipeWriter.GetSpan(HeaderSize);

            // Compression flag
            headerData[0] = compress ? (byte)1 : (byte)0;

            // Message length
            BinaryPrimitives.WriteUInt32BigEndian(headerData.Slice(1), (uint)length);

            pipeWriter.Advance(HeaderSize);
        }
        private static async Task <byte[]> Write(PipeWriter output)
        {
            var count = Random.Next(1, 1024);
            var input = new byte[count];

            Random.NextBytes(input);

            var memory = output.GetMemory(count);

            input.CopyTo(memory);
            output.Advance(count);
            await output.FlushAsync();

            return(input);
        }