Improved serialization of node tree and began tree generation.

This commit is contained in:
That-One-Nerd 2023-05-07 13:39:59 -04:00
parent 46f4c779d2
commit 03128d3a57
4 changed files with 48 additions and 32 deletions

View File

@ -6,9 +6,9 @@ public static class VdfConvert
{ {
private static readonly Dictionary<string, string> p_escapeCodes = new() private static readonly Dictionary<string, string> p_escapeCodes = new()
{ {
{ "\\", "\\\\" },
{ "\'", "\\\'" }, { "\'", "\\\'" },
{ "\"", "\\\"" }, { "\"", "\\\"" },
{ "\\", "\\\\" },
{ "\0", "\\0" }, { "\0", "\\0" },
{ "\a", "\\a" }, { "\a", "\\a" },
{ "\b", "\\b" }, { "\b", "\\b" },
@ -19,10 +19,22 @@ public static class VdfConvert
{ "\v", "\\v" } { "\v", "\\v" }
}; };
public static void SerializeNode(StreamWriter writer, VdfNode node, string name, public static void SerializeNode(StreamWriter writer, VdfNode? node, string name,
VdfOptions options) => SerializeNode(writer, node, name, options, 0);
public static void SerializeNode(StreamWriter writer, VdfNode? node, string name) =>
SerializeNode(writer, node, name, VdfOptions.Default, 0);
public static VdfNode? ToNodeTree(object? obj) => ToNodeTree(obj, VdfOptions.Default);
public static VdfNode? ToNodeTree(object? obj, VdfOptions options)
{
return null;
}
private static void SerializeNode(StreamWriter writer, VdfNode? node, string name,
VdfOptions options, int indentLevel) VdfOptions options, int indentLevel)
{ {
if (node is VdfSingleNode single) SerializeSingleNode(writer, single, name, options, indentLevel); if (node is null) return;
else if (node is VdfSingleNode single) SerializeSingleNode(writer, single, name, options, indentLevel);
else if (node is VdfTreeNode tree) SerializeTreeNode(writer, tree, name, options, indentLevel); else if (node is VdfTreeNode tree) SerializeTreeNode(writer, tree, name, options, indentLevel);
else throw new("Unknown node type."); else throw new("Unknown node type.");
} }
@ -30,11 +42,14 @@ public static class VdfConvert
private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name, private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name,
VdfOptions options, int indentLevel) VdfOptions options, int indentLevel)
{ {
string? serializedValue = SerializeObject(node.value, options);
if (serializedValue is null) return;
writer.Write(new string(' ', indentLevel)); writer.Write(new string(' ', indentLevel));
writer.Write(SerializeString(name, options)); writer.Write(SerializeString(name, options));
writer.Write(' '); writer.Write(' ');
string serializedValue = SerializeString(SerializeObject(node.value, options), options); serializedValue = SerializeString(serializedValue, options);
writer.WriteLine(serializedValue); writer.WriteLine(serializedValue);
} }
private static void SerializeTreeNode(StreamWriter writer, VdfTreeNode node, string name, private static void SerializeTreeNode(StreamWriter writer, VdfTreeNode node, string name,
@ -44,27 +59,15 @@ public static class VdfConvert
writer.WriteLine(SerializeString(name, options)); writer.WriteLine(SerializeString(name, options));
writer.WriteLine(new string(' ', indentLevel) + '{'); writer.WriteLine(new string(' ', indentLevel) + '{');
foreach (KeyValuePair<string, VdfNode> subNode in node) foreach (KeyValuePair<string, VdfNode?> subNode in node)
{ SerializeNode(writer, subNode.Value, subNode.Key, options, indentLevel + options.indentSize);
if (subNode.Value is VdfSingleNode singleSubNode && singleSubNode.value.GetType().IsArray)
{
Array array = (Array)singleSubNode.value;
Dictionary<string, VdfNode> items = new();
for (int i = 0; i < array.Length; i++)
{
object? item = array.GetValue(i);
if (item is VdfNode subNodeItem) items.Add(i.ToString(), subNodeItem);
else items.Add(i.ToString(), new VdfSingleNode(item));
}
}
else SerializeNode(writer, subNode.Value, subNode.Key, options, indentLevel + options.indentSize);
}
writer.WriteLine(new string(' ', indentLevel) + '}'); writer.WriteLine(new string(' ', indentLevel) + '}');
} }
private static string SerializeObject(object obj, VdfOptions options) private static string? SerializeObject(object? obj, VdfOptions options)
{ {
if (obj is null) return null;
return obj.ToString() ?? string.Empty; return obj.ToString() ?? string.Empty;
} }

