Using native Convert from hex function for .NET 8
This commit is contained in:
@@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- .NET 8.0: `System.Net.IPNetwork`
|
- .NET 8.0: `System.Net.IPNetwork`
|
||||||
- Moved `MessagePack` formatter extensions to own package `AMWD.Common.MessagePack`
|
- Moved `MessagePack` formatter extensions to own package `AMWD.Common.MessagePack`
|
||||||
- `GetAlignedInterval()` (without Local/Utc) is now public accessible
|
- `GetAlignedInterval()` (without Local/Utc) is now public accessible
|
||||||
|
- Using native `Convert.FromHexString` on .NET 8.0 on `HexToBytes` extension
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace System
|
|||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
private const string EmailRegex = @"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a hex string into a byte array.
|
/// Converts a hex string into a byte array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -30,23 +32,28 @@ namespace System
|
|||||||
/// <returns>The bytes.</returns>
|
/// <returns>The bytes.</returns>
|
||||||
public static IEnumerable<byte> HexToBytes(this string hexString, string delimiter = "")
|
public static IEnumerable<byte> HexToBytes(this string hexString, string delimiter = "")
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(hexString))
|
if (hexString == null)
|
||||||
yield break;
|
throw new ArgumentNullException(nameof(hexString));
|
||||||
|
|
||||||
string str = string.IsNullOrEmpty(delimiter) ? hexString : hexString.Replace(delimiter, "");
|
string str = string.IsNullOrEmpty(delimiter)
|
||||||
if (str.Length % 2 == 1)
|
? hexString
|
||||||
yield break;
|
: hexString.Replace(delimiter, "");
|
||||||
|
|
||||||
#if NET8_0_OR_GREATER
|
#if NET8_0_OR_GREATER
|
||||||
if (InvalidHexCharRegex().IsMatch(str))
|
return Convert.FromHexString(str);
|
||||||
yield break;
|
|
||||||
#else
|
#else
|
||||||
if (Regex.IsMatch(str, "[^0-9a-fA-F]", RegexOptions.Compiled))
|
if (Regex.IsMatch(str, "[^0-9a-fA-F]", RegexOptions.Compiled))
|
||||||
yield break;
|
throw new FormatException("The input is not a valid hex string as it contains a non-hex character.");
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < str.Length; i += 2)
|
if (str.Length % 2 != 0)
|
||||||
yield return Convert.ToByte(str.Substring(i, 2), 16);
|
throw new FormatException("The input is not a valid hex string as its length is not a multiple of 2.");
|
||||||
|
|
||||||
|
byte[] bytes = new byte[str.Length / 2];
|
||||||
|
for (int i = 0; i < bytes.Length; i++)
|
||||||
|
bytes[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -193,8 +200,7 @@ namespace System
|
|||||||
if (!ValidEmailRegex().IsMatch(emailAddress))
|
if (!ValidEmailRegex().IsMatch(emailAddress))
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
string emailRegex = @"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$";
|
if (!Regex.IsMatch(emailAddress, EmailRegex, RegexOptions.Compiled))
|
||||||
if (!Regex.IsMatch(emailAddress, emailRegex, RegexOptions.Compiled))
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -248,10 +254,7 @@ namespace System
|
|||||||
=> sb.Append(value).Append(newLine);
|
=> sb.Append(value).Append(newLine);
|
||||||
|
|
||||||
#if NET8_0_OR_GREATER
|
#if NET8_0_OR_GREATER
|
||||||
[GeneratedRegex("[^0-9a-fA-F]", RegexOptions.Compiled)]
|
[GeneratedRegex(EmailRegex, RegexOptions.Compiled)]
|
||||||
private static partial Regex InvalidHexCharRegex();
|
|
||||||
|
|
||||||
[GeneratedRegex(@"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$", RegexOptions.Compiled)]
|
|
||||||
private static partial Regex ValidEmailRegex();
|
private static partial Regex ValidEmailRegex();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AMWD.NetRevisionTask" Version="1.2.0">
|
<PackageReference Include="AMWD.NetRevisionTask" Version="1.2.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -8,6 +8,19 @@ namespace AMWD.Common.Tests.Extensions
|
|||||||
[TestClass]
|
[TestClass]
|
||||||
public class StringExtensionsTest
|
public class StringExtensionsTest
|
||||||
{
|
{
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentNullException))]
|
||||||
|
public void ShouldThrowArgumentNullExceptionWhenNull()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
string hex = null;
|
||||||
|
|
||||||
|
// act
|
||||||
|
var bytes = hex.HexToBytes();
|
||||||
|
|
||||||
|
// assert - ArgumentNullException
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void ShouldReturnEmptyList()
|
public void ShouldReturnEmptyList()
|
||||||
{
|
{
|
||||||
@@ -22,28 +35,19 @@ namespace AMWD.Common.Tests.Extensions
|
|||||||
Assert.IsFalse(bytes.Any());
|
Assert.IsFalse(bytes.Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[DataTestMethod]
|
||||||
public void ShouldReturnEmptyListWhenInvalid()
|
[DataRow("aff", null)]
|
||||||
|
[DataRow("de:ad:be:e", ":")]
|
||||||
|
[DataRow("hell", "")]
|
||||||
|
[ExpectedException(typeof(FormatException))]
|
||||||
|
public void ShouldThrowFormatExceptionWhenInvalid(string hex, string delimiter)
|
||||||
{
|
{
|
||||||
// arrange
|
// arrange
|
||||||
string hex1 = "aff";
|
|
||||||
string hex2 = "de:ad:be:e";
|
|
||||||
string hex3 = "hell";
|
|
||||||
|
|
||||||
// act
|
// act
|
||||||
var bytes1 = hex1.HexToBytes();
|
var bytes = hex.HexToBytes(delimiter);
|
||||||
var bytes2 = hex2.HexToBytes(":");
|
|
||||||
var bytes3 = hex3.HexToBytes();
|
|
||||||
|
|
||||||
// assert
|
// assert - FormatException
|
||||||
Assert.IsNotNull(bytes1);
|
|
||||||
Assert.IsFalse(bytes1.Any());
|
|
||||||
|
|
||||||
Assert.IsNotNull(bytes2);
|
|
||||||
Assert.IsFalse(bytes2.Any());
|
|
||||||
|
|
||||||
Assert.IsNotNull(bytes3);
|
|
||||||
Assert.IsFalse(bytes3.Any());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|||||||
Reference in New Issue
Block a user