Skip to content

Commit

Permalink
Fix bug preventing SerialisedObject children from having quoted names
Browse files Browse the repository at this point in the history
Fixes #35
  • Loading branch information
LogicAndTrick committed Aug 17, 2024
1 parent e9052f1 commit 6d10305
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 20 deletions.
33 changes: 33 additions & 0 deletions Sledge.Formats.Tests/Valve/TestSerialisedObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,37 @@ static SerialisedObject Create(string str)
return new SerialisedObject(ms);
}
}

[TestMethod]
public void TestNestedObjectsWithQuotedNames()
{
var input = @"
""One""
{
""A"" ""B""
Two
{
""Three""
{
""Key"" ""Value""
}
""C"" ""D""
}
}";
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
var fmt = new SerialisedObjectFormatter();
var output = fmt.Deserialize(stream).ToList();

Assert.AreEqual(1, output.Count);
Assert.AreEqual("One", output[0].Name);
Assert.AreEqual("B", output[0].Get<string>("A"));

Assert.AreEqual(1, output[0].Children.Count);
Assert.AreEqual("Two", output[0].Children[0].Name);
Assert.AreEqual("D", output[0].Children[0].Get<string>("C"));

Assert.AreEqual(1, output[0].Children[0].Children.Count);
Assert.AreEqual("Three", output[0].Children[0].Children[0].Name);
Assert.AreEqual("Value", output[0].Children[0].Children[0].Get<string>("Key"));
}
}
4 changes: 2 additions & 2 deletions Sledge.Formats/Sledge.Formats.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
<RepositoryUrl>https://github.com/LogicAndTrick/sledge-formats</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<PackageTags>half-life quake valve liblist vdf</PackageTags>
<PackageReleaseNotes>Add some basic colour utils</PackageReleaseNotes>
<PackageReleaseNotes>Fix bug preventing SerialisedObject children from having quoted names</PackageReleaseNotes>
<PackageLicenseFile></PackageLicenseFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>1.2.5</Version>
<Version>1.2.6</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand Down
52 changes: 34 additions & 18 deletions Sledge.Formats/Valve/SerialisedObjectFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public IEnumerable<SerialisedObject> Deserialize(Stream serializationStream)
}

#region Printer

/// <summary>
/// Ensure a string doesn't exceed a length limit.
/// </summary>
Expand Down Expand Up @@ -123,7 +123,7 @@ public static IEnumerable<SerialisedObject> Parse(TextReader reader)
{
SerialisedObject current = null;
var stack = new Stack<SerialisedObject>();

var tokens = Tokeniser.Tokenise(reader);
using (var it = tokens.GetEnumerator())
{
Expand Down Expand Up @@ -160,30 +160,46 @@ public static IEnumerable<SerialisedObject> Parse(TextReader reader)
{
throw new ArgumentOutOfRangeException();
}
case TokenType.String when current == null:
case TokenType.String:
case TokenType.Name:
if (!it.MoveNext() || it.Current == null || it.Current.Type != TokenType.Symbol || it.Current.Symbol != Tokens.Symbols.OpenBrace)
if (!it.MoveNext() || it.Current == null)
{
throw new TokenParsingException(t, "Expected structure open brace");
throw new TokenParsingException(t, "Unexpected end of file");
}
var next = new SerialisedObject(t.Value);
if (current == null)

if (it.Current.Type == TokenType.Symbol && it.Current.Symbol == Tokens.Symbols.OpenBrace)
{
current = next;
var next = new SerialisedObject(t.Value);
if (current == null)
{
current = next;
}
else
{
stack.Push(current);
current = next;
}

break;
}
else if (t.Type == TokenType.String && it.Current.Type == TokenType.String)
{
if (current == null) throw new TokenParsingException(t, "No structure to add key/values to");

var key = t.Value;
var value = it.Current.Value;
current.Properties.Add(new KeyValuePair<string, string>(key, value));

break;
}
else if (t.Type == TokenType.Name)
{
throw new TokenParsingException(t, "Expected structure open brace");
}
else
{
stack.Push(current);
current = next;
throw new TokenParsingException(t, "Expected string value or open brace to follow string key");
}
break;
case TokenType.String:
if (current == null) throw new TokenParsingException(t, "No structure to add key/values to");
var key = t.Value;
if (!it.MoveNext() || it.Current == null || it.Current.Type != TokenType.String) throw new TokenParsingException(t, "Expected string value to follow key");
var value = it.Current.Value;
current.Properties.Add(new KeyValuePair<string, string>(key, value));
break;
case TokenType.End:
if (current != null) throw new TokenParsingException(t, "Unterminated structure at end of file");
yield break;
Expand Down

0 comments on commit 6d10305

Please sign in to comment.