Skip to content
Open
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
6 changes: 3 additions & 3 deletions sandbox/ConsoleApp/ConsoleApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../opensource.snk</AssemblyOriginatorKeyFile>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.0" />
<PackageReference Include="System.Text.Json" Version="9.0.5" />
<ProjectReference Include="..\..\src\ZString\ZString.csproj">
<SetTargetFramework>TargetFramework=netstandard2.1</SetTargetFramework>
</ProjectReference>
Expand Down
2 changes: 1 addition & 1 deletion sandbox/PerfBenchmark/PerfBenchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.0" />
<PackageReference Include="StringFormatter" Version="1.0.0.13" />
</ItemGroup>

Expand Down
9 changes: 4 additions & 5 deletions src/ZString/EnumUtil.cs
Original file line number Diff line number Diff line change
@@ -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<T>
// where T : Enum
internal static class EnumUtil<T> where T : notnull
{
const string InvalidName = "$";

Expand Down Expand Up @@ -45,7 +44,7 @@ public static bool TryFormatUtf16(T value, Span<char> 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;
Expand All @@ -56,7 +55,7 @@ public static bool TryFormatUtf8(T value, Span<byte> 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;
Expand Down
12 changes: 6 additions & 6 deletions src/ZString/FormatHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is noise in the delta. BOM must not be added or removed.

using System.Text;
using System.Buffers;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -47,7 +47,7 @@ private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb,
{
if (typeof(T) == typeof(string))
{
var s = Unsafe.As<string>(arg);
var s = Unsafe.As<string>(arg)!;
int padding = width - s.Length;
if (padding > 0)
{
Expand Down Expand Up @@ -82,7 +82,7 @@ private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb,
}

var span = sb.GetSpan(charsWritten);
s.CopyTo(span);
s.Slice(0, charsWritten).CopyTo(span);
sb.Advance(charsWritten);
}
}
Expand Down Expand Up @@ -130,7 +130,7 @@ private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb,
{
if (typeof(T) == typeof(string))
{
var s = Unsafe.As<string>(arg);
var s = Unsafe.As<string>(arg)!;
int padding = width - s.Length;
if (padding > 0)
{
Expand Down Expand Up @@ -163,10 +163,10 @@ private static void FormatToRightJustify<TBufferWriter, T>(ref TBufferWriter sb,
}

var span = sb.GetSpan(charsWritten);
s.CopyTo(span);
s.Slice(0, charsWritten).CopyTo(span);
sb.Advance(charsWritten);
}
}
}

}
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noise in the delta. Trailing newline must not be removed or added.

32 changes: 16 additions & 16 deletions src/ZString/Utf16ValueStringBuilder.cs

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are numerous changes in this file that change buffer to buffer!. All of them are correct, but redundant if buffer declaration is adjusted from char[]? buffer; to char[] buffer;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While true, the domain of the buffer field is indeed byte[]?. See the Dispose method which sets buffer to null and checks for it being null. I suppose ideally the methods would check if the struct was disposed, but that has performance implications.

Structs are also zero-init by default. For example default(Utf16ValueStringBuilder).AppendLine(); will NRE because buffer is null.

I argue that it should be a nullable type since it captures the true domain of the variable, and that explicitly adding the null forgiveness operator at use sites captures the intent of ignoring this nullability. Of course deciding whether buffer should be a nullable type is at the discretion of the author/maintainer.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is noise in the delta. BOM must not be added or removed.

using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -47,11 +47,11 @@ static Utf16ValueStringBuilder()
/// <summary>Length of written buffer.</summary>
public int Length => index;
/// <summary>Get the written buffer data.</summary>
public ReadOnlySpan<char> AsSpan() => buffer.AsSpan(0, index);
public ReadOnlySpan<char> AsSpan() => buffer!.AsSpan(0, index);
/// <summary>Get the written buffer data.</summary>
public ReadOnlyMemory<char> AsMemory() => buffer.AsMemory(0, index);
public ReadOnlyMemory<char> AsMemory() => buffer!.AsMemory(0, index);
/// <summary>Get the written buffer data.</summary>
public ArraySegment<char> AsArraySegment() => new ArraySegment<char>(buffer, 0, index);
public ArraySegment<char> AsArraySegment() => new ArraySegment<char>(buffer!, 0, index);

/// <summary>
/// Initializes a new instance
Expand Down Expand Up @@ -263,7 +263,7 @@ public void AppendLine(ReadOnlySpan<char> value)
/// <summary>Appends the string representation of a specified value to this instance.</summary>
public void Append<T>(T value)
{
if (!FormatterCache<T>.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default))
if (!FormatterCache<T>.TryFormatDelegate(value, buffer!.AsSpan(index), out var written, default))
{
Grow(written);
if (!FormatterCache<T>.TryFormatDelegate(value, buffer.AsSpan(index), out written, default))
Expand Down Expand Up @@ -326,7 +326,7 @@ public void Insert(int index, ReadOnlySpan<char> value, int count)
var newSize = index + value.Length * count;
var newBuffer = ArrayPool<char>.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++)
Expand All @@ -338,7 +338,7 @@ public void Insert(int index, ReadOnlySpan<char> 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)
{
Expand Down Expand Up @@ -462,7 +462,7 @@ public void Replace(ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue, in

var newBuffer = ArrayPool<char>.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)
Expand All @@ -482,7 +482,7 @@ public void Replace(ReadOnlySpan<char> oldValue, ReadOnlySpan<char> newValue, in
i += pos;
}

if (buffer!.Length != ThreadStaticBufferSize)
if (buffer.Length != ThreadStaticBufferSize)
{
ArrayPool<char>.Shared.Return(buffer);
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -558,7 +558,7 @@ public bool TryCopyTo(Span<char> destination, out int charsWritten)
}

charsWritten = index;
buffer.AsSpan(0, index).CopyTo(destination);
buffer!.AsSpan(0, index).CopyTo(destination);
return true;
}

Expand All @@ -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
Expand Down Expand Up @@ -621,7 +621,7 @@ void AppendFormatInternal<T>(T arg, int width, ReadOnlySpan<char> format, string
{
width *= -1;

if (!FormatterCache<T>.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format))
if (!FormatterCache<T>.TryFormatDelegate(arg, buffer!.AsSpan(index), out var charsWritten, format))
{
Grow(charsWritten);
if (!FormatterCache<T>.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format))
Expand All @@ -642,7 +642,7 @@ void AppendFormatInternal<T>(T arg, int width, ReadOnlySpan<char> format, string
{
if (typeof(T) == typeof(string))
{
var s = Unsafe.As<string>(arg);
var s = Unsafe.As<string>(arg)!;
int padding = width - s.Length;
if (padding > 0)
{
Expand Down Expand Up @@ -731,7 +731,7 @@ static FormatterCache()
}
}

TryFormatDelegate = formatter;
TryFormatDelegate = formatter!;
}

static bool TryFormatString(T value, Span<char> dest, out int written, ReadOnlySpan<char> format)
Expand Down Expand Up @@ -762,7 +762,7 @@ static bool TryFormatDefault(T value, Span<char> 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);
}
}
Expand Down
28 changes: 14 additions & 14 deletions src/ZString/Utf8ValueStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ static Utf8ValueStringBuilder()
public int Length => index;

/// <summary>Get the written buffer data.</summary>
public ReadOnlySpan<byte> AsSpan() => buffer.AsSpan(0, index);
public ReadOnlySpan<byte> AsSpan() => buffer!.AsSpan(0, index);

/// <summary>Get the written buffer data.</summary>
public ReadOnlyMemory<byte> AsMemory() => buffer.AsMemory(0, index);
public ReadOnlyMemory<byte> AsMemory() => buffer!.AsMemory(0, index);

/// <summary>Get the written buffer data.</summary>
public ArraySegment<byte> AsArraySegment() => new ArraySegment<byte>(buffer, 0, index);
public ArraySegment<byte> AsArraySegment() => new ArraySegment<byte>(buffer!, 0, index);

/// <summary>
/// Initializes a new instance
Expand Down Expand Up @@ -292,7 +292,7 @@ public void AppendLiteral(ReadOnlySpan<byte> value)
/// <summary>Appends the string representation of a specified value to this instance.</summary>
public void Append<T>(T value)
{
if (!FormatterCache<T>.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default))
if (!FormatterCache<T>.TryFormatDelegate(value, buffer!.AsSpan(index), out var written, default))
{
Grow(written);
if (!FormatterCache<T>.TryFormatDelegate(value, buffer.AsSpan(index), out written, default))
Expand Down Expand Up @@ -330,20 +330,20 @@ public bool TryCopyTo(Span<byte> destination, out int bytesWritten)
}

bytesWritten = index;
buffer.AsSpan(0, index).CopyTo(destination);
buffer!.AsSpan(0, index).CopyTo(destination);
return true;
}

/// <summary>Write inner buffer to stream.</summary>
public Task WriteToAsync(Stream stream)
{
return stream.WriteAsync(buffer, 0, index);
return stream.WriteAsync(buffer!, 0, index);
}

/// <summary>Write inner buffer to stream.</summary>
public Task WriteToAsync(Stream stream, CancellationToken cancellationToken)
{
return stream.WriteAsync(buffer, 0, index, cancellationToken);
return stream.WriteAsync(buffer!, 0, index, cancellationToken);
}

/// <summary>Encode the innner utf8 buffer to a System.String.</summary>
Expand All @@ -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
Expand Down Expand Up @@ -411,7 +411,7 @@ private void AppendFormatInternal<T>(T arg, int width, StandardFormat format, st
{
width *= -1;

if (!FormatterCache<T>.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format))
if (!FormatterCache<T>.TryFormatDelegate(arg, buffer!.AsSpan(index), out var charsWritten, format))
{
Grow(charsWritten);
if (!FormatterCache<T>.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format))
Expand All @@ -432,7 +432,7 @@ private void AppendFormatInternal<T>(T arg, int width, StandardFormat format, st
{
if (typeof(T) == typeof(string))
{
var s = Unsafe.As<string>(arg);
var s = Unsafe.As<string>(arg)!;
int padding = width - s.Length;
if (padding > 0)
{
Expand Down Expand Up @@ -460,7 +460,7 @@ private void AppendFormatInternal<T>(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);
}
}
Expand Down Expand Up @@ -513,7 +513,7 @@ static FormatterCache()
}
}

TryFormatDelegate = formatter;
TryFormatDelegate = formatter!;
}

static bool TryFormatDefault(T value, Span<byte> dest, out int written, StandardFormat format)
Expand All @@ -524,12 +524,12 @@ static bool TryFormatDefault(T value, Span<byte> dest, out int written, Standard
return true;
}

var s = typeof(T) == typeof(string) ? Unsafe.As<string>(value) :
var s = typeof(T) == typeof(string) ? Unsafe.As<string>(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;
Expand Down
4 changes: 2 additions & 2 deletions src/ZString/ZString.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -270,7 +270,7 @@ static string JoinInternal<T>(ReadOnlySpan<char> separator, ReadOnlySpan<T> valu
}
else if (typeof(T) == typeof(string) && values.Length == 1)
{
return Unsafe.As<string>(values[0]);
return Unsafe.As<string>(values[0])!;
}

var sb = new Utf16ValueStringBuilder(true);
Expand Down
6 changes: 3 additions & 3 deletions src/ZString/ZString.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.1;netstandard2.0;net6.0;net9.0</TargetFrameworks>
<RootNamespace>Cysharp.Text</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down Expand Up @@ -30,11 +30,11 @@
</ItemGroup>

<ItemGroup Condition="$(TargetFramework) == 'netstandard2.1'">
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework) == 'netstandard2.0'">
<PackageReference Include="System.Memory" Version="4.5.3" />
<PackageReference Include="System.Memory" Version="4.6.3" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading