Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove some allocations in text token reader #108

Merged
merged 2 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Linq;
using System.Text;

namespace ValveKeyValue.Deserialization.KeyValues1
Expand All @@ -20,6 +19,7 @@ public KV1TokenReader(TextReader textReader, KVSerializerOptions options) : base
this.options = options;
}

readonly StringBuilder sb = new();
readonly KVSerializerOptions options;

public KVToken ReadNextToken()
Expand Down Expand Up @@ -69,8 +69,6 @@ KVToken ReadComment()
{
ReadChar(CommentBegin);

var sb = new StringBuilder();

// Some keyvalues implementations have a bug where only a single slash is needed for a comment
// If the file ends with a single slash then we have an empty comment, bail out
if (!TryGetNext(out var next))
Expand Down Expand Up @@ -102,14 +100,15 @@ KVToken ReadComment()
}

var text = sb.ToString();
sb.Clear();

return new KVToken(KVTokenType.Comment, text);
}

KVToken ReadCondition()
{
ReadChar(ConditionBegin);
var text = ReadUntil(ConditionEnd);
var text = ReadUntil(static (c) => c == ConditionEnd);
ReadChar(ConditionEnd);

return new KVToken(KVTokenType.Condition, text);
Expand All @@ -118,7 +117,7 @@ KVToken ReadCondition()
KVToken ReadInclusion()
{
ReadChar(InclusionMark);
var term = ReadUntil(new[] { ' ', '\t' });
var term = ReadUntil(static c => c is ' ' or '\t');
var value = ReadStringRaw();

if (string.Equals(term, "include", StringComparison.Ordinal))
Expand All @@ -133,13 +132,11 @@ KVToken ReadInclusion()
throw new InvalidDataException($"Unrecognized term after '#' symbol (line {Line}, column {Column})");
}

string ReadUntil(params char[] terminators)
string ReadUntil(Func<int, bool> isTerminator)
{
var sb = new StringBuilder();
var escapeNext = false;

var integerTerminators = new HashSet<int>(terminators.Select(t => (int)t));
while (!integerTerminators.Contains(Peek()) || escapeNext)
while (escapeNext || !isTerminator(Peek()))
{
var next = Next();

Expand Down Expand Up @@ -178,6 +175,7 @@ string ReadUntil(params char[] terminators)
}

var result = sb.ToString();
sb.Clear();

// Valve bug-for-bug compatibility with tier1 KeyValues/CUtlBuffer: an invalid escape sequence is a null byte which
// causes the text to be trimmed to the point of that null byte.
Expand All @@ -190,8 +188,6 @@ string ReadUntil(params char[] terminators)

string ReadUntilWhitespaceOrQuote()
{
var sb = new StringBuilder();

while (true)
{
var next = Peek();
Expand All @@ -203,7 +199,10 @@ string ReadUntilWhitespaceOrQuote()
sb.Append(Next());
}

return sb.ToString();
var result = sb.ToString();
sb.Clear();

return result;
}

string ReadStringRaw()
Expand All @@ -222,7 +221,7 @@ string ReadStringRaw()
string ReadQuotedStringRaw()
{
ReadChar(QuotationMark);
var text = ReadUntil(QuotationMark);
var text = ReadUntil(static (c) => c == QuotationMark);
ReadChar(QuotationMark);
return text;
}
Expand Down
13 changes: 1 addition & 12 deletions ValveKeyValue/ValveKeyValue/KVObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,6 @@ KVCollectionValue GetCollectionValue()
return collection;
}

string DebuggerDescription
{
get
{
var description = new StringBuilder();
description.Append(Name);
description.Append(": ");
description.Append(Value.ToString());

return description.ToString();
}
}
string DebuggerDescription => $"{Name}: {Value}";
}
}