using System.Xml.XPath;
using System.Xml.Xsl;
+#if NET_2_0
+using NSResolver = System.Xml.IXmlNamespaceResolver;
+#else
+using NSResolver = System.Xml.XmlNamespaceManager;
+#endif
+
namespace System.Xml.XPath
{
internal abstract class BaseIterator : XPathNodeIterator
{
- private XmlNamespaceManager _nsm;
- protected bool _needClone = true; // TODO: use this field in practice.
+ NSResolver _nsm;
+ int position;
internal BaseIterator (BaseIterator other)
{
_nsm = other._nsm;
+ position = other.position;
}
- internal BaseIterator (XmlNamespaceManager nsm)
+ internal BaseIterator (NSResolver nsm)
{
_nsm = nsm;
}
- public XmlNamespaceManager NamespaceManager
+ public NSResolver NamespaceManager
{
get { return _nsm; }
set { _nsm = value; }
}
}
+ public override int CurrentPosition {
+ get { return position; }
+ }
+
+ public override bool MoveNext ()
+ {
+ if (!MoveNextCore ())
+ return false;
+ position++;
+ return true;
+ }
+
+ public abstract bool MoveNextCore ();
+
public override string ToString ()
{
if (Current != null)
{
XPathNodeIterator iter;
- public WrapperIterator (XPathNodeIterator iter, XmlNamespaceManager nsm)
+ public WrapperIterator (XPathNodeIterator iter, NSResolver nsm)
: base (nsm)
{
this.iter = iter;
}
+ private WrapperIterator (WrapperIterator other)
+ : base (other)
+ {
+ iter = other.iter.Clone ();
+ }
+
public override XPathNodeIterator Clone ()
{
- return new WrapperIterator (iter.Clone (), NamespaceManager);
+ return new WrapperIterator (this);
}
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
return iter.MoveNext ();
}
get { return iter.Current; }
}
- public override int CurrentPosition {
- get { return iter.CurrentPosition; }
- }
-
public override bool RequireSorting {
get { return true; }
}
protected readonly BaseIterator _iter;
protected readonly XPathNavigator _nav;
protected XPathNavigator _current;
- protected int _pos;
- public SimpleIterator (BaseIterator iter) : base (iter)
+ public SimpleIterator (BaseIterator iter) : base (iter.NamespaceManager)
{
_iter = iter;
_nav = iter.Current.Clone ();
- _current = _nav.Clone ();
}
- protected SimpleIterator (SimpleIterator other) : base (other)
+ protected SimpleIterator (SimpleIterator other, bool clone) : base (other)
{
if (other._nav == null)
_iter = (BaseIterator) other._iter.Clone ();
else
_nav = other._nav.Clone ();
- _pos = other._pos;
- _current = other._current.Clone ();
}
- public SimpleIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nsm)
+ public SimpleIterator (XPathNavigator nav, NSResolver nsm) : base (nsm)
{
_nav = nav.Clone ();
- _current = nav.Clone ();
}
- public override XPathNavigator Current { get { return _current; }}
- public override int CurrentPosition { get { return _pos; }}
+ public override XPathNavigator Current {
+ get {
+ if (_current == null) // position == 0
+ _current = _nav.Clone ();
+ return _current;
+ }
+ }
}
internal class SelfIterator : SimpleIterator
{
public SelfIterator (BaseIterator iter) : base (iter) {}
- public SelfIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
- protected SelfIterator (SelfIterator other) : base (other) {}
- public override XPathNodeIterator Clone () { return new SelfIterator (this); }
- public override bool MoveNext ()
+ public SelfIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
+ protected SelfIterator (SelfIterator other, bool clone) : base (other, true)
+ {
+ if (other._current != null)
+ _current = _nav;
+ }
+
+ public override XPathNodeIterator Clone () { return new SelfIterator (this, true); }
+ public override bool MoveNextCore ()
{
- if (_pos == 0)
+ if (CurrentPosition == 0)
{
- _pos = 1;
- _current = _needClone ? _nav.Clone () : _nav;
+ _current = _nav;
return true;
}
return false;
{
public NullIterator (BaseIterator iter) : base (iter) {}
public NullIterator (XPathNavigator nav) : this (nav, null) {}
- public NullIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
- protected NullIterator (NullIterator other) : base (other) {}
+ public NullIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
+ private NullIterator (NullIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new NullIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
return false;
}
internal class ParensIterator : BaseIterator
{
BaseIterator _iter;
- public ParensIterator (BaseIterator iter) : base (iter)
+ public ParensIterator (BaseIterator iter) : base (iter.NamespaceManager)
{
_iter = iter;
}
- protected ParensIterator (ParensIterator other) : base (other)
+ private ParensIterator (ParensIterator other) : base (other)
{
_iter = (BaseIterator) other._iter.Clone ();
}
public override XPathNodeIterator Clone () { return new ParensIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
return _iter.MoveNext ();
}
public override XPathNavigator Current { get { return _iter.Current; }}
- public override int CurrentPosition { get { return _iter.CurrentPosition; } }
public override bool RequireSorting { get { return _iter.RequireSorting; } }
internal class ParentIterator : SimpleIterator
{
public ParentIterator (BaseIterator iter) : base (iter) {}
- protected ParentIterator (ParentIterator other) : base (other) {}
- public ParentIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
+ private ParentIterator (ParentIterator other) : base (other, true)
+ {
+ if (other._current != null)
+ _current = _nav;
+ }
+ public ParentIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
public override XPathNodeIterator Clone () { return new ParentIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
- if (_pos == 0 && _nav.MoveToParent ())
+ if (CurrentPosition == 0 && _nav.MoveToParent ())
{
- _pos = 1;
- _current = _needClone ? _nav.Clone () : _nav;
+ _current = _nav;
return true;
}
return false;
public override bool ReverseAxis { get { return true; } }
- public override bool RequireSorting { get { return true; } }
+ public override bool RequireSorting { get { return false; } }
}
internal class ChildIterator : SimpleIterator
{
public ChildIterator (BaseIterator iter) : base (iter) {}
- protected ChildIterator (ChildIterator other) : base (other) {}
+ private ChildIterator (ChildIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new ChildIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
- bool fSuccess = (_pos == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
+ bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
if (fSuccess) {
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
}
return fSuccess;
}
internal class FollowingSiblingIterator : SimpleIterator
{
public FollowingSiblingIterator (BaseIterator iter) : base (iter) {}
- protected FollowingSiblingIterator (FollowingSiblingIterator other) : base (other) {}
+ private FollowingSiblingIterator (FollowingSiblingIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
switch (_nav.NodeType) {
case XPathNodeType.Attribute:
}
if (_nav.MoveToNext ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
return false;
public PrecedingSiblingIterator (BaseIterator iter) : base (iter)
{
startPosition = iter.Current.Clone ();
- _current = startPosition.Clone ();
}
- protected PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other)
+ private PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other, true)
{
startPosition = other.startPosition;
started = other.started;
finished = other.finished;
- _current = other._current.Clone ();
}
public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (finished)
return false;
}
_nav.MoveToFirst ();
- if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Same) {
- _pos++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ if (!_nav.IsSamePosition (startPosition)) {
+ _current = null;
return true;
}
} else {
finished = true;
return false;
} else {
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
internal class AncestorIterator : SimpleIterator
{
- bool finished;
- bool started;
- ArrayList positions = new ArrayList ();
+ int currentPosition;
+ ArrayList navigators;
XPathNavigator startPosition;
- int nextDepth;
+
public AncestorIterator (BaseIterator iter) : base (iter)
{
startPosition = iter.Current.Clone ();
- _current = startPosition.Clone ();
}
- protected AncestorIterator (AncestorIterator other) : base (other)
+
+ private AncestorIterator (AncestorIterator other)
+ : base (other, true)
{
startPosition = other.startPosition;
- started = other.started;
- finished = other.finished;
- positions = (ArrayList) other.positions.Clone ();
- nextDepth = other.nextDepth;
- _current = other._current.Clone ();
+ if (other.navigators != null)
+ navigators = (ArrayList) other.navigators.Clone ();
+ currentPosition = other.currentPosition;
}
- public override XPathNodeIterator Clone () { return new AncestorIterator (this); }
- public override bool MoveNext ()
+
+ public override XPathNodeIterator Clone ()
{
- if (finished)
- return false;
- if (!started) {
- started = true;
- // This clone cannot be omitted
- XPathNavigator ancestors = startPosition.Clone ();
- ancestors.MoveToParent ();
- _nav.MoveToParent ();
- while (ancestors.NodeType != XPathNodeType.Root) {
- int i = 0;
- _nav.MoveToFirst ();
- while (_nav.ComparePosition (ancestors) == XmlNodeOrder.Before) {
- _nav.MoveToNext ();
- i++;
- }
- positions.Add (i);
- if (!ancestors.MoveToParent ())
- break; // It is for detached nodes under XmlDocumentNavigator
- _nav.MoveToParent ();
- }
+ return new AncestorIterator (this);
+ }
+ private void CollectResults ()
+ {
+ navigators = new ArrayList ();
- positions.Reverse ();
+ XPathNavigator ancestors = startPosition.Clone ();
+ if (!ancestors.MoveToParent ())
+ return;
+ while (ancestors.NodeType != XPathNodeType.Root) {
+ navigators.Add (ancestors.Clone ());
+ ancestors.MoveToParent ();
+ }
+ currentPosition = navigators.Count;
+ }
+ public override bool MoveNextCore ()
+ {
+ if (navigators == null) {
+ CollectResults ();
if (startPosition.NodeType != XPathNodeType.Root) {
// First time it returns Root
- _pos++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _nav.MoveToRoot ();
+ _current = null;
return true;
}
}
- // Don't worry about node type of start position, like AncestorOrSelf.
- // It should be Element or Root.
- if (nextDepth < positions.Count) {
- int thisTimePos = (int) positions [nextDepth];
- _nav.MoveToFirstChild ();
- for (int i = 0; i < thisTimePos; i++)
- _nav.MoveToNext ();
- nextDepth++;
- _pos++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
- return true;
- }
- finished = true;
- return false;
+ if (currentPosition == 0)
+ return false;
+ _nav.MoveTo ((XPathNavigator) navigators [--currentPosition]);
+ _current = null;
+ return true;
}
public override bool ReverseAxis {
public override bool RequireSorting { get { return true; } }
- public override int Count { get { return positions.Count; } }
+ public override int Count {
+ get {
+ if (navigators == null)
+ CollectResults ();
+ return navigators.Count;
+ }
+ }
}
internal class AncestorOrSelfIterator : SimpleIterator
{
- bool finished;
- bool started;
- ArrayList positions = new ArrayList ();
+ int currentPosition;
+ ArrayList navigators;
XPathNavigator startPosition;
- int nextDepth;
public AncestorOrSelfIterator (BaseIterator iter) : base (iter)
{
startPosition = iter.Current.Clone ();
- _current = startPosition.Clone ();
}
- protected AncestorOrSelfIterator (AncestorOrSelfIterator other) : base (other)
+
+ private AncestorOrSelfIterator (AncestorOrSelfIterator other)
+ : base (other, true)
{
startPosition = other.startPosition;
- started = other.started;
- finished = other.finished;
- positions = (ArrayList) other.positions.Clone ();
- nextDepth = other.nextDepth;
- _current = other._current.Clone ();
+ if (other.navigators != null)
+ navigators = (ArrayList) other.navigators.Clone ();
+ currentPosition = other.currentPosition;
}
- public override XPathNodeIterator Clone () { return new AncestorOrSelfIterator (this); }
- public override bool MoveNext ()
+
+ public override XPathNodeIterator Clone ()
{
- bool initialIteration = false;
- if (finished)
- return false;
- if (!started) {
- initialIteration = true;
- started = true;
- // This clone cannot be omitted
- XPathNavigator ancestors = startPosition.Clone ();
- do {
- int i = 0;
- _nav.MoveToFirst ();
- while (_nav.ComparePosition (ancestors) == XmlNodeOrder.Before) {
- _nav.MoveToNext ();
- i++;
- }
- positions.Add (i);
- if (!ancestors.MoveToParent ())
- break; // for detached nodes under XmlDocumentNavigator.
- _nav.MoveToParent ();
- } while (ancestors.NodeType != XPathNodeType.Root);
- positions.Reverse ();
+ return new AncestorOrSelfIterator (this);
+ }
+
+ private void CollectResults ()
+ {
+ navigators = new ArrayList ();
+
+ XPathNavigator ancestors = startPosition.Clone ();
+ if (!ancestors.MoveToParent ())
+ return;
+ while (ancestors.NodeType != XPathNodeType.Root) {
+ navigators.Add (ancestors.Clone ());
+ ancestors.MoveToParent ();
}
- if (initialIteration && startPosition.NodeType != XPathNodeType.Root) {
- // This clone cannot be omitted
- _current = _nav.Clone ();
- return true;
- } else if (nextDepth + 1 == positions.Count) {
- nextDepth++;
- _pos++;
- _nav.MoveTo (startPosition);
- // This clone cannot be omitted
- _current = _nav.Clone ();
- return true;
+ currentPosition = navigators.Count;
+ }
+
+ public override bool MoveNextCore ()
+ {
+ if (navigators == null) {
+ CollectResults ();
+ if (startPosition.NodeType != XPathNodeType.Root) {
+ // First time it returns Root
+ _nav.MoveToRoot ();
+ _current = null;
+ return true;
+ }
}
- else if (nextDepth < positions.Count) {
- int thisTimePos = (int) positions [nextDepth];
- _nav.MoveToFirstChild ();
- for (int i = 0; i < thisTimePos; i++)
- _nav.MoveToNext ();
- nextDepth++;
- _pos++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
- return true;
+ if (currentPosition == -1)
+ return false;
+ if (currentPosition-- == 0) {
+ _nav.MoveTo (startPosition);
+ _current = null;
+ return true; // returns self.
}
- finished = true;
- return false;
+ _nav.MoveTo ((XPathNavigator) navigators [currentPosition]);
+ _current = null;
+ return true;
}
public override bool ReverseAxis {
public override bool RequireSorting { get { return true; } }
- public override int Count { get { return positions.Count; } }
+ public override int Count {
+ get {
+ if (navigators == null)
+ CollectResults ();
+ return navigators.Count + 1;
+ }
+ }
}
internal class DescendantIterator : SimpleIterator
{
- protected int _depth;
+ private int _depth;
private bool _finished;
public DescendantIterator (BaseIterator iter) : base (iter) {}
- protected DescendantIterator (DescendantIterator other) : base (other)
+ private DescendantIterator (DescendantIterator other) : base (other)
{
_depth = other._depth;
_finished = other._finished;
- _current = other._current.Clone ();
}
public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (_finished)
return false;
if (_nav.MoveToFirstChild ())
{
_depth ++;
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
while (_depth != 0)
{
if (_nav.MoveToNext ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
if (!_nav.MoveToParent ()) // should NEVER fail!
internal class DescendantOrSelfIterator : SimpleIterator
{
- protected int _depth;
+ private int _depth;
private bool _finished;
public DescendantOrSelfIterator (BaseIterator iter) : base (iter) {}
- protected DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other)
+ private DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other, true)
{
_depth = other._depth;
- _current = other._current.Clone ();
}
public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (_finished)
return false;
- if (_pos == 0)
+ if (CurrentPosition == 0)
{
// self
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
if (_nav.MoveToFirstChild ())
{
_depth ++;
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
while (_depth != 0)
{
if (_nav.MoveToNext ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
if (!_nav.MoveToParent ()) // should NEVER fail!
{
private bool _finished = false;
public FollowingIterator (BaseIterator iter) : base (iter) {}
- protected FollowingIterator (FollowingIterator other) : base (other) {}
+ private FollowingIterator (FollowingIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new FollowingIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (_finished)
return false;
- if (_pos == 0)
+ if (CurrentPosition == 0)
{
if (_nav.MoveToNext ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
} else {
while (_nav.MoveToParent ()) {
if (_nav.MoveToNext ()) {
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
{
if (_nav.MoveToFirstChild ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
do
{
if (_nav.MoveToNext ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
public PrecedingIterator (BaseIterator iter) : base (iter)
{
startPosition = iter.Current.Clone ();
- _current = startPosition.Clone ();
}
- protected PrecedingIterator (PrecedingIterator other) : base (other)
+ private PrecedingIterator (PrecedingIterator other) : base (other, true)
{
startPosition = other.startPosition;
started = other.started;
finished = other.finished;
- _current = other._current.Clone ();
}
public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (finished)
return false;
finished = true;
return false;
} else {
- _pos ++;
- // This cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
internal class NamespaceIterator : SimpleIterator
{
public NamespaceIterator (BaseIterator iter) : base (iter) {}
- protected NamespaceIterator (NamespaceIterator other) : base (other) {}
+ private NamespaceIterator (NamespaceIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new NamespaceIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
- if (_pos == 0)
+ if (CurrentPosition == 0)
{
if (_nav.MoveToFirstNamespace ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
else if (_nav.MoveToNextNamespace ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
return false;
internal class AttributeIterator : SimpleIterator
{
public AttributeIterator (BaseIterator iter) : base (iter) {}
- protected AttributeIterator (AttributeIterator other) : base (other) {}
+ private AttributeIterator (AttributeIterator other) : base (other, true) {}
public override XPathNodeIterator Clone () { return new AttributeIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
- if (_pos == 0)
+ if (CurrentPosition == 0)
{
if (_nav.MoveToFirstAttribute ())
{
- _pos += 1;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
}
else if (_nav.MoveToNextAttribute ())
{
- _pos ++;
- // This clone cannot be omitted
- _current = _nav.Clone ();
+ _current = null;
return true;
}
return false;
internal class AxisIterator : BaseIterator
{
- protected SimpleIterator _iter;
- protected NodeTest _test;
- protected int _pos;
+ private SimpleIterator _iter;
+ private NodeTest _test;
string name, ns;
XPathNodeType matchType;
- public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter)
+ public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter.NamespaceManager)
{
_iter = iter;
_test = test;
// ns = Current.NameTable.Add (ns);
}
- protected AxisIterator (AxisIterator other) : base (other)
+ private AxisIterator (AxisIterator other) : base (other)
{
_iter = (SimpleIterator) other._iter.Clone ();
_test = other._test;
- _pos = other._pos;
name = other.name;
ns = other.ns;
matchType = other.matchType;
}
public override XPathNodeIterator Clone () { return new AxisIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
while (_iter.MoveNext ())
{
if (_test.Match (NamespaceManager, Current))
{
- _pos ++;
return true;
}
}
return false;
}
public override XPathNavigator Current { get { return _iter.Current; }}
- public override int CurrentPosition { get { return _pos; }}
bool Match ()
{
internal class SlashIterator : BaseIterator
{
- protected BaseIterator _iterLeft;
- protected BaseIterator _iterRight;
- protected NodeSet _expr;
- protected int _pos;
+ private BaseIterator _iterLeft;
+ private BaseIterator _iterRight;
+ private NodeSet _expr;
ArrayList _navStore;
SortedList _iterList;
bool _finished;
BaseIterator _nextIterRight;
- public SlashIterator (BaseIterator iter, NodeSet expr) : base (iter)
+ public SlashIterator (BaseIterator iter, NodeSet expr) : base (iter.NamespaceManager)
{
_iterLeft = iter;
_expr = expr;
+ if (_iterLeft.RequireSorting || _expr.RequireSorting)
+ CollectResults ();
}
- protected SlashIterator (SlashIterator other) : base (other)
+ private SlashIterator (SlashIterator other) : base (other)
{
_iterLeft = (BaseIterator) other._iterLeft.Clone ();
if (other._iterRight != null)
_iterRight = (BaseIterator) other._iterRight.Clone ();
_expr = other._expr;
- _pos = other._pos;
if (other._iterList != null)
_iterList = (SortedList) other._iterList.Clone ();
if (other._navStore != null)
}
public override XPathNodeIterator Clone () { return new SlashIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (_finished)
return false;
- if (RequireSorting) {
- if (_navStore == null) {
- CollectResults ();
- if (_navStore.Count == 0) {
- _finished = true;
- return false;
- }
- }
- _pos++;
- if (_navStore.Count < _pos) {
+ if (_navStore != null) {
+ // Which requires sorting::
+ if (_navStore.Count < CurrentPosition + 1) {
_finished = true;
- _pos--;
return false;
}
- while (_navStore.Count > _pos) {
- if (((XPathNavigator) _navStore [_pos]).ComparePosition (
- (XPathNavigator) _navStore [_pos - 1]) == XmlNodeOrder.Same)
- _navStore.RemoveAt (_pos);
+ while (_navStore.Count > CurrentPosition + 1) {
+ if (((XPathNavigator) _navStore [CurrentPosition + 1]).IsSamePosition (
+ (XPathNavigator) _navStore [CurrentPosition]))
+ _navStore.RemoveAt (CurrentPosition + 1);
else
break;
}
return true;
- } else {
- if (_iterRight == null) { // First time
- if (!_iterLeft.MoveNext ())
+ }
+ // Which does not require sorting::
+
+ if (_iterRight == null) { // First time
+ if (!_iterLeft.MoveNext ())
+ return false;
+ _iterRight = _expr.EvaluateNodeSet (_iterLeft);
+ _iterList = new SortedList (XPathIteratorComparer.Instance);
+ }
+
+ while (true) {
+ while (!_iterRight.MoveNext ()) {
+ if (_iterList.Count > 0) {
+ int last = _iterList.Count - 1;
+ BaseIterator tmpIter = (BaseIterator) _iterList.GetByIndex (last);
+ _iterList.RemoveAt (last);
+ switch (tmpIter.Current.ComparePosition (_iterRight.Current)) {
+ case XmlNodeOrder.Same:
+ case XmlNodeOrder.Before:
+ _iterRight = tmpIter;
+ continue;
+ default:
+ _iterRight = tmpIter;
+ break;
+ }
+ break;
+ } else if (_nextIterRight != null) {
+ _iterRight = _nextIterRight;
+ _nextIterRight = null;
+ break;
+ } else if (!_iterLeft.MoveNext ()) {
+ _finished = true;
return false;
- _iterRight = _expr.EvaluateNodeSet (_iterLeft);
- _iterList = new SortedList (XPathIteratorComparer.Instance);
+ }
+ else
+ _iterRight = _expr.EvaluateNodeSet (_iterLeft);
}
-
- while (true) {
- while (!_iterRight.MoveNext ()) {
- if (_iterList.Count > 0) {
- int last = _iterList.Count - 1;
- BaseIterator tmpIter = (BaseIterator) _iterList.GetByIndex (last);
- _iterList.RemoveAt (last);
- switch (tmpIter.Current.ComparePosition (_iterRight.Current)) {
- case XmlNodeOrder.Same:
- case XmlNodeOrder.Before:
- _iterRight = tmpIter;
- continue;
- default:
- _iterRight = tmpIter;
+ bool loop = true;
+ while (loop) {
+ loop = false;
+ if (_nextIterRight == null) {
+ bool noMoreNext = false;
+ while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
+ if(_iterLeft.MoveNext ())
+ _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
+ else {
+ noMoreNext = true;
break;
}
- break;
- } else if (_nextIterRight != null) {
+ }
+ if (noMoreNext)
+ _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
+ }
+ if (_nextIterRight != null) {
+ switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
+ case XmlNodeOrder.After:
+ _iterList.Add (_iterList.Count, _iterRight);
_iterRight = _nextIterRight;
_nextIterRight = null;
+ loop = true;
break;
- } else if (!_iterLeft.MoveNext ()) {
- _finished = true;
- return false;
- }
- else
- _iterRight = _expr.EvaluateNodeSet (_iterLeft);
- }
- bool loop = true;
- while (loop) {
- loop = false;
- if (_nextIterRight == null) {
- bool noMoreNext = false;
- while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
- if(_iterLeft.MoveNext ())
- _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
- else {
- noMoreNext = true;
- break;
- }
- }
- if (noMoreNext)
- _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
- }
- if (_nextIterRight != null) {
- switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
- case XmlNodeOrder.After:
- _iterList.Add (_iterList.Count, _iterRight);
- _iterRight = _nextIterRight;
+ case XmlNodeOrder.Same:
+ if (!_nextIterRight.MoveNext ())
_nextIterRight = null;
- loop = true;
- break;
- case XmlNodeOrder.Same:
- if (!_nextIterRight.MoveNext ())
- _nextIterRight = null;
-
- else {
- int last = _iterList.Count;
- if (last > 0) {
- _iterList.Add (last, _nextIterRight);
- _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
- _iterList.RemoveAt (last);
- }
- }
- loop = true;
- break;
+ else {
+ int last = _iterList.Count;
+ if (last > 0) {
+ _iterList.Add (last, _nextIterRight);
+ _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
+ _iterList.RemoveAt (last);
+ }
}
+
+ loop = true;
+ break;
}
}
- _pos ++;
- return true;
}
+ return true;
}
}
+
private void CollectResults ()
{
- if (_navStore != null)
- return;
_navStore = new ArrayList ();
while (true) {
while (_iterRight == null || !_iterRight.MoveNext ()) {
_iterRight = _expr.EvaluateNodeSet (_iterLeft);
}
XPathNavigator nav = _iterRight.Current;
- _navStore.Add (_needClone ? nav.Clone () : nav);
+ _navStore.Add (nav);
}
}
public override XPathNavigator Current {
get {
- if (_pos <= 0) return null;
- if (RequireSorting) {
- return (XPathNavigator) _navStore [_pos - 1];
+ if (CurrentPosition <= 0) return null;
+ if (_navStore != null) {
+ return (XPathNavigator) _navStore [CurrentPosition - 1];
} else {
return _iterRight.Current;
}
}
}
- public override int CurrentPosition { get { return _pos; }}
public override bool RequireSorting {
- get {
- return _iterLeft.RequireSorting || _expr.RequireSorting;
- }
+ // It always does not need to be sorted.
+ get { return false; }
}
public override int Count { get { return _navStore == null ? base.Count : _navStore.Count; } }
internal class PredicateIterator : BaseIterator
{
- protected BaseIterator _iter;
- protected Expression _pred;
- protected int _pos;
- protected XPathResultType resType;
+ private BaseIterator _iter;
+ private Expression _pred;
+ private XPathResultType resType;
- public PredicateIterator (BaseIterator iter, Expression pred) : base (iter)
+ public PredicateIterator (BaseIterator iter, Expression pred) : base (iter.NamespaceManager)
{
_iter = iter;
_pred = pred;
resType = pred.GetReturnType (iter);
}
- protected PredicateIterator (PredicateIterator other) : base (other)
+ private PredicateIterator (PredicateIterator other) : base (other)
{
_iter = (BaseIterator) other._iter.Clone ();
_pred = other._pred;
- _pos = other._pos;
resType = other.resType;
}
public override XPathNodeIterator Clone () { return new PredicateIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
while (_iter.MoveNext ())
{
break;
}
- _pos ++;
return true;
}
return false;
}
public override XPathNavigator Current { get { return _iter.Current; }}
- public override int CurrentPosition { get { return _pos; }}
public override bool ReverseAxis {
get { return _iter.ReverseAxis; }
}
- public override bool RequireSorting { get { return true; } }
- }
-
- /*
- internal class EnumeratorIterator : BaseIterator
- {
- protected IEnumerator _enum;
- protected int _pos;
- bool _requireSorting;
-
- public EnumeratorIterator (BaseIterator iter, IEnumerator enumerator, bool requireSorting) : base (iter)
- {
- if (!(enumerator is ICloneable))
- throw new ArgumentException ("Target enumerator must be cloneable.");
- _enum = enumerator;
- _requireSorting = requireSorting;
- }
-
- public EnumeratorIterator (IEnumerator enumerator, XmlNamespaceManager nsm, bool requireSorting) : base (nsm)
- {
- if (!(enumerator is ICloneable))
- throw new ArgumentException ("Target enumerator must be cloneable.");
- _enum = enumerator;
- _requireSorting = requireSorting;
- }
-
- protected EnumeratorIterator (EnumeratorIterator other) : base (other)
- {
- ICloneable enumClone = other._enum as ICloneable;
- _enum = (IEnumerator) enumClone.Clone ();
- _pos = other._pos;
- _requireSorting = other._requireSorting;
- }
- public override XPathNodeIterator Clone () { return new EnumeratorIterator (this); }
-
- public override bool MoveNext ()
- {
- if (!_enum.MoveNext ())
- return false;
- _pos++;
- return true;
- }
- public override XPathNavigator Current { get { return (XPathNavigator) _enum.Current; }}
- public override int CurrentPosition { get { return _pos; }}
-
- public override bool RequireSorting { get { return _requireSorting; } }
+ public override bool RequireSorting { get { return _iter.RequireSorting || _pred.RequireSorting; } }
}
- */
internal class ListIterator : BaseIterator
{
- protected IList _list;
- protected int _pos;
+ private IList _list;
bool _requireSorting;
- public ListIterator (BaseIterator iter, IList list, bool requireSorting) : base (iter)
+ public ListIterator (BaseIterator iter, IList list, bool requireSorting) : base (iter.NamespaceManager)
{
if (!(list is ICloneable))
throw new ArgumentException ("Target enumerator must be cloneable.");
_requireSorting = requireSorting;
}
- public ListIterator (IList list, XmlNamespaceManager nsm, bool requireSorting) : base (nsm)
+ public ListIterator (IList list, NSResolver nsm, bool requireSorting) : base (nsm)
{
if (!(list is ICloneable))
throw new ArgumentException ("Target enumerator must be cloneable.");
_requireSorting = requireSorting;
}
- protected ListIterator (ListIterator other) : base (other)
+ private ListIterator (ListIterator other) : base (other)
{
ICloneable listClone = other._list as ICloneable;
_list = (IList) listClone.Clone ();
- _pos = other._pos;
_requireSorting = other._requireSorting;
}
public override XPathNodeIterator Clone () { return new ListIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
- if (_pos >= _list.Count)
+ if (CurrentPosition >= _list.Count)
return false;
- _pos++;
return true;
}
public override XPathNavigator Current {
get {
if (_list.Count == 0)
return null;
- return (XPathNavigator) _list [_pos - 1];
+ return (XPathNavigator) _list [CurrentPosition - 1];
}
}
- public override int CurrentPosition { get { return _pos; }}
public override bool RequireSorting { get { return _requireSorting; } }
internal class UnionIterator : BaseIterator
{
- protected BaseIterator _left, _right;
- private int _pos;
+ private BaseIterator _left, _right;
private bool keepLeft;
private bool keepRight;
private bool useRight;
- public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter)
+ public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter.NamespaceManager)
{
_left = left;
_right = right;
}
- protected UnionIterator (UnionIterator other) : base (other)
+ private UnionIterator (UnionIterator other) : base (other)
{
_left = (BaseIterator) other._left.Clone ();
_right = (BaseIterator) other._right.Clone ();
- _pos = other._pos;
keepLeft = other.keepLeft;
keepRight = other.keepRight;
useRight = other.useRight;
}
public override XPathNodeIterator Clone () { return new UnionIterator (this); }
- public override bool MoveNext ()
+ public override bool MoveNextCore ()
{
if (!keepLeft)
keepLeft = _left.MoveNext ();
if (!keepLeft && !keepRight)
return false;
- _pos ++;
if (!keepRight) {
keepLeft = useRight = false;
return true;
{
get
{
- if (_pos == 0)
+ if (CurrentPosition == 0)
return null;
if (useRight)
return _right.Current;
return _left.Current;
}
}
- public override int CurrentPosition { get { return _pos; }}
public override bool RequireSorting { get { return _left.RequireSorting || _right.RequireSorting; } }
}