File: XPathDocumentIterator.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (271 lines) | stat: -rw-r--r-- 9,396 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
//------------------------------------------------------------------------------
// <copyright file="XPathDocumentIterator.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
using System;
using System.Xml;
using System.Xml.XPath;
using System.Diagnostics;

namespace MS.Internal.Xml.Cache {

    /// <summary>
    /// Base internal class of all XPathDocument XPathNodeIterator implementations.
    /// </summary>
    internal abstract class XPathDocumentBaseIterator : XPathNodeIterator {
        protected XPathDocumentNavigator ctxt;
        protected int pos;

        /// <summary>
        /// Create a new iterator that is initially positioned on the "ctxt" node.
        /// </summary>
        protected XPathDocumentBaseIterator(XPathDocumentNavigator ctxt) {
            this.ctxt = new XPathDocumentNavigator(ctxt);
        }

        /// <summary>
        /// Create a new iterator that is a copy of "iter".
        /// </summary>
        protected XPathDocumentBaseIterator(XPathDocumentBaseIterator iter) {
            this.ctxt = new XPathDocumentNavigator(iter.ctxt);
            this.pos = iter.pos;
        }

        /// <summary>
        /// Return the current navigator.
        /// </summary>
        public override XPathNavigator Current {
            get { return this.ctxt; }
        }

        /// <summary>
        /// Return the iterator's current position.
        /// </summary>
        public override int CurrentPosition {
            get { return this.pos; }
        }
    }


    /// <summary>
    /// Iterate over all element children with a particular QName.
    /// </summary>
    internal class XPathDocumentElementChildIterator : XPathDocumentBaseIterator {
        private string localName, namespaceUri;

        /// <summary>
        /// Create an iterator that ranges over all element children of "parent" having the specified QName.
        /// </summary>
        public XPathDocumentElementChildIterator(XPathDocumentNavigator parent, string name, string namespaceURI) : base(parent) {
            if (namespaceURI == null) throw new ArgumentNullException("namespaceURI");

            this.localName = parent.NameTable.Get(name);
            this.namespaceUri = namespaceURI;
        }

        /// <summary>
        /// Create a new iterator that is a copy of "iter".
        /// </summary>
        public XPathDocumentElementChildIterator(XPathDocumentElementChildIterator iter) : base(iter) {
            this.localName = iter.localName;
            this.namespaceUri = iter.namespaceUri;
        }

        /// <summary>
        /// Create a copy of this iterator.
        /// </summary>
        public override XPathNodeIterator Clone() {
            return new XPathDocumentElementChildIterator(this);
        }

        /// <summary>
        /// Position the iterator to the next matching child.
        /// </summary>
        public override bool MoveNext() {
            if (this.pos == 0) {
                if (!this.ctxt.MoveToChild(this.localName, this.namespaceUri))
                    return false;
            }
            else {
                if (!this.ctxt.MoveToNext(this.localName, this.namespaceUri))
                    return false;
            }

            this.pos++;
            return true;
        }
    }


    /// <summary>
    /// Iterate over all content children with a particular XPathNodeType.
    /// </summary>
    internal class XPathDocumentKindChildIterator : XPathDocumentBaseIterator {
        private XPathNodeType typ;

        /// <summary>
        /// Create an iterator that ranges over all content children of "parent" having the specified XPathNodeType.
        /// </summary>
        public XPathDocumentKindChildIterator(XPathDocumentNavigator parent, XPathNodeType typ) : base(parent) {
            this.typ = typ;
        }

        /// <summary>
        /// Create a new iterator that is a copy of "iter".
        /// </summary>
        public XPathDocumentKindChildIterator(XPathDocumentKindChildIterator iter) : base(iter) {
            this.typ = iter.typ;
        }

        /// <summary>
        /// Create a copy of this iterator.
        /// </summary>
        public override XPathNodeIterator Clone() {
            return new XPathDocumentKindChildIterator(this);
        }

