Skip to content

Commit 7fc5a2e

Browse files
committed
fix Utf8Formatter always assume invariant culture when formatting a floating-point whole number
1 parent b9c61b1 commit 7fc5a2e

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

Hexa.NET.Utilities.Tests/Utf8FormatterTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,52 @@ public unsafe void FormatDoubleTest(double value, int digit, string expected)
4949
// Assert
5050
Assert.That(Encoding.UTF8.GetString(utf8Span), Is.EqualTo(expected));
5151
}
52+
53+
[TestCase(10, 0, ".","10")]
54+
[TestCase(10, 0, "\uFF0C","10")]
55+
[TestCase(0.75f, 2, ".","0.75")]
56+
[TestCase(0.75f, 2, "\uFF0C","0\uFF0C75")]
57+
public unsafe void FormatFloatCultureTest(float value, int digit, string separator, string expected)
58+
{
59+
// Arrange
60+
byte* buffer = stackalloc byte[128];
61+
var culture = new CultureInfo( "", false )
62+
{
63+
NumberFormat =
64+
{
65+
CurrencyDecimalSeparator = separator
66+
}
67+
};
68+
69+
// Act
70+
int len = Utf8Formatter.Format(value, buffer, 128, culture, digit);
71+
ReadOnlySpan<byte> utf8Span = new ReadOnlySpan<byte>(buffer, len);
72+
73+
// Assert
74+
Assert.That(Encoding.UTF8.GetString(utf8Span), Is.EqualTo(expected));
75+
}
76+
77+
[TestCase(10, 0, ".","10")]
78+
[TestCase(10, 0, "\uFF0C","10")]
79+
[TestCase(0.75, 2, ".","0.75")]
80+
[TestCase(0.75, 2, "\uFF0C","0\uFF0C75")]
81+
public unsafe void FormatDoubleCultureTest(double value, int digit, string separator, string expected)
82+
{
83+
// Arrange
84+
byte* buffer = stackalloc byte[128];
85+
var culture = new CultureInfo( "", false )
86+
{
87+
NumberFormat =
88+
{
89+
CurrencyDecimalSeparator = separator
90+
}
91+
};
92+
93+
// Act
94+
int len = Utf8Formatter.Format(value, buffer, 128, culture, digit);
95+
var utf8Span = new ReadOnlySpan<byte>(buffer, len);
96+
97+
// Assert
98+
Assert.That(Encoding.UTF8.GetString(utf8Span), Is.EqualTo(expected));
99+
}
52100
}

Hexa.NET.Utilities/Text/Utf8Formatter.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,9 @@ public static unsafe int Format(float value, byte* buffer, int bufSize, CultureI
326326
return (int)(buffer - start);
327327
}
328328

329+
byte* beforeSeparator = buffer;
329330
buffer += ConvertUtf16ToUtf8(format.CurrencyDecimalSeparator, buffer, (int)(end - buffer));
331+
byte* afterSeparator = buffer;
330332

331333
digits = digits >= 0 ? digits : 7;
332334

@@ -340,14 +342,14 @@ public static unsafe int Format(float value, byte* buffer, int bufSize, CultureI
340342
if (fraction < 1e-14) break;
341343
}
342344

343-
while (*(buffer - 1) == '0')
345+
while (buffer != afterSeparator && *(buffer - 1) == '0')
344346
{
345347
buffer--;
346348
}
347349

348-
while (*(buffer - 1) == '.')
350+
if (buffer == afterSeparator)
349351
{
350-
buffer--;
352+
buffer = beforeSeparator;
351353
}
352354

353355
end:
@@ -409,7 +411,9 @@ public static unsafe int Format(double value, byte* buffer, int bufSize, Culture
409411
return (int)(buffer - start);
410412
}
411413

414+
byte* beforeSeparator = buffer;
412415
buffer += ConvertUtf16ToUtf8(format.CurrencyDecimalSeparator, buffer, (int)(end - buffer));
416+
byte* afterSeparator = buffer;
413417

414418
digits = digits >= 0 ? digits : 7;
415419

@@ -423,14 +427,14 @@ public static unsafe int Format(double value, byte* buffer, int bufSize, Culture
423427
if (fraction < 1e-14) break;
424428
}
425429

426-
while (*(buffer - 1) == '0')
430+
while (buffer != afterSeparator && *(buffer - 1) == '0')
427431
{
428432
buffer--;
429433
}
430-
431-
while (*(buffer - 1) == '.')
434+
435+
if (buffer == afterSeparator)
432436
{
433-
buffer--;
437+
buffer = beforeSeparator;
434438
}
435439

436440
end:

0 commit comments

Comments
 (0)