using System; using System.Text; using System.IO; using System.Globalization; namespace NeXt.Vdf { /// /// Class that handles serialization of VdfValue objects into Vdf formatted strings /// public class VdfSerializer { /// /// Creates a VdfSerializer object /// /// the VdfValue to serialize public VdfSerializer(VdfValue value) { root = value; } private const string Newline = "\n"; private const string ValueDelimiter = "\""; private const string CommentDelimiter = "//"; private const string TableOpen = "{"; private const string TableClose = "}"; private const string KVSeperator = "\t\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 step, string text, bool escape) { step(ValueDelimiter); if(escape) { step(EscapeString(text)); } else { step(text); } step(ValueDelimiter); } private void RunSerialization(Action 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.Long: { onStep(KVSeperator); WriteString(onStep, (current as VdfLong).Content.ToString(CultureInfo.InvariantCulture), false); onStep(Newline); break; } case VdfValueType.Decimal: { onStep(KVSeperator); WriteString(onStep, (current as VdfDecimal).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; } } } /// /// Serialize the object to string /// /// a string representing the VdfValue public string Serialize() { StringBuilder sb = new StringBuilder(); RunSerialization((s) => sb.Append(s), root); return sb.ToString(); } /// /// Serialize the object to a file /// /// full path to the file to serialize into public void Serialize(string filePath) { Serialize(filePath, Encoding.Unicode); } /// /// Serialize the object to a file using the given encoding /// /// /// public void Serialize(string filePath, Encoding encoding) { using(StreamWriter writer = new StreamWriter(filePath, false, encoding)) { RunSerialization(writer.Write, root); writer.Flush(); } } } }