perf: use 0 for null strings (#926)

* Use 0 for null strings

* Fix test

* No need for special case for ""

* No need for special case for ""

* Update Assets/Mirror/Runtime/NetworkReader.cs

Co-Authored-By: Paul Pacheco <paulpach@gmail.com>
This commit is contained in:
MichalPetryka 2019-06-27 15:01:57 +02:00 committed by Paul Pacheco
parent 205bb73669
commit 7181cd9ca1
3 changed files with 41 additions and 42 deletions

View File

@ -110,34 +110,32 @@ public decimal ReadDecimal()
// note: this will throw an ArgumentException if an invalid utf8 string is sent
// null support, see NetworkWriter
public string ReadString()
{
// isNull?
if (ReadBoolean())
{
// read number of bytes
ushort size = ReadUInt16();
if (size == 0)
return "";
return null;
int realSize = size - 1;
// make sure it's within limits to avoid allocation attacks etc.
if (size >= NetworkWriter.MaxStringLength)
if (realSize >= NetworkWriter.MaxStringLength)
{
throw new EndOfStreamException("ReadString too long: " + size + ". Limit is: " + NetworkWriter.MaxStringLength);
throw new EndOfStreamException("ReadString too long: " + realSize + ". Limit is: " + NetworkWriter.MaxStringLength);
}
// check if within buffer limits
if (Position + size > buffer.Count)
if (Position + realSize > buffer.Count)
{
throw new EndOfStreamException("ReadString can't read " + size + " bytes because it would read past the end of the stream. " + ToString());
throw new EndOfStreamException("ReadString can't read " + realSize + " bytes because it would read past the end of the stream. " + ToString());
}
// convert directly from buffer to string via encoding
string result = encoding.GetString(buffer.Array, buffer.Offset + Position, size);
Position += size;
string result = encoding.GetString(buffer.Array, buffer.Offset + Position, realSize);
Position += realSize;
return result;
}
return null;
}
// read bytes into the passed buffer
public byte[] ReadBytes(byte[] bytes, int count)

View File

@ -121,15 +121,17 @@ public void Write(decimal value)
public void Write(string value)
{
// write bool for null support first
// write 0 for null support, increment real size by 1
// (note: original HLAPI would write "" for null strings, but if a
// string is null on the server then it should also be null
// on the client)
Write(value != null);
if (value == null)
{
Write((ushort)0);
return;
}
// write string with same method as NetworkReader
if (value != null)
{
// convert to byte[]
int size = encoding.GetBytes(value, 0, value.Length, stringBuffer, 0);
@ -140,9 +142,8 @@ public void Write(string value)
}
// write size and bytes
Write((ushort)size);
Write(stringBuffer, 0, (ushort)size);
}
Write(checked((ushort)(size + 1)));
Write(stringBuffer, 0, size);
}
// for byte arrays with consistent size, where the reader knows how many to read

View File

@ -107,7 +107,7 @@ public void TestOverwritingData()
writer.SetLength(128);
byte[] output = writer.ToArray();
//Debug.Log(BitConverter.ToString(output));
byte[] expected = new byte[]{
byte[] expected = {
0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -118,8 +118,8 @@ public void TestOverwritingData()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x0E, 0x00, 0x6E, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x72,
0x69, 0x65, 0x73, 0x2C, 0x20, 0x6D, 0x38, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x6E, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x72, 0x69,
0x65, 0x73, 0x2C, 0x20, 0x6D, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
Assert.That(output, Is.EqualTo(expected));