Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Xml / System / Xml / XPath / Internal / XPathAncestorQuery.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XPathAncestorQuery.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
7
8 namespace MS.Internal.Xml.XPath {
9     using System;
10     using System.Xml;
11     using System.Xml.XPath;
12     using System.Diagnostics;
13     using System.Collections.Generic;
14
15     internal sealed class XPathAncestorQuery : CacheAxisQuery {
16         private bool matchSelf;
17
18         public XPathAncestorQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest, bool matchSelf) : base(qyInput, name, prefix, typeTest)  {
19             this.matchSelf = matchSelf;
20         }
21         private XPathAncestorQuery(XPathAncestorQuery other) : base(other) {
22             this.matchSelf = other.matchSelf;
23         }
24
25         public override object Evaluate(XPathNodeIterator context) {
26             base.Evaluate(context);
27
28             XPathNavigator ancestor = null;            
29             XPathNavigator input;
30             while ((input = qyInput.Advance()) != null) {
31                 if (matchSelf) {
32                     if (matches(input)) {
33                         if (!Insert(outputBuffer, input)) {
34                             // If input is already in output buffer all its ancestors are in a buffer as well.
35                             continue; 
36                         }
37                     }
38                 }
39                 if (ancestor == null || ! ancestor.MoveTo(input)) {
40                     ancestor = input.Clone();
41                 }
42                 while (ancestor.MoveToParent()) {
43                     if (matches(ancestor)) {
44                         if (!Insert(outputBuffer, ancestor)) {
45                             // If input is already in output buffer all its ancestors are in a buffer as well.
46                             break;
47                         }
48                     }
49                 }
50             }
51             return this;
52         }
53
54         public override XPathNodeIterator Clone() { return new XPathAncestorQuery(this); }
55         public override int CurrentPosition { get { return outputBuffer.Count - count + 1; } }
56         public override QueryProps Properties { get { return base.Properties | QueryProps.Reverse; } }
57
58         public override void PrintQuery(XmlWriter w) {
59             w.WriteStartElement(this.GetType().Name);
60             if (matchSelf) {
61                 w.WriteAttributeString("self", "yes");
62             }
63             if (NameTest) {
64                 w.WriteAttributeString("name", Prefix.Length != 0 ? Prefix + ':' + Name : Name);
65             }
66             if (TypeTest != XPathNodeType.Element) {
67                 w.WriteAttributeString("nodeType", TypeTest.ToString());
68             }
69             qyInput.PrintQuery(w);
70             w.WriteEndElement();
71         }
72     }
73 }