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.Modules.ObjectModels;
|
||||
global using SrcMod.Shell.ObjectModels;
|
||||
global using SrcMod.Shell.Valve;
|
||||
global using System;
|
||||
global using System.Collections;
|
||||
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