-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathVdfSerializer.cs
155 lines (140 loc) · 4.66 KB
/
VdfSerializer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using System.Text;
using System.IO;
using System.Globalization;
namespace NeXt.Vdf
{
/// <summary>
/// Class that handles serialization of VdfValue objects into Vdf formatted strings
/// </summary>
public class VdfSerializer
{
/// <summary>
/// Creates a VdfSerializer object
/// </summary>
/// <param name="value">the VdfValue to serialize</param>
public VdfSerializer(VdfValue value)
{
root = value;
}
private const string Newline = "\r\n";
private const string ValueDelimiter = "\"";
private const string CommentDelimiter = "//";
private const string TableOpen = "{";
private const string TableClose = "}";
private const string KVSeperator = "\t";
private string IndentString
{
get
{
return "\t".Repeat(indentLevel);
}
}
private VdfValue root;
private int indentLevel = 0;
private string EscapeString(string v)
{
return v.Replace("\\", @"\\").Replace("\t", @"\t").Replace("\n", @"\n").Replace("\r",@"\r").Replace("\"", @"\""");
}
private void WriteString(Action<string> step, string text, bool escape)
{
step(ValueDelimiter);
if(escape)
{
step(EscapeString(text));
}
else
{
step(text);
}
step(ValueDelimiter);
}
private void RunSerialization(Action<string> onStep, VdfValue current)
{
if(current.Comments.Count > 0)
{
foreach(var s in current.Comments)
{
onStep(IndentString);
onStep(CommentDelimiter);
onStep(EscapeString(s));
onStep(Newline);
}
}
onStep(IndentString);
WriteString(onStep, current.Name, true);
switch(current.Type)
{
case VdfValueType.String:
{
onStep(KVSeperator);
WriteString(onStep, (current as VdfString).Content, true);
onStep(Newline);
break;
}
case VdfValueType.Integer:
{
onStep(KVSeperator);
WriteString(onStep, (current as VdfInteger).Content.ToString(CultureInfo.InvariantCulture), false);
onStep(Newline);
break;
}
case VdfValueType.Double:
{
onStep(KVSeperator);
WriteString(onStep, (current as VdfDouble).Content.ToString(CultureInfo.InvariantCulture), false);
onStep(Newline);
break;
}
case VdfValueType.Table:
{
onStep(Newline);
onStep(IndentString);
onStep(TableOpen);
onStep(Newline);
indentLevel++;
foreach(var v in current as VdfTable)
{
RunSerialization(onStep, v);
}
indentLevel--;
onStep(IndentString);
onStep(TableClose);
onStep(Newline);
break;
}
}
}
/// <summary>
/// Serialize the object to string
/// </summary>
/// <returns>a string representing the VdfValue</returns>
public string Serialize()
{
StringBuilder sb = new StringBuilder();
RunSerialization((s) => sb.Append(s), root);
return sb.ToString();
}
/// <summary>
/// Serialize the object to a file
/// </summary>
/// <param name="filePath">full path to the file to serialize into</param>
public void Serialize(string filePath)
{
Serialize(filePath, Encoding.Unicode);
}
/// <summary>
/// Serialize the object to a file using the given encoding
/// </summary>
/// <param name="filePath"></param>
/// <param name="encoding"></param>
public void Serialize(string filePath, Encoding encoding)
{
using(StreamWriter writer = new StreamWriter(filePath, false, encoding))
{
RunSerialization(writer.Write, root);
writer.Flush();
}
}
}
}