More development on the serializer.

This commit is contained in:
That_One_Nerd 2023-04-27 09:10:34 -04:00
parent 4e2a8ec05c
commit 46f4c779d2
4 changed files with 57 additions and 29 deletions

View File

@ -1,58 +1,79 @@
namespace SrcMod.Shell.Valve; using System.Security.Cryptography;
interface static class VdfConvert namespace SrcMod.Shell.Valve;
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" },
{ "\f", "\\\f" }, { "\f", "\\f" },
{ "\n", "\\\n" }, { "\n", "\\n" },
{ "\r", "\\\r" }, { "\r", "\\r" },
{ "\t", "\\\t" }, { "\t", "\\t" },
{ "\v", "\\\v" } { "\v", "\\v" }
}; };
public static void SerializeNode(StreamWriter writer, VdfNode node, string name, public static void SerializeNode(StreamWriter writer, VdfNode node, string name,
ref VdfOptions options, int indentLevel) VdfOptions options, int indentLevel)
{ {
if (node is VdfSingleNode single) SerializeSingleNode(writer, single, name, ref options, indentLevel); if (node is VdfSingleNode single) SerializeSingleNode(writer, single, name, options, indentLevel);
else if (node is VdfTreeNode tree) SerializeTreeNode(writer, tree, name, ref 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.");
} }
private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name, private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name,
ref VdfOptions options, int indentLevel) VdfOptions options, int indentLevel)
{ {
string serializedName = SerializeString(name, ref options), writer.Write(new string(' ', indentLevel));
serializedValue = SerializeObject(node.value, ref options); writer.Write(SerializeString(name, options));
writer.WriteLine($"{new string(' ', indentLevel)}{serializedName} {serializedValue}"); writer.Write(' ');
string serializedValue = SerializeString(SerializeObject(node.value, options), options);
writer.WriteLine(serializedValue);
} }
private static void SerializeTreeNode(StreamWriter writer, VdfTreeNode node, string name, private static void SerializeTreeNode(StreamWriter writer, VdfTreeNode node, string name,
ref VdfOptions options, int indentLevel) VdfOptions options, int indentLevel)
{ {
string serializedName = SerializeString(name, ref options), writer.Write(new string(' ', indentLevel));
serializedValue = ""; // TODO: serialize each value with a higher indent writer.WriteLine(SerializeString(name, options));
writer.WriteLine(new string(' ', indentLevel) + '{');
string indent = new(' ', indentLevel); foreach (KeyValuePair<string, VdfNode> subNode in node)
writer.WriteLine($"{indent}{serializedName}\n{indent}{{\n{serializedValue}\n{indent}}}"); {
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) + '}');
} }
private static string SerializeObject(object obj, ref VdfOptions options) private static string SerializeObject(object obj, VdfOptions options)
{ {
// TODO: serialize an object return obj.ToString() ?? string.Empty;
return "";
} }
private static string SerializeString(string content, ref VdfOptions options) private static string SerializeString(string content, VdfOptions options)
{ {
if (options.useEscapeCodes) if (options.useEscapeCodes)
foreach (KeyValuePair<string, string> escapeCode in p_escapeCodes) foreach (KeyValuePair<string, string> escapeCode in p_escapeCodes)
content = content.Replace(escapeCode.Key, escapeCode.Value); content = content.Replace(escapeCode.Key, escapeCode.Value);
if (options.useQuotes) content = $"\"{content}\"";
return content; return content;
} }
} }

View File

@ -6,6 +6,7 @@ public record class VdfOptions
public bool closeWhenFinished; public bool closeWhenFinished;
public int indentSize; public int indentSize;
public bool resetStreamPosition;
public bool useEscapeCodes; public bool useEscapeCodes;
public bool useQuotes; public bool useQuotes;
@ -13,6 +14,7 @@ public record class VdfOptions
{ {
closeWhenFinished = true; closeWhenFinished = true;
indentSize = 4; indentSize = 4;
resetStreamPosition = false;
useEscapeCodes = false; useEscapeCodes = false;
useQuotes = false; useQuotes = false;
} }

View File

@ -14,8 +14,10 @@ public class VdfSerializer
public void Serialize(Stream stream, VdfNode parentNode, string parentNodeName) public void Serialize(Stream stream, VdfNode parentNode, string parentNodeName)
{ {
StreamWriter writer = p_options.closeWhenFinished ? new(stream) : new(stream, leaveOpen: true); StreamWriter writer = new(stream, leaveOpen: !p_options.closeWhenFinished);
VdfConvert.SerializeNode(writer, parentNode, parentNodeName, ref p_options, 0); VdfConvert.SerializeNode(writer, parentNode, parentNodeName, p_options, 0);
writer.Close(); writer.Close();
if (!p_options.closeWhenFinished && p_options.resetStreamPosition) stream.Seek(0, SeekOrigin.Begin);
} }
} }

View File

@ -1,6 +1,6 @@
namespace SrcMod.Shell.Valve; namespace SrcMod.Shell.Valve;
public class VdfTreeNode : VdfNode public class VdfTreeNode : VdfNode, IEnumerable<KeyValuePair<string, VdfNode>>
{ {
public int SubNodeCount => p_subNodes.Count; public int SubNodeCount => p_subNodes.Count;
@ -29,4 +29,7 @@ public class VdfTreeNode : VdfNode
p_subNodes[p_subNodes.Keys.ElementAt(index)] = value; p_subNodes[p_subNodes.Keys.ElementAt(index)] = value;
} }
} }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<KeyValuePair<string, VdfNode>> GetEnumerator() => p_subNodes.GetEnumerator();
} }