297 lines
5.5 KiB
C#
297 lines
5.5 KiB
C#
|
using System;
|
||
|
using System.Globalization;
|
||
|
using System.IO;
|
||
|
|
||
|
namespace ES3Internal
|
||
|
{
|
||
|
internal class ES3JSONWriter : ES3Writer
|
||
|
{
|
||
|
internal StreamWriter baseWriter;
|
||
|
|
||
|
private bool isFirstProperty = true;
|
||
|
|
||
|
public ES3JSONWriter(Stream stream, ES3Settings settings)
|
||
|
: this(stream, settings, writeHeaderAndFooter: true, mergeKeys: true)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
internal ES3JSONWriter(Stream stream, ES3Settings settings, bool writeHeaderAndFooter, bool mergeKeys)
|
||
|
: base(settings, writeHeaderAndFooter, mergeKeys)
|
||
|
{
|
||
|
baseWriter = new StreamWriter(stream);
|
||
|
StartWriteFile();
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(int value)
|
||
|
{
|
||
|
baseWriter.Write(value);
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(float value)
|
||
|
{
|
||
|
baseWriter.Write(value.ToString("R", CultureInfo.InvariantCulture));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(bool value)
|
||
|
{
|
||
|
baseWriter.Write(value ? "true" : "false");
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(decimal value)
|
||
|
{
|
||
|
baseWriter.Write(value.ToString(CultureInfo.InvariantCulture));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(double value)
|
||
|
{
|
||
|
baseWriter.Write(value.ToString("R", CultureInfo.InvariantCulture));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(long value)
|
||
|
{
|
||
|
baseWriter.Write(value);
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(ulong value)
|
||
|
{
|
||
|
baseWriter.Write(value);
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(uint value)
|
||
|
{
|
||
|
baseWriter.Write(value);
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(byte value)
|
||
|
{
|
||
|
baseWriter.Write(Convert.ToInt32(value));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(sbyte value)
|
||
|
{
|
||
|
baseWriter.Write(Convert.ToInt32(value));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(short value)
|
||
|
{
|
||
|
baseWriter.Write(Convert.ToInt32(value));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(ushort value)
|
||
|
{
|
||
|
baseWriter.Write(Convert.ToInt32(value));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(char value)
|
||
|
{
|
||
|
WritePrimitive(value.ToString());
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(byte[] value)
|
||
|
{
|
||
|
WritePrimitive(Convert.ToBase64String(value));
|
||
|
}
|
||
|
|
||
|
internal override void WritePrimitive(string value)
|
||
|
{
|
||
|
baseWriter.Write("\"");
|
||
|
foreach (char c in value)
|
||
|
{
|
||
|
switch (c)
|
||
|
{
|
||
|
case '"':
|
||
|
case '/':
|
||
|
case '\\':
|
||
|
case '“':
|
||
|
case '”':
|
||
|
baseWriter.Write('\\');
|
||
|
baseWriter.Write(c);
|
||
|
break;
|
||
|
case '\b':
|
||
|
baseWriter.Write("\\b");
|
||
|
break;
|
||
|
case '\f':
|
||
|
baseWriter.Write("\\f");
|
||
|
break;
|
||
|
case '\n':
|
||
|
baseWriter.Write("\\n");
|
||
|
break;
|
||
|
case '\r':
|
||
|
baseWriter.Write("\\r");
|
||
|
break;
|
||
|
case '\t':
|
||
|
baseWriter.Write("\\t");
|
||
|
break;
|
||
|
default:
|
||
|
baseWriter.Write(c);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
baseWriter.Write("\"");
|
||
|
}
|
||
|
|
||
|
internal override void WriteNull()
|
||
|
{
|
||
|
baseWriter.Write("null");
|
||
|
}
|
||
|
|
||
|
private static bool CharacterRequiresEscaping(char c)
|
||
|
{
|
||
|
if (c != '"' && c != '\\' && c != '“')
|
||
|
{
|
||
|
return c == '”';
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private void WriteCommaIfRequired()
|
||
|
{
|
||
|
if (!isFirstProperty)
|
||
|
{
|
||
|
baseWriter.Write(',');
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
isFirstProperty = false;
|
||
|
}
|
||
|
WriteNewlineAndTabs();
|
||
|
}
|
||
|
|
||
|
internal override void WriteRawProperty(string name, byte[] value)
|
||
|
{
|
||
|
StartWriteProperty(name);
|
||
|
baseWriter.Write(settings.encoding.GetString(value, 0, value.Length));
|
||
|
EndWriteProperty(name);
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteFile()
|
||
|
{
|
||
|
if (writeHeaderAndFooter)
|
||
|
{
|
||
|
baseWriter.Write('{');
|
||
|
}
|
||
|
base.StartWriteFile();
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteFile()
|
||
|
{
|
||
|
base.EndWriteFile();
|
||
|
WriteNewlineAndTabs();
|
||
|
if (writeHeaderAndFooter)
|
||
|
{
|
||
|
baseWriter.Write('}');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteProperty(string name)
|
||
|
{
|
||
|
base.StartWriteProperty(name);
|
||
|
WriteCommaIfRequired();
|
||
|
Write(name);
|
||
|
if (settings.prettyPrint)
|
||
|
{
|
||
|
baseWriter.Write(' ');
|
||
|
}
|
||
|
baseWriter.Write(':');
|
||
|
if (settings.prettyPrint)
|
||
|
{
|
||
|
baseWriter.Write(' ');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteProperty(string name)
|
||
|
{
|
||
|
base.EndWriteProperty(name);
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteObject(string name)
|
||
|
{
|
||
|
base.StartWriteObject(name);
|
||
|
isFirstProperty = true;
|
||
|
baseWriter.Write('{');
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteObject(string name)
|
||
|
{
|
||
|
base.EndWriteObject(name);
|
||
|
isFirstProperty = false;
|
||
|
WriteNewlineAndTabs();
|
||
|
baseWriter.Write('}');
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteCollection()
|
||
|
{
|
||
|
base.StartWriteCollection();
|
||
|
baseWriter.Write('[');
|
||
|
WriteNewlineAndTabs();
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteCollection()
|
||
|
{
|
||
|
base.EndWriteCollection();
|
||
|
WriteNewlineAndTabs();
|
||
|
baseWriter.Write(']');
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteCollectionItem(int index)
|
||
|
{
|
||
|
if (index != 0)
|
||
|
{
|
||
|
baseWriter.Write(',');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteCollectionItem(int index)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteDictionary()
|
||
|
{
|
||
|
StartWriteObject(null);
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteDictionary()
|
||
|
{
|
||
|
EndWriteObject(null);
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteDictionaryKey(int index)
|
||
|
{
|
||
|
if (index != 0)
|
||
|
{
|
||
|
baseWriter.Write(',');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteDictionaryKey(int index)
|
||
|
{
|
||
|
baseWriter.Write(':');
|
||
|
}
|
||
|
|
||
|
internal override void StartWriteDictionaryValue(int index)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
internal override void EndWriteDictionaryValue(int index)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public override void Dispose()
|
||
|
{
|
||
|
baseWriter.Dispose();
|
||
|
}
|
||
|
|
||
|
public void WriteNewlineAndTabs()
|
||
|
{
|
||
|
if (settings.prettyPrint)
|
||
|
{
|
||
|
baseWriter.Write(Environment.NewLine);
|
||
|
for (int i = 0; i < serializationDepth; i++)
|
||
|
{
|
||
|
baseWriter.Write('\t');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|