View File

@ -12,10 +12,15 @@ public class VdfSerializer
p_options = options; p_options = options;
} }
public void Serialize(Stream stream, VdfNode parentNode, string parentNodeName) public void Serialize(Stream stream, object? value, string parentNodeName)
{
VdfNode? nodeTree = VdfConvert.ToNodeTree(value, p_options);
Serialize(stream, nodeTree, parentNodeName);
}
public void Serialize(Stream stream, VdfNode? parentNode, string parentNodeName)
{ {
StreamWriter writer = new(stream, leaveOpen: !p_options.closeWhenFinished); StreamWriter writer = new(stream, leaveOpen: !p_options.closeWhenFinished);
VdfConvert.SerializeNode(writer, parentNode, parentNodeName, p_options, 0); VdfConvert.SerializeNode(writer, parentNode, parentNodeName, p_options);
writer.Close(); writer.Close();
if (!p_options.closeWhenFinished && p_options.resetStreamPosition) stream.Seek(0, SeekOrigin.Begin); if (!p_options.closeWhenFinished && p_options.resetStreamPosition) stream.Seek(0, SeekOrigin.Begin);

View File

@ -2,10 +2,10 @@
public class VdfSingleNode : VdfNode public class VdfSingleNode : VdfNode
{ {
public object value; public object? value;
public VdfSingleNode(object? value = null) : base() public VdfSingleNode(object? value = null) : base()
{ {
this.value = value ?? new(); this.value = value;
} }
} }

View File

@ -1,28 +1,36 @@
namespace SrcMod.Shell.Valve; namespace SrcMod.Shell.Valve;
public class VdfTreeNode : VdfNode, IEnumerable<KeyValuePair<string, VdfNode>> public class VdfTreeNode : VdfNode, IEnumerable<KeyValuePair<string, VdfNode?>>
{ {
public int SubNodeCount => p_subNodes.Count; public int SubNodeCount => p_subNodes.Count;
private Dictionary<string, VdfNode> p_subNodes; private readonly Dictionary<string, VdfNode?> p_subNodes;
public VdfTreeNode(Dictionary<string, VdfNode>? subNodes = null) : base() public VdfTreeNode(Dictionary<string, VdfNode?>? subNodes = null) : base()
{ {
p_subNodes = subNodes ?? new(); p_subNodes = subNodes ?? new();
} }
public VdfNode this[string key] public VdfNode? this[string key]
{ {
get => p_subNodes[key]; get
{
if (p_subNodes.TryGetValue(key, out VdfNode? value)) return value;
else return null;
}
set set
{ {
if (p_subNodes.ContainsKey(key)) p_subNodes[key] = value; if (p_subNodes.ContainsKey(key)) p_subNodes[key] = value;
else p_subNodes.Add(key, value); else p_subNodes.Add(key, value);
} }
} }
public VdfNode this[int index] public VdfNode? this[int index]
{ {
get => p_subNodes.Values.ElementAt(index); get
{
if (p_subNodes.Count >= index || index < 0) return null;
return p_subNodes.Values.ElementAt(index);
}
set set
{ {
if (p_subNodes.Count >= index || index < 0) throw new IndexOutOfRangeException(); if (p_subNodes.Count >= index || index < 0) throw new IndexOutOfRangeException();
@ -31,5 +39,5 @@ public class VdfTreeNode : VdfNode, IEnumerable<KeyValuePair<string, VdfNode>>
} }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<KeyValuePair<string, VdfNode>> GetEnumerator() => p_subNodes.GetEnumerator(); public IEnumerator<KeyValuePair<string, VdfNode?>> GetEnumerator() => p_subNodes.GetEnumerator();
} }