From 03128d3a5758a4543929978e84218efd646cda0b Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Sun, 7 May 2023 13:39:59 -0400 Subject: [PATCH] Improved serialization of node tree and began tree generation. --- SrcMod/Shell/Valve/VdfConvert.cs | 43 +++++++++++++++-------------- SrcMod/Shell/Valve/VdfSerializer.cs | 9 ++++-- SrcMod/Shell/Valve/VdfSingleNode.cs | 4 +-- SrcMod/Shell/Valve/VdfTreeNode.cs | 24 ++++++++++------ 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/SrcMod/Shell/Valve/VdfConvert.cs b/SrcMod/Shell/Valve/VdfConvert.cs index fa919dd..7f65ae0 100644 --- a/SrcMod/Shell/Valve/VdfConvert.cs +++ b/SrcMod/Shell/Valve/VdfConvert.cs @@ -6,9 +6,9 @@ public static class VdfConvert { private static readonly Dictionary p_escapeCodes = new() { + { "\\", "\\\\" }, { "\'", "\\\'" }, { "\"", "\\\"" }, - { "\\", "\\\\" }, { "\0", "\\0" }, { "\a", "\\a" }, { "\b", "\\b" }, @@ -19,10 +19,22 @@ public static class VdfConvert { "\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) { - 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 throw new("Unknown node type."); } @@ -30,11 +42,14 @@ public static class VdfConvert private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name, VdfOptions options, int indentLevel) { + string? serializedValue = SerializeObject(node.value, options); + if (serializedValue is null) return; + writer.Write(new string(' ', indentLevel)); writer.Write(SerializeString(name, options)); writer.Write(' '); - string serializedValue = SerializeString(SerializeObject(node.value, options), options); + serializedValue = SerializeString(serializedValue, options); writer.WriteLine(serializedValue); } 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(new string(' ', indentLevel) + '{'); - foreach (KeyValuePair subNode in node) - { - if (subNode.Value is VdfSingleNode singleSubNode && singleSubNode.value.GetType().IsArray) - { - Array array = (Array)singleSubNode.value; - Dictionary 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); - } + foreach (KeyValuePair subNode in node) + SerializeNode(writer, subNode.Value, subNode.Key, options, indentLevel + options.indentSize); 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; } diff --git a/SrcMod/Shell/Valve/VdfSerializer.cs b/SrcMod/Shell/Valve/VdfSerializer.cs index b0509b8..4ae766b 100644 --- a/SrcMod/Shell/Valve/VdfSerializer.cs +++ b/SrcMod/Shell/Valve/VdfSerializer.cs @@ -12,10 +12,15 @@ public class VdfSerializer 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); - VdfConvert.SerializeNode(writer, parentNode, parentNodeName, p_options, 0); + VdfConvert.SerializeNode(writer, parentNode, parentNodeName, p_options); writer.Close(); if (!p_options.closeWhenFinished && p_options.resetStreamPosition) stream.Seek(0, SeekOrigin.Begin); diff --git a/SrcMod/Shell/Valve/VdfSingleNode.cs b/SrcMod/Shell/Valve/VdfSingleNode.cs index 5e68b48..429025f 100644 --- a/SrcMod/Shell/Valve/VdfSingleNode.cs +++ b/SrcMod/Shell/Valve/VdfSingleNode.cs @@ -2,10 +2,10 @@ public class VdfSingleNode : VdfNode { - public object value; + public object? value; public VdfSingleNode(object? value = null) : base() { - this.value = value ?? new(); + this.value = value; } } diff --git a/SrcMod/Shell/Valve/VdfTreeNode.cs b/SrcMod/Shell/Valve/VdfTreeNode.cs index e8e944e..2cef7cf 100644 --- a/SrcMod/Shell/Valve/VdfTreeNode.cs +++ b/SrcMod/Shell/Valve/VdfTreeNode.cs @@ -1,28 +1,36 @@ namespace SrcMod.Shell.Valve; -public class VdfTreeNode : VdfNode, IEnumerable> +public class VdfTreeNode : VdfNode, IEnumerable> { public int SubNodeCount => p_subNodes.Count; - private Dictionary p_subNodes; + private readonly Dictionary p_subNodes; - public VdfTreeNode(Dictionary? subNodes = null) : base() + public VdfTreeNode(Dictionary? subNodes = null) : base() { 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 { if (p_subNodes.ContainsKey(key)) p_subNodes[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 { if (p_subNodes.Count >= index || index < 0) throw new IndexOutOfRangeException(); @@ -31,5 +39,5 @@ public class VdfTreeNode : VdfNode, IEnumerable> } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator> GetEnumerator() => p_subNodes.GetEnumerator(); + public IEnumerator> GetEnumerator() => p_subNodes.GetEnumerator(); }