mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-10 03:25:41 +00:00
Compare commits
No commits in common. "68197ef5c7e6bd6bcbe8496bbf4f1a662a2e7d55" and "d2924d7ac0055891ab73bbb0a46dccf373fb5051" have entirely different histories.
68197ef5c7
...
d2924d7ac0
@ -58,7 +58,6 @@ TypeInitializationException.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- X10D: Fixed `decimal.TryWriteBigEndianBytes` and `decimal.TryWriteLittleEndianBytes`.
|
|
||||||
- X10D.Hosting: Fixed `AddHostedSingleton` not accepting an interface as the service type.
|
- X10D.Hosting: Fixed `AddHostedSingleton` not accepting an interface as the service type.
|
||||||
|
|
||||||
## [3.3.0] - 2023-08-21
|
## [3.3.0] - 2023-08-21
|
||||||
|
@ -5,7 +5,7 @@ or submit a pull request.
|
|||||||
|
|
||||||
### Pull request guidelines
|
### Pull request guidelines
|
||||||
|
|
||||||
This project uses C# 12.0 language features where feasible, and adheres to StyleCop rules with some minor adjustments.
|
This project uses C# 11.0 language features where feasible, and adheres to StyleCop rules with some minor adjustments.
|
||||||
There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not
|
There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not
|
||||||
throw warnings.
|
throw warnings.
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ convetional commits specification.
|
|||||||
|
|
||||||
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:
|
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:
|
||||||
|
|
||||||
- Use C# 12.0 features where possible
|
- Use C# 11.0 features where possible
|
||||||
- Try to ensure code is CLS-compliant. Where this is not possible, decorate methods with `CLSCompliantAttribute` and pass `false`
|
- Try to ensure code is CLS-compliant. Where this is not possible, decorate methods with `CLSCompliantAttribute` and pass `false`
|
||||||
- Follow all .NET guidelines and coding conventions.
|
- Follow all .NET guidelines and coding conventions.
|
||||||
See https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions
|
See https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<LangVersion>12.0</LangVersion>
|
<LangVersion>11.0</LangVersion>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<ImplicitUsings>true</ImplicitUsings>
|
<ImplicitUsings>true</ImplicitUsings>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
using NUnit.Framework;
|
|
||||||
using X10D.IO;
|
|
||||||
|
|
||||||
namespace X10D.Tests.IO;
|
|
||||||
|
|
||||||
[TestFixture]
|
|
||||||
internal class DecimalTests
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void GetBigEndianBytes_ShouldReturnBytes_InBigEndian()
|
|
||||||
{
|
|
||||||
const decimal value = 1234m;
|
|
||||||
byte[] expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 210];
|
|
||||||
|
|
||||||
byte[] bytes = value.GetBigEndianBytes();
|
|
||||||
|
|
||||||
CollectionAssert.AreEqual(expected, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetLittleEndianBytes_ShouldReturnBytes_InLittleEndian()
|
|
||||||
{
|
|
||||||
const decimal value = 1234m;
|
|
||||||
byte[] expected = [210, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
byte[] bytes = value.GetLittleEndianBytes();
|
|
||||||
|
|
||||||
CollectionAssert.AreEqual(expected, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TryWriteBigEndianBytes_ShouldWriteBytes_InBigEndian()
|
|
||||||
{
|
|
||||||
const decimal value = 1234m;
|
|
||||||
byte[] expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 210];
|
|
||||||
|
|
||||||
Span<byte> bytes = stackalloc byte[16];
|
|
||||||
value.TryWriteBigEndianBytes(bytes);
|
|
||||||
|
|
||||||
CollectionAssert.AreEqual(expected, bytes.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TryWriteLittleEndianBytes_ShouldWriteBytes_InLittleEndian()
|
|
||||||
{
|
|
||||||
const decimal value = 1234m;
|
|
||||||
byte[] expected = [210, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
Span<byte> bytes = stackalloc byte[16];
|
|
||||||
value.TryWriteLittleEndianBytes(bytes);
|
|
||||||
|
|
||||||
CollectionAssert.AreEqual(expected, bytes.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
@ -48,10 +48,9 @@ internal partial class StreamTests
|
|||||||
Span<byte> actual = stackalloc byte[16];
|
Span<byte> actual = stackalloc byte[16];
|
||||||
ReadOnlySpan<byte> expected = stackalloc byte[]
|
ReadOnlySpan<byte> expected = stackalloc byte[]
|
||||||
{
|
{
|
||||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x68
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x10, 0x00, 0x00
|
||||||
};
|
};
|
||||||
int read = stream.Read(actual);
|
int read = stream.Read(actual);
|
||||||
Trace.WriteLine(string.Join(' ', actual.ToArray()));
|
|
||||||
|
|
||||||
Assert.That(read, Is.EqualTo(16));
|
Assert.That(read, Is.EqualTo(16));
|
||||||
CollectionAssert.AreEqual(expected.ToArray(), actual.ToArray());
|
CollectionAssert.AreEqual(expected.ToArray(), actual.ToArray());
|
||||||
|
@ -92,12 +92,14 @@ public static class SpanExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dotcover disable
|
// dotcover disable
|
||||||
|
//NOSONAR
|
||||||
default:
|
default:
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
throw new UnreachableException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
throw new UnreachableException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
||||||
#else
|
#else
|
||||||
throw new ArgumentException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
throw new ArgumentException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
||||||
#endif
|
#endif
|
||||||
|
//NOSONAR
|
||||||
// dotcover enable
|
// dotcover enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@ -12,11 +13,11 @@ public static class DecimalExtensions
|
|||||||
/// Converts the current decimal number into an array of bytes, as little endian.
|
/// Converts the current decimal number into an array of bytes, as little endian.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The <see cref="int" /> value.</param>
|
/// <param name="value">The <see cref="int" /> value.</param>
|
||||||
/// <returns>An array of bytes with length 16.</returns>
|
/// <returns>An array of bytes with length 4.</returns>
|
||||||
[Pure]
|
[Pure]
|
||||||
public static byte[] GetBigEndianBytes(this decimal value)
|
public static byte[] GetBigEndianBytes(this decimal value)
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[16];
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
value.TryWriteBigEndianBytes(buffer);
|
value.TryWriteBigEndianBytes(buffer);
|
||||||
return buffer.ToArray();
|
return buffer.ToArray();
|
||||||
}
|
}
|
||||||
@ -25,11 +26,11 @@ public static class DecimalExtensions
|
|||||||
/// Converts the current decimal number into an array of bytes, as little endian.
|
/// Converts the current decimal number into an array of bytes, as little endian.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The <see cref="int" /> value.</param>
|
/// <param name="value">The <see cref="int" /> value.</param>
|
||||||
/// <returns>An array of bytes with length 16.</returns>
|
/// <returns>An array of bytes with length 4.</returns>
|
||||||
[Pure]
|
[Pure]
|
||||||
public static byte[] GetLittleEndianBytes(this decimal value)
|
public static byte[] GetLittleEndianBytes(this decimal value)
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[16];
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
value.TryWriteLittleEndianBytes(buffer);
|
value.TryWriteLittleEndianBytes(buffer);
|
||||||
return buffer.ToArray();
|
return buffer.ToArray();
|
||||||
}
|
}
|
||||||
@ -43,17 +44,23 @@ public static class DecimalExtensions
|
|||||||
public static bool TryWriteBigEndianBytes(this decimal value, Span<byte> destination)
|
public static bool TryWriteBigEndianBytes(this decimal value, Span<byte> destination)
|
||||||
{
|
{
|
||||||
Span<int> buffer = stackalloc int[4];
|
Span<int> buffer = stackalloc int[4];
|
||||||
decimal.GetBits(value, buffer);
|
GetBits(value, buffer);
|
||||||
|
|
||||||
Span<byte> result = stackalloc byte[16];
|
if (buffer[0].TryWriteBigEndianBytes(destination[..4]) &&
|
||||||
MemoryMarshal.Cast<int, byte>(buffer).CopyTo(result);
|
buffer[1].TryWriteBigEndianBytes(destination[4..8]) &&
|
||||||
|
buffer[2].TryWriteBigEndianBytes(destination[8..12]) &&
|
||||||
if (BitConverter.IsLittleEndian)
|
buffer[3].TryWriteBigEndianBytes(destination[12..]))
|
||||||
{
|
{
|
||||||
result.Reverse();
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
destination.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.TryCopyTo(destination);
|
destination.Clear();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -65,16 +72,44 @@ public static class DecimalExtensions
|
|||||||
public static bool TryWriteLittleEndianBytes(this decimal value, Span<byte> destination)
|
public static bool TryWriteLittleEndianBytes(this decimal value, Span<byte> destination)
|
||||||
{
|
{
|
||||||
Span<int> buffer = stackalloc int[4];
|
Span<int> buffer = stackalloc int[4];
|
||||||
decimal.GetBits(value, buffer);
|
GetBits(value, buffer);
|
||||||
|
|
||||||
Span<byte> result = stackalloc byte[16];
|
if (buffer[0].TryWriteLittleEndianBytes(destination[..4]) &&
|
||||||
MemoryMarshal.Cast<int, byte>(buffer).CopyTo(result);
|
buffer[1].TryWriteLittleEndianBytes(destination[4..8]) &&
|
||||||
|
buffer[2].TryWriteLittleEndianBytes(destination[8..12]) &&
|
||||||
if (!BitConverter.IsLittleEndian)
|
buffer[3].TryWriteLittleEndianBytes(destination[12..]))
|
||||||
{
|
{
|
||||||
result.Reverse();
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
destination.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.TryCopyTo(destination);
|
destination.Clear();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void GetBits(decimal value, Span<int> destination)
|
||||||
|
{
|
||||||
|
_ = decimal.GetBits(value, destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !NET5_0_OR_GREATER
|
||||||
|
private static void WriteBits(Span<int> destination, Span<byte> buffer)
|
||||||
|
{
|
||||||
|
var flags = MemoryMarshal.Read<int>(buffer[..4]);
|
||||||
|
var hi = MemoryMarshal.Read<int>(buffer[4..8]);
|
||||||
|
var lo = MemoryMarshal.Read<long>(buffer[8..]);
|
||||||
|
|
||||||
|
var low = (uint)lo;
|
||||||
|
var mid = (uint)(lo >> 32);
|
||||||
|
|
||||||
|
destination[0] = (int)low;
|
||||||
|
destination[1] = (int)mid;
|
||||||
|
destination[2] = hi;
|
||||||
|
destination[3] = flags;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ public static class RuneExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dotcover disable
|
// dotcover disable
|
||||||
|
//NOSONAR
|
||||||
default:
|
default:
|
||||||
string exceptionFormat = ExceptionMessages.UnexpectedRuneUtf8SequenceLength;
|
string exceptionFormat = ExceptionMessages.UnexpectedRuneUtf8SequenceLength;
|
||||||
string message = string.Format(CultureInfo.CurrentCulture, exceptionFormat, length);
|
string message = string.Format(CultureInfo.CurrentCulture, exceptionFormat, length);
|
||||||
@ -106,6 +107,7 @@ public static class RuneExtensions
|
|||||||
#else
|
#else
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
#endif
|
#endif
|
||||||
|
//NOSONAR
|
||||||
// dotcover enable
|
// dotcover enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user