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;
}
}
}