diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs index a030aa685f62..87a389aecbb5 100644 --- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs @@ -551,7 +551,7 @@ public void NumberToDouble_Valid(string jsonValue, double expectedParsedValue) } [Test] -#if !NET50 +#if !NET5_0 [TestCase("1.7977e308")] [TestCase("-1.7977e308")] [TestCase("1e309")] diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs index 2de0304b29cc..55ec02ea023f 100644 --- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs @@ -199,7 +199,7 @@ public void NumberValue(string json, double expectedValue) [TestCase("1e-")] [TestCase("--")] [TestCase("--1")] -#if !NET50 +#if !NET5_0 [TestCase("-1.7977e308")] [TestCase("1.7977e308")] #endif diff --git a/csharp/src/Google.Protobuf/WritingPrimitives.cs b/csharp/src/Google.Protobuf/WritingPrimitives.cs index d4c2dcef9c35..d8e1fbe7dd80 100644 --- a/csharp/src/Google.Protobuf/WritingPrimitives.cs +++ b/csharp/src/Google.Protobuf/WritingPrimitives.cs @@ -53,7 +53,7 @@ internal static class WritingPrimitives #if NET5_0 internal static Encoding Utf8Encoding => Encoding.UTF8; // allows JIT to devirtualize #else - internal static Encoding Utf8Encoding = Encoding.UTF8; // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.) + internal static readonly Encoding Utf8Encoding = Encoding.UTF8; // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.) #endif #region Writing of values (not including tags) @@ -179,6 +179,8 @@ public static void WriteString(ref Span buffer, ref WriterInternalState st { if (length == value.Length) // Must be all ASCII... { + int currentIndex = 0; + // If 64bit, and value has at least 4 chars, process 4 chars at a time. if (IntPtr.Size == 8 && value.Length >= 4) { @@ -187,29 +189,23 @@ public static void WriteString(ref Span buffer, ref WriterInternalState st // Process 4 chars at a time until there are less than 4 remaining. // We already know all characters are ASCII so there is no need to validate the source. - int currentIndex = 0; - int lastIndexWhereCanReadFourChars = (2 * value.Length - 8); + int lastIndexWhereCanReadFourChars = value.Length - 4; do { NarrowFourUtf16CharsToAsciiAndWriteToBuffer( - ref Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)(currentIndex / 2)), - Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref sourceBytes, (IntPtr)currentIndex))); + ref Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex), + Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref sourceBytes, (IntPtr)(currentIndex * 2)))); - } while ((currentIndex += 8) <= lastIndexWhereCanReadFourChars); + } while ((currentIndex += 4) <= lastIndexWhereCanReadFourChars); - // Process remainder. - for (int i = currentIndex / 2; i < length; i++) - { - buffer[state.position + i] = (byte)value[i]; - } + // Any chars remaining are processed in for loop below. } - else + + for (int i = currentIndex; i < length; i++) { - for (int i = 0; i < length; i++) - { - buffer[state.position + i] = (byte)value[i]; - } + buffer[state.position + i] = (byte)value[i]; } + state.position += length; } else