Skip to content

Commit

Permalink
Changed target to .NET 7 with latest language version
Browse files Browse the repository at this point in the history
Changed to use latest language/runtime, as well as adopt modern style/syntax.
  • Loading branch information
ForeverZer0 committed Aug 26, 2023
1 parent 44e723f commit d73bc2f
Show file tree
Hide file tree
Showing 43 changed files with 4,753 additions and 5,456 deletions.
186 changes: 92 additions & 94 deletions SharpNBT/BufferedTagWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,116 +3,114 @@
using System.IO.Compression;
using System.Threading.Tasks;
using JetBrains.Annotations;
using SharpNBT.ZLib;

namespace SharpNBT
namespace SharpNBT;

/// <summary>
/// Provides a <see cref="TagWriter"/> object that writes to an internal buffer instead of a <see cref="Stream"/> object, which then can be retrieved as
/// an array of bytes or written directly to a stream. This is especially convenient when creating packets to be sent over a network, where the size of
/// the packet must be pre-determined before sending.
/// </summary>
[PublicAPI]
public class BufferedTagWriter : TagWriter
{
private readonly MemoryStream buffer;

/// <summary>
/// Provides a <see cref="TagWriter"/> object that writes to an internal buffer instead of a <see cref="Stream"/> object, which then can be retrieved as
/// an array of bytes or written directly to a stream. This is especially convenient when creating packets to be sent over a network, where the size of
/// the packet must be pre-determined before sending.
/// Creates a new instance of the <see cref="BufferedTagWriter"/> class.
/// </summary>
[PublicAPI]
public class BufferedTagWriter : TagWriter
/// <param name="compression">Indicates the compression algorithm used to compress the file.</param>
/// <param name="options">Bitwise flags to configure how data should be handled for compatibility between different specifications.</param>
/// <returns>A newly created <see cref="BufferedTagWriter"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when an invalid compression type is specified.</exception>
public static BufferedTagWriter Create(CompressionType compression, FormatOptions options)
{
private readonly MemoryStream buffer;

/// <summary>
/// Creates a new instance of the <see cref="BufferedTagWriter"/> class.
/// </summary>
/// <param name="compression">Indicates the compression algorithm used to compress the file.</param>
/// <param name="options">Bitwise flags to configure how data should be handled for compatibility between different specifications.</param>
/// <returns>A newly created <see cref="BufferedTagWriter"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when an invalid compression type is specified.</exception>
public static BufferedTagWriter Create(CompressionType compression, FormatOptions options)
{
// ReSharper disable once IntroduceOptionalParameters.Global
return Create(compression, options, 4096);
}
// ReSharper disable once IntroduceOptionalParameters.Global
return Create(compression, options, 4096);
}

/// <summary>
/// Creates a new instance of the <see cref="BufferedTagWriter"/> class.
/// </summary>
/// <param name="compression">Indicates the compression algorithm used to compress the file.</param>
/// <param name="options">Bitwise flags to configure how data should be handled for compatibility between different specifications.</param>
/// <param name="capacity">The initial capacity of the buffer.</param>
/// <returns>A newly created <see cref="BufferedTagWriter"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when an invalid compression type is specified.</exception>
public static BufferedTagWriter Create(CompressionType compression, FormatOptions options, int capacity)
/// <summary>
/// Creates a new instance of the <see cref="BufferedTagWriter"/> class.
/// </summary>
/// <param name="compression">Indicates the compression algorithm used to compress the file.</param>
/// <param name="options">Bitwise flags to configure how data should be handled for compatibility between different specifications.</param>
/// <param name="capacity">The initial capacity of the buffer.</param>
/// <returns>A newly created <see cref="BufferedTagWriter"/> instance.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when an invalid compression type is specified.</exception>
public static BufferedTagWriter Create(CompressionType compression, FormatOptions options, int capacity)
{
var buffer = new MemoryStream(capacity);
Stream stream = compression switch
{
var buffer = new MemoryStream(capacity);
Stream stream = compression switch
{
CompressionType.None => buffer,
CompressionType.GZip => new GZipStream(buffer, CompressionMode.Compress, false),
CompressionType.ZLib => new ZLibStream(buffer, CompressionMode.Compress),
_ => throw new ArgumentOutOfRangeException(nameof(compression), compression, null)
};
CompressionType.None => buffer,
CompressionType.GZip => new GZipStream(buffer, CompressionMode.Compress, false),
CompressionType.ZLib => new ZLibStream(buffer, CompressionMode.Compress),
_ => throw new ArgumentOutOfRangeException(nameof(compression), compression, null)
};

return new BufferedTagWriter(stream, buffer, options);
}
return new BufferedTagWriter(stream, buffer, options);
}

