Some development with the serializer.
This commit is contained in:
parent
4d64b0bae6
commit
4e2a8ec05c
@ -7,6 +7,7 @@ global using SrcMod.Shell.Extensions;
|
|||||||
global using SrcMod.Shell.Interop;
|
global using SrcMod.Shell.Interop;
|
||||||
global using SrcMod.Shell.Modules.ObjectModels;
|
global using SrcMod.Shell.Modules.ObjectModels;
|
||||||
global using SrcMod.Shell.ObjectModels;
|
global using SrcMod.Shell.ObjectModels;
|
||||||
|
global using SrcMod.Shell.Valve;
|
||||||
global using System;
|
global using System;
|
||||||
global using System.Collections;
|
global using System.Collections;
|
||||||
global using System.Collections.Generic;
|
global using System.Collections.Generic;
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
namespace SrcMod.Shell.Valve;
|
|
||||||
|
|
||||||
public static class KeyValueConvert
|
|
||||||
{
|
|
||||||
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" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string SerializeName(string content, KeyValueSerializer.Options? options = null)
|
|
||||||
{
|
|
||||||
options ??= KeyValueSerializer.Options.Default;
|
|
||||||
if (options.useNameQuotes) content = $"\"{content}\"";
|
|
||||||
if (options.useEscapeCodes)
|
|
||||||
foreach (KeyValuePair<string, string> escapeCode in p_escapeCodes)
|
|
||||||
content = content.Replace(escapeCode.Key, escapeCode.Value);
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
namespace SrcMod.Shell.Valve;
|
|
||||||
|
|
||||||
public class KeyValueNode
|
|
||||||
{
|
|
||||||
public int SubNodeCount => p_subNodes.Count;
|
|
||||||
|
|
||||||
public object value;
|
|
||||||
|
|
||||||
private Dictionary<string, KeyValueNode> p_subNodes;
|
|
||||||
|
|
||||||
internal KeyValueNode()
|
|
||||||
{
|
|
||||||
value = new();
|
|
||||||
p_subNodes = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyValueNode this[string name] => p_subNodes[name];
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
namespace SrcMod.Shell.Valve;
|
|
||||||
|
|
||||||
public class KeyValueSerializer
|
|
||||||
{
|
|
||||||
public int? IndentSize => p_options.indentSize;
|
|
||||||
public bool UseEscapeCodes => p_options.useEscapeCodes;
|
|
||||||
public bool UseNameQuotes => p_options.useNameQuotes;
|
|
||||||
public bool UseValueQuotes => p_options.useValueQuotes;
|
|
||||||
|
|
||||||
private readonly Options p_options;
|
|
||||||
|
|
||||||
public KeyValueSerializer() : this(Options.Default) { }
|
|
||||||
public KeyValueSerializer(Options options)
|
|
||||||
{
|
|
||||||
p_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringBuilder Serialize(StringBuilder builder, KeyValueNode parentNode, string? parentNodeName = null)
|
|
||||||
{
|
|
||||||
if (parentNodeName is not null) builder.AppendLine(KeyValueConvert.SerializeName(parentNodeName, p_options));
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public record class Options
|
|
||||||
{
|
|
||||||
public static Options Default => new();
|
|
||||||
|
|
||||||
public int? indentSize;
|
|
||||||
public bool useEscapeCodes;
|
|
||||||
public bool useNameQuotes;
|
|
||||||
public bool useValueQuotes;
|
|
||||||
|
|
||||||
public Options()
|
|
||||||
{
|
|
||||||
indentSize = null;
|
|
||||||
useEscapeCodes = false;
|
|
||||||
useNameQuotes = true;
|
|
||||||
useValueQuotes = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
58
SrcMod/Shell/Valve/VdfConvert.cs
Normal file
58
SrcMod/Shell/Valve/VdfConvert.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
interface 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" }
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void SerializeNode(StreamWriter writer, VdfNode node, string name,
|
||||||
|
ref 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);
|
||||||
|
else throw new("Unknown node type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SerializeSingleNode(StreamWriter writer, VdfSingleNode node, string name,
|
||||||
|
ref VdfOptions options, int indentLevel)
|
||||||
|
{
|
||||||
|
string serializedName = SerializeString(name, ref options),
|
||||||
|
serializedValue = SerializeObject(node.value, ref options);
|
||||||
|
writer.WriteLine($"{new string(' ', indentLevel)}{serializedName} {serializedValue}");
|
||||||
|
}
|
||||||
|
private static void SerializeTreeNode(StreamWriter writer, VdfTreeNode node, string name,
|
||||||
|
ref VdfOptions options, int indentLevel)
|
||||||
|
{
|
||||||
|
string serializedName = SerializeString(name, ref options),
|
||||||
|
serializedValue = ""; // TODO: serialize each value with a higher indent
|
||||||
|
|
||||||
|
string indent = new(' ', indentLevel);
|
||||||
|
writer.WriteLine($"{indent}{serializedName}\n{indent}{{\n{serializedValue}\n{indent}}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string SerializeObject(object obj, ref VdfOptions options)
|
||||||
|
{
|
||||||
|
// TODO: serialize an object
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string SerializeString(string content, ref VdfOptions options)
|
||||||
|
{
|
||||||
|
if (options.useEscapeCodes)
|
||||||
|
foreach (KeyValuePair<string, string> escapeCode in p_escapeCodes)
|
||||||
|
content = content.Replace(escapeCode.Key, escapeCode.Value);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
SrcMod/Shell/Valve/VdfNode.cs
Normal file
6
SrcMod/Shell/Valve/VdfNode.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
public abstract class VdfNode
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
19
SrcMod/Shell/Valve/VdfOptions.cs
Normal file
19
SrcMod/Shell/Valve/VdfOptions.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
public record class VdfOptions
|
||||||
|
{
|
||||||
|
public static VdfOptions Default => new();
|
||||||
|
|
||||||
|
public bool closeWhenFinished;
|
||||||
|
public int indentSize;
|
||||||
|
public bool useEscapeCodes;
|
||||||
|
public bool useQuotes;
|
||||||
|
|
||||||
|
public VdfOptions()
|
||||||
|
{
|
||||||
|
closeWhenFinished = true;
|
||||||
|
indentSize = 4;
|
||||||
|
useEscapeCodes = false;
|
||||||
|
useQuotes = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
SrcMod/Shell/Valve/VdfSerializer.cs
Normal file
21
SrcMod/Shell/Valve/VdfSerializer.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
public class VdfSerializer
|
||||||
|
{
|
||||||
|
public VdfOptions Options => p_options;
|
||||||
|
|
||||||
|
private VdfOptions p_options;
|
||||||
|
|
||||||
|
public VdfSerializer() : this(VdfOptions.Default) { }
|
||||||
|
public VdfSerializer(VdfOptions options)
|
||||||
|
{
|
||||||
|
p_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
writer.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
SrcMod/Shell/Valve/VdfSingleNode.cs
Normal file
11
SrcMod/Shell/Valve/VdfSingleNode.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
public class VdfSingleNode : VdfNode
|
||||||
|
{
|
||||||
|
public object value;
|
||||||
|
|
||||||
|
public VdfSingleNode(object? value = null) : base()
|
||||||
|
{
|
||||||
|
this.value = value ?? new();
|
||||||
|
}
|
||||||
|
}
|
||||||
32
SrcMod/Shell/Valve/VdfTreeNode.cs
Normal file
32
SrcMod/Shell/Valve/VdfTreeNode.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
namespace SrcMod.Shell.Valve;
|
||||||
|
|
||||||
|
public class VdfTreeNode : VdfNode
|
||||||
|
{
|
||||||
|
public int SubNodeCount => p_subNodes.Count;
|
||||||
|
|
||||||
|
private Dictionary<string, VdfNode> p_subNodes;
|
||||||
|
|
||||||
|
public VdfTreeNode(Dictionary<string, VdfNode>? subNodes = null) : base()
|
||||||
|
{
|
||||||
|
p_subNodes = subNodes ?? new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VdfNode this[string key]
|
||||||
|
{
|
||||||
|
get => p_subNodes[key];
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (p_subNodes.ContainsKey(key)) p_subNodes[key] = value;
|
||||||
|
else p_subNodes.Add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public VdfNode this[int index]
|
||||||
|
{
|
||||||
|
get => p_subNodes.Values.ElementAt(index);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (p_subNodes.Count >= index || index < 0) throw new IndexOutOfRangeException();
|
||||||
|
p_subNodes[p_subNodes.Keys.ElementAt(index)] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user