internal static void ToLower(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.ToLower(c, cl, out char h, out char l); destination[i] = h; destination[i + 1] = l; i++; // skip the low surrogate continue; } } destination[i] = ToLower(c); } }
internal static string ToLower(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.ToLower(source[i], source[i + 1], out char h, out char l); if (source[i] != h || source[i + 1] != l) { break; } i += 2; continue; } if (ToLower(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.ToLower(src.Slice(state.i), destination.Slice(state.i)); })); }