295 lines
5.8 KiB
C#
295 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Gaia.FullSerializer
|
|
{
|
|
public static class fsJsonPrinter
|
|
{
|
|
private static void InsertSpacing(TextWriter stream, int count)
|
|
{
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
stream.Write(" ");
|
|
}
|
|
}
|
|
|
|
private static string EscapeString(string str)
|
|
{
|
|
bool flag = false;
|
|
foreach (char c in str)
|
|
{
|
|
int num = Convert.ToInt32(c);
|
|
if (num < 0 || num > 127)
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
switch (c)
|
|
{
|
|
case '\0':
|
|
case '\a':
|
|
case '\b':
|
|
case '\t':
|
|
case '\n':
|
|
case '\f':
|
|
case '\r':
|
|
case '"':
|
|
case '\\':
|
|
flag = true;
|
|
break;
|
|
}
|
|
if (flag)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
return str;
|
|
}
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
foreach (char c2 in str)
|
|
{
|
|
int num2 = Convert.ToInt32(c2);
|
|
if (num2 < 0 || num2 > 127)
|
|
{
|
|
stringBuilder.Append($"\\u{num2:x4} ".Trim());
|
|
continue;
|
|
}
|
|
switch (c2)
|
|
{
|
|
case '"':
|
|
stringBuilder.Append("\\\"");
|
|
break;
|
|
case '\\':
|
|
stringBuilder.Append("\\\\");
|
|
break;
|
|
case '\a':
|
|
stringBuilder.Append("\\a");
|
|
break;
|
|
case '\b':
|
|
stringBuilder.Append("\\b");
|
|
break;
|
|
case '\f':
|
|
stringBuilder.Append("\\f");
|
|
break;
|
|
case '\n':
|
|
stringBuilder.Append("\\n");
|
|
break;
|
|
case '\r':
|
|
stringBuilder.Append("\\r");
|
|
break;
|
|
case '\t':
|
|
stringBuilder.Append("\\t");
|
|
break;
|
|
case '\0':
|
|
stringBuilder.Append("\\0");
|
|
break;
|
|
default:
|
|
stringBuilder.Append(c2);
|
|
break;
|
|
}
|
|
}
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
private static void BuildCompressedString(fsData data, TextWriter stream)
|
|
{
|
|
switch (data.Type)
|
|
{
|
|
case fsDataType.Null:
|
|
stream.Write("null");
|
|
break;
|
|
case fsDataType.Boolean:
|
|
if (data.AsBool)
|
|
{
|
|
stream.Write("true");
|
|
}
|
|
else
|
|
{
|
|
stream.Write("false");
|
|
}
|
|
break;
|
|
case fsDataType.Double:
|
|
stream.Write(ConvertDoubleToString(data.AsDouble));
|
|
break;
|
|
case fsDataType.Int64:
|
|
stream.Write(data.AsInt64);
|
|
break;
|
|
case fsDataType.UInt64:
|
|
stream.Write(data.AsUInt64);
|
|
break;
|
|
case fsDataType.String:
|
|
stream.Write('"');
|
|
stream.Write(EscapeString(data.AsString));
|
|
stream.Write('"');
|
|
break;
|
|
case fsDataType.Object:
|
|
{
|
|
stream.Write('{');
|
|
bool flag2 = false;
|
|
foreach (KeyValuePair<string, fsData> item in data.AsDictionary)
|
|
{
|
|
if (flag2)
|
|
{
|
|
stream.Write(',');
|
|
}
|
|
flag2 = true;
|
|
stream.Write('"');
|
|
stream.Write(item.Key);
|
|
stream.Write('"');
|
|
stream.Write(":");
|
|
BuildCompressedString(item.Value, stream);
|
|
}
|
|
stream.Write('}');
|
|
break;
|
|
}
|
|
case fsDataType.Array:
|
|
{
|
|
stream.Write('[');
|
|
bool flag = false;
|
|
foreach (fsData @as in data.AsList)
|
|
{
|
|
if (flag)
|
|
{
|
|
stream.Write(',');
|
|
}
|
|
flag = true;
|
|
BuildCompressedString(@as, stream);
|
|
}
|
|
stream.Write(']');
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void BuildPrettyString(fsData data, TextWriter stream, int depth)
|
|
{
|
|
switch (data.Type)
|
|
{
|
|
case fsDataType.Null:
|
|
stream.Write("null");
|
|
break;
|
|
case fsDataType.Boolean:
|
|
if (data.AsBool)
|
|
{
|
|
stream.Write("true");
|
|
}
|
|
else
|
|
{
|
|
stream.Write("false");
|
|
}
|
|
break;
|
|
case fsDataType.Double:
|
|
stream.Write(ConvertDoubleToString(data.AsDouble));
|
|
break;
|
|
case fsDataType.Int64:
|
|
stream.Write(data.AsInt64);
|
|
break;
|
|
case fsDataType.UInt64:
|
|
stream.Write(data.AsUInt64);
|
|
break;
|
|
case fsDataType.String:
|
|
stream.Write('"');
|
|
stream.Write(EscapeString(data.AsString));
|
|
stream.Write('"');
|
|
break;
|
|
case fsDataType.Object:
|
|
{
|
|
stream.Write('{');
|
|
stream.WriteLine();
|
|
bool flag2 = false;
|
|
foreach (KeyValuePair<string, fsData> item in data.AsDictionary)
|
|
{
|
|
if (flag2)
|
|
{
|
|
stream.Write(',');
|
|
stream.WriteLine();
|
|
}
|
|
flag2 = true;
|
|
InsertSpacing(stream, depth + 1);
|
|
stream.Write('"');
|
|
stream.Write(item.Key);
|
|
stream.Write('"');
|
|
stream.Write(": ");
|
|
BuildPrettyString(item.Value, stream, depth + 1);
|
|
}
|
|
stream.WriteLine();
|
|
InsertSpacing(stream, depth);
|
|
stream.Write('}');
|
|
break;
|
|
}
|
|
case fsDataType.Array:
|
|
{
|
|
if (data.AsList.Count == 0)
|
|
{
|
|
stream.Write("[]");
|
|
break;
|
|
}
|
|
bool flag = false;
|
|
stream.Write('[');
|
|
stream.WriteLine();
|
|
foreach (fsData @as in data.AsList)
|
|
{
|
|
if (flag)
|
|
{
|
|
stream.Write(',');
|
|
stream.WriteLine();
|
|
}
|
|
flag = true;
|
|
InsertSpacing(stream, depth + 1);
|
|
BuildPrettyString(@as, stream, depth + 1);
|
|
}
|
|
stream.WriteLine();
|
|
InsertSpacing(stream, depth);
|
|
stream.Write(']');
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void PrettyJson(fsData data, TextWriter outputStream)
|
|
{
|
|
BuildPrettyString(data, outputStream, 0);
|
|
}
|
|
|
|
public static string PrettyJson(fsData data)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
using StringWriter stream = new StringWriter(stringBuilder);
|
|
BuildPrettyString(data, stream, 0);
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static void CompressedJson(fsData data, StreamWriter outputStream)
|
|
{
|
|
BuildCompressedString(data, outputStream);
|
|
}
|
|
|
|
public static string CompressedJson(fsData data)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
using StringWriter stream = new StringWriter(stringBuilder);
|
|
BuildCompressedString(data, stream);
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
private static string ConvertDoubleToString(double d)
|
|
{
|
|
if (double.IsInfinity(d) || double.IsNaN(d))
|
|
{
|
|
return d.ToString(CultureInfo.InvariantCulture);
|
|
}
|
|
string text = d.ToString(CultureInfo.InvariantCulture);
|
|
if (!text.Contains("."))
|
|
{
|
|
text += ".0";
|
|
}
|
|
return text;
|
|
}
|
|
}
|
|
}
|