internal static void AssertIsHighSurrogateCodePoint(uint codePoint) { if (!UnicodeUtility.IsHighSurrogateCodePoint(codePoint)) { Debug.Fail($"The value {ToHexString(codePoint)} is not a valid UTF-16 high surrogate code point."); } }
// returns a negative number on failure private static int ReadRuneFromString(string input, int index) { if (input is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input); } if ((uint)index >= (uint)input.Length) { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } // Optimistically assume input is within BMP. uint returnValue = input[index]; if (UnicodeUtility.IsSurrogateCodePoint(returnValue)) { if (!UnicodeUtility.IsHighSurrogateCodePoint(returnValue)) { return(-1); } // Treat 'returnValue' as the high surrogate. // // If this becomes a hot code path, we can skip the below bounds check by reading // off the end of the string using unsafe code. Since strings are null-terminated, // we're guaranteed not to read a valid low surrogate, so we'll fail correctly if // the string terminates unexpectedly. index++; if ((uint)index >= (uint)input.Length) { return(-1); // not an argument exception - just a "bad data" failure } uint potentialLowSurrogate = input[index]; if (!UnicodeUtility.IsLowSurrogateCodePoint(potentialLowSurrogate)) { return(-1); } returnValue = UnicodeUtility.GetScalarFromUtf16SurrogatePair(returnValue, potentialLowSurrogate); } return((int)returnValue); }
// returns a negative number on failure internal static int ReadFirstRuneFromUtf16Buffer(ReadOnlySpan <char> input) { if (input.IsEmpty) { return(-1); } // Optimistically assume input is within BMP. uint returnValue = input[0]; if (UnicodeUtility.IsSurrogateCodePoint(returnValue)) { if (!UnicodeUtility.IsHighSurrogateCodePoint(returnValue)) { return(-1); } // Treat 'returnValue' as the high surrogate. if (1 >= (uint)input.Length) { return(-1); // not an argument exception - just a "bad data" failure } uint potentialLowSurrogate = input[1]; if (!UnicodeUtility.IsLowSurrogateCodePoint(potentialLowSurrogate)) { return(-1); } returnValue = UnicodeUtility.GetScalarFromUtf16SurrogatePair(returnValue, potentialLowSurrogate); } return((int)returnValue); }