Skip to content

Commit

Permalink
Implement StringPool for binary kv1 used by Steam
Browse files Browse the repository at this point in the history
  • Loading branch information
xPaw committed Jun 27, 2024
1 parent f7d32f2 commit b85e45b
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ namespace ValveKeyValue.Abstraction
{
interface IParsingVisitationListener : IVisitationListener
{
public string[] StringPool { get; set; }

void DiscardCurrentObject();

IParsingVisitationListener GetMergeListener();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class KVObjectBuilder : IParsingVisitationListener
{
readonly IList<KVObjectBuilder> associatedBuilders = new List<KVObjectBuilder>();

public string[] StringPool { get; set; }

public KVObject GetObject()
{
if (stateStack.Count != 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class KV1BinaryReader : IVisitingReader
{
public const int BinaryMagicHeader = 0x564B4256; // VBKV

public KV1BinaryReader(Stream stream, IVisitationListener listener)
public KV1BinaryReader(Stream stream, IParsingVisitationListener listener)
{
Require.NotNull(stream, nameof(stream));
Require.NotNull(listener, nameof(listener));
Expand All @@ -25,7 +25,7 @@ public KV1BinaryReader(Stream stream, IVisitationListener listener)

readonly Stream stream;
readonly BinaryReader reader;
readonly IVisitationListener listener;
readonly IParsingVisitationListener listener;
bool disposed;
KV1BinaryNodeType endMarker = KV1BinaryNodeType.End;

Expand Down Expand Up @@ -76,9 +76,18 @@ void ReadObjectCore()

void ReadValue(KV1BinaryNodeType type)
{
var name = Encoding.UTF8.GetString(ReadNullTerminatedBytes());
string name;
KVValue value;

if (listener.StringPool != null)
{
name = listener.StringPool[reader.ReadInt32()];
}
else
{
name = Encoding.UTF8.GetString(ReadNullTerminatedBytes());
}

switch (type)
{
case KV1BinaryNodeType.ChildObject:
Expand Down
5 changes: 4 additions & 1 deletion ValveKeyValue/ValveKeyValue/KVSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ public static KVSerializer Create(KVSerializationFormat format)
public KVDocument Deserialize(Stream stream, KVSerializerOptions options = null)
{
Require.NotNull(stream, nameof(stream));
var builder = new KVObjectBuilder();
var builder = new KVObjectBuilder
{
StringPool = options?.StringPool
};

using (var reader = MakeReader(stream, builder, options ?? KVSerializerOptions.DefaultOptions))
{
Expand Down
5 changes: 5 additions & 0 deletions ValveKeyValue/ValveKeyValue/KVSerializerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public sealed class KVSerializerOptions
/// </summary>
public static KVSerializerOptions DefaultOptions => new();

/// <summary>
/// If KV1 is serialized using a string pool for the keys, provide the string pool here.
/// </summary>
public string[] StringPool;

static IEnumerable<string> GetDefaultConditions()
{
// TODO: In the future we will want to skip this for consoles and mobile devices?
Expand Down

0 comments on commit b85e45b

Please sign in to comment.