Skip to content

Commit

Permalink
Merge pull request #6 from Cysharp/hadashiA/fix-multibyte-alignment
Browse files Browse the repository at this point in the history
Make sure string alignment calculate as char count
  • Loading branch information
neuecc authored Nov 16, 2023
2 parents 8f4b9f1 + 0b3c0e7 commit 1497912
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Utf8StringInterpolation/Utf8String.AppendFormatted.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Buffers;
using System.Buffers.Text;
using System.Runtime.CompilerServices;
using System.Text;

namespace Utf8StringInterpolation;

Expand Down
30 changes: 27 additions & 3 deletions src/Utf8StringInterpolation/Utf8StringWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,19 @@ public void AppendFormatted(string value, int alignment = 0, string? format = nu
var buffer = rentArray.AsSpan();
var bytesWritten = Encoding.UTF8.GetBytes(value.AsSpan(), buffer);

var space = alignment - bytesWritten;
int charCount;
#if NETSTANDARD2_0
unsafe
{
fixed (byte* ptr = &buffer[0])
{
charCount = Encoding.UTF8.GetCharCount(ptr, bytesWritten);
}
}
#else
charCount = Encoding.UTF8.GetCharCount(buffer.Slice(0, bytesWritten));
#endif
var space = alignment - charCount;
if (space > 0)
{
AppendWhitespace(space);
Expand All @@ -190,18 +202,30 @@ public void AppendFormatted(string value, int alignment = 0, string? format = nu
destination = destination.Slice(bytesWritten);
currentWritten += bytesWritten;
ArrayPool<byte>.Shared.Return(rentArray);
return;
}
else
{
// add right whitespace
var max = GetStringByteCount(value.AsSpan());
TryGrow(max);
var bytesWritten = Encoding.UTF8.GetBytes(value.AsSpan(), destination);

int charCount;
#if NETSTANDARD2_0
unsafe
{
fixed (byte* ptr = &destination[currentWritten])
{
charCount = Encoding.UTF8.GetCharCount(ptr, bytesWritten);
}
}
#else
charCount = Encoding.UTF8.GetCharCount(destination.Slice(0, bytesWritten));
#endif
destination = destination.Slice(bytesWritten);
currentWritten += bytesWritten;

var space = bytesWritten + alignment;
var space = charCount + alignment;
if (space < 0)
{
AppendWhitespace(-space);
Expand Down
7 changes: 7 additions & 0 deletions tests/Utf8StringInterpolation.Tests/FormatTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,12 @@ public void Unicode()
Utf8String.Format($"\u30cf\u30fc\u30c8: {"\u2764"}, \u5bb6\u65cf: {"\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67"}(\u7d75\u6587\u5b57)")
.Should().Be($"\u30cf\u30fc\u30c8: {"\u2764"}, \u5bb6\u65cf: {"\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67"}(\u7d75\u6587\u5b57)");
}

[Fact]
public void MultibyteStringAlignment()
{
Utf8String.Format($"abc{"あいう",10}").Should().Be($"abc{"あいう",10}");
Utf8String.Format($"def{"えおか",-10}").Should().Be($"def{"えおか",-10}");
}
}
}

0 comments on commit 1497912

Please sign in to comment.