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
11 changes: 10 additions & 1 deletion src/Utf8StringSplitter/Shims.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


using System.Runtime.CompilerServices;
using System.Text;

Expand Down Expand Up @@ -50,4 +50,13 @@ public static string GetString(ReadOnlySpan<byte> bytes)
#endif
}
}

internal static class ArgumentExceptionEx
{
public static void Throw(string message)
{
throw new ArgumentException(message);
}
}

}
37 changes: 17 additions & 20 deletions src/Utf8StringSplitter/Utf8Splitter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand All @@ -12,7 +12,7 @@ public static SplitEnumerator Split(ReadOnlySpan<byte> source, byte separator, U
const Utf8StringSplitOptions AllOptions = Utf8StringSplitOptions.TrimEntries | Utf8StringSplitOptions.RemoveEmptyEntries;
if ((splitOptions & ~AllOptions) != 0)
{
throw new ArgumentException("Utf8StringSplitOptions Value is Invalid.");
ArgumentExceptionEx.Throw("The specified 'Utf8StringSplitOptions' value is not valid.");
}

return new SplitEnumerator(source, separator, splitOptions);
Expand All @@ -23,7 +23,7 @@ public static SplitEnumerator Split(ReadOnlySpan<byte> source, ReadOnlySpan<byte
const Utf8StringSplitOptions AllOptions = Utf8StringSplitOptions.TrimEntries | Utf8StringSplitOptions.RemoveEmptyEntries;
if ((splitOptions & ~AllOptions) != 0)
{
throw new ArgumentException("Utf8StringSplitOptions Value is Invalid.");
ArgumentExceptionEx.Throw("The specified 'Utf8StringSplitOptions' value is not valid.");
}

return new SplitEnumerator(source, separator, splitOptions);
Expand All @@ -34,7 +34,7 @@ public static SplitAnyEnumerator SplitAny(ReadOnlySpan<byte> source, ReadOnlySpa
const Utf8StringSplitOptions AllOptions = Utf8StringSplitOptions.TrimEntries | Utf8StringSplitOptions.RemoveEmptyEntries;
if ((splitOptions & ~AllOptions) != 0)
{
throw new ArgumentException("Utf8StringSplitOptions Value is Invalid.");
ArgumentExceptionEx.Throw("The specified 'Utf8StringSplitOptions' value is not valid.");
}

switch(separatorOptions)
Expand All @@ -43,7 +43,8 @@ public static SplitAnyEnumerator SplitAny(ReadOnlySpan<byte> source, ReadOnlySpa
case Utf8StringSeparatorOptions.Bytes:
return new SplitAnyEnumerator(source, separators, splitOptions, separatorOptions);
default:
throw new ArgumentException("Utf8StringSeparatorOptions Value is Invalid.");
ArgumentExceptionEx.Throw("The specified 'Utf8StringSeparatorOptions' value is not valid.");
return default; // It will not reach here.
}
}
}
Expand Down Expand Up @@ -105,7 +106,7 @@ internal SplitEnumerator(ReadOnlySpan<byte> source, ReadOnlySpan<byte> separator

public readonly SplitEnumerator GetEnumerator() => this;

internal readonly int sourceLength => source.Length;
internal readonly int SourceLength => source.Length;

public bool MoveNext()
{
Expand All @@ -122,7 +123,7 @@ public bool MoveNext()

public readonly byte[][] ToArray()
{
var writer = new ExtendableArray<byte[]>(sourceLength);
var writer = new ExtendableArray<byte[]>(SourceLength);
foreach (var i in this)
{
writer.Add(i.ToArray());
Expand All @@ -133,7 +134,7 @@ public readonly byte[][] ToArray()

public readonly string[] ToUtf16Array()
{
var writer = new ExtendableArray<string>(sourceLength);
var writer = new ExtendableArray<string>(SourceLength);
foreach (var i in this)
{
writer.Add(UTF8Ex.GetString(i));
Expand Down Expand Up @@ -207,8 +208,6 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
var index = source.IndexOf(separator);
if (index < 0 || separator.Length == 0) // end
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(source, startIndex, endIndex);

if (trimEntries)
{
if (source.Length == 1 && source[0] == 0x20)
Expand All @@ -217,6 +216,7 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(source, startIndex, endIndex);
source = source[startIndex..endIndex];
}
}
Expand All @@ -235,13 +235,13 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
source = source[index..];
if (trimEntries)
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
if (current.Length == 1 && current[0] == 0x20)
{
current = ReadOnlySpan<byte>.Empty;
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
current = current[startIndex..endIndex];
}
}
Expand All @@ -255,8 +255,6 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
index = source.IndexOf(separator);
if (index < 0) // end
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(source, 0, source.Length);

if (trimEntries)
{
if (source.Length == 1 && source[0] == 0x20)
Expand All @@ -265,6 +263,7 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(source, 0, source.Length);
source = source[startIndex..endIndex];
}
}
Expand All @@ -283,13 +282,13 @@ private bool MoveNextInternalWithOptions(scoped ReadOnlySpan<byte> separator)
source = source[index..];
if (trimEntries)
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
if (current.Length == 1 && current[0] == 0x20)
{
current = ReadOnlySpan<byte>.Empty;
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
current = current[startIndex..endIndex];
}
}
Expand Down Expand Up @@ -437,8 +436,6 @@ private bool MoveNextWithOptions()
}
if (index < 0) // end
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(target, startIndex, endIndex);

if (trimEntries)
{
if (target.Length == 1 && target[0] == 0x20)
Expand All @@ -447,6 +444,7 @@ private bool MoveNextWithOptions()
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(target, startIndex, endIndex);
target = target[startIndex..endIndex];
}
}
Expand All @@ -465,13 +463,13 @@ private bool MoveNextWithOptions()
target = target[index..];
if (trimEntries)
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
if (current.Length == 1 && current[0] == 0x20)
{
current = ReadOnlySpan<byte>.Empty;
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
current = current[startIndex..endIndex];
}
}
Expand All @@ -495,8 +493,6 @@ private bool MoveNextWithOptions()
}
if (index < 0) // end
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(target, 0, target.Length);

