Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET Standard 2.1 対応 #117

Merged
merged 7 commits into from
Feb 23, 2022
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
8 changes: 8 additions & 0 deletions .github/workflows/build-dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ jobs:
shell: pwsh
run: Write-Output "::set-output name=dotnet::$(Test-Path *.sln)"

- name: Set DOTNET_INSTALL_DIR
if: steps.check.outputs.dotnet == 'True' && !startswith(matrix.os, 'mac')
shell: pwsh
run: |
$os = '${{ matrix.os }}'
$installDir = $os.StartsWith('windows') ? 'C:/Program Files/dotnet' : '/usr/share/dotnet';
Write-Output "DOTNET_INSTALL_DIR=$installDir" | Out-File $Env:GITHUB_ENV -Encoding utf8 -Append

- name: Setup .NET
if: steps.check.outputs.dotnet == 'True'
uses: actions/setup-dotnet@v1
Expand Down
2 changes: 1 addition & 1 deletion Source/Utf8Utility/Helpers/ThrowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static class ThrowHelper
public static void ThrowArgumentOutOfRangeException(string paramName)
=> throw new ArgumentOutOfRangeException(paramName);

#if NETSTANDARD2_0
#if NETSTANDARD2_1
/// <summary>
/// 新しい<see cref="ArgumentNullException"/>例外をスローします。
/// </summary>
Expand Down
30 changes: 3 additions & 27 deletions Source/Utf8Utility/Text/UnicodeUtility.IsAscii.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,71 +172,47 @@ static bool IsAsciiUlong(ReadOnlySpan<byte> value)

do
{
#if NET6_0_OR_GREATER
maskA |= Unsafe.AddByteOffset(ref current, index);
maskB |= Unsafe.AddByteOffset(ref current, index + sizeof(ulong));
maskC |= Unsafe.AddByteOffset(ref current, index + (sizeof(ulong) * 2));
maskD |= Unsafe.AddByteOffset(ref current, index + (sizeof(ulong) * 3));
#else
maskA |= Unsafe.AddByteOffset(ref current, (nint)index);
maskB |= Unsafe.AddByteOffset(ref current, (nint)(index + sizeof(ulong)));
maskC |= Unsafe.AddByteOffset(ref current, (nint)(index + (sizeof(ulong) * 2)));
maskD |= Unsafe.AddByteOffset(ref current, (nint)(index + (sizeof(ulong) * 3)));
#endif

index += sizeof(ulong) * 4;
}
while ((int)index < endIndex);
}

if (value.Length - (int)index >= sizeof(ulong) * 2)
{
#if NET6_0_OR_GREATER
ref var current = ref Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref first, index));
#else
ref var current = ref Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref first, (nint)index));
#endif

maskA |= current;
maskA |= Unsafe.Add(ref current, 1);

index += sizeof(ulong) * 2;
}

if (value.Length - (int)index >= sizeof(ulong))
{
#if NET6_0_OR_GREATER
maskA |= Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref first, index));
#else
maskA |= Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref first, (nint)index));
#endif
index += sizeof(ulong);
}

if (value.Length - (int)index >= sizeof(uint))
{
#if NET6_0_OR_GREATER
maskA |= Unsafe.As<byte, uint>(ref Unsafe.AddByteOffset(ref first, index));
#else
maskA |= Unsafe.As<byte, uint>(ref Unsafe.AddByteOffset(ref first, (nint)index));
#endif
index += sizeof(uint);
}

if (value.Length - (int)index >= sizeof(ushort))
{
#if NET6_0_OR_GREATER
maskA |= Unsafe.As<byte, ushort>(ref Unsafe.AddByteOffset(ref first, index));
#else
maskA |= Unsafe.As<byte, ushort>(ref Unsafe.AddByteOffset(ref first, (nint)index));
#endif
index += sizeof(ushort);
}

if ((int)index < value.Length)
{
#if NET6_0_OR_GREATER
maskA |= Unsafe.AddByteOffset(ref first, index);
#else
maskA |= Unsafe.AddByteOffset(ref first, (nint)index);
#endif
}

return ((maskA | maskB | maskC | maskD) & 0x8080808080808080) == 0;
Expand Down
39 changes: 3 additions & 36 deletions Source/Utf8Utility/Utf8Array.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using CommunityToolkit.HighPerformance;
using Utf8Utility.Helpers;
using Utf8Utility.Text;
#if NET6_0_OR_GREATER
using System.Buffers;
using System.Runtime.InteropServices;
using System.Text.Unicode;
#endif

