public bool MoveNext() { // Make copies of fields to avoid tearing issues since we're // about to perform unsafe accesses. ReadOnlySpan <byte> bytes = _obj.AsBytesSkipNullCheck(); int nextByteIdx = _nextByteIdx; if ((uint)nextByteIdx >= (uint)bytes.Length) { return(false); // no more data } bytes = bytes.Slice(nextByteIdx); // TODO_UTF8STRING: Can we skip correctness checks below? // Perhaps not, this enumerator struct is potentially tearable. OperationStatus status = Rune.DecodeFromUtf8(bytes, out _currentRune, out int bytesConsumedJustNow); Debug.Assert(status == OperationStatus.Done); _nextByteIdx = nextByteIdx + bytesConsumedJustNow; return(true); }
public bool MoveNext() { // Make copies of fields to avoid tearing issues since we're // about to perform unsafe accesses. uint currentCharPair = _currentCharPair; 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 = currentCharPair >> 16; return(true); } ReadOnlySpan <byte> bytes = _obj.AsBytesSkipNullCheck(); int nextByteIdx = _nextByteIdx; if ((uint)nextByteIdx >= (uint)bytes.Length) { return(false); // no more data } // TODO_UTF8STRING: Can we skip correctness checks below? // Perhaps not, this enumerator struct is potentially tearable. OperationStatus status = Rune.DecodeFromUtf8(bytes.Slice(nextByteIdx), out Rune currentRune, out int bytesConsumedJustNow); Debug.Assert(status == OperationStatus.Done); _nextByteIdx = nextByteIdx + bytesConsumedJustNow; if (currentRune.IsBmp) { // Common case - BMP scalar value. _currentCharPair = (uint)currentRune.Value; } else { // Uncommon case - supplementary (astral) plane 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); } return(true); }
public bool MoveNext() { int nextByteIdx = _nextByteIdx; ReadOnlySpan <byte> objAsBytes = _obj.AsBytesSkipNullCheck(); if ((uint)nextByteIdx < (uint)objAsBytes.Length) { Current = objAsBytes[nextByteIdx]; _nextByteIdx = nextByteIdx + 1; return(true); } else { return(false); } }