merge -r 60814:60815
[mono.git] / mcs / class / System.XML / System.Xml / XmlIteratorNodeList.cs
1 //
2 // System.Xml.XmlIteratorNodeList
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C) 2006 Novell Inc.
8 //
9
10 //
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.
29 //
30
31 using System;
32 using System.Collections;
33 using System.Xml.XPath;
34
35 namespace System.Xml
36 {
37         internal class XmlIteratorNodeList : XmlNodeList
38         {
39                 XPathNodeIterator source;
40                 XPathNodeIterator iterator;
41                 XmlNode previous;
42                 ArrayList list;
43                 bool finished;
44
45                 #region Constructors
46
47                 public XmlIteratorNodeList (XPathNodeIterator iter)
48                 {
49                         source = iter;
50                         iterator = iter.Clone ();
51                         list = new ArrayList ();
52                 }
53
54                 #endregion
55
56                 #region Properties
57
58                 public override int Count {
59                         get {
60 /*
61                                 // The performance on Count depends on the 
62                                 // iterator which is actually used. In some
63                                 // iterators, getting iterator.Count is much
64                                 // faster.
65
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
70                                 // performance.
71                                 
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.
77
78                                 if (!finished) {
79                                         BaseIterator iter = iterator as BaseIterator;
80                                         if (iter != null && iter.ReverseAxis || iter is SlashIterator)
81                                                 return iter.Count;
82
83                                         while (iterator.MoveNext ())
84                                                 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
85                                         finished = true;
86                                 }
87                                 return list.Count;
88 */
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;
94                         }
95                 }
96
97                 #endregion
98
99                 #region Methods
100
101                 public override IEnumerator GetEnumerator ()
102                 {
103                         if (finished)
104                                 return list.GetEnumerator ();
105                         else
106                                 return new XPathNodeIteratorNodeListIterator (source);
107 //                              return new XPathNodeIteratorNodeListIterator2 (this);
108                 }
109
110                 public override XmlNode Item (int index)
111                 {
112                         if (index < 0)
113                                 return null;
114                         if (index < list.Count)
115                                 return (XmlNode) list [index];
116                         index++;
117                         while (iterator.CurrentPosition < index) {
118                                 if (!iterator.MoveNext ()) {
119                                         finished = true;
120                                         return null;
121                                 }
122                                 list.Add (((IHasXmlNode) iterator.Current).GetNode ());
123                         }
124                         return (XmlNode) list [index - 1];
125                 }
126
127                 #endregion
128
129                 class XPathNodeIteratorNodeListIterator : IEnumerator
130                 {
131                         XPathNodeIterator iter;
132                         XPathNodeIterator source;
133                         public XPathNodeIteratorNodeListIterator (XPathNodeIterator source)
134                         {
135                                 this.source = source;
136                                 Reset ();
137                         }
138
139                         public bool MoveNext ()
140                         {
141                                 return iter.MoveNext ();
142                         }
143
144                         public object Current {
145                                 get { return ((IHasXmlNode) iter.Current).GetNode (); }
146                         }
147
148                         public void Reset ()
149                         {
150                                 iter = source.Clone ();
151                         }
152                 }
153
154                 /*
155                 class XPathNodeIteratorNodeListIterator2 : IEnumerator
156                 {
157                         int current = -1;
158                         XmlIteratorNodeList source;
159
160                         public XPathNodeIteratorNodeListIterator2 (XmlIteratorNodeList source)
161                         {
162                                 this.source = source;
163                         }
164
165                         public bool MoveNext ()
166                         {
167                                 return source [++current] != null;
168                         }
169
170                         public object Current {
171                                 get { return source [current]; }
172                         }
173
174                         public void Reset ()
175                         {
176                                 current = -1;
177                         }
178                 }
179                 */
180         }
181 }