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()
{
{ "\'", "\\\'" },
{ "\"", "\\\"" },
{ "\\", "\\\\" },
{ "\0", "\\\0" },
{ "\a", "\\\a" },
{ "\b", "\\\b" },
{ "\f", "\\\f" },
{ "\n", "\\\n" },
{ "\r", "\\\r" },
{ "\t", "\\\t" },
{ "\v", "\\\v" }
{ "\0", "\\0" },
{ "\a", "\\a" },
{ "\b", "\\b" },
{ "\f", "\\f" },
{ "\n", "\\n" },
{ "\r", "\\r" },
{ "\t", "\\t" },
{ "\v", "\\v" }
};
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);
else if (node is VdfTreeNode tree) SerializeTreeNode(writer, tree, 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, options, indentLevel);
else throw new("Unknown node type.");
}
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),
serializedValue = SerializeObject(node.value, ref options);
writer.WriteLine($"{new string(' ', indentLevel)}{serializedName} {serializedValue}");
writer.Write(new string(' ', indentLevel));
writer.Write(SerializeString(name, options));
writer.Write(' ');
string serializedValue = SerializeString(SerializeObject(node.value, options), options);
writer.WriteLine(serializedValue);
}
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),
serializedValue = ""; // TODO: serialize each value with a higher indent
writer.Write(new string(' ', indentLevel));
writer.WriteLine(SerializeString(name, options));
writer.WriteLine(new string(' ', indentLevel) + '{');
string indent = new(' ', indentLevel);
writer.WriteLine($"{indent}{serializedName}\n{indent}{{\n{serializedValue}\n{indent}}}");
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);
}
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 "";
return obj.ToString() ?? string.Empty;
}
private static string SerializeString(string content, ref VdfOptions options)
private static string SerializeString(string content, VdfOptions options)
{
if (options.useEscapeCodes)
foreach (KeyValuePair<string, string> escapeCode in p_escapeCodes)
content = content.Replace(escapeCode.Key, escapeCode.Value);
if (options.useQuotes) content = $"\"{content}\"";
return content;
}
}

View File

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

View File

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

View File

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