internal static void ToUpper(ReadOnlySpan <char> source, Span <char> destination) { Debug.Assert(GlobalizationMode.Invariant); Debug.Assert(source.Length <= destination.Length); for (int i = 0; i < source.Length; i++) { char c = source[i]; if (char.IsHighSurrogate(c) && i < source.Length - 1) { char cl = source[i + 1]; if (char.IsLowSurrogate(cl)) { // well formed surrogates SurrogateCasing.ToUpper(c, cl, out char h, out char l); destination[i] = h; destination[i + 1] = l; i++; // skip the low surrogate continue; } } destination[i] = ToUpper(c); } }
private static void InvariantCreateSortKeyOrdinalIgnoreCase(ReadOnlySpan <char> source, Span <byte> sortKey) { Debug.Assert(sortKey.Length >= source.Length * sizeof(char)); for (int i = 0; i < source.Length; i++) { char c = source[i]; if (char.IsHighSurrogate(c) && i < source.Length - 1) { char cl = source[i + 1]; if (char.IsLowSurrogate(cl)) { SurrogateCasing.ToUpper(c, cl, out char hr, out char lr); BinaryPrimitives.WriteUInt16BigEndian(sortKey, hr); BinaryPrimitives.WriteUInt16BigEndian(sortKey, lr); i++; sortKey = sortKey.Slice(2 * sizeof(ushort)); continue; } } // convert machine-endian to big-endian BinaryPrimitives.WriteUInt16BigEndian(sortKey, (ushort)InvariantModeCasing.ToUpper(c)); sortKey = sortKey.Slice(sizeof(ushort)); } }
internal static string ToUpper(string s) { if (s.Length == 0) { return(string.Empty); } ReadOnlySpan <char> source = s; int i = 0; while (i < s.Length) { if (char.IsHighSurrogate(source[i]) && i < s.Length - 1 && char.IsLowSurrogate(source[i + 1])) { SurrogateCasing.ToUpper(source[i], source[i + 1], out char h, out char l); if (source[i] != h || source[i + 1] != l) { break; } i += 2; continue; } if (ToUpper(source[i]) != source[i]) { break; } i++; } if (i >= s.Length) { return(s); } return(string.Create(s.Length, (s, i), static (destination, state) => { ReadOnlySpan <char> src = state.s; src.Slice(0, state.i).CopyTo(destination); InvariantModeCasing.ToUpper(src.Slice(state.i), destination.Slice(state.i)); })); }