2 // System.Xml.XmlIteratorNodeList
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // (C) 2006 Novell Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Xml.XPath;
37 internal class XmlIteratorNodeList : XmlNodeList
39 XPathNodeIterator source;
40 XPathNodeIterator iterator;
47 public XmlIteratorNodeList (XPathNodeIterator iter)
50 iterator = iter.Clone ();
51 list = new ArrayList ();
58 public override int Count {
61 // The performance on Count depends on the
62 // iterator which is actually used. In some
63 // iterators, getting iterator.Count is much
66 // With (current) implementation in general,
67 // those iterators that requires sorting is
68 // likely to have already-computed arrays, so
69 // for them getting Count does not impact on
72 // But by default, getting iterator.Count means
73 // it internally iterates all the nodes. That
74 // might result in duplicate iteration (so
75 // ineffective). So here I decided that it
76 // just collects all the nodes to the list.
79 BaseIterator iter = iterator as BaseIterator;
80 if (iter != null && iter.ReverseAxis || iter is SlashIterator)
83 while (iterator.MoveNext ())
84 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
89 // anyways such code that uses
90 // XmlNodeList.Count already gives up
91 // performance. Also, storing things in the
92 // list causes extra memory consumption.
93 return iterator.Count;
101 public override IEnumerator GetEnumerator ()
104 return list.GetEnumerator ();
106 return new XPathNodeIteratorNodeListIterator (source);
107 // return new XPathNodeIteratorNodeListIterator2 (this);
110 public override XmlNode Item (int index)
114 if (index < list.Count)
115 return (XmlNode) list [index];
117 while (iterator.CurrentPosition < index) {
118 if (!iterator.MoveNext ()) {
122 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
124 return (XmlNode) list [index - 1];
129 class XPathNodeIteratorNodeListIterator : IEnumerator
131 XPathNodeIterator iter;
132 XPathNodeIterator source;
133 public XPathNodeIteratorNodeListIterator (XPathNodeIterator source)
135 this.source = source;
139 public bool MoveNext ()
141 return iter.MoveNext ();
144 public object Current {
145 get { return ((IHasXmlNode) iter.Current).GetNode (); }
150 iter = source.Clone ();
155 class XPathNodeIteratorNodeListIterator2 : IEnumerator
158 XmlIteratorNodeList source;
160 public XPathNodeIteratorNodeListIterator2 (XmlIteratorNodeList source)
162 this.source = source;
165 public bool MoveNext ()
167 return source [++current] != null;
170 public object Current {
171 get { return source [current]; }