Skip to content

Commit

Permalink
Optimize reading binary strings
Browse files Browse the repository at this point in the history
Fixes #98
  • Loading branch information
xPaw committed Sep 15, 2024
1 parent 9e78198 commit 48d4560
Showing 1 changed file with 35 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Buffers;
using System.Text;
using ValveKeyValue.Abstraction;
using ValveKeyValue.KeyValues1;
Expand Down Expand Up @@ -84,7 +85,7 @@ string ReadKeyForNextValue()
return stringTable[index];
}

return Encoding.UTF8.GetString(ReadNullTerminatedBytes());
return ReadNullTerminatedUtf8String();
}

void ReadValue(KV1BinaryNodeType type)
Expand All @@ -102,7 +103,7 @@ void ReadValue(KV1BinaryNodeType type)

case KV1BinaryNodeType.String:
// UTF8 encoding is used for string values
value = new KVObjectValue<string>(Encoding.UTF8.GetString(ReadNullTerminatedBytes()), KVValueType.String);
value = new KVObjectValue<string>(ReadNullTerminatedUtf8String(), KVValueType.String);
break;

case KV1BinaryNodeType.WideString:
Expand Down Expand Up @@ -137,16 +138,41 @@ void ReadValue(KV1BinaryNodeType type)
listener.OnKeyValuePair(name, value);
}

byte[] ReadNullTerminatedBytes()
string ReadNullTerminatedUtf8String()
{
using var mem = new MemoryStream();
byte nextByte;
while ((nextByte = reader.ReadByte()) != 0)
var buffer = ArrayPool<byte>.Shared.Rent(32);

try
{
mem.WriteByte(nextByte);
var position = 0;

do
{
var b = reader.ReadByte();

if (b <= 0) // null byte or stream ended
{
break;
}

if (position >= buffer.Length)
{
var newBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length * 2);
Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
ArrayPool<byte>.Shared.Return(buffer);
buffer = newBuffer;
}

buffer[position++] = b;
}
while (true);

return Encoding.UTF8.GetString(buffer[..position]);
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}

return mem.ToArray();
}

void DetectMagicHeader()
Expand Down

0 comments on commit 48d4560

Please sign in to comment.