Initial sync
This commit is contained in:
401
Nbt/Serialization/SNbt.cs
Executable file
401
Nbt/Serialization/SNbt.cs
Executable file
@@ -0,0 +1,401 @@
|
||||
namespace Nbt.Serialization;
|
||||
|
||||
using System.Globalization;
|
||||
using Nbt.Tag;
|
||||
|
||||
public static class SNbt
|
||||
{
|
||||
#region Serialize
|
||||
|
||||
public enum SerializationStyle
|
||||
{
|
||||
Compact, Spaced, Indented
|
||||
}
|
||||
|
||||
public class SerializerOptions
|
||||
{
|
||||
public static readonly SerializerOptions Default = new();
|
||||
|
||||
public SerializationStyle Style { get; init; } = SerializationStyle.Compact;
|
||||
public bool AlwaysQuoteTagNames { get; init; } = false;
|
||||
// public bool AlwaysQuoteStringTags { get; init; } = false;
|
||||
}
|
||||
|
||||
public static string Serialize(INbtTag tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(NamedTag tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtList tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtCompound tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<sbyte> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<int> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<long> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<sbyte> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<short> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<int> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<long> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<float> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<double> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<string> tag, SerializerOptions? options = null) => Serialize(options, serializer => serializer.Serialize(tag));
|
||||
|
||||
public static void Serialize(TextWriter writer, INbtTag tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, NamedTag tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtList tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtCompound tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<sbyte> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<int> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<long> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<sbyte> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<short> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<int> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<long> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<float> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<double> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<string> tag, SerializerOptions? options = null) => Serialize(writer, options, serializer => serializer.Serialize(tag));
|
||||
|
||||
public static void Serialize(Stream stream, INbtTag tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, NamedTag tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtList tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtCompound tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<sbyte> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<int> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<long> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<sbyte> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<short> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<int> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<long> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<float> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<double> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<string> tag, SerializerOptions? options = null) => Serialize(stream, options, serializer => serializer.Serialize(tag));
|
||||
|
||||
private static void Serialize(TextWriter writer, SerializerOptions? options, Action<Serializer> serialize)
|
||||
{
|
||||
var serializer = new Serializer(writer, options);
|
||||
serialize(serializer);
|
||||
}
|
||||
|
||||
private static void Serialize(Stream stream, SerializerOptions? options, Action<Serializer> serialize)
|
||||
{
|
||||
using var writer = new StreamWriter(stream, leaveOpen: true);
|
||||
Serialize(writer, options, serialize);
|
||||
}
|
||||
|
||||
private static string Serialize(SerializerOptions? options, Action<Serializer> serialize)
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
Serialize(writer, options, serialize);
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
private sealed class Serializer(TextWriter writer, SerializerOptions? options)
|
||||
{
|
||||
private readonly TextWriter writer = writer;
|
||||
private readonly SerializerOptions options = options ?? SerializerOptions.Default;
|
||||
private uint depth = 0u;
|
||||
|
||||
private void WriteIndent()
|
||||
{
|
||||
for (var i = 0u; i < depth; i++)
|
||||
{
|
||||
writer.Write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(INbtTag tag)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case INbtArray arrayTag:
|
||||
Serialize(arrayTag);
|
||||
break;
|
||||
|
||||
case INbtValue valueTag:
|
||||
Serialize(valueTag);
|
||||
break;
|
||||
|
||||
case INbtList listTag:
|
||||
Serialize(listTag);
|
||||
break;
|
||||
|
||||
case INbtCompound compoundTag:
|
||||
Serialize(compoundTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(NamedTag namedTag)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(namedTag.Name))
|
||||
{
|
||||
writer.Write(NbtUtils.QuoteString(namedTag.Name, onlyIfNeeded: !options.AlwaysQuoteTagNames));
|
||||
writer.Write(':');
|
||||
if (options.Style is not SerializationStyle.Compact)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
|
||||
Serialize(namedTag.Tag);
|
||||
}
|
||||
|
||||
public void Serialize(INbtList tag)
|
||||
{
|
||||
writer.Write('[');
|
||||
|
||||
depth++;
|
||||
|
||||
var style = options.Style;
|
||||
var isSpaced = style is SerializationStyle.Spaced;
|
||||
var isIndented = style is SerializationStyle.Indented;
|
||||
|
||||
var b = false;
|
||||
|
||||
foreach (var entry in tag)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
writer.Write(',');
|
||||
if (isSpaced)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
|
||||
if (isIndented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
Serialize(entry);
|
||||
}
|
||||
|
||||
depth--;
|
||||
|
||||
if (b && isIndented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
writer.Write(']');
|
||||
}
|
||||
|
||||
public void Serialize(INbtCompound tag)
|
||||
{
|
||||
writer.Write('{');
|
||||
|
||||
depth++;
|
||||
|
||||
var style = options.Style;
|
||||
var isSpaced = style is SerializationStyle.Spaced;
|
||||
var isIndented = style is SerializationStyle.Indented;
|
||||
|
||||
var b = false;
|
||||
|
||||
foreach (var entry in tag as IEnumerable<NamedTag>)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
writer.Write(',');
|
||||
if (isSpaced)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
|
||||
if (isIndented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
Serialize(entry);
|
||||
}
|
||||
|
||||
depth--;
|
||||
|
||||
if (b && isIndented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
writer.Write('}');
|
||||
}
|
||||
|
||||
public void Serialize(INbtArray tag)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case INbtArray<sbyte> byteArrayTag:
|
||||
Serialize(byteArrayTag);
|
||||
break;
|
||||
|
||||
case INbtArray<int> intArrayTag:
|
||||
Serialize(intArrayTag);
|
||||
break;
|
||||
|
||||
case INbtArray<long> longArrayTag:
|
||||
Serialize(longArrayTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(INbtValue valueTag)
|
||||
{
|
||||
switch (valueTag)
|
||||
{
|
||||
case INbtValue<sbyte> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<short> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<int> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<long> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<float> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<double> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
|
||||
case INbtValue<string> tag:
|
||||
Serialize(tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(INbtArray<sbyte> tag) => Serialize(tag, 'B', Serialize);
|
||||
|
||||
public void Serialize(INbtArray<int> tag) => Serialize(tag, 'I', Serialize);
|
||||
|
||||
public void Serialize(INbtArray<long> tag) => Serialize(tag, 'L', Serialize);
|
||||
|
||||
public void Serialize(INbtValue<sbyte> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<short> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<int> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<long> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<float> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<double> tag) => Serialize(tag.Value);
|
||||
|
||||
public void Serialize(INbtValue<string> tag) => Serialize(tag.Value);
|
||||
|
||||
private void Serialize<T>(INbtArray<T> tag, char decorator, Action<T> writeValue) where T : notnull
|
||||
{
|
||||
writer.Write('[');
|
||||
writer.Write(decorator);
|
||||
writer.Write(';');
|
||||
|
||||
if (tag.Value.Length > 0)
|
||||
{
|
||||
var isNotCompact = options.Style is not SerializationStyle.Compact;
|
||||
|
||||
if (isNotCompact)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
|
||||
var b = false;
|
||||
|
||||
foreach (var e in tag)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
writer.Write(',');
|
||||
if (isNotCompact)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
|
||||
writeValue(e);
|
||||
}
|
||||
}
|
||||
|
||||
writer.Write(']');
|
||||
}
|
||||
|
||||
private void Serialize(sbyte value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
writer.Write('b');
|
||||
}
|
||||
|
||||
private void Serialize(short value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
writer.Write('s');
|
||||
}
|
||||
|
||||
private void Serialize(int value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
private void Serialize(long value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
writer.Write('L');
|
||||
}
|
||||
|
||||
private void Serialize(float value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (float.IsFinite(value))
|
||||
{
|
||||
writer.Write('F');
|
||||
}
|
||||
}
|
||||
|
||||
private void Serialize(double value)
|
||||
{
|
||||
writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (double.IsFinite(value))
|
||||
{
|
||||
writer.Write('D');
|
||||
}
|
||||
}
|
||||
|
||||
private void Serialize(string value)
|
||||
{
|
||||
// Utils.Quote(writer, value, NbtUtils.DOUBLE_QUOTE_CHAR, NbtUtils.ESCAPE_CHAR);
|
||||
writer.Write(NbtUtils.QuoteString(value, onlyIfNeeded: false));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user