Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / XsltOld / CopyOfAction.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="CopyOfAction.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Xsl.XsltOld {
9     using Res = System.Xml.Utils.Res;
10     using System;
11     using System.Diagnostics;
12     using System.Xml;
13     using System.Xml.XPath;
14     using MS.Internal.Xml.XPath;
15
16     internal class CopyOfAction : CompiledAction {
17         private const int ResultStored  = 2;
18         private const int NodeSetCopied = 3;
19
20         private int    selectKey   = Compiler.InvalidQueryKey;
21
22         internal override void Compile(Compiler compiler) {
23             CompileAttributes(compiler);
24             CheckRequiredAttribute(compiler, selectKey != Compiler.InvalidQueryKey, "select");
25             CheckEmpty(compiler);
26         }
27
28         internal override bool CompileAttribute(Compiler compiler) {
29             string name   = compiler.Input.LocalName;
30             string value  = compiler.Input.Value;
31             if (Ref.Equal(name, compiler.Atoms.Select)) {
32                 this.selectKey = compiler.AddQuery(value);
33             }
34             else {
35                 return false;
36             }
37
38             return true;
39         }
40
41         internal override void Execute(Processor processor, ActionFrame frame) {
42             Debug.Assert(processor != null && frame != null);
43
44             switch (frame.State) {
45             case Initialized:
46                 Debug.Assert(frame.NodeSet != null);
47                 Query query = processor.GetValueQuery(this.selectKey);
48                 object result = query.Evaluate(frame.NodeSet);
49
50                 if (result is XPathNodeIterator) {
51                     // we cash this query because otherwise current() works incorrectly. Bug#382166.
52                     // To be perfect we should use frame.NewNodeSet here
53                     processor.PushActionFrame(CopyNodeSetAction.GetAction(), new XPathArrayIterator(query));
54                     frame.State = NodeSetCopied;
55                     break;
56                 }
57
58                 XPathNavigator nav = result as XPathNavigator;
59                 if (nav != null) {
60                     processor.PushActionFrame(CopyNodeSetAction.GetAction(), new XPathSingletonIterator(nav));
61                     frame.State = NodeSetCopied;
62                     break; 
63                 }
64
65                 string value = XmlConvert.ToXPathString(result);
66                 if (processor.TextEvent(value)) {
67                     frame.Finished();
68                 } else {
69                     frame.StoredOutput = value;
70                     frame.State        = ResultStored;
71                 }
72                 break;
73
74             case ResultStored:
75                 Debug.Assert(frame.StoredOutput != null);
76                 processor.TextEvent(frame.StoredOutput);
77                 frame.Finished();
78                 break;
79
80             case NodeSetCopied:
81                 Debug.Assert(frame.State == NodeSetCopied);
82                 frame.Finished();
83                 break;
84             }
85         }
86     }
87 }