예제 #1
0
                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);
                }
예제 #2
0
                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);
                }
예제 #3
0
 internal sealed override OperationStatus DecodeFirstRune(ReadOnlySpan <byte> bytes, out Rune value, out int bytesConsumed)
 {
     return(Rune.DecodeFromUtf8(bytes, out value, out bytesConsumed));
 }