private BufferedTagWriter([NotNull] Stream stream, MemoryStream buffer, FormatOptions options) : base(stream, options, false)
{
this.buffer = buffer;
}
private BufferedTagWriter(Stream stream, MemoryStream buffer, FormatOptions options) : base(stream, options, false)
{
this.buffer = buffer;
}

/// <summary>
/// Gets the number of bytes in the internal buffer.
/// </summary>
public long Length
/// <summary>
/// Gets the number of bytes in the internal buffer.
/// </summary>
public long Length
{
get
{
get
{
BaseStream.Flush();
return buffer.Length;
}
BaseStream.Flush();
return buffer.Length;
}
}

/// <summary>
/// Gets the capacity of the internal buffer.
/// </summary>
/// <remarks>The capacity will expand automatically as-needed.</remarks>
public long Capacity => buffer.Capacity;
/// <summary>
/// Gets the capacity of the internal buffer.
/// </summary>
/// <remarks>The capacity will expand automatically as-needed.</remarks>
public long Capacity => buffer.Capacity;

/// <summary>
/// Gets the internal buffer as an array of bytes containing the NBT data written so far.
/// </summary>
/// <returns>An array of bytes containing the NBT data.</returns>
[Pure]
public byte[] ToArray()
{
BaseStream.Flush();
return buffer.ToArray();
}
/// <summary>
/// Gets the internal buffer as an array of bytes containing the NBT data written so far.
/// </summary>
/// <returns>An array of bytes containing the NBT data.</returns>
[Pure]
public byte[] ToArray()
{
BaseStream.Flush();
return buffer.ToArray();
}

/// <summary>
/// Copies the internal buffer to the specified <paramref name="stream"/>;
/// </summary>
/// <param name="stream">A <see cref="Stream"/> instance to write to.</param>
public void CopyTo([NotNull] Stream stream)
{
BaseStream.Flush();
buffer.CopyTo(stream);
}
/// <summary>
/// Copies the internal buffer to the specified <paramref name="stream"/>;
/// </summary>
/// <param name="stream">A <see cref="Stream"/> instance to write to.</param>
public void CopyTo(Stream stream)
{
BaseStream.Flush();
buffer.CopyTo(stream);
}

/// <summary>
/// Asynchronously copies the internal buffer to the specified <paramref name="stream"/>;
/// </summary>
/// <param name="stream">A <see cref="Stream"/> instance to write to.</param>
public async Task CopyToAsync([NotNull] Stream stream)
{
await BaseStream.FlushAsync();
await buffer.CopyToAsync(stream);
}
/// <summary>
/// Asynchronously copies the internal buffer to the specified <paramref name="stream"/>;
/// </summary>
/// <param name="stream">A <see cref="Stream"/> instance to write to.</param>
public async Task CopyToAsync(Stream stream)
{
await BaseStream.FlushAsync();
await buffer.CopyToAsync(stream);
}

/// <summary>
/// Implicit conversion of <see cref="BufferedTagWriter"/> to a <see cref="ReadOnlySpan{T}"/>.
/// </summary>
public static implicit operator ReadOnlySpan<byte>(BufferedTagWriter writer)
{
writer.BaseStream.Flush();
return writer.buffer.ToArray();
}
/// <summary>
/// Implicit conversion of <see cref="BufferedTagWriter"/> to a <see cref="ReadOnlySpan{T}"/>.
/// </summary>
public static implicit operator ReadOnlySpan<byte>(BufferedTagWriter writer)
{
writer.BaseStream.Flush();
return writer.buffer.ToArray();
}
}
46 changes: 22 additions & 24 deletions SharpNBT/CompressionType.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
using JetBrains.Annotations;

namespace SharpNBT
namespace SharpNBT;

/// <summary>
/// Describes compression formats supported by the NBT specification.
/// </summary>
[PublicAPI]
public enum CompressionType : byte
{
/// <summary>
/// Describes compression formats supported by the NBT specification.
/// No compression.
/// </summary>
[PublicAPI]
public enum CompressionType : byte
{
/// <summary>
/// No compression.
/// </summary>
None,
None,

/// <summary>
/// GZip compression
/// </summary>
GZip,
/// <summary>
/// GZip compression
/// </summary>
GZip,

/// <summary>
/// ZLib compression
/// </summary>
ZLib,
/// <summary>
/// ZLib compression
/// </summary>
ZLib,

/// <summary>
/// Automatically detect compression using magic numbers.
/// </summary>
/// <remarks>This is not a valid value when specifying a compression type for <b>writing</b>.</remarks>
AutoDetect = 0xFF
}

/// <summary>
/// Automatically detect compression using magic numbers.
/// </summary>
/// <remarks>This is not a valid value when specifying a compression type for <b>writing</b>.</remarks>
AutoDetect = 0xFF
}
115 changes: 57 additions & 58 deletions SharpNBT/EndianExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,73 @@
using System.Runtime.CompilerServices;
using JetBrains.Annotations;

namespace SharpNBT
namespace SharpNBT;

/// <summary>
/// Contains extension methods dealing with endianness of numeric types.
/// </summary>
[PublicAPI]
public static class EndianExtensions
{
/// <summary>
/// Contains extension methods dealing with endianness of numeric types.
/// Swap the endian of the given <paramref name="value"/>.
/// </summary>
[PublicAPI]
public static class EndianExtensions
/// <param name="value">The value to swap endian of.</param>
/// <returns>The value with bytes in opposite format.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short SwapEndian(this short value)
{
/// <summary>
/// Swap the endian of the given <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to swap endian of.</param>
/// <returns>The value with bytes in opposite format.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short SwapEndian(this short value)
{
return (short) ((value << 8) | ((value >> 8) & 0xFF));
}
return (short) ((value << 8) | ((value >> 8) & 0xFF));
}

/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort SwapEndian(this ushort value)
{
return (ushort)((value << 8) | (value >> 8 ));
}
/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort SwapEndian(this ushort value)
{
return (ushort)((value << 8) | (value >> 8 ));
}

/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int SwapEndian(this int value) => unchecked((int) SwapEndian(unchecked((uint)value)));
/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int SwapEndian(this int value) => unchecked((int) SwapEndian(unchecked((uint)value)));

/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint SwapEndian(this uint value)
{
value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
return (value << 16) | (value >> 16);
}
/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint SwapEndian(this uint value)
{
value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
return (value << 16) | (value >> 16);
}

/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong SwapEndian(this ulong value)
{
value = ((value << 8) & 0xFF00FF00FF00FF00UL) | ((value >> 8) & 0x00FF00FF00FF00FFUL);
value = ((value << 16) & 0xFFFF0000FFFF0000UL) | ((value >> 16) & 0x0000FFFF0000FFFFUL);
return (value << 32) | (value >> 32);
}
/// <inheritdoc cref="SwapEndian(short)"/>
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong SwapEndian(this ulong value)
{
value = ((value << 8) & 0xFF00FF00FF00FF00UL) | ((value >> 8) & 0x00FF00FF00FF00FFUL);
value = ((value << 16) & 0xFFFF0000FFFF0000UL) | ((value >> 16) & 0x0000FFFF0000FFFFUL);
return (value << 32) | (value >> 32);
}

/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long SwapEndian(this long value) => unchecked((long) SwapEndian(unchecked((ulong)value)));
/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long SwapEndian(this long value) => unchecked((long) SwapEndian(unchecked((ulong)value)));

/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float SwapEndian(this float value)
{
var n = BitConverter.SingleToInt32Bits(value);
return BitConverter.Int32BitsToSingle(n.SwapEndian());
}
/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float SwapEndian(this float value)
{
var n = BitConverter.SingleToInt32Bits(value);
return BitConverter.Int32BitsToSingle(n.SwapEndian());
}

/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double SwapEndian(this double value)
{
var n = BitConverter.DoubleToInt64Bits(value);
return BitConverter.Int64BitsToDouble(n.SwapEndian());
}
/// <inheritdoc cref="SwapEndian(short)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double SwapEndian(this double value)
{
var n = BitConverter.DoubleToInt64Bits(value);
return BitConverter.Int64BitsToDouble(n.SwapEndian());
}
}
Loading

0 comments on commit d73bc2f

Please sign in to comment.