protected override void Write()

in src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs [202:285]


        protected override void Write(JsonRpcMessage content, CancellationToken cancellationToken)
        {
            Assumes.NotNull(this.Writer);
            unsafe int WriteHeaderText(string value, Span<byte> memory)
            {
                fixed (char* pValue = &MemoryMarshal.GetReference(value.AsSpan()))
                {
                    fixed (byte* pMemory = &MemoryMarshal.GetReference(memory))
                    {
                        return HeaderEncoding.GetBytes(pValue, value.Length, pMemory, memory.Length);
                    }
                }
            }

            cancellationToken.ThrowIfCancellationRequested();
            Encoding contentEncoding = this.Encoding;
            try
            {
                this.Formatter.Serialize(this.contentSequenceBuilder, content);
                ReadOnlySequence<byte> contentSequence = this.contentSequenceBuilder.AsReadOnlySequence;

                // Some formatters (e.g. MessagePackFormatter) needs the encoded form in order to produce JSON for tracing.
                // Other formatters (e.g. JsonMessageFormatter) would prefer to do its own tracing while it still has a JToken.
                // We only help the formatters that need the byte-encoded form here. The rest can do it themselves.
                if (this.Formatter is IJsonRpcFormatterTracingCallbacks tracer)
                {
                    tracer.OnSerializationComplete(content, this.contentSequenceBuilder);
                }

                Memory<byte> headerMemory = this.Writer.GetMemory(1024);
                int bytesWritten = 0;

                // Transmit the Content-Length header.
                ContentLengthHeaderName.CopyTo(headerMemory.Slice(bytesWritten));
                bytesWritten += ContentLengthHeaderName.Length;
                HeaderKeyValueDelimiter.CopyTo(headerMemory.Slice(bytesWritten));
                bytesWritten += HeaderKeyValueDelimiter.Length;

                Assumes.True(Utf8Formatter.TryFormat(contentSequence.Length, headerMemory.Span.Slice(bytesWritten), out int formattedBytes));
                bytesWritten += formattedBytes;

                CrlfBytes.CopyTo(headerMemory.Slice(bytesWritten));
                bytesWritten += CrlfBytes.Length;

                // Transmit the Content-Type header, but only when using a non-default encoding.
                // We suppress it when it is the default both for smaller messages and to avoid
                // having to load System.Net.Http on the receiving end in order to parse it.
                if (DefaultContentEncoding.WebName != contentEncoding.WebName || this.SubType != DefaultSubType)
                {
                    ContentTypeHeaderName.CopyTo(headerMemory.Slice(bytesWritten));
                    bytesWritten += ContentTypeHeaderName.Length;
                    HeaderKeyValueDelimiter.CopyTo(headerMemory.Slice(bytesWritten));
                    bytesWritten += HeaderKeyValueDelimiter.Length;

                    bytesWritten += WriteHeaderText("application/", headerMemory.Slice(bytesWritten).Span);
                    bytesWritten += WriteHeaderText(this.SubType, headerMemory.Slice(bytesWritten).Span);
                    bytesWritten += WriteHeaderText("; charset=", headerMemory.Slice(bytesWritten).Span);
                    bytesWritten += WriteHeaderText(contentEncoding.WebName, headerMemory.Slice(bytesWritten).Span);

                    CrlfBytes.CopyTo(headerMemory.Slice(bytesWritten));
                    bytesWritten += CrlfBytes.Length;
                }

                // Terminate the headers.
                CrlfBytes.CopyTo(headerMemory.Slice(bytesWritten));
                bytesWritten += CrlfBytes.Length;
                this.Writer.Advance(bytesWritten);
                bytesWritten = 0;

                // Transmit the content itself.
                Memory<byte> contentMemory = this.Writer.GetMemory((int)contentSequence.Length);
                contentSequence.CopyTo(contentMemory.Span);
                this.Writer.Advance((int)contentSequence.Length);

                if (JsonRpcEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Informational, System.Diagnostics.Tracing.EventKeywords.None))
                {
                    JsonRpcEventSource.Instance.HandlerTransmitted(contentSequence.Length);
                }
            }
            finally
            {
                this.contentSequenceBuilder.Reset();
            }
        }