From 379160707f6c045de541af94181c340a87f7da53 Mon Sep 17 00:00:00 2001 From: Pawel Kadluczka Date: Thu, 16 Nov 2017 09:20:40 -0800 Subject: [PATCH] Switching to new base64 APIs (#1127) --- .../MessageParserBenchmark.cs | 8 +++---- .../Internal/Encoders/Base64Encoder.cs | 22 ++++++++++++++----- .../Internal/Encoders/IDataEncoder.cs | 4 +++- .../LengthPrefixedTextMessageParser.cs | 10 ++++----- .../Internal/Encoders/PassThroughEncoder.cs | 4 +++- .../Formatters/BinaryMessageParser.cs | 4 ++-- .../Internal/Formatters/TextMessageParser.cs | 4 ++-- .../Internal/Protocol/IHubProtocol.cs | 2 +- .../Internal/Protocol/JsonHubProtocol.cs | 2 +- .../Protocol/MessagePackHubProtocol.cs | 2 +- .../Internal/Protocol/NegotiationProtocol.cs | 2 +- .../HubConnectionTests.cs | 2 +- .../LengthPrefixedTextMessageParserTests.cs | 14 ++++++------ .../Formatters/BinaryMessageFormatterTests.cs | 2 +- .../Formatters/BinaryMessageParserTests.cs | 17 ++++++++------ .../Formatters/TextMessageParserTests.cs | 8 +++---- 16 files changed, 62 insertions(+), 45 deletions(-) diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs index 0661272907..e608892e65 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs @@ -9,8 +9,8 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks public class MessageParserBenchmark { private static readonly Random Random = new Random(); - private ReadOnlyMemory _binaryInput; - private ReadOnlyMemory _textInput; + private byte[] _binaryInput; + private byte[] _textInput; [Params(32, 64)] public int ChunkSize { get; set; } @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks [Benchmark] public void SingleBinaryMessage() { - var buffer = _binaryInput; + ReadOnlySpan buffer = _binaryInput; if (!BinaryMessageParser.TryParseMessage(ref buffer, out _)) { throw new InvalidOperationException("Failed to parse"); @@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks [Benchmark] public void SingleTextMessage() { - var buffer = _textInput; + ReadOnlySpan buffer = _textInput; if (!TextMessageParser.TryParseMessage(ref buffer, out _)) { throw new InvalidOperationException("Failed to parse"); diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/Base64Encoder.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/Base64Encoder.cs index 881b05112d..1b36313cb3 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/Base64Encoder.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/Base64Encoder.cs @@ -2,27 +2,37 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; using System.IO; -using System.Text; namespace Microsoft.AspNetCore.SignalR.Internal.Encoders { public class Base64Encoder : IDataEncoder { - public byte[] Decode(byte[] payload) + public ReadOnlySpan Decode(byte[] payload) { - var buffer = new ReadOnlyMemory(payload); + ReadOnlySpan buffer = payload; LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out var message); - return Convert.FromBase64String(Encoding.UTF8.GetString(message.ToArray())); + Span decoded = new byte[Base64.GetMaxDecodedFromUtf8Length(message.Length)]; + var status = Base64.DecodeFromUtf8(message, decoded, out _, out var written); + Debug.Assert(status == OperationStatus.Done); + + return decoded.Slice(0, written); } public byte[] Encode(byte[] payload) { - var buffer = Encoding.UTF8.GetBytes(Convert.ToBase64String(payload)); + Span buffer = new byte[Base64.GetMaxEncodedToUtf8Length(payload.Length)]; + + var status = Base64.EncodeToUtf8(payload, buffer, out _, out var written); + Debug.Assert(status == OperationStatus.Done); + using (var stream = new MemoryStream()) { - LengthPrefixedTextMessageWriter.WriteMessage(buffer, stream); + LengthPrefixedTextMessageWriter.WriteMessage(buffer.Slice(0, written), stream); return stream.ToArray(); } } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/IDataEncoder.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/IDataEncoder.cs index 07b724dfcf..8ca5f05ad6 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/IDataEncoder.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/IDataEncoder.cs @@ -1,11 +1,13 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; + namespace Microsoft.AspNetCore.SignalR.Internal.Encoders { public interface IDataEncoder { byte[] Encode(byte[] payload); - byte[] Decode(byte[] payload); + ReadOnlySpan Decode(byte[] payload); } } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs index 686add4a15..0a800eebce 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/LengthPrefixedTextMessageParser.cs @@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Encoders /// Attempts to parse a message from the buffer. Returns 'false' if there is not enough data to complete a message. Throws an /// exception if there is a format error in the provided data. /// - public static bool TryParseMessage(ref ReadOnlyMemory buffer, out ReadOnlyMemory payload) + public static bool TryParseMessage(ref ReadOnlySpan buffer, out ReadOnlySpan payload) { - payload = default(ReadOnlyMemory); + payload = default; - if (!TryReadLength(buffer.Span, out var index, out var length)) + if (!TryReadLength(buffer, out var index, out var length)) { return false; } var remaining = buffer.Slice(index); - if (!TryReadDelimiter(remaining.Span, LengthPrefixedTextMessageWriter.FieldDelimiter, "length")) + if (!TryReadDelimiter(remaining, LengthPrefixedTextMessageWriter.FieldDelimiter, "length")) { return false; } @@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Encoders remaining = remaining.Slice(length); - if (!TryReadDelimiter(remaining.Span, LengthPrefixedTextMessageWriter.MessageDelimiter, "payload")) + if (!TryReadDelimiter(remaining, LengthPrefixedTextMessageWriter.MessageDelimiter, "payload")) { return false; } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/PassThroughEncoder.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/PassThroughEncoder.cs index a3e5016495..06621470e7 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/PassThroughEncoder.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Encoders/PassThroughEncoder.cs @@ -1,11 +1,13 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; + namespace Microsoft.AspNetCore.SignalR.Internal.Encoders { public class PassThroughEncoder : IDataEncoder { - public byte[] Decode(byte[] payload) + public ReadOnlySpan Decode(byte[] payload) { return payload; } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/BinaryMessageParser.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/BinaryMessageParser.cs index 4889ea33f4..a795180975 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/BinaryMessageParser.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/BinaryMessageParser.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Formatters private static int[] _numBitsToShift = new[] { 0, 7, 14, 21, 28 }; private const int MaxLengthPrefixSize = 5; - public static bool TryParseMessage(ref ReadOnlyMemory buffer, out ReadOnlyMemory payload) + public static bool TryParseMessage(ref ReadOnlySpan buffer, out ReadOnlySpan payload) { payload = default; @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Formatters var length = 0U; var numBytes = 0; - var lengthPrefixBuffer = buffer.Span.Slice(0, Math.Min(MaxLengthPrefixSize, buffer.Length)); + var lengthPrefixBuffer = buffer.Slice(0, Math.Min(MaxLengthPrefixSize, buffer.Length)); byte byteRead; do { diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/TextMessageParser.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/TextMessageParser.cs index fac697290e..e8b0cb5e82 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/TextMessageParser.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Formatters/TextMessageParser.cs @@ -7,11 +7,11 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Formatters { public static class TextMessageParser { - public static bool TryParseMessage(ref ReadOnlyMemory buffer, out ReadOnlyMemory payload) + public static bool TryParseMessage(ref ReadOnlySpan buffer, out ReadOnlySpan payload) { payload = default; - var index = buffer.Span.IndexOf(TextMessageFormatter.RecordSeparator); + var index = buffer.IndexOf(TextMessageFormatter.RecordSeparator); if (index == -1) { return false; diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocol.cs index c02cea455b..1dc73512b8 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/IHubProtocol.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol ProtocolType Type { get; } - bool TryParseMessages(ReadOnlyMemory input, IInvocationBinder binder, out IList messages); + bool TryParseMessages(ReadOnlySpan input, IInvocationBinder binder, out IList messages); void WriteMessage(HubMessage message, Stream output); } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs index 4efa8a3e6b..52a043eb63 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/JsonHubProtocol.cs @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol public ProtocolType Type => ProtocolType.Text; - public bool TryParseMessages(ReadOnlyMemory input, IInvocationBinder binder, out IList messages) + public bool TryParseMessages(ReadOnlySpan input, IInvocationBinder binder, out IList messages) { messages = new List(); diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs index 30c85781c7..4d93cee7f7 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/MessagePackHubProtocol.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol _serializationContext = serializationContext; } - public bool TryParseMessages(ReadOnlyMemory input, IInvocationBinder binder, out IList messages) + public bool TryParseMessages(ReadOnlySpan input, IInvocationBinder binder, out IList messages) { messages = new List(); diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/NegotiationProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/NegotiationProtocol.cs index c886a10ec2..8c2ead483d 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/NegotiationProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Internal/Protocol/NegotiationProtocol.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol } } - public static bool TryParseMessage(ReadOnlyMemory input, out NegotiationMessage negotiationMessage) + public static bool TryParseMessage(ReadOnlySpan input, out NegotiationMessage negotiationMessage) { if (!TextMessageParser.TryParseMessage(ref input, out var payload)) { diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs index 13da4d90ec..0d13efc2e1 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs @@ -215,7 +215,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests public ProtocolType Type => ProtocolType.Binary; - public bool TryParseMessages(ReadOnlyMemory input, IInvocationBinder binder, out IList messages) + public bool TryParseMessages(ReadOnlySpan input, IInvocationBinder binder, out IList messages) { messages = new List(); diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Encoders/LengthPrefixedTextMessageParserTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Encoders/LengthPrefixedTextMessageParserTests.cs index 923e80dd66..eba7ac832d 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Encoders/LengthPrefixedTextMessageParserTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Encoders/LengthPrefixedTextMessageParserTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Encoders [InlineData("12:Hello, World;", "Hello, World")] public void ReadTextMessage(string encoded, string payload) { - ReadOnlyMemory buffer = Encoding.UTF8.GetBytes(encoded); + ReadOnlySpan buffer = Encoding.UTF8.GetBytes(encoded); Assert.True(LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out var message)); Assert.Equal(0, buffer.Length); @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Encoders public void ReadMultipleMessages() { const string encoded = "0:;14:Hello,\r\nWorld!;"; - ReadOnlyMemory buffer = Encoding.UTF8.GetBytes(encoded); + ReadOnlySpan buffer = Encoding.UTF8.GetBytes(encoded); var messages = new List(); while (LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out var message)) @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Encoders [InlineData("5:ABCDE")] public void ReadIncompleteMessages(string encoded) { - ReadOnlyMemory buffer = Encoding.UTF8.GetBytes(encoded); + ReadOnlySpan buffer = Encoding.UTF8.GetBytes(encoded); Assert.False(LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out _)); } @@ -66,9 +66,9 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Encoders [InlineData("5:ABCDEF", "Missing delimiter ';' after payload")] public void ReadInvalidMessages(string encoded, string expectedMessage) { - ReadOnlyMemory buffer = Encoding.UTF8.GetBytes(encoded); var ex = Assert.Throws(() => { + ReadOnlySpan buffer = Encoding.UTF8.GetBytes(encoded); LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out _); }); Assert.Equal(expectedMessage, ex.Message); @@ -77,11 +77,11 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Encoders [Fact] public void ReadInvalidEncodedMessage() { - // Invalid because first character is a UTF-8 "continuation" character - // We need to include the ':' so that - ReadOnlyMemory buffer = new byte[] { 0x48, 0x65, 0x80, 0x6C, 0x6F, (byte)':' }; var ex = Assert.Throws(() => { + // Invalid because first character is a UTF-8 "continuation" character + // We need to include the ':' so that + ReadOnlySpan buffer = new byte[] { 0x48, 0x65, 0x80, 0x6C, 0x6F, (byte)':' }; LengthPrefixedTextMessageParser.TryParseMessage(ref buffer, out _); }); Assert.Equal("Invalid length: 'He�lo'", ex.Message); diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs index b727e8124d..a60405217b 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs @@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests.Internal.Formatters using (var ms = new MemoryStream()) { BinaryMessageFormatter.WriteMessage(payload, ms); - var buffer = new ReadOnlyMemory(ms.ToArray()); + var buffer = new ReadOnlySpan(ms.ToArray()); Assert.True(BinaryMessageParser.TryParseMessage(ref buffer, out var roundtripped)); Assert.Equal(payload, roundtripped.ToArray()); } diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs index 7a42eca843..49e426292c 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [InlineData(new byte[] { 0x0B, 0x41, 0x0A, 0x52, 0x0D, 0x43, 0x0D, 0x0A, 0x3B, 0x44, 0x45, 0x46 }, "A\nR\rC\r\n;DEF")] public void ReadMessage(byte[] encoded, string payload) { - ReadOnlyMemory span = encoded; + ReadOnlySpan span = encoded; Assert.True(BinaryMessageParser.TryParseMessage(ref span, out var message)); Assert.Equal(0, span.Length); @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters })] public void ReadBinaryMessage(byte[] encoded, byte[] payload) { - ReadOnlyMemory span = encoded; + ReadOnlySpan< byte> span = encoded; Assert.True(BinaryMessageParser.TryParseMessage(ref span, out var message)); Assert.Equal(0, span.Length); Assert.Equal(payload, message.ToArray()); @@ -64,8 +64,11 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [InlineData(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF })] public void BinaryMessageParserThrowsForMessagesOver2GB(byte[] payload) { - var buffer = new ReadOnlyMemory(payload); - var ex = Assert.Throws(() => BinaryMessageParser.TryParseMessage(ref buffer, out var message)); + var ex = Assert.Throws(() => + { + var buffer = new ReadOnlySpan(payload); + BinaryMessageParser.TryParseMessage(ref buffer, out var message); + }); Assert.Equal("Messages over 2GB in size are not supported.", ex.Message); } @@ -76,7 +79,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [InlineData(new byte[] { 0x80 })] // size is cut public void BinaryMessageParserReturnsFalseForPartialPayloads(byte[] payload) { - var buffer = new ReadOnlyMemory(payload); + var buffer = new ReadOnlySpan(payload); Assert.False(BinaryMessageParser.TryParseMessage(ref buffer, out var message)); } @@ -90,8 +93,8 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters /* length: */ 0x0E, /* body: */ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x0D, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, }; - ReadOnlyMemory buffer = encoded; + ReadOnlySpan buffer = encoded; var messages = new List(); while (BinaryMessageParser.TryParseMessage(ref buffer, out var message)) { @@ -110,7 +113,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [InlineData(new byte[] { 0x09, 0x00, 0x00 })] // Not enough data for payload public void ReadIncompleteMessages(byte[] encoded) { - ReadOnlyMemory buffer = encoded; + ReadOnlySpan buffer = encoded; Assert.False(BinaryMessageParser.TryParseMessage(ref buffer, out var message)); Assert.Equal(encoded.Length, buffer.Length); } diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs index 9dbc7b2866..2376895d23 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [Fact] public void ReadMessage() { - var message = new ReadOnlyMemory(Encoding.UTF8.GetBytes("ABC\u001e")); + var message = new ReadOnlySpan(Encoding.UTF8.GetBytes("ABC\u001e")); Assert.True(TextMessageParser.TryParseMessage(ref message, out var payload)); Assert.Equal("ABC", Encoding.UTF8.GetString(payload.ToArray())); @@ -23,14 +23,14 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [Fact] public void TryReadingIncompleteMessage() { - var message = new ReadOnlyMemory(Encoding.UTF8.GetBytes("ABC")); + var message = new ReadOnlySpan(Encoding.UTF8.GetBytes("ABC")); Assert.False(TextMessageParser.TryParseMessage(ref message, out var payload)); } [Fact] public void TryReadingMultipleMessages() { - var message = new ReadOnlyMemory(Encoding.UTF8.GetBytes("ABC\u001eXYZ\u001e")); + var message = new ReadOnlySpan(Encoding.UTF8.GetBytes("ABC\u001eXYZ\u001e")); Assert.True(TextMessageParser.TryParseMessage(ref message, out var payload)); Assert.Equal("ABC", Encoding.UTF8.GetString(payload.ToArray())); Assert.True(TextMessageParser.TryParseMessage(ref message, out payload)); @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters [Fact] public void IncompleteTrailingMessage() { - var message = new ReadOnlyMemory(Encoding.UTF8.GetBytes("ABC\u001eXYZ\u001e123")); + var message = new ReadOnlySpan(Encoding.UTF8.GetBytes("ABC\u001eXYZ\u001e123")); Assert.True(TextMessageParser.TryParseMessage(ref message, out var payload)); Assert.Equal("ABC", Encoding.UTF8.GetString(payload.ToArray())); Assert.True(TextMessageParser.TryParseMessage(ref message, out payload));