using System.Collections; using System.Collections.Generic; namespace System.Unicode { /// Supports a permissive iteration of code points in a . public struct PermissiveCodePointEnumerator : IEnumerator { private readonly string text; private int current; private int index; /// Initializes a new instance of the struct. /// The text whose code point should be enumerated. /// is . public PermissiveCodePointEnumerator(string text) { if (text == null) throw new ArgumentNullException(nameof(text)); this.text = text; this.current = 0; this.index = -1; } /// Gets the element in the collection at the current position of the enumerator.. /// The element in the collection at the current position of the enumerator. public int Current { get { return current; } } object IEnumerator.Current { get { return current; } } void IDisposable.Dispose() { } /// Advances the enumerator to the next element of the collection. /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { if (index < text.Length && (index += current > 0xFFFF ? 2 : 1) < text.Length) { current = GetUtf32(text, index); return true; } else { current = 0; return false; } } void IEnumerator.Reset() { current = 0; index = -1; } private static int GetUtf32(string s, int index) { char c1 = s[index]; if (char.IsHighSurrogate(c1) && ++index < s.Length) { char c2 = s[index]; if (char.IsLowSurrogate(c2)) return char.ConvertToUtf32(c1, c2); } return c1; } } }