Implement my own JSON serializer
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Nbt.Tag;
|
||||
@@ -9,93 +10,93 @@ public static class JsonNbt
|
||||
private static readonly JsonEncodedText TypeProperty = JsonEncodedText.Encode("type");
|
||||
private static readonly JsonEncodedText ValueProperty = JsonEncodedText.Encode("value");
|
||||
|
||||
#region Serialize lossless
|
||||
#region Serialize
|
||||
|
||||
public static string Serialize(INbtTag tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtList tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtCompound tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<sbyte> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<int> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtArray<long> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<sbyte> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<short> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<int> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<long> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<float> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<double> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
public static string Serialize(INbtValue<string> tag) => Serialize(serializer => serializer.Serialize(tag));
|
||||
#region Lossless
|
||||
|
||||
public static void Serialize(TextWriter writer, INbtTag tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtList tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtCompound tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<sbyte> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<int> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtArray<long> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<sbyte> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<short> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<int> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<long> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<float> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<double> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(TextWriter writer, INbtValue<string> tag) => Serialize(writer, serializer => serializer.Serialize(tag));
|
||||
public enum SerializationStyle
|
||||
{
|
||||
Compact, Spaced, Indented
|
||||
}
|
||||
|
||||
public static void Serialize(Stream stream, INbtTag tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtList tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtCompound tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<sbyte> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<int> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<long> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<sbyte> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<short> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<int> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<long> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<float> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<double> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<string> tag) => Serialize(stream, serializer => serializer.Serialize(tag));
|
||||
public class SerializerOptions
|
||||
{
|
||||
public static readonly SerializerOptions Default = new();
|
||||
|
||||
private static string Serialize(Action<Serializer> serialize)
|
||||
public SerializationStyle Style { get; init; } = SerializationStyle.Compact;
|
||||
public string Indent { get; init; } = " ";
|
||||
}
|
||||
|
||||
public static string Serialize(INbtTag 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, 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, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtList tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtCompound tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<sbyte> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<int> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtArray<long> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<sbyte> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<short> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<int> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<long> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<float> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<double> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
public static void Serialize(Stream stream, INbtValue<string> tag, Encoding? encoding = null, SerializerOptions? options = null) => Serialize(stream, encoding, options, serializer => serializer.Serialize(tag));
|
||||
|
||||
private static string Serialize(SerializerOptions? options, Action<LosslessSerializer> serialize)
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
Serialize(writer, serialize);
|
||||
Serialize(writer, options, serialize);
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
private static void Serialize(TextWriter writer, Action<Serializer> serialize)
|
||||
private static void Serialize(Stream stream, Encoding? encoding, SerializerOptions? options, Action<LosslessSerializer> serialize)
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
Serialize(stream, serialize);
|
||||
stream.Position = 0L;
|
||||
|
||||
using var reader = new StreamReader(stream, encoding: Encoding.UTF8, leaveOpen: true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
var i = reader.Read();
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
writer.Write((char)i);
|
||||
}
|
||||
using var writer = new StreamWriter(stream, encoding ?? Encoding.Default);
|
||||
Serialize(writer, options, serialize);
|
||||
}
|
||||
|
||||
private static void Serialize(Stream stream, Action<Serializer> serialize)
|
||||
private static void Serialize(TextWriter writer, SerializerOptions? options, Action<LosslessSerializer> serialize)
|
||||
{
|
||||
using var serializer = new Serializer(stream);
|
||||
using var serializer = new LosslessSerializer(writer, options);
|
||||
serialize(serializer);
|
||||
}
|
||||
|
||||
private sealed class Serializer(Stream stream) : IDisposable
|
||||
private sealed class LosslessSerializer(TextWriter writer, SerializerOptions? options, bool leaveOpen = false) : IDisposable
|
||||
{
|
||||
private readonly Utf8JsonWriter writer = new(stream, new() { Indented = true, SkipValidation = true });
|
||||
private readonly JsonWriter writer = new(writer, options, leaveOpen);
|
||||
|
||||
public void Serialize(INbtTag tag)
|
||||
{
|
||||
@@ -121,13 +122,13 @@ public static class JsonNbt
|
||||
|
||||
public void Serialize(INbtList tag)
|
||||
{
|
||||
using (new NbtObjectMeta(writer, tag.Type))
|
||||
using (new NbtObjectMeta(writer, tag))
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
|
||||
foreach (var entry in tag)
|
||||
{
|
||||
Serialize(entry);
|
||||
writer.WriteElement(entry, Serialize);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
@@ -136,14 +137,13 @@ public static class JsonNbt
|
||||
|
||||
public void Serialize(INbtCompound tag)
|
||||
{
|
||||
using (new NbtObjectMeta(writer, tag.Type))
|
||||
using (new NbtObjectMeta(writer, tag))
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer. WriteStartObject();
|
||||
|
||||
foreach (var entry in tag as IEnumerable<NamedTag>)
|
||||
{
|
||||
writer.WritePropertyName(entry.Name);
|
||||
Serialize(entry.Tag);
|
||||
writer.WriteProperty(entry.Name, entry.Tag, Serialize);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
@@ -216,13 +216,13 @@ public static class JsonNbt
|
||||
|
||||
private void Serialize<T>(INbtArray<T> tag, Action<T> writeValue) where T : notnull
|
||||
{
|
||||
using (new NbtObjectMeta(writer, tag.Type))
|
||||
using (new NbtObjectMeta(writer, tag))
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
|
||||
foreach (var e in tag)
|
||||
foreach (var element in tag)
|
||||
{
|
||||
writeValue(e);
|
||||
writer.WriteElement(element, writeValue);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
@@ -231,19 +231,19 @@ public static class JsonNbt
|
||||
|
||||
private void Serialize<T>(INbtValue<T> tag, Action<T> writeValue) where T : notnull
|
||||
{
|
||||
using (new NbtObjectMeta(writer, tag.Type))
|
||||
using (new NbtObjectMeta(writer, tag))
|
||||
{
|
||||
writeValue(tag.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Serialize(sbyte value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(short value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(int value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(long value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(float value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(double value) => writer.WriteNumberValue(value);
|
||||
private void Serialize(string value) => writer.WriteStringValue(value);
|
||||
private void Serialize(sbyte value) => writer.WriteValue(value);
|
||||
private void Serialize(short value) => writer.WriteValue(value);
|
||||
private void Serialize(int value) => writer.WriteValue(value);
|
||||
private void Serialize(long value) => writer.WriteValue(value);
|
||||
private void Serialize(float value) => writer.WriteValue(value);
|
||||
private void Serialize(double value) => writer.WriteValue(value);
|
||||
private void Serialize(string value) => writer.WriteValue(value);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -251,116 +251,82 @@ public static class JsonNbt
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private readonly struct NbtObjectMeta : IDisposable
|
||||
{
|
||||
private readonly Utf8JsonWriter writer;
|
||||
|
||||
public NbtObjectMeta(Utf8JsonWriter writer, NbtTagType tagType)
|
||||
{
|
||||
this.writer = writer;
|
||||
|
||||
writer.WriteStartObject();
|
||||
writer.WriteNumber(TypeProperty, (int)tagType);
|
||||
writer.WritePropertyName(ValueProperty);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialize lossy
|
||||
#region Lossy
|
||||
|
||||
public static string ToJson(INbtTag tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtList tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtCompound tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<sbyte> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<int> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<long> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<sbyte> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<short> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<int> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<long> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<float> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<double> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<string> tag) => ToJson(serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtTag tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtList tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtCompound tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<sbyte> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<int> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtArray<long> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<sbyte> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<short> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<int> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<long> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<float> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<double> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
public static string ToJson(INbtValue<string> tag, SerializerOptions? options = null) => ToJson(options, serializer => serializer.ToJson(tag));
|
||||
|
||||
public static void ToJson(TextWriter writer, INbtTag tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtList tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtCompound tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<sbyte> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<int> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<long> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<sbyte> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<short> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<int> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<long> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<float> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<double> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<string> tag) => ToJson(writer, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtTag tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtList tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtCompound tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<sbyte> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<int> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtArray<long> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<sbyte> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<short> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<int> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<long> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<float> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<double> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(TextWriter writer, INbtValue<string> tag, SerializerOptions? options = null) => ToJson(writer, options, serializer => serializer.ToJson(tag));
|
||||
|
||||
public static void ToJson(Stream stream, INbtTag tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtList tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtCompound tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<sbyte> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<int> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<long> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<sbyte> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<short> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<int> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<long> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<float> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<double> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<string> tag) => ToJson(stream, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtTag tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtList tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtCompound tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<sbyte> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<int> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtArray<long> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<sbyte> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<short> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<int> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<long> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<float> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<double> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
public static void ToJson(Stream stream, INbtValue<string> tag, Encoding? encoding = null, SerializerOptions? options = null) => ToJson(stream, encoding, options, serializer => serializer.ToJson(tag));
|
||||
|
||||
private static string ToJson(Action<LossySerializer> serialize)
|
||||
private static string ToJson(SerializerOptions? options, Action<LossySerializer> serialize)
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
ToJson(writer, serialize);
|
||||
ToJson(writer, options, serialize);
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
private static void ToJson(TextWriter writer, Action<LossySerializer> serialize)
|
||||
private static void ToJson(Stream stream, Encoding? encoding, SerializerOptions? options, Action<LossySerializer> serialize)
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
ToJson(stream, serialize);
|
||||
stream.Position = 0L;
|
||||
|
||||
using var reader = new StreamReader(stream, encoding: Encoding.UTF8, leaveOpen: true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
var i = reader.Read();
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
writer.Write((char)i);
|
||||
}
|
||||
using var writer = new StreamWriter(stream, encoding ?? Encoding.Default);
|
||||
ToJson(writer, options, serialize);
|
||||
}
|
||||
|
||||
private static void ToJson(Stream stream, Action<LossySerializer> serialize)
|
||||
private static void ToJson(TextWriter writer, SerializerOptions? options, Action<LossySerializer> serialize)
|
||||
{
|
||||
using var serializer = new LossySerializer(stream);
|
||||
using var serializer = new LossySerializer(writer, options);
|
||||
serialize(serializer);
|
||||
}
|
||||
|
||||
private sealed class LossySerializer(Stream stream) : IDisposable
|
||||
private sealed class LossySerializer(TextWriter writer, SerializerOptions? options, bool leaveOpen = false) : IDisposable
|
||||
{
|
||||
private readonly Utf8JsonWriter writer = new(stream, new() { Indented = true, SkipValidation = true });
|
||||
private readonly JsonWriter writer = new(writer, options, leaveOpen);
|
||||
|
||||
public void ToJson(INbtTag tag)
|
||||
{
|
||||
@@ -390,7 +356,7 @@ public static class JsonNbt
|
||||
|
||||
foreach (var entry in tag)
|
||||
{
|
||||
ToJson(entry);
|
||||
writer.WriteElement(entry, ToJson);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
@@ -402,8 +368,7 @@ public static class JsonNbt
|
||||
|
||||
foreach (var entry in tag as IEnumerable<NamedTag>)
|
||||
{
|
||||
writer.WritePropertyName(entry.Name);
|
||||
ToJson(entry.Tag);
|
||||
writer.WriteProperty(entry.Name, entry.Tag, ToJson);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
@@ -479,7 +444,7 @@ public static class JsonNbt
|
||||
|
||||
foreach (var e in tag)
|
||||
{
|
||||
writeValue(e);
|
||||
writer.WriteElement(e, writeValue);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
@@ -487,13 +452,13 @@ public static class JsonNbt
|
||||
|
||||
private static void ToJson<T>(INbtValue<T> tag, Action<T> writeValue) where T : notnull => writeValue(tag.Value);
|
||||
|
||||
private void ToJson(sbyte value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(short value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(int value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(long value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(float value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(double value) => writer.WriteNumberValue(value);
|
||||
private void ToJson(string value) => writer.WriteStringValue(value);
|
||||
private void ToJson(sbyte value) => writer.WriteValue(value);
|
||||
private void ToJson(short value) => writer.WriteValue(value);
|
||||
private void ToJson(int value) => writer.WriteValue(value);
|
||||
private void ToJson(long value) => writer.WriteValue(value);
|
||||
private void ToJson(float value) => writer.WriteValue(value);
|
||||
private void ToJson(double value) => writer.WriteValue(value);
|
||||
private void ToJson(string value) => writer.WriteValue(value);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -505,6 +470,192 @@ public static class JsonNbt
|
||||
|
||||
#endregion
|
||||
|
||||
private sealed class JsonWriter(TextWriter writer, SerializerOptions? options, bool leaveOpen = false) : IDisposable
|
||||
{
|
||||
private readonly TextWriter writer = writer;
|
||||
private readonly SerializerOptions options = options ?? SerializerOptions.Default;
|
||||
private readonly bool leaveOpen = leaveOpen;
|
||||
private int depth = 0;
|
||||
private Context context = new(null, 0);
|
||||
|
||||
public void WriteStartArray()
|
||||
{
|
||||
writer.Write('[');
|
||||
|
||||
depth++;
|
||||
context = new(context, 1);
|
||||
}
|
||||
|
||||
public void WriteEndArray()
|
||||
{
|
||||
depth--;
|
||||
|
||||
if (context.length > 0 && options.Style is SerializationStyle.Indented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
context = context.parent!;
|
||||
|
||||
writer.Write(']');
|
||||
}
|
||||
|
||||
public void WriteStartObject()
|
||||
{
|
||||
writer.Write('{');
|
||||
|
||||
depth++;
|
||||
context = new(context, 2);
|
||||
}
|
||||
|
||||
public void WriteEndObject()
|
||||
{
|
||||
depth--;
|
||||
|
||||
if (context.length > 0 && options.Style is SerializationStyle.Indented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
context = context.parent!;
|
||||
|
||||
writer.Write('}');
|
||||
}
|
||||
|
||||
public void WriteElement(byte value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(sbyte value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(short value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(ushort value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(int value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(uint value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(long value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(ulong value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(float value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(double value) => WriteElement(value, WriteValue);
|
||||
public void WriteElement(string value) => WriteElement(value, WriteValue);
|
||||
|
||||
public void WriteElement<T>(T value, Action<T> elementWriter)
|
||||
{
|
||||
WriteSeparator();
|
||||
|
||||
elementWriter(value);
|
||||
|
||||
context.length++;
|
||||
}
|
||||
|
||||
public void WriteProperty(string name, byte value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, sbyte value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, short value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, ushort value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, int value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, uint value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, long value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, ulong value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, float value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, double value) => WriteProperty(name, value, WriteValue);
|
||||
public void WriteProperty(string name, string value) => WriteProperty(name, value, WriteValue);
|
||||
|
||||
public void WritePropertyName(string name)
|
||||
{
|
||||
WriteSeparator();
|
||||
|
||||
WriteValue(name);
|
||||
|
||||
writer.Write(':');
|
||||
if (options.Style is not SerializationStyle.Compact)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteProperty<T>(string name, T value, Action<T> valueWriter)
|
||||
{
|
||||
WritePropertyName(name);
|
||||
|
||||
valueWriter(value);
|
||||
|
||||
context.length++;
|
||||
}
|
||||
|
||||
public void WriteValue(byte value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(sbyte value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(short value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(ushort value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(int value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(uint value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(long value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(ulong value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(float value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(double value) => writer.Write(value.ToString(CultureInfo.InvariantCulture));
|
||||
public void WriteValue(string value) => Utils.Quote(writer, value, '"', '\\');
|
||||
|
||||
private void WriteSeparator()
|
||||
{
|
||||
if (context.length > 0)
|
||||
{
|
||||
writer.Write(',');
|
||||
if (options.Style is SerializationStyle.Spaced)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
}
|
||||
|
||||
if (options.Style is SerializationStyle.Indented)
|
||||
{
|
||||
writer.WriteLine();
|
||||
WriteIndent();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIndent()
|
||||
{
|
||||
for (var i = 0; i < depth; i++)
|
||||
{
|
||||
writer.Write(options.Indent);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!leaveOpen)
|
||||
{
|
||||
writer.Dispose();
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private class Context(Context? parent, byte type)
|
||||
{
|
||||
public readonly Context? parent = parent;
|
||||
public readonly byte type = type;
|
||||
public int length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct NbtObjectMeta : IDisposable
|
||||
{
|
||||
private readonly JsonWriter writer;
|
||||
|
||||
public NbtObjectMeta(JsonWriter writer, INbtTag tag)
|
||||
{
|
||||
this.writer = writer;
|
||||
|
||||
writer.WriteStartObject();
|
||||
writer.WriteProperty(TypeProperty.Value, (int)tag.Type);
|
||||
writer.WritePropertyName(ValueProperty.Value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Deserialize
|
||||
|
||||
public static INbtTag Deserialize(string s)
|
||||
|
||||
Reference in New Issue
Block a user