2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.XML / System.Xml / XmlIteratorNodeList.cs
blobfc5518e98e5ed6ba286dd5c6be569c26c132a766
1 //
2 // System.Xml.XmlIteratorNodeList
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C) 2006 Novell Inc.
8 //
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:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
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.
31 using System;
32 using System.Collections;
33 using System.Xml.XPath;
35 namespace System.Xml
37 internal class XmlIteratorNodeList : XmlNodeList
39 XPathNodeIterator source;
40 XPathNodeIterator iterator;
41 ArrayList list;
42 bool finished;
44 #region Constructors
46 public XmlIteratorNodeList (XPathNodeIterator iter)
48 source = iter;
49 iterator = iter.Clone ();
50 list = new ArrayList ();
53 #endregion
55 #region Properties
57 public override int Count {
58 get {
60 // The performance on Count depends on the
61 // iterator which is actually used. In some
62 // iterators, getting iterator.Count is much
63 // faster.
65 // With (current) implementation in general,
66 // those iterators that requires sorting is
67 // likely to have already-computed arrays, so
68 // for them getting Count does not impact on
69 // performance.
71 // But by default, getting iterator.Count means
72 // it internally iterates all the nodes. That
73 // might result in duplicate iteration (so
74 // ineffective). So here I decided that it
75 // just collects all the nodes to the list.
77 if (!finished) {
78 BaseIterator iter = iterator as BaseIterator;
79 if (iter != null && iter.ReverseAxis || iter is SlashIterator)
80 return iter.Count;
82 while (iterator.MoveNext ())
83 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
84 finished = true;
86 return list.Count;
88 // anyways such code that uses
89 // XmlNodeList.Count already gives up
90 // performance. Also, storing things in the
91 // list causes extra memory consumption.
92 return iterator.Count;
96 #endregion
98 #region Methods
100 public override IEnumerator GetEnumerator ()
102 if (finished)
103 return list.GetEnumerator ();
104 else
105 return new XPathNodeIteratorNodeListIterator (source);
106 // return new XPathNodeIteratorNodeListIterator2 (this);
109 public override XmlNode Item (int index)
111 if (index < 0)
112 return null;
113 if (index < list.Count)
114 return (XmlNode) list [index];
115 index++;
116 while (iterator.CurrentPosition < index) {
117 if (!iterator.MoveNext ()) {
118 finished = true;
119 return null;
121 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
123 return (XmlNode) list [index - 1];
126 #endregion
128 class XPathNodeIteratorNodeListIterator : IEnumerator
130 XPathNodeIterator iter;
131 XPathNodeIterator source;
132 public XPathNodeIteratorNodeListIterator (XPathNodeIterator source)
134 this.source = source;
135 Reset ();
138 public bool MoveNext ()
140 return iter.MoveNext ();
143 public object Current {
144 get { return ((IHasXmlNode) iter.Current).GetNode (); }
147 public void Reset ()
149 iter = source.Clone ();
154 class XPathNodeIteratorNodeListIterator2 : IEnumerator
156 int current = -1;
157 XmlIteratorNodeList source;
159 public XPathNodeIteratorNodeListIterator2 (XmlIteratorNodeList source)
161 this.source = source;
164 public bool MoveNext ()
166 return source [++current] != null;
169 public object Current {
170 get { return source [current]; }
173 public void Reset ()
175 current = -1;