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()
{
{ "\\", "\\\\" },
{ "\'", "\\\'" },
{ "\"", "\\\"" },
{ "\\", "\\\\" },
{ "\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<string, VdfNode> subNode in node)
{
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);
}
foreach (KeyValuePair<string, VdfNode?> 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;
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -1,28 +1,36 @@
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;
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();
}
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<KeyValuePair<string, VdfNode>>
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<KeyValuePair<string, VdfNode>> GetEnumerator() => p_subNodes.GetEnumerator();
public IEnumerator<KeyValuePair<string, VdfNode?>> GetEnumerator() => p_subNodes.GetEnumerator();
}