Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions PolyShim.Tests/NetCore21/BigIntegerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using System;
using System.Numerics;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.NetCore21;

public class BigIntegerTests
{
[Fact]
public void ToByteArray_SignedLittleEndian_Test()
{
// Arrange
var value = new BigInteger(33022);

// Act
var bytes = value.ToByteArray(isUnsigned: false, isBigEndian: false);

// Assert
bytes.Should().Equal(0xFE, 0x80, 0x00);
}

[Fact]
public void ToByteArray_SignedBigEndian_Test()
{
// Arrange
var value = new BigInteger(33022);

// Act
var bytes = value.ToByteArray(isUnsigned: false, isBigEndian: true);

// Assert
bytes.Should().Equal(0x00, 0x80, 0xFE);
}

[Fact]
public void ToByteArray_UnsignedLittleEndian_Test()
{
// Arrange
var value = new BigInteger(33022);

// Act
var bytes = value.ToByteArray(isUnsigned: true, isBigEndian: false);

// Assert
bytes.Should().Equal(0xFE, 0x80);
}

[Fact]
public void ToByteArray_UnsignedBigEndian_Test()
{
// Arrange
var value = new BigInteger(33022);

// Act
var bytes = value.ToByteArray(isUnsigned: true, isBigEndian: true);

// Assert
bytes.Should().Equal(0x80, 0xFE);
}

[Fact]
public void ToByteArray_Zero_Test()
{
// Arrange
var value = BigInteger.Zero;

// Act
var bytes = value.ToByteArray(isUnsigned: true, isBigEndian: true);

// Assert
bytes.Should().Equal(0x00);
}

[Fact]
public void ToByteArray_NegativeUnsigned_Test()
{
// Arrange
var value = new BigInteger(-1);

// Act & assert
var act = () => value.ToByteArray(isUnsigned: true);
act.Should().Throw<OverflowException>();
}

[Fact]
public void GetByteCount_Test()
{
// Arrange
var value = new BigInteger(33022);

// Act & assert
value.GetByteCount().Should().Be(3);
value.GetByteCount(isUnsigned: true).Should().Be(2);
}

[Fact]
public void TryWriteBytes_Success_Test()
{
// Arrange
var value = new BigInteger(33022);
var destination = new byte[3];

// Act
var result = value.TryWriteBytes(destination, out var bytesWritten);

// Assert
result.Should().BeTrue();
bytesWritten.Should().Be(3);
destination.Should().Equal(0xFE, 0x80, 0x00);
}

[Fact]
public void TryWriteBytes_TooSmallDestination_Test()
{
// Arrange
var value = new BigInteger(33022);
var destination = new byte[1];

// Act
var result = value.TryWriteBytes(destination, out var bytesWritten);

// Assert
result.Should().BeFalse();
bytesWritten.Should().Be(0);
}

[Fact]
public void TryWriteBytes_UnsignedBigEndian_Test()
{
// Arrange
var value = new BigInteger(33022);
var destination = new byte[2];

// Act
var result = value.TryWriteBytes(
destination,
out var bytesWritten,
isUnsigned: true,
isBigEndian: true
);

// Assert
result.Should().BeTrue();
bytesWritten.Should().Be(2);
destination.Should().Equal(0x80, 0xFE);
}
}
71 changes: 71 additions & 0 deletions PolyShim/NetCore21/BigInteger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#if (NETCOREAPP && !NETCOREAPP2_1_OR_GREATER) || (NETFRAMEWORK) || (NETSTANDARD && !NETSTANDARD2_1_OR_GREATER)
// BigInteger is only available on .NET Framework 4.0+ and .NET Standard 1.1+
#if (!NETFRAMEWORK || NET40_OR_GREATER) && (!NETSTANDARD || NETSTANDARD1_1_OR_GREATER)
#nullable enable
#pragma warning disable CS0436

using System;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;

#if !POLYSHIM_INCLUDE_COVERAGE
[ExcludeFromCodeCoverage]
#endif
internal static class MemberPolyfills_NetCore21_BigInteger
{
extension(BigInteger value)
{
// https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.getbytecount
public int GetByteCount(bool isUnsigned = false) =>
value.ToByteArray(isUnsigned, isBigEndian: false).Length;

// https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.tobytearray#system-numerics-biginteger-tobytearray(system-boolean-system-boolean)
public byte[] ToByteArray(bool isUnsigned = false, bool isBigEndian = false)
{
if (isUnsigned && value.Sign < 0)
throw new OverflowException(
"Negative values do not have an unsigned representation."
);

var bytes = value.ToByteArray();

// The signed little-endian representation may contain an extra zero byte in the
// most significant position, used solely to disambiguate the sign. That byte is
// redundant for an unsigned representation, so it can be safely dropped.
if (isUnsigned && bytes.Length > 1 && bytes[bytes.Length - 1] == 0)
{
var trimmedBytes = new byte[bytes.Length - 1];
Array.Copy(bytes, trimmedBytes, trimmedBytes.Length);
bytes = trimmedBytes;
}

if (isBigEndian)
Array.Reverse(bytes);

return bytes;
}

// https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.trywritebytes
public bool TryWriteBytes(
Span<byte> destination,
out int bytesWritten,
bool isUnsigned = false,
bool isBigEndian = false
)
{
var bytes = value.ToByteArray(isUnsigned, isBigEndian);
if (bytes.Length > destination.Length)
{
bytesWritten = 0;
return false;
}

bytes.CopyTo(destination);
bytesWritten = bytes.Length;

return true;
}
}
}
#endif
#endif
8 changes: 6 additions & 2 deletions Signatures.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Signatures

- **Total:** 611
- **Total:** 614
- **Types:** 120
- **Members:** 491
- **Members:** 494

___

Expand Down Expand Up @@ -45,6 +45,10 @@ ___
- [**[struct]**](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.asyncvaluetaskmethodbuilder) <sup><sub>.NET Core 2.1</sub></sup>
- `AsyncValueTaskMethodBuilder<TResult>`
- [**[struct]**](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.asyncvaluetaskmethodbuilder-1) <sup><sub>.NET Core 2.1</sub></sup>
- `BigInteger`
- [`bool TryWriteBytes(Span<byte>, out int, bool, bool)`](https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.trywritebytes) <sup><sub>.NET Core 2.1</sub></sup>
- [`byte[] ToByteArray(bool, bool)`](https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.tobytearray#system-numerics-biginteger-tobytearray(system-boolean-system-boolean)) <sup><sub>.NET Core 2.1</sub></sup>
- [`int GetByteCount(bool)`](https://learn.microsoft.com/dotnet/api/system.numerics.biginteger.getbytecount) <sup><sub>.NET Core 2.1</sub></sup>
- `BinaryPrimitives`
- [**[class]**](https://learn.microsoft.com/dotnet/api/system.buffers.binary.binaryprimitives) <sup><sub>.NET Core 2.1</sub></sup>
- [`static bool TryReadDoubleBigEndian(ReadOnlySpan<byte>, out double)`](https://learn.microsoft.com/dotnet/api/system.buffers.binary.binaryprimitives.tryreaddoublebigendian) <sup><sub>.NET 5.0</sub></sup>
Expand Down
Loading