internal static bool TryGetUnicodeEquivalent(string hostname, ref ValueStringBuilder dest) { Debug.Assert(ReferenceEquals(hostname, UriHelper.StripBidiControlCharacters(hostname, hostname))); int curPos = 0; // We run a loop where for every label // a) if label is ascii and no ace then we lowercase it // b) if label is ascii and ace and not valid idn then just lowercase it // c) if label is ascii and ace and is valid idn then get its unicode eqvl // d) if label is unicode then clean it by running it through idnmapping do { if (curPos != 0) { dest.Append('.'); } bool asciiLabel = true; //find the dot or hit the end int newPos; for (newPos = curPos; (uint)newPos < (uint)hostname.Length; newPos++) { char c = hostname[newPos]; if (c == '.') { break; } if (c > '\x7F') { asciiLabel = false; if ((c == '\u3002') || // IDEOGRAPHIC FULL STOP (c == '\uFF0E') || // FULLWIDTH FULL STOP (c == '\uFF61')) // HALFWIDTH IDEOGRAPHIC FULL STOP { break; } } } if (!asciiLabel) { try { string asciiForm = s_idnMapping.GetAscii(hostname, curPos, newPos - curPos); dest.Append(s_idnMapping.GetUnicode(asciiForm)); } catch (ArgumentException) { return(false); } } else { bool aceValid = false; if ((uint)(curPos + 3) < (uint)hostname.Length && hostname[curPos] == 'x' && hostname[curPos + 1] == 'n' && hostname[curPos + 2] == '-' && hostname[curPos + 3] == '-') { // check ace validity try { dest.Append(s_idnMapping.GetUnicode(hostname, curPos, newPos - curPos)); aceValid = true; } catch (ArgumentException) { // not valid ace so treat it as a normal ascii label } } if (!aceValid) { // for invalid aces we just lowercase the label ReadOnlySpan <char> slice = hostname.AsSpan(curPos, newPos - curPos); int charsWritten = slice.ToLowerInvariant(dest.AppendSpan(slice.Length)); Debug.Assert(charsWritten == slice.Length); } } curPos = newPos + 1; } while (curPos < hostname.Length); return(true); }