More development on the serializer.
This commit is contained in:
parent
4e2a8ec05c
commit
46f4c779d2
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string SerializeObject(object obj, ref VdfOptions options)
|
writer.WriteLine(new string(' ', indentLevel) + '}');
|
||||||
{
|
|
||||||
// TODO: serialize an object
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string SerializeString(string content, ref VdfOptions options)
|
private static string SerializeObject(object obj, VdfOptions options)
|
||||||
|
{
|
||||||
|
return obj.ToString() ?? string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user