diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index e225b75..c6fa777 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -2,15 +2,15 @@ Exe - net7.0 + net9.0 true ../../opensource.snk false - - + + TargetFramework=netstandard2.1 diff --git a/sandbox/PerfBenchmark/PerfBenchmark.csproj b/sandbox/PerfBenchmark/PerfBenchmark.csproj index 1c3b0ed..1f65918 100644 --- a/sandbox/PerfBenchmark/PerfBenchmark.csproj +++ b/sandbox/PerfBenchmark/PerfBenchmark.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/ZString/EnumUtil.cs b/src/ZString/EnumUtil.cs index 98601e3..cbdaa36 100644 --- a/src/ZString/EnumUtil.cs +++ b/src/ZString/EnumUtil.cs @@ -1,12 +1,11 @@ -using System; +using System; using System.Buffers; using System.Collections.Generic; using System.Text; namespace Cysharp.Text { - internal static class EnumUtil - // where T : Enum + internal static class EnumUtil where T : notnull { const string InvalidName = "$"; @@ -45,7 +44,7 @@ public static bool TryFormatUtf16(T value, Span dest, out int written, Rea { if (!names.TryGetValue(value, out var v) || v == InvalidName) { - v = value!.ToString(); // T is Enum, not null always + v = value!.ToString()!; } written = v.Length; @@ -56,7 +55,7 @@ public static bool TryFormatUtf8(T value, Span dest, out int written, Stan { if (!utf8names.TryGetValue(value, out var v) || v.Length == 0) { - v = Encoding.UTF8.GetBytes(value!.ToString()); + v = Encoding.UTF8.GetBytes(value!.ToString()!); } written = v.Length; diff --git a/src/ZString/FormatHelper.cs b/src/ZString/FormatHelper.cs index de9846c..82804aa 100644 --- a/src/ZString/FormatHelper.cs +++ b/src/ZString/FormatHelper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using System.Buffers; using System.Runtime.CompilerServices; @@ -47,7 +47,7 @@ private static void FormatToRightJustify(ref TBufferWriter sb, { if (typeof(T) == typeof(string)) { - var s = Unsafe.As(arg); + var s = Unsafe.As(arg)!; int padding = width - s.Length; if (padding > 0) { @@ -82,7 +82,7 @@ private static void FormatToRightJustify(ref TBufferWriter sb, } var span = sb.GetSpan(charsWritten); - s.CopyTo(span); + s.Slice(0, charsWritten).CopyTo(span); sb.Advance(charsWritten); } } @@ -130,7 +130,7 @@ private static void FormatToRightJustify(ref TBufferWriter sb, { if (typeof(T) == typeof(string)) { - var s = Unsafe.As(arg); + var s = Unsafe.As(arg)!; int padding = width - s.Length; if (padding > 0) { @@ -163,10 +163,10 @@ private static void FormatToRightJustify(ref TBufferWriter sb, } var span = sb.GetSpan(charsWritten); - s.CopyTo(span); + s.Slice(0, charsWritten).CopyTo(span); sb.Advance(charsWritten); } } } -} \ No newline at end of file +} diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index df6ec3b..8ca5dda 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Buffers; using System.IO; using System.Runtime.CompilerServices; @@ -47,11 +47,11 @@ static Utf16ValueStringBuilder() /// Length of written buffer. public int Length => index; /// Get the written buffer data. - public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + public ReadOnlySpan AsSpan() => buffer!.AsSpan(0, index); /// Get the written buffer data. - public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + public ReadOnlyMemory AsMemory() => buffer!.AsMemory(0, index); /// Get the written buffer data. - public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + public ArraySegment AsArraySegment() => new ArraySegment(buffer!, 0, index); /// /// Initializes a new instance @@ -263,7 +263,7 @@ public void AppendLine(ReadOnlySpan value) /// Appends the string representation of a specified value to this instance. public void Append(T value) { - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(value, buffer!.AsSpan(index), out var written, default)) { Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) @@ -326,7 +326,7 @@ public void Insert(int index, ReadOnlySpan value, int count) var newSize = index + value.Length * count; var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, newSize)); - buffer.AsSpan(0, index).CopyTo(newBuffer); + buffer!.AsSpan(0, index).CopyTo(newBuffer); int newBufferIndex = index; for (int i = 0; i < count; i++) @@ -338,7 +338,7 @@ public void Insert(int index, ReadOnlySpan value, int count) int remainLnegth = this.index - index; buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); - if (buffer!.Length != ThreadStaticBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { if (buffer != null) { @@ -462,7 +462,7 @@ public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, in var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, Length + (newValue.Length - oldValue.Length) * matchCount)); - buffer.AsSpan(0, startIndex).CopyTo(newBuffer); + buffer!.AsSpan(0, startIndex).CopyTo(newBuffer); int newBufferIndex = startIndex; for (int i = startIndex; i < endIndex; i += oldValue.Length) @@ -482,7 +482,7 @@ public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, in i += pos; } - if (buffer!.Length != ThreadStaticBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } @@ -541,7 +541,7 @@ public void Remove(int startIndex, int length) } int remain = startIndex + length; - buffer.AsSpan(remain, Length - remain).CopyTo(buffer.AsSpan(startIndex)); + buffer!.AsSpan(remain, Length - remain).CopyTo(buffer.AsSpan(startIndex)); index -= length; } @@ -558,7 +558,7 @@ public bool TryCopyTo(Span destination, out int charsWritten) } charsWritten = index; - buffer.AsSpan(0, index).CopyTo(destination); + buffer!.AsSpan(0, index).CopyTo(destination); return true; } @@ -568,7 +568,7 @@ public override string ToString() if (index == 0) return string.Empty; - return new string(buffer, 0, index); + return new string(buffer!, 0, index); } // IBufferWriter @@ -621,7 +621,7 @@ void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string { width *= -1; - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) + if (!FormatterCache.TryFormatDelegate(arg, buffer!.AsSpan(index), out var charsWritten, format)) { Grow(charsWritten); if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) @@ -642,7 +642,7 @@ void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string { if (typeof(T) == typeof(string)) { - var s = Unsafe.As(arg); + var s = Unsafe.As(arg)!; int padding = width - s.Length; if (padding > 0) { @@ -731,7 +731,7 @@ static FormatterCache() } } - TryFormatDelegate = formatter; + TryFormatDelegate = formatter!; } static bool TryFormatString(T value, Span dest, out int written, ReadOnlySpan format) @@ -762,7 +762,7 @@ static bool TryFormatDefault(T value, Span dest, out int written, ReadOnly value.ToString(); // also use this length when result is false. - written = s.Length; + written = s!.Length; return s.AsSpan().TryCopyTo(dest); } } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 19df488..87cec87 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -52,13 +52,13 @@ static Utf8ValueStringBuilder() public int Length => index; /// Get the written buffer data. - public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + public ReadOnlySpan AsSpan() => buffer!.AsSpan(0, index); /// Get the written buffer data. - public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + public ReadOnlyMemory AsMemory() => buffer!.AsMemory(0, index); /// Get the written buffer data. - public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + public ArraySegment AsArraySegment() => new ArraySegment(buffer!, 0, index); /// /// Initializes a new instance @@ -292,7 +292,7 @@ public void AppendLiteral(ReadOnlySpan value) /// Appends the string representation of a specified value to this instance. public void Append(T value) { - if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(value, buffer!.AsSpan(index), out var written, default)) { Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) @@ -330,20 +330,20 @@ public bool TryCopyTo(Span destination, out int bytesWritten) } bytesWritten = index; - buffer.AsSpan(0, index).CopyTo(destination); + buffer!.AsSpan(0, index).CopyTo(destination); return true; } /// Write inner buffer to stream. public Task WriteToAsync(Stream stream) { - return stream.WriteAsync(buffer, 0, index); + return stream.WriteAsync(buffer!, 0, index); } /// Write inner buffer to stream. public Task WriteToAsync(Stream stream, CancellationToken cancellationToken) { - return stream.WriteAsync(buffer, 0, index, cancellationToken); + return stream.WriteAsync(buffer!, 0, index, cancellationToken); } /// Encode the innner utf8 buffer to a System.String. @@ -352,7 +352,7 @@ public override string ToString() if (index == 0) return string.Empty; - return UTF8NoBom.GetString(buffer, 0, index); + return UTF8NoBom.GetString(buffer!, 0, index); } // IBufferWriter @@ -411,7 +411,7 @@ private void AppendFormatInternal(T arg, int width, StandardFormat format, st { width *= -1; - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) + if (!FormatterCache.TryFormatDelegate(arg, buffer!.AsSpan(index), out var charsWritten, format)) { Grow(charsWritten); if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) @@ -432,7 +432,7 @@ private void AppendFormatInternal(T arg, int width, StandardFormat format, st { if (typeof(T) == typeof(string)) { - var s = Unsafe.As(arg); + var s = Unsafe.As(arg)!; int padding = width - s.Length; if (padding > 0) { @@ -460,7 +460,7 @@ private void AppendFormatInternal(T arg, int width, StandardFormat format, st Append(' ', padding); // TODO Fill Method is too slow. } - s.CopyTo(GetSpan(charsWritten)); + s.Slice(0, charsWritten).CopyTo(GetSpan(charsWritten)); Advance(charsWritten); } } @@ -513,7 +513,7 @@ static FormatterCache() } } - TryFormatDelegate = formatter; + TryFormatDelegate = formatter!; } static bool TryFormatDefault(T value, Span dest, out int written, StandardFormat format) @@ -524,12 +524,12 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard return true; } - var s = typeof(T) == typeof(string) ? Unsafe.As(value) : + var s = typeof(T) == typeof(string) ? Unsafe.As(value)! : (value is IFormattable formattable && format != default) ? formattable.ToString(format.ToString(), null) : value.ToString(); // also use this length when result is false. - written = UTF8NoBom.GetMaxByteCount(s.Length); + written = UTF8NoBom.GetMaxByteCount(s!.Length); if (dest.Length < written) { return false; diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index c0db0a7..6506a64 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -270,7 +270,7 @@ static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan valu } else if (typeof(T) == typeof(string) && values.Length == 1) { - return Unsafe.As(values[0]); + return Unsafe.As(values[0])!; } var sb = new Utf16ValueStringBuilder(true); diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index f30c041..a5775e4 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -1,7 +1,7 @@  - netstandard2.1;netstandard2.0;net6.0;net7.0 + netstandard2.1;netstandard2.0;net6.0;net9.0 Cysharp.Text true true @@ -30,11 +30,11 @@ - + - + diff --git a/src/ZString/ZStringWriter.cs b/src/ZString/ZStringWriter.cs index c89b89e..700dfdd 100644 --- a/src/ZString/ZStringWriter.cs +++ b/src/ZString/ZStringWriter.cs @@ -82,7 +82,7 @@ public override void Write(char[] buffer, int index, int count) sb.Append(buffer, index, count); } - public override void Write(string value) + public override void Write(string? value) { AssertNotDisposed(); @@ -98,7 +98,7 @@ public override Task WriteAsync(char value) return Task.CompletedTask; } - public override Task WriteAsync(string value) + public override Task WriteAsync(string? value) { Write(value); return Task.CompletedTask; @@ -116,7 +116,7 @@ public override Task WriteLineAsync(char value) return Task.CompletedTask; } - public override Task WriteLineAsync(string value) + public override Task WriteLineAsync(string? value) { WriteLine(value); return Task.CompletedTask; diff --git a/tests/ZString.Tests/NestedStringBuilder.cs b/tests/ZString.Tests/NestedStringBuilder.cs index 8a9074d..543ab7c 100644 --- a/tests/ZString.Tests/NestedStringBuilder.cs +++ b/tests/ZString.Tests/NestedStringBuilder.cs @@ -61,7 +61,6 @@ public void NotDisposedUtf16() } ); } - Utf16ValueStringBuilder.scratchBufferUsed.IsSameOrEqualTo(true); Utf16ValueStringBuilder.scratchBufferUsed = false; } @@ -115,7 +114,6 @@ public void NotDisposedUtf8() } ); } - Utf8ValueStringBuilder.scratchBufferUsed.IsSameOrEqualTo(true); Utf8ValueStringBuilder.scratchBufferUsed = false; } diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj index c53bd2f..597dd37 100644 --- a/tests/ZString.Tests/ZString.Tests.csproj +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -1,7 +1,7 @@ - net7.0 + net9.0 false ZStringTests true @@ -9,14 +9,14 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive