-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Ensure that INumberBase implements IUtf8SpanFormattable #88840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fe94d1b
183c7b2
fc54f30
0c8d6b3
9ab1604
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ public interface INumberBase<TSelf> | |
ISubtractionOperators<TSelf, TSelf, TSelf>, | ||
IUnaryPlusOperators<TSelf, TSelf>, | ||
IUnaryNegationOperators<TSelf, TSelf>, | ||
IUtf8SpanFormattable, | ||
IUtf8SpanParsable<TSelf> | ||
where TSelf : INumberBase<TSelf>? | ||
{ | ||
|
@@ -297,7 +298,7 @@ static virtual TSelf Parse(ReadOnlySpan<byte> utf8Text, NumberStyles style, IFor | |
if (textMaxCharCount < 256) | ||
{ | ||
utf16TextArray = null; | ||
utf16Text = stackalloc char[512]; | ||
utf16Text = stackalloc char[256]; | ||
} | ||
else | ||
{ | ||
|
@@ -425,7 +426,7 @@ static virtual bool TryParse(ReadOnlySpan<byte> utf8Text, NumberStyles style, IF | |
if (textMaxCharCount < 256) | ||
{ | ||
utf16TextArray = null; | ||
utf16Text = stackalloc char[512]; | ||
utf16Text = stackalloc char[256]; | ||
} | ||
else | ||
{ | ||
|
@@ -456,6 +457,60 @@ static virtual bool TryParse(ReadOnlySpan<byte> utf8Text, NumberStyles style, IF | |
return succeeded; | ||
} | ||
|
||
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider) | ||
{ | ||
char[]? utf16DestinationArray; | ||
scoped Span<char> utf16Destination; | ||
int destinationMaxCharCount = Encoding.UTF8.GetMaxCharCount(utf8Destination.Length); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I would just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, its not strictly "needed" and in the 99% case won't even be different since it really only is But, its nice to be consistent with the generally "correct" pattern and helps cover any edges that might creep in for user code. Our own APIs won't be hitting the DIM anyways. |
||
|
||
if (destinationMaxCharCount < 256) | ||
{ | ||
utf16DestinationArray = null; | ||
utf16Destination = stackalloc char[256]; | ||
} | ||
else | ||
{ | ||
utf16DestinationArray = ArrayPool<char>.Shared.Rent(destinationMaxCharCount); | ||
tannergooding marked this conversation as resolved.
Show resolved
Hide resolved
|
||
utf16Destination = utf16DestinationArray.AsSpan(0, destinationMaxCharCount); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: No slice is needed here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its not "needed", but its nice to be consistent with the general pattern that is needed in most algorithms. It helps avoid copy/paste or refactoring errors. It also helps limit the amount of work done if the |
||
} | ||
|
||
if (!TryFormat(utf16Destination, out int charsWritten, format, provider)) | ||
{ | ||
if (utf16DestinationArray != null) | ||
{ | ||
// Return rented buffers if necessary | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, I don't think these comments add much There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It’s a copy/paste of the same comment we have throughout similar code. I agree it probably doesn’t add much, but it’s consistent atm |
||
ArrayPool<char>.Shared.Return(utf16DestinationArray); | ||
} | ||
|
||
bytesWritten = 0; | ||
return false; | ||
} | ||
|
||
// Make sure we slice the buffer to just the characters written | ||
utf16Destination = utf16Destination.Slice(0, charsWritten); | ||
|
||
OperationStatus utf8DestinationStatus = Utf8.FromUtf16(utf16Destination, utf8Destination, out _, out bytesWritten, replaceInvalidSequences: false); | ||
tannergooding marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (utf16DestinationArray != null) | ||
{ | ||
// Return rented buffers if necessary | ||
ArrayPool<char>.Shared.Return(utf16DestinationArray); | ||
} | ||
|
||
if (utf8DestinationStatus == OperationStatus.Done) | ||
{ | ||
return true; | ||
} | ||
|
||
if (utf8DestinationStatus != OperationStatus.DestinationTooSmall) | ||
{ | ||
ThrowHelper.ThrowInvalidOperationException_InvalidUtf8(); | ||
} | ||
|
||
bytesWritten = 0; | ||
return false; | ||
} | ||
|
||
static TSelf IUtf8SpanParsable<TSelf>.Parse(ReadOnlySpan<byte> utf8Text, IFormatProvider? provider) | ||
{ | ||
// Convert text using stackalloc for <= 256 characters and ArrayPool otherwise | ||
|
Uh oh!
There was an error while loading. Please reload this page.