NetworkReaderExtensions: removed static state by moving .encoding into each reader

This commit is contained in:
vis2k 2022-09-25 13:46:36 +07:00
parent e97da2605c
commit 2ce8ee72a8
2 changed files with 15 additions and 7 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
@ -31,6 +32,18 @@ public class NetworkReader
[Obsolete("NetworkReader.Length was renamed to Capacity")] // 2022-09-25
public int Length => Capacity;
// cache encoding for ReadString instead of creating it with each time
// 1000 readers before: 1MB GC, 30ms
// 1000 readers after: 0.8MB GC, 18ms
// member(!) to avoid static state.
//
// throwOnInvalidBytes is true.
// if false, it would silently ignore the invalid bytes but continue
// with the valid ones, creating strings like "a<><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>".
// instead, we want to catch it manually and return String.Empty.
// this is safer. see test: ReadString_InvalidUTF8().
internal readonly UTF8Encoding encoding = new UTF8Encoding(false, true);
public NetworkReader(ArraySegment<byte> segment)
{
buffer = segment;

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
namespace Mirror
@ -10,11 +9,6 @@ namespace Mirror
// but they do all need to be extensions.
public static class NetworkReaderExtensions
{
// cache encoding instead of creating it each time
// 1000 readers before: 1MB GC, 30ms
// 1000 readers after: 0.8MB GC, 18ms
static readonly UTF8Encoding encoding = new UTF8Encoding(false, true);
public static byte ReadByte(this NetworkReader reader) => reader.ReadBlittable<byte>();
public static byte? ReadByteNullable(this NetworkReader reader) => reader.ReadBlittableNullable<byte>();
@ -81,7 +75,8 @@ public static string ReadString(this NetworkReader reader)
ArraySegment<byte> data = reader.ReadBytesSegment(realSize);
// convert directly from buffer to string via encoding
return encoding.GetString(data.Array, data.Offset, data.Count);
// throws in case of invalid utf8.
return reader.encoding.GetString(data.Array, data.Offset, data.Count);
}
/// <exception cref="T:OverflowException">if count is invalid</exception>