2017-09-07 23:10:17 +02:00
using System.Collections ;
2014-11-26 22:27:09 +01:00
using System.Collections.Generic ;
namespace System.Unicode
{
2014-12-16 00:53:15 +01:00
/// <summary>Supports a permissive iteration of code points in a <see cref="string"/>.</summary>
2014-11-26 22:27:09 +01:00
public struct PermissiveCodePointEnumerator : IEnumerator < int >
{
private readonly string text ;
private int current ;
private int index ;
2014-12-16 00:53:15 +01:00
/// <summary>Initializes a new instance of the <see cref="PermissiveCodePointEnumerator"/> struct.</summary>
/// <param name="text">The text whose code point should be enumerated.</param>
/// <exception cref="ArgumentNullException"><paramref cref="text"/> is <see langword="null"/>.</exception>
2014-11-26 22:27:09 +01:00
public PermissiveCodePointEnumerator ( string text )
{
if ( text == null ) throw new ArgumentNullException ( nameof ( text ));
this . text = text ;
this . current = 0 ;
this . index = - 1 ;
}
2014-12-16 00:53:15 +01:00
/// <summary>Gets the element in the collection at the current position of the enumerator..</summary>
/// <value>The element in the collection at the current position of the enumerator.</value>
2014-11-26 22:27:09 +01:00
public int Current { get { return current ; } }
object IEnumerator . Current { get { return current ; } }
void IDisposable . Dispose () { }
2014-12-16 00:53:15 +01:00
/// <summary>Advances the enumerator to the next element of the collection.</summary>
/// <returns><see langword="true"/> if the enumerator was successfully advanced to the next element; <see langword="false"/> if the enumerator has passed the end of the collection.</returns>
2014-11-26 22:27:09 +01:00
public bool MoveNext ()
{
if ( index < text . Length && ( index += current > 0xFFFF ? 2 : 1 ) < text . Length )
{
current = GetUtf32 ( text , index );
2017-09-07 23:10:17 +02:00
return true ;
2014-11-26 22:27:09 +01:00
}
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 ;
}
}
}