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

DangerousAsSpan追加 #104

Merged
merged 5 commits into from
Jan 8, 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
32 changes: 18 additions & 14 deletions Source/Utf8Utility/Utf8Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public override bool Equals(object? obj)

/// <inheritdoc/>
public bool Equals(Utf8Array other)
=> _value.AsSpan().SequenceEqual(other._value);
=> AsSpan().SequenceEqual(other.AsSpan());

/// <inheritdoc/>
public override int GetHashCode() => _value.GetDjb2HashCode();
Expand All @@ -208,6 +208,21 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(Utf8Array other) => Compare(this, other);

/// <summary>
/// <see cref="ReadOnlySpan{Byte}"/>構造体を取得します。
/// このメソッドは引数チェックを行いません。
/// </summary>
/// <param name="start">初期インデックス</param>
/// <returns><see cref="ReadOnlySpan{Byte}"/>構造体</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<byte> DangerousAsSpan(int start)
{
// 引数の検証をスキップするために、手動でReadOnlySpanを作成する。
var length = _value.Length - start;
ref var valueStart = ref Unsafe.AddByteOffset(ref DangerousGetReference(), (nint)(uint)start);
return MemoryMarshal.CreateReadOnlySpan(ref valueStart, length);
}
#endif

/// <summary>
Expand All @@ -217,8 +232,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<byte> AsSpan()
{
// 引数の検証をスキップするために、手動でReadOnlySpanを作成する。
#if NET6_0_OR_GREATER
// 引数の検証をスキップするために、手動でReadOnlySpanを作成する。
ref var valueStart = ref DangerousGetReference();
return MemoryMarshal.CreateReadOnlySpan(ref valueStart, _value.Length);
#else
Expand All @@ -233,18 +248,7 @@ public ReadOnlySpan<byte> AsSpan()
/// <param name="start">初期インデックス</param>
/// <returns><see cref="ReadOnlySpan{Byte}"/>構造体</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<byte> AsSpan(int start)
{
// 引数の検証をスキップするために、手動でReadOnlySpanを作成する。
#if NET6_0_OR_GREATER
var length = _value.Length - start;
ref var valueStart = ref Unsafe.AddByteOffset(ref DangerousGetReference(), (nint)(uint)length);
return MemoryMarshal.CreateReadOnlySpan(ref valueStart, length);
#else
var span = new ReadOnlySpan<byte>(_value, start, _value.Length - start);
return span;
#endif
}
public ReadOnlySpan<byte> AsSpan(int start) => new(_value, start, _value.Length - start);

/// <summary>
/// UTF-8文字数を取得します。
Expand Down
13 changes: 9 additions & 4 deletions Tests/Utf8Utility.Tests/Utf8ArrayAsSpanTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ public void 初期インデックス0(string value)

[Theory]
[InlineData("abcdef")]
public void 初期インデックス3(string value)
public void 初期インデックス設定(string value)
{
var span = new Utf8Array(value).AsSpan(3);
var array = Encoding.UTF8.GetBytes(value).AsSpan(3);
var utf8Value = Encoding.UTF8.GetBytes(value);

span.SequenceEqual(array).Should().BeTrue();
for (var i = 0; i < value.Length; i++)
{
var span = new Utf8Array(utf8Value).AsSpan(i);
var array = utf8Value.AsSpan(i);

span.SequenceEqual(array).Should().BeTrue();
}
}
}
25 changes: 25 additions & 0 deletions Tests/Utf8Utility.Tests/Utf8ArrayDangerousAsSpanTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#if NET6_0_OR_GREATER
using System.Text;
using FluentAssertions;
using Xunit;

namespace Utf8Utility.Tests;

public sealed class Utf8ArrayDangerousAsSpanTest
{
[Theory]
[InlineData("abcdef")]
public void 初期インデックス設定(string value)
{
var utf8Value = Encoding.UTF8.GetBytes(value);

for (var i = 0; i < value.Length; i++)
{
var span = new Utf8Array(utf8Value).DangerousAsSpan(i);
var array = utf8Value.AsSpan(i);

span.SequenceEqual(array).Should().BeTrue();
}
}
}
#endif