Expand Down Expand Up @@ -84,33 +84,9 @@ public Utf8Array(string s)
/// <param name="chars">UTF-16でエンコードされた<see cref="ReadOnlySpan{T}"/>構造体</param>
public Utf8Array(ReadOnlySpan<char> chars)
{
int count;

#if NET6_0_OR_GREATER
count = Encoding.UTF8.GetByteCount(chars);
var count = Encoding.UTF8.GetByteCount(chars);
_value = new byte[count];
Encoding.UTF8.GetBytes(chars, _value);
#else
if (chars.IsEmpty)
{
_value = Array.Empty<byte>();
return;
}

unsafe
{
fixed (char* c = chars)
{
count = Encoding.UTF8.GetByteCount(c, chars.Length);
_value = new byte[count];

fixed (byte* bytes = _value)
{
Encoding.UTF8.GetBytes(c, chars.Length, bytes, _value.Length);
}
}
}
#endif
}

/// <summary>
Expand Down Expand Up @@ -208,6 +184,7 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(Utf8Array other) => Compare(this, other);
#endif

/// <summary>
/// <see cref="ReadOnlySpan{Byte}"/>構造体を取得します。
Expand All @@ -223,7 +200,6 @@ public ReadOnlySpan<byte> DangerousAsSpan(int start)
ref var valueStart = ref Unsafe.AddByteOffset(ref DangerousGetReference(), (nint)(uint)start);
return MemoryMarshal.CreateReadOnlySpan(ref valueStart, length);
}
#endif

/// <summary>
/// <see cref="ReadOnlySpan{Byte}"/>構造体を取得します。
Expand All @@ -232,14 +208,9 @@ public ReadOnlySpan<byte> DangerousAsSpan(int start)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<byte> AsSpan()
{
#if NET6_0_OR_GREATER
// 引数の検証をスキップするために、手動でReadOnlySpanを作成する。
ref var valueStart = ref DangerousGetReference();
return MemoryMarshal.CreateReadOnlySpan(ref valueStart, _value.Length);
#else
var span = new ReadOnlySpan<byte>(_value, 0, _value.Length);
return span;
#endif
}

/// <summary>
Expand Down Expand Up @@ -288,11 +259,7 @@ public int GetLength()
while ((int)index < ByteCount)
{
// 最適化の関係でrefローカル変数にしてはいけない。
#if NET6_0_OR_GREATER
var value = Unsafe.AddByteOffset(ref _value.DangerousGetReference(), index);
#else
var value = Unsafe.AddByteOffset(ref _value.DangerousGetReference(), (nint)index);
#endif

if ((value & 0xC0) != 0x80)
{
Expand Down
33 changes: 1 addition & 32 deletions Source/Utf8Utility/Utf8ArrayDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,7 @@ public bool TryGetValue(ReadOnlySpan<byte> key, [MaybeNullWhen(false)] out TValu
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetValue(ReadOnlySpan<char> key, [MaybeNullWhen(false)] out TValue value)
{
int count;

#if NET5_0_OR_GREATER
count = Encoding.UTF8.GetByteCount(key);
#else
if (key.IsEmpty)
{
return TryGetValue(ReadOnlySpan<byte>.Empty, out value);
}

unsafe
{
fixed (char* chars = key)
{
count = Encoding.UTF8.GetByteCount(chars, key.Length);
}
}
#endif
var count = Encoding.UTF8.GetByteCount(key);

byte[]? rentedUtf8Key = null;
Span<byte> utf8Key = count <= 256
Expand All @@ -144,21 +127,7 @@ public bool TryGetValue(ReadOnlySpan<char> key, [MaybeNullWhen(false)] out TValu

try
{
#if NET5_0_OR_GREATER
Encoding.UTF8.GetBytes(key, utf8Key);
#else
unsafe
{
fixed (char* chars = key)
{
fixed (byte* bytes = utf8Key)
{
Encoding.UTF8.GetBytes(chars, key.Length, bytes, utf8Key.Length);
}
}
}
#endif

return TryGetValue(utf8Key, out value);
}
finally
Expand Down
7 changes: 2 additions & 5 deletions Source/Utf8Utility/Utf8Utility.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net6.0;netstandard2.1</TargetFrameworks>
<IsPackable>true</IsPackable>
</PropertyGroup>

Expand All @@ -15,10 +15,7 @@
<PackageReference Include="CommunityToolkit.HighPerformance" Version="7.1.2" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

Expand Down
4 changes: 1 addition & 3 deletions Tests/Utf8Utility.Tests/Utf8ArrayDangerousAsSpanTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if NET6_0_OR_GREATER
using System.Text;
using System.Text;
using FluentAssertions;
using Xunit;

Expand All @@ -22,4 +21,3 @@ public void 初期インデックス設定(string value)
}
}
}
#endif
2 changes: 1 addition & 1 deletion Tests/Utf8Utility.Tests/Utf8Utility.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net48</TargetFrameworks>
<TargetFrameworks>net6.0;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down