Skip to content

Commit

Permalink
Merge pull request #108 from ValveResourceFormat/allocs
Browse files Browse the repository at this point in the history
Remove some allocations in text token reader
  • Loading branch information
xPaw authored Sep 17, 2024
2 parents 29a24e8 + 0f99eae commit de2c130
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 25 deletions.
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}";
}
}

0 comments on commit de2c130

Please sign in to comment.