diff options
author | Stephen Toub <stoub@microsoft.com> | 2018-12-07 23:49:29 -0500 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-12-07 20:49:29 -0800 |
commit | ca60cf7c507e73f3bb28de0f7781b201a66cf8d2 (patch) | |
tree | 1ffb64711339392110d92b75fa96cb5c7d0d5752 | |
parent | 1cba6f8c32a74a7e7e20fad004be6796a7282c94 (diff) | |
download | coreclr-ca60cf7c507e73f3bb28de0f7781b201a66cf8d2.tar.gz coreclr-ca60cf7c507e73f3bb28de0f7781b201a66cf8d2.tar.bz2 coreclr-ca60cf7c507e73f3bb28de0f7781b201a66cf8d2.zip |
Use string.Create in ConvertFromUtf32 (#21409)
* Use string.Create in ConvertFromUtf32
Removes the unsafe code from the method. Also happens to make it a bit faster.
* Improve Rune.ToString performance
-rw-r--r-- | src/System.Private.CoreLib/shared/System/Char.cs | 22 | ||||
-rw-r--r-- | src/System.Private.CoreLib/shared/System/String.cs | 9 | ||||
-rw-r--r-- | src/System.Private.CoreLib/shared/System/Text/Rune.cs | 11 |
3 files changed, 21 insertions, 21 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Char.cs b/src/System.Private.CoreLib/shared/System/Char.cs index e6ce2fd763..1312380296 100644 --- a/src/System.Private.CoreLib/shared/System/Char.cs +++ b/src/System.Private.CoreLib/shared/System/Char.cs @@ -15,6 +15,7 @@ using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; +using System.Text; namespace System { @@ -921,29 +922,12 @@ namespace System public static string ConvertFromUtf32(int utf32) { - // For UTF32 values from U+00D800 ~ U+00DFFF, we should throw. They - // are considered as irregular code unit sequence, but they are not illegal. - if (((uint)utf32 > UNICODE_PLANE16_END) || (utf32 >= CharUnicodeInfo.HIGH_SURROGATE_START && utf32 <= CharUnicodeInfo.LOW_SURROGATE_END)) + if (!UnicodeUtility.IsValidUnicodeScalar((uint)utf32)) { throw new ArgumentOutOfRangeException(nameof(utf32), SR.ArgumentOutOfRange_InvalidUTF32); } - if (utf32 < UNICODE_PLANE01_START) - { - // This is a BMP character. - return (char.ToString((char)utf32)); - } - - unsafe - { - // This is a supplementary character. Convert it to a surrogate pair in UTF-16. - utf32 -= UNICODE_PLANE01_START; - uint surrogate = 0; // allocate 2 chars worth of stack space - char* address = (char*)&surrogate; - address[0] = (char)((utf32 / 0x400) + (int)CharUnicodeInfo.HIGH_SURROGATE_START); - address[1] = (char)((utf32 % 0x400) + (int)CharUnicodeInfo.LOW_SURROGATE_START); - return new string(address, 0, 2); - } + return Rune.UnsafeCreate((uint)utf32).ToString(); } diff --git a/src/System.Private.CoreLib/shared/System/String.cs b/src/System.Private.CoreLib/shared/System/String.cs index 366b678a22..ea8b5e3799 100644 --- a/src/System.Private.CoreLib/shared/System/String.cs +++ b/src/System.Private.CoreLib/shared/System/String.cs @@ -11,6 +11,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; +using Internal.Runtime.CompilerServices; namespace System { @@ -499,6 +500,14 @@ namespace System return result; } + internal static string CreateFromChar(char c1, char c2) + { + string result = FastAllocateString(2); + result._firstChar = c1; + Unsafe.Add(ref result._firstChar, 1) = c2; + return result; + } + internal static unsafe void wstrcpy(char* dmem, char* smem, int charCount) { Buffer.Memmove((byte*)dmem, (byte*)smem, ((uint)charCount) * 2); diff --git a/src/System.Private.CoreLib/shared/System/Text/Rune.cs b/src/System.Private.CoreLib/shared/System/Text/Rune.cs index 7de9c2d1e4..74aecbe5db 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Rune.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Rune.cs @@ -335,8 +335,15 @@ namespace System.Text /// </summary> public override string ToString() { - Span<char> chars = stackalloc char[2]; // worst case - return new string(chars.Slice(0, EncodeToUtf16(chars))); + if (IsBmp) + { + return string.CreateFromChar((char)_value); + } + else + { + UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar(_value, out char high, out char low); + return string.CreateFromChar(high, low); + } } /// <summary> |