public bool MoveNext() { // We don't need to worry about tearing since this enumerator is a ref struct. if (_currentCharPair > char.MaxValue) { // There was a surrogate pair smuggled in here from a previous operation. // Shift out the high surrogate value and return immediately. _currentCharPair >>= 16; return(true); } if (_remainingUtf8Bytes.IsEmpty) { return(false); } // TODO_UTF8STRING: Since we assume Utf8String instances are well-formed, we may instead // call an optimized version of the "decode" routine below which skips well-formedness checks. OperationStatus status = Rune.DecodeFromUtf8(_remainingUtf8Bytes, out Rune currentRune, out int bytesConsumed); Debug.Assert(status == OperationStatus.Done, "Somebody fed us invalid data?"); if (currentRune.IsBmp) { // Common case - BMP scalar value. _currentCharPair = (uint)currentRune.Value; } else { // Uncommon case - supplementary plane (astral) scalar value. // We'll smuggle the two UTF-16 code units into a single 32-bit value, // with the leading surrogate packed into the low 16 bits of the value, // and the trailing surrogate packed into the high 16 bits of the value. UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)currentRune.Value, out char leadingCodeUnit, out char trailingCodeUnit); _currentCharPair = (uint)leadingCodeUnit + ((uint)trailingCodeUnit << 16); } // TODO_UTF8STRING: We can consider unsafe slicing below if we wish since we know we're // not going to overrun the end of the span. _remainingUtf8Bytes = _remainingUtf8Bytes.Slice(bytesConsumed); return(true); }
public bool MoveNext() { // We don't need to worry about tearing since this enumerator is a ref struct. if (_remainingUtf8Bytes.IsEmpty) { return(false); } // TODO_UTF8STRING: Since we assume Utf8Span instances are well-formed, we may instead // call an optimized version of the "decode" routine below which skips well-formedness checks. OperationStatus status = Rune.DecodeFromUtf8(_remainingUtf8Bytes, out _currentRune, out int bytesConsumed); Debug.Assert(status == OperationStatus.Done, "Somebody fed us invalid data?"); // TODO_UTF8STRING: We can consider unsafe slicing below if we wish since we know we're // not going to overrun the end of the span. _remainingUtf8Bytes = _remainingUtf8Bytes.Slice(bytesConsumed); return(true); }
internal sealed override OperationStatus DecodeFirstRune(ReadOnlySpan <byte> bytes, out Rune value, out int bytesConsumed) { return(Rune.DecodeFromUtf8(bytes, out value, out bytesConsumed)); }