Converted DataContract members to ISerializable interface for finer control
This commit is contained in:
parent
4aa2959e7e
commit
22aef3be81
|
@ -0,0 +1,22 @@
|
|||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace SharpNBT.Tests
|
||||
{
|
||||
public class ConversionTest
|
||||
{
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public ConversionTest(ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonOutput1()
|
||||
{
|
||||
var bigtest = TestHelper.GetTag("bigtest.nbt", CompressionType.GZip);
|
||||
output.WriteLine(bigtest.ToJsonString(true));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,28 +15,17 @@ namespace SharpNBT.Tests
|
|||
this.output = output;
|
||||
}
|
||||
|
||||
private static Stream GetFile(string filename)
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
return assembly.GetManifestResourceStream($"SharpNBT.Tests.Data.{filename}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadUncompressed()
|
||||
{
|
||||
using var stream = GetFile("hello_world.nbt");
|
||||
using var reader = new TagReader(stream, FormatOptions.Java);
|
||||
var compound = reader.ReadTag<CompoundTag>();
|
||||
var compound = TestHelper.GetTag("hello_world.nbt", CompressionType.None);
|
||||
output.WriteLine(compound.PrettyPrinted());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadGZipped()
|
||||
{
|
||||
using var stream = GetFile("bigtest.nbt");
|
||||
using var gzip = new GZipStream(stream, CompressionMode.Decompress);
|
||||
using var reader = new TagReader(gzip, FormatOptions.Java);
|
||||
var compound = reader.ReadTag<CompoundTag>();
|
||||
var compound = TestHelper.GetTag("bigtest.nbt", CompressionType.GZip);
|
||||
output.WriteLine(compound.PrettyPrinted());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using SharpNBT.ZLib;
|
||||
|
||||
namespace SharpNBT.Tests
|
||||
{
|
||||
public class TestHelper
|
||||
{
|
||||
public static Stream GetFile(string filename, CompressionType compression)
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var stream = assembly.GetManifestResourceStream($"SharpNBT.Tests.Data.{filename}");
|
||||
if (stream is null)
|
||||
throw new FileNotFoundException(filename);
|
||||
|
||||
return compression switch
|
||||
{
|
||||
CompressionType.None => stream,
|
||||
CompressionType.GZip => new GZipStream(stream, CompressionMode.Decompress),
|
||||
CompressionType.ZLib => new ZLibStream(stream, CompressionMode.Decompress),
|
||||
_ => throw new Exception()
|
||||
};
|
||||
}
|
||||
|
||||
public static CompoundTag GetTag(string filename, CompressionType compression)
|
||||
{
|
||||
using var stream = GetFile(filename, compression);
|
||||
using var reader = new TagReader(stream, FormatOptions.Java);
|
||||
return reader.ReadTag<CompoundTag>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -423,7 +423,7 @@ namespace SharpNBT
|
|||
return Encoding.UTF8.GetString(utf8);
|
||||
}
|
||||
|
||||
private int ReadCount() => UseVarInt ? ReadInt32() : VarInt.Read(BaseStream, ZigZagEncoding);
|
||||
private int ReadCount() => UseVarInt ? VarInt.Read(BaseStream, ZigZagEncoding) : ReadInt32();
|
||||
|
||||
/// <summary>
|
||||
/// Reads a 64-bit signed (big-endian) integer from the stream, converting to native endian when necessary.
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpNBT
|
|||
/// While this class uses the CLS compliant <see cref="byte"/> (0..255), the NBT specification uses a signed value with a range of -128..127, so ensure
|
||||
/// the bits are equivalent for your values.
|
||||
/// </remarks>
|
||||
[PublicAPI][DataContract(Name = "byte_array")]
|
||||
[PublicAPI][Serializable]
|
||||
public class ByteArrayTag : EnumerableTag<byte>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpNBT
|
|||
/// recommended to use the <see cref="SignedValue"/> property if your language supports a signed 8-bit value, otherwise simply ensure the bits are
|
||||
/// equivalent.
|
||||
/// </remarks>
|
||||
[PublicAPI][DataContract(Name = "byte")]
|
||||
[PublicAPI][Serializable]
|
||||
public class ByteTag : Tag<byte>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
@ -12,7 +13,7 @@ namespace SharpNBT
|
|||
/// This along with the <see cref="ListTag"/> class define the structure of the NBT format. Children are not order-dependent, nor is order guaranteed. The
|
||||
/// closing <see cref="EndTag"/> does not require to be explicitly added, it will be added automatically during serialization.
|
||||
/// </remarks>
|
||||
[PublicAPI][DataContract(Name = "compound")]
|
||||
[PublicAPI][Serializable]
|
||||
public class CompoundTag : TagContainer
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
|
@ -6,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that contains a single IEEE-754 double-precision floating point number.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "double")]
|
||||
[PublicAPI][Serializable]
|
||||
public class DoubleTag : Tag<double>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Represents the end of <see cref="CompoundTag"/>.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "end")]
|
||||
[PublicAPI]
|
||||
public class EndTag : Tag
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -12,13 +12,12 @@ namespace SharpNBT
|
|||
/// Base class for tags that contain a collection of values and can be enumerated.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the item the tag contains.</typeparam>
|
||||
[PublicAPI][DataContract(Name = "array")]
|
||||
[PublicAPI][Serializable]
|
||||
public abstract class EnumerableTag<T> : Tag, IList<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal list implementation.
|
||||
/// </summary>
|
||||
[DataMember(Name = "values")]
|
||||
private readonly List<T> internalList = new List<T>();
|
||||
|
||||
/// <summary>
|
||||
|
@ -63,6 +62,23 @@ namespace SharpNBT
|
|||
internalList.AddRange(values.ToArray());
|
||||
}
|
||||
|
||||
protected EnumerableTag(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
var dummy = info.GetInt32("count");
|
||||
internalList.AddRange((T[]) info.GetValue("values", typeof(T[])));
|
||||
}
|
||||
|
||||
/// <summary>Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with the data needed to serialize the target object.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> to populate with data.</param>
|
||||
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext" />) for this serialization.</param>
|
||||
/// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission.</exception>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("count", Count);
|
||||
info.AddValue("values", internalList.ToArray(), typeof(T[]));
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the collection.</returns>
|
||||
/// <footer><a href="https://docs.microsoft.com/en-us/dotnet/api/System.Collections.Generic.IEnumerable-1.GetEnumerator?view=netcore-5.0">`IEnumerable.GetEnumerator` on docs.microsoft.com</a></footer>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
|
@ -6,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that contains a single IEEE-754 single-precision floating point number.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "float")]
|
||||
[PublicAPI][Serializable]
|
||||
public class FloatTag : Tag<float>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that whose value is a contiguous sequence of 32-bit integers.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "int_array")]
|
||||
[PublicAPI][Serializable]
|
||||
public class IntArrayTag : EnumerableTag<int>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that contains a single 32-bit integer value.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "int")]
|
||||
[PublicAPI][Serializable]
|
||||
public class IntTag : Tag<int>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
@ -11,13 +12,12 @@ namespace SharpNBT
|
|||
/// <remarks>
|
||||
/// All child tags <b>must</b> be have the same <see cref="Tag.Type"/> value, and their <see cref="Tag.Name"/> value will be omitted during serialization.
|
||||
/// </remarks>
|
||||
[PublicAPI][DataContract(Name = "list")]
|
||||
[PublicAPI][Serializable]
|
||||
public class ListTag : TagContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the NBT type of this tag's children.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true, Name = "child_type", Order = 2)]
|
||||
public TagType ChildType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that whose value is a contiguous sequence of 64-bit integers.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "long_array")]
|
||||
[PublicAPI][Serializable]
|
||||
public class LongArrayTag : EnumerableTag<long>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that contains a single 64-bit integer value.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "long")]
|
||||
[PublicAPI][Serializable]
|
||||
public class LongTag : Tag<long>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag that contains a single 16-bit integer value.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "short")]
|
||||
[PublicAPI][Serializable]
|
||||
public class ShortTag : Tag<short>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
|
@ -6,7 +7,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// A tag the contains a UTF-8 string.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract(Name = "string")]
|
||||
[PublicAPI][Serializable]
|
||||
public class StringTag : Tag<string>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Abstract base class that all NBT tags inherit from.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract][KnownType("GetKnownTypes")]
|
||||
public abstract class Tag : IEquatable<Tag>
|
||||
[PublicAPI][Serializable]
|
||||
public abstract class Tag : IEquatable<Tag>, ISerializable
|
||||
{
|
||||
private static IEnumerable<Type> GetKnownTypes()
|
||||
{
|
||||
|
@ -47,7 +47,6 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Gets a constant describing the NBT type this object represents.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true, Name = "type", Order = 0)]
|
||||
public TagType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -59,7 +58,6 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Gets the name assigned to this <see cref="Tag"/>.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "name")]
|
||||
[CanBeNull]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
@ -169,6 +167,22 @@ namespace SharpNBT
|
|||
}
|
||||
}
|
||||
|
||||
protected Tag(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
Type = (TagType) info.GetByte("type");
|
||||
Name = info.GetString("name");
|
||||
}
|
||||
|
||||
/// <summary>Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with the data needed to serialize the target object.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> to populate with data.</param>
|
||||
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext" />) for this serialization.</param>
|
||||
/// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission.</exception>
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("type", (byte) Type);
|
||||
info.AddValue("name", Name);
|
||||
}
|
||||
|
||||
public static bool operator ==(Tag left, Tag right) => Equals(left, right);
|
||||
|
||||
public static bool operator !=(Tag left, Tag right) => !Equals(left, right);
|
||||
|
@ -178,14 +192,28 @@ namespace SharpNBT
|
|||
/// Abstract base class for <see cref="Tag"/> types that contain a single primitive value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the value the tag represents.</typeparam>
|
||||
[PublicAPI][DataContract]
|
||||
[PublicAPI][Serializable]
|
||||
public abstract class Tag<T> : Tag, IEquatable<Tag<T>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the tag.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = false, Name = "value")]
|
||||
public T Value { get; set; }
|
||||
|
||||
protected Tag(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
Value = (T)info.GetValue("value", typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with the data needed to serialize the target object.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> to populate with data.</param>
|
||||
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext" />) for this serialization.</param>
|
||||
/// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission.</exception>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("value", Value, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DoubleTag"/> class with the specified <paramref name="value"/>.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Base class for tags that contain a collection of other <see cref="Tag"/> objects and can be enumerated.
|
||||
/// </summary>
|
||||
[PublicAPI][DataContract]
|
||||
[PublicAPI][Serializable]
|
||||
public abstract class TagContainer : EnumerableTag<Tag>
|
||||
{
|
||||
protected bool NamedChildren;
|
||||
|
@ -34,6 +34,23 @@ namespace SharpNBT
|
|||
protected TagContainer(TagType type, [CanBeNull] string name, [NotNull][ItemNotNull] IEnumerable<Tag> values) : base(type, name, values)
|
||||
{
|
||||
}
|
||||
|
||||
protected TagContainer(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
RequiredType = (TagType?) info.GetValue("child_type", typeof(TagType?));
|
||||
NamedChildren = !RequiredType.HasValue;
|
||||
}
|
||||
|
||||
/// <summary>Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with the data needed to serialize the target object.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> to populate with data.</param>
|
||||
/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext" />) for this serialization.</param>
|
||||
/// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission.</exception>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
if (RequiredType.HasValue)
|
||||
info.AddValue("child_type", RequiredType.Value);
|
||||
}
|
||||
|
||||
/// <summary>Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.</summary>
|
||||
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace SharpNBT
|
||||
|
@ -5,7 +6,7 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Strongly-typed numerical constants that are prefixed to tags to denote their type.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[PublicAPI][Serializable]
|
||||
public enum TagType : byte
|
||||
{
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in New Issue