if (trimEntries)
{
if (target.Length == 1 && target[0] == 0x20)
Expand All @@ -505,6 +501,7 @@ private bool MoveNextWithOptions()
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(target, 0, target.Length);
target = target[startIndex..endIndex];
}
}
Expand All @@ -523,13 +520,13 @@ private bool MoveNextWithOptions()
target = target[index..];
if (trimEntries)
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
if (current.Length == 1 && current[0] == 0x20)
{
current = ReadOnlySpan<byte>.Empty;
}
else
{
(startIndex, endIndex) = Utf8StringUtility.TrimSplitEntries(current, 0, current.Length);
current = current[startIndex..endIndex];
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Utf8StringSplitter/Utf8StringSplitter.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0;net9.0;net10.0;</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
<LangVersion>13</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<VersionPrefix>1.0.1</VersionPrefix>
<VersionPrefix>1.1.0</VersionPrefix>
<Authors>prozolic</Authors>
<Copyright>prozolic</Copyright>
<PackageProjectUrl>https://github.com/prozolic/Utf8StringSplitter</PackageProjectUrl>
Expand Down
49 changes: 42 additions & 7 deletions tests/Utf8StringSplitter.Tests/Utf8SplitterTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Shouldly;
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Xml;

namespace Utf8StringSplitter.Tests
{
Expand Down Expand Up @@ -1117,14 +1119,14 @@ public void SplitAnyWithTrimEntriesAndRemoveEmptyEntriesTest2()
[Fact]
public void SplitAnyWithUtf8SeparatorOptionsTest()
{
var source = new byte[] { 227, 129, 130, 227, 129, 132, 227, 129, 134, 227, 129, 136, 227, 129, 134, 227, 129, 138 }; //‚ ‚¢‚¤‚¦‚¤‚¨
var separator = new byte[] { 227, 129, 134 }; //‚¤
var source = new byte[] { 227, 129, 130, 227, 129, 132, 227, 129, 134, 227, 129, 136, 227, 129, 134, 227, 129, 138 }; //あいうえうお
var separator = new byte[] { 227, 129, 134 }; //う
{
var expected = new List<byte[]>()
{
new byte[] { 227, 129, 130, 227, 129, 132 }, // ‚ ‚¢
new byte[] { 227, 129, 136}, // ‚¦
new byte[] { 227, 129, 138}, // ‚¨
new byte[] { 227, 129, 130, 227, 129, 132 }, // あい
new byte[] { 227, 129, 136}, // え
new byte[] { 227, 129, 138}, // お
};
var index = 0;
foreach (var s in Utf8Splitter.SplitAny(source, separator))
Expand Down Expand Up @@ -1154,8 +1156,8 @@ public void SplitAnyWithUtf8SeparatorOptionsTest()
[Fact]
public void SplitAnyWithBytesSeparatorOptionsTest()
{
var source = new byte[] { 227, 129, 130, 227, 129, 132, 227, 129, 134, 227, 129, 136, 227, 129, 134, 227, 129, 138 }; //‚ ‚¢‚¤‚¦‚¤‚¨
var separator = new byte[] { 227, 129, 134 }; //‚¤
var source = new byte[] { 227, 129, 130, 227, 129, 132, 227, 129, 134, 227, 129, 136, 227, 129, 134, 227, 129, 138 }; //あいうえうお
var separator = new byte[] { 227, 129, 134 }; //う
{
var actual = new List<byte[]>();
var expected = new List<byte[]>();
Expand Down Expand Up @@ -1238,5 +1240,38 @@ public void ToUtf16ArrayTest2()
result.Length.ShouldBe(expected.Length);
}

[Fact]
public void ThrowArgumentExceptionTest()
{
{
var ex = Should.Throw<ArgumentException>(() =>
{
_ = Utf8Splitter.Split("1,2,3,4,5"u8, (byte)',', splitOptions:(Utf8StringSplitOptions)(-1));
});
ex.Message.ShouldBe("The specified 'Utf8StringSplitOptions' value is not valid.");
}
{
var ex = Should.Throw<ArgumentException>(() =>
{
_ = Utf8Splitter.Split("1,2,3,4,5"u8, ","u8, splitOptions:(Utf8StringSplitOptions)(-1));
});
ex.Message.ShouldBe("The specified 'Utf8StringSplitOptions' value is not valid.");
}
{
var ex = Should.Throw<ArgumentException>(() =>
{
_ = Utf8Splitter.SplitAny("1,2-3;4-5"u8, "-,;"u8, splitOptions:(Utf8StringSplitOptions)(-1));
});
ex.Message.ShouldBe("The specified 'Utf8StringSplitOptions' value is not valid.");
}
{
var ex = Should.Throw<ArgumentException>(() =>
{
_ = Utf8Splitter.SplitAny("1,2-3;4-5"u8, "-,;"u8, separatorOptions:(Utf8StringSeparatorOptions)(-1));
});
ex.Message.ShouldBe("The specified 'Utf8StringSeparatorOptions' value is not valid.");
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">net48</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);net6.0;net8.0;net9.0;net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12.0</LangVersion>
Expand Down
Loading