Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ActionFrame.cs « XsltOld « Xsl « Xml « System « System.Data.SqlXml « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d76ef09966791c5b1dd99aa10c588b850e970713 (plain)
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
//------------------------------------------------------------------------------
// <copyright file="ActionFrame.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------

namespace System.Xml.Xsl.XsltOld {
    using Res = System.Xml.Utils.Res;
    using System;
    using System.Xml;
    using System.Xml.XPath;
    using MS.Internal.Xml.XPath;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Xml.Xsl.XsltOld.Debugger;

    internal class ActionFrame : IStackFrame {
        private int               state;         // Action execution state
        private int               counter;       // Counter, for the use of particular action
        private object []         variables;     // Store for template local variable values
        private Hashtable         withParams;
        private Action            action;        // Action currently being executed
        private ActionFrame       container;     // Frame of enclosing container action and index within it
        private int               currentAction;
        private XPathNodeIterator nodeSet;       // Current node set
        private XPathNodeIterator newNodeSet;    // Node set for processing children or other templates

        // Variables to store action data between states:
        private PrefixQName       calulatedName; // Used in ElementAction and AttributeAction
        private string            storedOutput;  // Used in NumberAction, CopyOfAction, ValueOfAction and ProcessingInstructionAction

        internal PrefixQName CalulatedName {
            get { return this.calulatedName; }
            set { this.calulatedName = value; }
        }

        internal string StoredOutput {
            get { return this.storedOutput; }
            set { this.storedOutput = value; }
        }

        internal int State {
            get { return this.state; }
            set { this.state = value; }
        }

        internal int Counter {
            get { return this.counter; }
            set { this.counter = value; }
        }

        internal ActionFrame Container {
            get { return this.container; }
        }

        internal XPathNavigator Node {
            get {
                if (this.nodeSet != null)  {
                    return this.nodeSet.Current;
                }
                return null;
            }
        }

        internal XPathNodeIterator NodeSet {
            get { return this.nodeSet; }
        }

        internal XPathNodeIterator NewNodeSet {
            get { return this.newNodeSet; }
        }

        internal int IncrementCounter() {
            return ++ this.counter;
        }

        internal void AllocateVariables(int count) {
            if (0 < count) {
                this.variables = new object [count];
            }
            else {
                this.variables = null;
            }
        }

        internal object GetVariable(int index) {
            Debug.Assert(this.variables != null && index < this.variables.Length);
            return this.variables[index];
        }

        internal void SetVariable(int index, object value) {
            Debug.Assert(this.variables != null && index < this.variables.Length);
            this.variables[index] = value;
        }

        internal void SetParameter(XmlQualifiedName name, object value) {
            if (this.withParams == null) {
                this.withParams = new Hashtable();
            }
            Debug.Assert(! this.withParams.Contains(name), "We should check duplicate params at compile time");
            this.withParams[name] = value;
        }

        internal void ResetParams() {
            if (this.withParams != null)
                this.withParams.Clear();
        }

        internal object GetParameter(XmlQualifiedName name) {
            if (this.withParams != null) {
                return this.withParams[name];
            }
            return null;
        }

        internal void InitNodeSet(XPathNodeIterator nodeSet) {
            Debug.Assert(nodeSet != null);
            this.nodeSet = nodeSet;
        }

        internal void InitNewNodeSet(XPathNodeIterator nodeSet) {
            Debug.Assert(nodeSet != null);
            this.newNodeSet = nodeSet;
        }

        internal void SortNewNodeSet(Processor proc, ArrayList sortarray) {
            Debug.Assert(0 < sortarray.Count);
            int numSorts = sortarray.Count;
            XPathSortComparer comparer = new XPathSortComparer(numSorts);
            for (int i = 0; i < numSorts; i++) {
                Sort sort = (Sort) sortarray[i];
                Query expr = proc.GetCompiledQuery(sort.select);
                
                comparer.AddSort(expr, new XPathComparerHelper(sort.order, sort.caseOrder, sort.lang, sort.dataType));
            }
            List<SortKey> results = new List<SortKey>();

            Debug.Assert(proc.ActionStack.Peek() == this, "the trick we are doing with proc.Current will work only if this is topmost frame");

            while (NewNextNode(proc)) {
                XPathNodeIterator savedNodeset = this.nodeSet;
                this.nodeSet = this.newNodeSet;              // trick proc.Current node

                SortKey key = new SortKey(numSorts, /*originalPosition:*/results.Count, this.newNodeSet.Current.Clone());

                for (int j = 0; j < numSorts; j ++) {
                    key[j] = comparer.Expression(j).Evaluate(this.newNodeSet);
                }
                results.Add(key);

                this.nodeSet = savedNodeset;                 // restore proc.Current node
            }
            results.Sort(comparer);
            this.newNodeSet = new XPathSortArrayIterator(results);
        }

        // Finished
        internal void Finished() {
            State = Action.Finished;
        }