        /// <summary>
        /// Position the iterator to the next descendant.
        /// </summary>
        public override bool MoveNext() {
            if (this.pos == 0) {
                if (!this.ctxt.MoveToChild(this.typ))
                    return false;
            }
            else {
                if (!this.ctxt.MoveToNext(this.typ))
                    return false;
            }

            this.pos++;
            return true;
        }
    }


    /// <summary>
    /// Iterate over all element descendants with a particular QName.
    /// </summary>
    internal class XPathDocumentElementDescendantIterator : XPathDocumentBaseIterator {
        private XPathDocumentNavigator end;
        private string localName, namespaceUri;
        private bool matchSelf;

        /// <summary>
        /// Create an iterator that ranges over all element descendants of "root" having the specified QName.
        /// </summary>
        public XPathDocumentElementDescendantIterator(XPathDocumentNavigator root, string name, string namespaceURI, bool matchSelf) : base(root) {
            if (namespaceURI == null) throw new ArgumentNullException("namespaceURI");

            this.localName = root.NameTable.Get(name);
            this.namespaceUri = namespaceURI;
            this.matchSelf = matchSelf;

            // Find the next non-descendant node that follows "root" in document order
            if (root.NodeType != XPathNodeType.Root) {
                this.end = new XPathDocumentNavigator(root);
                this.end.MoveToNonDescendant();
            }
        }

        /// <summary>
        /// Create a new iterator that is a copy of "iter".
        /// </summary>
        public XPathDocumentElementDescendantIterator(XPathDocumentElementDescendantIterator iter) : base(iter) {
            this.end = iter.end;
            this.localName = iter.localName;
            this.namespaceUri = iter.namespaceUri;
            this.matchSelf = iter.matchSelf;
        }

        /// <summary>
        /// Create a copy of this iterator.
        /// </summary>
        public override XPathNodeIterator Clone() {
            return new XPathDocumentElementDescendantIterator(this);
        }

        /// <summary>
        /// Position the iterator to the next descendant.
        /// </summary>
        public override bool MoveNext() {
            if (this.matchSelf) {
                this.matchSelf = false;

                if (this.ctxt.IsElementMatch(this.localName, this.namespaceUri)) {
                    this.pos++;
                    return true;
                }
            }

            if (!this.ctxt.MoveToFollowing(this.localName, this.namespaceUri, this.end))
                return false;

            this.pos++;
            return true;
        }
    }


    /// <summary>
    /// Iterate over all content descendants with a particular XPathNodeType.
    /// </summary>
    internal class XPathDocumentKindDescendantIterator : XPathDocumentBaseIterator {
        private XPathDocumentNavigator end;
        private XPathNodeType typ;
        private bool matchSelf;

        /// <summary>
        /// Create an iterator that ranges over all content descendants of "root" having the specified XPathNodeType.
        /// </summary>
        public XPathDocumentKindDescendantIterator(XPathDocumentNavigator root, XPathNodeType typ, bool matchSelf) : base(root) {
            this.typ = typ;
            this.matchSelf = matchSelf;

            // Find the next non-descendant node that follows "root" in document order
            if (root.NodeType != XPathNodeType.Root) {
                this.end = new XPathDocumentNavigator(root);
                this.end.MoveToNonDescendant();
            }
        }

        /// <summary>
        /// Create a new iterator that is a copy of "iter".
        /// </summary>
        public XPathDocumentKindDescendantIterator(XPathDocumentKindDescendantIterator iter) : base(iter) {
            this.end = iter.end;
            this.typ = iter.typ;
            this.matchSelf = iter.matchSelf;
        }

        /// <summary>
        /// Create a copy of this iterator.
        /// </summary>
        public override XPathNodeIterator Clone() {
            return new XPathDocumentKindDescendantIterator(this);
        }

        /// <summary>
        /// Position the iterator to the next descendant.
        /// </summary>
        public override bool MoveNext() {
            if (this.matchSelf) {
                this.matchSelf = false;

                if (this.ctxt.IsKindMatch(this.typ)) {
                    this.pos++;
                    return true;
                }
            }

            if (!this.ctxt.MoveToFollowing(this.typ, this.end))
                return false;

            this.pos++;
            return true;
        }
    }
}