* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.XML / System.Xml / XmlNodeListChildren.cs
1 //
2 // System.Xml.XmlNodeList
3 //
4 // Author:
5 //   Kral Ferch <kral_ferch@hotmail.com>
6 //
7 // (C) 2002 Kral Ferch
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
34 namespace System.Xml
35 {
36         internal class XmlNodeListChildren : XmlNodeList
37         {
38                 #region Enumerator
39
40                 private class Enumerator : IEnumerator
41                 {
42                         IHasXmlChildNode parent;
43                         XmlLinkedNode currentChild;
44                         bool passedLastNode;
45
46                         internal Enumerator (IHasXmlChildNode parent)
47                         {
48                                 currentChild = null;
49                                 this.parent = parent;
50                                 passedLastNode = false;
51                         }
52
53                         public virtual object Current {
54                                 get {
55                                         if ((currentChild == null) ||
56                                                 (parent.LastLinkedChild == null) ||
57                                                 (passedLastNode == true))
58                                                 throw new InvalidOperationException();
59
60                                         return currentChild;
61                                 }
62                         }
63
64                         public virtual bool MoveNext()
65                         {
66                                 bool movedNext = true;
67
68                                 if (parent.LastLinkedChild == null) {
69                                         movedNext = false;
70                                 }
71                                 else if (currentChild == null) {
72                                         currentChild = parent.LastLinkedChild.NextLinkedSibling;
73                                 }
74                                 else {
75                                         if (Object.ReferenceEquals(currentChild, parent.LastLinkedChild)) {
76                                                 movedNext = false;
77                                                 passedLastNode = true;
78                                         }
79                                         else {
80                                                 currentChild = currentChild.NextLinkedSibling;
81                                         }
82                                 }
83
84                                 return movedNext;
85                         }
86
87                         public virtual void Reset()
88                         {
89                                 currentChild = null;
90                         }
91                 }
92
93                 #endregion
94
95                 #region Fields
96
97                 IHasXmlChildNode parent;
98
99                 #endregion
100
101                 #region Constructors
102                 public XmlNodeListChildren(IHasXmlChildNode parent)
103                 {
104                         this.parent = parent;
105                 }
106
107                 #endregion
108
109                 #region Properties
110
111                 public override int Count {
112                         get {
113                                 int count = 0;
114
115                                 if (parent.LastLinkedChild != null) {
116                                         XmlLinkedNode currentChild = parent.LastLinkedChild.NextLinkedSibling;
117                                         
118                                         count = 1;
119                                         while (!Object.ReferenceEquals(currentChild, parent.LastLinkedChild)) {
120                                                 currentChild = currentChild.NextLinkedSibling;
121                                                 count++;
122                                         }
123                                 }
124
125                                 return count;
126                         }
127                 }
128
129                 #endregion
130
131                 #region Methods
132
133                 public override IEnumerator GetEnumerator ()
134                 {
135                         return new Enumerator(parent);
136                 }
137
138                 public override XmlNode Item (int index)
139                 {
140                         XmlNode requestedNode = null;
141
142                         // Return null if index is out of range. by  DOM design.
143                         if (Count <= index)
144                                 return null;
145
146                         // Instead of checking for && index < Count which has to walk
147                         // the whole list to get a count, we'll just keep a count since
148                         // we have to walk the list anyways to get to index.
149                         if ((index >= 0) && (parent.LastLinkedChild != null)) {
150                                 XmlLinkedNode currentChild = parent.LastLinkedChild.NextLinkedSibling;
151                                 int count = 0;
152
153                                 while ((count < index) && !Object.ReferenceEquals(currentChild, parent.LastLinkedChild)) 
154                                 {
155                                         currentChild = currentChild.NextLinkedSibling;
156                                         count++;
157                                 }
158
159                                 if (count == index) {
160                                         requestedNode = currentChild;
161                                 }
162                         }
163
164                         return requestedNode;
165                 }
166
167                 #endregion
168         }
169
170         
171 }