        internal void Inherit(ActionFrame parent) {
            Debug.Assert(parent != null);
            this.variables = parent.variables;
        }

        private void Init(Action action, ActionFrame container, XPathNodeIterator nodeSet) {
            this.state         = Action.Initialized;
            this.action        = action;
            this.container     = container;
            this.currentAction = 0;
            this.nodeSet       = nodeSet;
            this.newNodeSet    = null;
        }

        internal void Init(Action action, XPathNodeIterator nodeSet) {
            Init(action, null, nodeSet);
        }

        internal void Init(ActionFrame containerFrame, XPathNodeIterator nodeSet) {
            Init(containerFrame.GetAction(0), containerFrame, nodeSet);
        }

        internal void SetAction(Action action) {
            SetAction(action, Action.Initialized);
        }

        internal void SetAction(Action action, int state) {
            this.action = action;
            this.state  = state;
        }

        private Action GetAction(int actionIndex) {
            Debug.Assert(this.action is ContainerAction);
            return((ContainerAction) this.action).GetAction(actionIndex);
        }

        internal void Exit() {
            Finished();
            this.container = null;
        }

        /*
         * Execute
         *  return values: true - pop, false - nothing
         */
        internal bool Execute(Processor processor) {
            if (this.action == null) {
                return true;
            }

            // Execute the action
            this.action.Execute(processor, this);

            // Process results
            if (State == Action.Finished) {
                // Advanced to next action
                if(this.container != null) {
                    this.currentAction ++;
                    this.action =  this.container.GetAction(this.currentAction);
                    State = Action.Initialized;
                }
                else {
                    this.action = null;
                }
                return this.action == null;
            }

            return false;                       // Do not pop, unless specified otherwise
        }

       internal bool NextNode(Processor proc) {
            bool next = this.nodeSet.MoveNext();
            if (next && proc.Stylesheet.Whitespace) {
                XPathNodeType type = this.nodeSet.Current.NodeType;
                if (type == XPathNodeType.Whitespace) {
                    XPathNavigator nav = this.nodeSet.Current.Clone();
                    bool flag;
                    do {
                        nav.MoveTo(this.nodeSet.Current);
                        nav.MoveToParent();
                        flag = ! proc.Stylesheet.PreserveWhiteSpace(proc, nav) && (next = this.nodeSet.MoveNext());
                        type = this.nodeSet.Current.NodeType;                    
                    }
                    while (flag && (type == XPathNodeType.Whitespace ));
                }
            }
            return next;
        }

        internal bool NewNextNode(Processor proc) {
            bool next = this.newNodeSet.MoveNext();
            if (next && proc.Stylesheet.Whitespace) {
                XPathNodeType type = this.newNodeSet.Current.NodeType;
                if (type == XPathNodeType.Whitespace) {
                    XPathNavigator nav = this.newNodeSet.Current.Clone();
                    bool flag;
                    do {
                        nav.MoveTo(this.newNodeSet.Current);
                        nav.MoveToParent();
                        flag = ! proc.Stylesheet.PreserveWhiteSpace(proc, nav) &&  (next = this.newNodeSet.MoveNext()) ;
                        type = this.newNodeSet.Current.NodeType;
                    }
                    while(flag && (type == XPathNodeType.Whitespace ));
                }                            
            }
            return next;
        }

        // ----------------------- IStackFrame : --------------------
        XPathNavigator    IStackFrame.Instruction { 
            get { 
                if (this.action == null) {
                    return null; // for builtIn action this shoud be null;
                }
                return this.action.GetDbgData(this).StyleSheet; 
            }
        }
        XPathNodeIterator IStackFrame.NodeSet { 
            get { return this.nodeSet.Clone(); }
        }
        // Variables:
        int               IStackFrame.GetVariablesCount() {
            if (this.action == null) {
                return 0;
            }
            return this.action.GetDbgData(this).Variables.Length;
        }
        XPathNavigator    IStackFrame.GetVariable(int varIndex) {
            return this.action.GetDbgData(this).Variables[varIndex].GetDbgData(null).StyleSheet;
        }
        object            IStackFrame.GetVariableValue(int varIndex) { 
            return GetVariable(this.action.GetDbgData(this).Variables[varIndex].VarKey); 
        }

        // special array iterator that iterates over ArrayList of SortKey
        private class XPathSortArrayIterator : XPathArrayIterator {
            public XPathSortArrayIterator(List<SortKey> list) : base(list) { }
            public XPathSortArrayIterator(XPathSortArrayIterator it) : base(it) {}

            public override XPathNodeIterator Clone() {
                return new XPathSortArrayIterator(this);
            }

            public override XPathNavigator Current {
                get {
                    Debug.Assert(index > 0, "MoveNext() wasn't called");
                    return ((SortKey) this.list[this.index - 1]).Node;
                }
            }
        }
    }
}