NodeEnumerable
using System;
using System.Collections;
using System.Collections.Generic;
namespace AngleSharp.Dom
{
internal sealed class NodeEnumerable : IEnumerable<INode>, IEnumerable
{
private class NodeEnumerator : IEnumerator<INode>, IEnumerator, IDisposable
{
private readonly struct EnumerationFrame
{
public readonly INode Parent;
public readonly int ChildIndex;
public EnumerationFrame(INode parent, int childIndex)
{
Parent = parent;
ChildIndex = childIndex;
}
}
private readonly Stack<EnumerationFrame> _frameStack;
public INode Current { get; set; }
object IEnumerator.Current {
get {
return Current;
}
}
public NodeEnumerator(INode startingNode)
{
_frameStack = new Stack<EnumerationFrame>();
TryPushFrame(startingNode, 0);
}
public bool MoveNext()
{
if (_frameStack.Count > 0) {
EnumerationFrame enumerationFrame = _frameStack.Pop();
Current = enumerationFrame.Parent.ChildNodes[enumerationFrame.ChildIndex];
TryPushFrame(enumerationFrame.Parent, enumerationFrame.ChildIndex + 1);
TryPushFrame(Current, 0);
return true;
}
return false;
}
private void TryPushFrame(INode parent, int childIndex)
{
if (childIndex < parent.ChildNodes.Length)
_frameStack.Push(new EnumerationFrame(parent, childIndex));
}
public void Dispose()
{
}
public void Reset()
{
throw new NotSupportedException();
}
}
private readonly INode _startingNode;
public NodeEnumerable(INode startingNode)
{
_startingNode = startingNode;
}
public IEnumerator<INode> GetEnumerator()
{
return new NodeEnumerator(_startingNode);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}