Processor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / XmlUtils / System / Xml / Xsl / XsltOld / Processor.cs / 1 / Processor.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Xsl.XsltOld { 
    using Res = System.Xml.Utils.Res;
    using System.Globalization; 
    using System.Diagnostics;
    using System.IO;
    using System.Xml.XPath;
    using MS.Internal.Xml.XPath; 
    using System.Text;
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Xml.Xsl.XsltOld.Debugger;
    using System.Reflection; 
    using System.Security;

    internal sealed class Processor : IXsltProcessor {
        // 
        // Static constants
        // 
 
        const int StackIncrement = 10;
 
        //
        // Execution result
        //
 
        internal enum ExecResult {
            Continue,           // Continues next iteration immediately 
            Interrupt,          // Returns to caller, was processed enough 
            Done                // Execution finished
        } 

        internal enum OutputResult {
            Continue,
            Interrupt, 
            Overflow,
            Error, 
            Ignore 
        }
 
        private ExecResult     execResult;

        //
        // Compiled stylesheet 
        //
 
        private Stylesheet      stylesheet;     // Root of import tree of template managers 
        private RootAction      rootAction;
        private Key[]           keyList; 
        private List  queryStore;
        public  PermissionSet   permissions;   // used by XsltCompiledContext in document and extension functions

        // 
        // Document Being transformed
        // 
 
        private XPathNavigator    document;
 
        //
        // Execution action stack
        //
 
        private HWStack         actionStack;
        private HWStack         debuggerStack; 
 
        //
        // Register for returning value from calling nested action 
        //

        private StringBuilder   sharedStringBuilder;
 
        //
        // Output related member variables 
        // 
        int                     ignoreLevel;
        StateMachine            xsm; 
        RecordBuilder           builder;

        XsltOutput              output;
 
        XmlNameTable            nameTable      = new NameTable();
 
        XmlResolver             resolver; 

#pragma warning disable 618 
        XsltArgumentList        args;
#pragma warning restore 618
        Hashtable               scriptExtensions;
 
        ArrayList               numberList;
        // 
        // Template lookup action 
        //
 
        TemplateLookupAction    templateLookup = new TemplateLookupAction();

        private IXsltDebugger   debugger;
        Query[]                 queryList; 

        private ArrayList sortArray; 
 
        private Hashtable documentCache;
 
        // NOTE: ValueOf() can call Matches() through XsltCompileContext.PreserveWhitespace(),
        // that's why we use two different contexts here, valueOfContext and matchesContext
        private XsltCompileContext  valueOfContext;
        private XsltCompileContext  matchesContext; 

        internal XPathNavigator Current { 
            get { 
                ActionFrame frame = (ActionFrame) this.actionStack.Peek();
                return frame != null ? frame.Node : null; 
            }
        }

        internal ExecResult ExecutionResult { 
            get { return this.execResult; }
 
            set { 
                Debug.Assert(this.execResult == ExecResult.Continue);
                this.execResult = value; 
            }
        }

        internal Stylesheet Stylesheet { 
            get { return this.stylesheet; }
        } 
 
        internal XmlResolver Resolver {
            get { 
                Debug.Assert(this.resolver != null, "Constructor should create it if null passed");
                return this.resolver;
            }
        } 

        internal ArrayList SortArray { 
            get { 
                Debug.Assert(this.sortArray != null, "InitSortArray() wasn't called");
                return this.sortArray; 
            }
        }

        internal Key[] KeyList { 
            get { return this.keyList; }
        } 
 
        internal XPathNavigator GetNavigator(Uri ruri) {
            XPathNavigator result = null; 
            if (documentCache != null) {
                result = documentCache[ruri] as XPathNavigator;
                if (result != null) {
                    return result.Clone(); 
                }
            } 
            else { 
                documentCache = new Hashtable();
            } 

            Object input = resolver.GetEntity(ruri, null, null);
            if (input is Stream) {
                XmlTextReaderImpl tr  = new XmlTextReaderImpl(ruri.ToString(), (Stream) input); { 
                    tr.XmlResolver = this.resolver;
                } 
                // reader is closed by Compiler.LoadDocument() 
                result = ((IXPathNavigable)Compiler.LoadDocument(tr)).CreateNavigator();
            } 
            else if (input is XPathNavigator){
                result = (XPathNavigator) input;
            }
            else { 
                throw XsltException.Create(Res.Xslt_CantResolve, ruri.ToString());
            } 
            documentCache[ruri] = result.Clone(); 
            return result;
        } 

        internal void AddSort(Sort sortinfo) {
            Debug.Assert(this.sortArray != null, "InitSortArray() wasn't called");
            this.sortArray.Add(sortinfo); 
        }
 
        internal void InitSortArray() { 
            if (this.sortArray == null) {
                this.sortArray = new ArrayList(); 
            }
            else {
                this.sortArray.Clear();
            } 
        }
 
        internal object GetGlobalParameter(XmlQualifiedName qname) { 
            object parameter = args.GetParam(qname.Name, qname.Namespace);
            if (parameter == null) { 
                return null;
            }
            //
            if ( 
                parameter is XPathNodeIterator ||
                parameter is XPathNavigator || 
                parameter is Boolean || 
                parameter is Double ||
                parameter is String 
            ) {
                // doing nothing
            } else if (
                parameter is Int16 || parameter is UInt16 || 
                parameter is Int32 || parameter is UInt32 ||
                parameter is Int64 || parameter is UInt64 || 
                parameter is Single || parameter is Decimal 
            ) {
                parameter = XmlConvert.ToXPathDouble(parameter); 
            } else {
                parameter = parameter.ToString();
            }
            return parameter; 
        }
 
        internal object GetExtensionObject(string nsUri) { 
            return args.GetExtensionObject(nsUri);
        } 

        internal object GetScriptObject(string nsUri) {
            return scriptExtensions[nsUri];
        } 

        internal RootAction RootAction { 
            get { return this.rootAction; } 
        }
 
        internal XPathNavigator Document {
            get { return this.document; }
        }
 
#if DEBUG
        private bool stringBuilderLocked = false; 
#endif 

        internal StringBuilder GetSharedStringBuilder() { 
#if DEBUG
            Debug.Assert(! stringBuilderLocked);
#endif
            if (sharedStringBuilder == null) { 
                sharedStringBuilder = new StringBuilder();
            } 
            else { 
                sharedStringBuilder.Length = 0;
            } 
#if DEBUG
            stringBuilderLocked = true;
#endif
            return sharedStringBuilder; 
        }
 
        internal void ReleaseSharedStringBuilder() { 
            // don't clean stringBuilderLocked here. ToString() will happen after this call
#if DEBUG 
            stringBuilderLocked = false;
#endif
        }
 
        internal ArrayList NumberList {
            get { 
                if (this.numberList == null) { 
                    this.numberList = new ArrayList();
                } 
                return this.numberList;
            }
        }
 
        internal IXsltDebugger Debugger {
            get { return this.debugger; } 
        } 

        internal HWStack ActionStack { 
            get { return this.actionStack; }
        }

        internal RecordBuilder Builder { 
            get { return this.builder; }
        } 
 
        internal XsltOutput Output {
            get { return this.output; } 
        }

        //
        // Construction 
        //
        public Processor( 
            XPathNavigator doc, XsltArgumentList args, XmlResolver resolver, 
            Stylesheet stylesheet, List queryStore, RootAction rootAction,
            IXsltDebugger debugger 
        ) {
            this.stylesheet = stylesheet;
            this.queryStore = queryStore;
            this.rootAction = rootAction; 
            this.queryList  = new Query[queryStore.Count]; {
                for(int i = 0; i < queryStore.Count; i ++) { 
                    queryList[i] = Query.Clone(queryStore[i].CompiledQuery.QueryTree); 
                }
            } 

            this.xsm                 = new StateMachine();
            this.document            = doc;
            this.builder             = null; 
            this.actionStack         = new HWStack(StackIncrement);
            this.output              = this.rootAction.Output; 
            this.permissions         = this.rootAction.permissions; 
            this.resolver            = resolver != null ? resolver : new XmlNullResolver();
            this.args                = args     != null ? args     : new XsltArgumentList(); 
            this.debugger            = debugger;
            if (this.debugger != null) {
                this.debuggerStack = new HWStack(StackIncrement, /*limit:*/1000);
                templateLookup     = new TemplateLookupActionDbg(); 
            }
 
            // Clone the compile-time KeyList 
            if (this.rootAction.KeyList != null) {
                this.keyList = new Key[this.rootAction.KeyList.Count]; 
                for (int i = 0; i < this.keyList.Length; i ++) {
                    this.keyList[i] = this.rootAction.KeyList[i].Clone();
                }
            } 

            this.scriptExtensions = new Hashtable(this.stylesheet.ScriptObjectTypes.Count); { 
                foreach(DictionaryEntry entry in this.stylesheet.ScriptObjectTypes) { 
                    string namespaceUri = (string)entry.Key;
                    if (GetExtensionObject(namespaceUri) != null) { 
                        throw XsltException.Create(Res.Xslt_ScriptDub, namespaceUri);
                    }
                    scriptExtensions.Add(namespaceUri, Activator.CreateInstance((Type)entry.Value,
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, null)); 
                }
            } 
 
            this.PushActionFrame(this.rootAction, /*nodeSet:*/null);
        } 

        public ReaderOutput StartReader() {
            ReaderOutput output = new ReaderOutput(this);
            this.builder = new RecordBuilder(output, this.nameTable); 
            return output;
        } 
 
        public void Execute(Stream stream) {
            RecordOutput recOutput = null; 

            switch (this.output.Method) {
            case XsltOutput.OutputMethod.Text:
                recOutput = new TextOnlyOutput(this, stream); 
                break;
            case XsltOutput.OutputMethod.Xml: 
            case XsltOutput.OutputMethod.Html: 
            case XsltOutput.OutputMethod.Other:
            case XsltOutput.OutputMethod.Unknown: 
                recOutput = new TextOutput(this, stream);
                break;
            }
            this.builder = new RecordBuilder(recOutput, this.nameTable); 
            Execute();
        } 
 
        public void Execute(TextWriter writer) {
            RecordOutput recOutput = null; 

            switch (this.output.Method) {
            case XsltOutput.OutputMethod.Text:
                recOutput = new TextOnlyOutput(this, writer); 
                break;
            case XsltOutput.OutputMethod.Xml: 
            case XsltOutput.OutputMethod.Html: 
            case XsltOutput.OutputMethod.Other:
            case XsltOutput.OutputMethod.Unknown: 
                recOutput = new TextOutput(this, writer);
                break;
            }
            this.builder = new RecordBuilder(recOutput, this.nameTable); 
            Execute();
        } 
 
        public void Execute(XmlWriter writer) {
            this.builder = new RecordBuilder(new WriterOutput(this, writer), this.nameTable); 
            Execute();
        }

        // 
        //  Execution part of processor
        // 
        internal void Execute() { 
            Debug.Assert(this.actionStack != null);
 
            while (this.execResult == ExecResult.Continue) {
                ActionFrame frame = (ActionFrame) this.actionStack.Peek();

                if (frame == null) { 
                    Debug.Assert(this.builder != null);
                    this.builder.TheEnd(); 
                    ExecutionResult = ExecResult.Done; 
                    break;
                } 

                // Execute the action which was on the top of the stack
                if (frame.Execute(this)) {
                    this.actionStack.Pop(); 
                }
            } 
 
            if (this.execResult == ExecResult.Interrupt) {
                this.execResult = ExecResult.Continue; 
            }
        }

        // 
        // Action frame support
        // 
 
        internal ActionFrame PushNewFrame() {
            ActionFrame prent = (ActionFrame) this.actionStack.Peek(); 
            ActionFrame frame = (ActionFrame) this.actionStack.Push();
            if (frame == null) {
                frame = new ActionFrame();
                this.actionStack.AddToTop(frame); 
            }
            Debug.Assert(frame != null); 
 
            if (prent != null) {
                frame.Inherit(prent); 
            }

            return frame;
        } 

        internal void PushActionFrame(Action action, XPathNodeIterator nodeSet) { 
            ActionFrame frame = PushNewFrame(); 
            frame.Init(action, nodeSet);
        } 

        internal void PushActionFrame(ActionFrame container) {
            this.PushActionFrame(container, container.NodeSet);
        } 

        internal void PushActionFrame(ActionFrame container, XPathNodeIterator nodeSet) { 
            ActionFrame frame = PushNewFrame(); 
            frame.Init(container, nodeSet);
        } 

        internal void PushTemplateLookup(XPathNodeIterator nodeSet, XmlQualifiedName mode, Stylesheet importsOf) {
            Debug.Assert(this.templateLookup != null);
            this.templateLookup.Initialize(mode, importsOf); 
            PushActionFrame(this.templateLookup, nodeSet);
        } 
 
        internal string GetQueryExpression(int key) {
            Debug.Assert(key != Compiler.InvalidQueryKey); 
            return this.queryStore[key].CompiledQuery.Expression;
        }

        internal Query GetCompiledQuery(int key) { 
            Debug.Assert(key != Compiler.InvalidQueryKey);
            TheQuery theQuery = this.queryStore[key]; 
            theQuery.CompiledQuery.CheckErrors(); 
            Query expr = Query.Clone(this.queryList[key]);
            expr.SetXsltContext(new XsltCompileContext(theQuery._ScopeManager, this)); 
            return expr;
        }

        internal Query GetValueQuery(int key) { 
            return GetValueQuery(key, null);
        } 
 
        internal Query GetValueQuery(int key, XsltCompileContext context) {
            Debug.Assert(key != Compiler.InvalidQueryKey); 
            TheQuery theQuery = this.queryStore[key];
            theQuery.CompiledQuery.CheckErrors();
            Query expr = this.queryList[key];
 
            if (context == null) {
                context = new XsltCompileContext(theQuery._ScopeManager, this); 
            } else { 
                context.Reinitialize(theQuery._ScopeManager, this);
            } 

            expr.SetXsltContext(context);
            return expr;
        } 

        private XsltCompileContext GetValueOfContext() { 
            if (this.valueOfContext == null) { 
                this.valueOfContext = new XsltCompileContext();
            } 
            return this.valueOfContext;
        }

        [Conditional("DEBUG")] 
        private void RecycleValueOfContext() {
            if (this.valueOfContext != null) { 
                this.valueOfContext.Recycle(); 
            }
        } 

        private XsltCompileContext GetMatchesContext() {
            if (this.matchesContext == null) {
                this.matchesContext = new XsltCompileContext(); 
            }
            return this.matchesContext; 
        } 

        [Conditional("DEBUG")] 
        private void RecycleMatchesContext() {
            if (this.matchesContext != null) {
                this.matchesContext.Recycle();
            } 
        }
 
        internal String ValueOf(ActionFrame context, int key) { 
            string result;
 
            Query query = this.GetValueQuery(key, GetValueOfContext());
            object value = query.Evaluate(context.NodeSet);
            if (value is XPathNodeIterator) {
                XPathNavigator n = query.Advance(); 
                result = n != null ? ValueOf(n) : string.Empty;
            } else { 
                result = XmlConvert.ToXPathString(value); 
            }
 
            RecycleValueOfContext();
            return result;
        }
 
        internal String ValueOf(XPathNavigator n) {
            if (this.stylesheet.Whitespace && n.NodeType == XPathNodeType.Element) { 
                StringBuilder builder = this.GetSharedStringBuilder(); 
                ElementValueWithoutWS(n, builder);
                this.ReleaseSharedStringBuilder(); 
                return builder.ToString();
            }
            return n.Value;
        } 

        private void ElementValueWithoutWS(XPathNavigator nav, StringBuilder builder) { 
            Debug.Assert(nav.NodeType == XPathNodeType.Element); 
            bool preserve = this.Stylesheet.PreserveWhiteSpace(this, nav);
            if (nav.MoveToFirstChild()) { 
                do {
                    switch (nav.NodeType) {
                    case XPathNodeType.Text :
                    case XPathNodeType.SignificantWhitespace : 
                        builder.Append(nav.Value);
                        break; 
                    case XPathNodeType.Whitespace : 
                        if (preserve) {
                            builder.Append(nav.Value); 
                        }
                        break;
                    case XPathNodeType.Element :
                        ElementValueWithoutWS(nav, builder); 
                        break;
                    } 
                }while (nav.MoveToNext()); 
                nav.MoveToParent();
            } 
        }

        internal XPathNodeIterator StartQuery(XPathNodeIterator context, int key) {
            Query query = GetCompiledQuery(key); 
            object result = query.Evaluate(context);
            if (result is XPathNodeIterator) { 
                // ToDo: We create XPathSelectionIterator to count positions, but it's better create special query in this case at compile time. 
                return new XPathSelectionIterator(context.Current, query);
            } 
            throw XsltException.Create(Res.XPath_NodeSetExpected);
        }

        internal object Evaluate(ActionFrame context, int key) { 
            return GetValueQuery(key).Evaluate(context.NodeSet);
        } 
 
        internal object RunQuery(ActionFrame context, int key) {
            Query query = GetCompiledQuery(key); 
            object value = query.Evaluate(context.NodeSet);
            XPathNodeIterator it = value as XPathNodeIterator;
            if (it != null) {
                return new XPathArrayIterator(it); 
            }
 
            return value; 
        }
 
        internal string EvaluateString(ActionFrame context, int key) {
            object objValue = Evaluate(context, key);
            string value = null;
            if (objValue != null) 
                value = XmlConvert.ToXPathString(objValue);
            if (value == null) 
                value = string.Empty; 
            return value;
        } 

        internal bool EvaluateBoolean(ActionFrame context, int key) {
            object objValue = Evaluate(context, key);
 
            if (objValue != null) {
                XPathNavigator nav = objValue as XPathNavigator; 
                return nav != null ? Convert.ToBoolean(nav.Value, CultureInfo.InvariantCulture) : Convert.ToBoolean(objValue, CultureInfo.InvariantCulture); 
            }
            else { 
                return false;
            }
        }
 
        internal bool Matches(XPathNavigator context, int key) {
            // We don't use XPathNavigator.Matches() to avoid cloning of Query on each call 
            Query query = this.GetValueQuery(key, GetMatchesContext()); 

            try { 
                bool result = query.MatchNode(context) != null;

                RecycleMatchesContext();
                return result; 
            } catch(XPathException) {
                throw XsltException.Create(Res.Xslt_InvalidPattern, this.GetQueryExpression(key)); 
            } 
        }
 
        //
        // Outputting part of processor
        //
 
        internal XmlNameTable NameTable {
            get { return this.nameTable; } 
        } 

        internal bool CanContinue { 
            get { return this.execResult == ExecResult.Continue; }
        }

        internal bool ExecutionDone { 
            get { return this.execResult == ExecResult.Done; }
        } 
 
        internal void ResetOutput() {
            Debug.Assert(this.builder != null); 
            this.builder.Reset();
        }
        internal bool BeginEvent(XPathNodeType nodeType, string prefix, string name, string nspace, bool empty) {
            return BeginEvent(nodeType, prefix, name,  nspace,  empty, null, true); 
        }
 
        internal bool BeginEvent(XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { 
            Debug.Assert(this.xsm != null);
 
            int stateOutlook = this.xsm.BeginOutlook(nodeType);

            if (this.ignoreLevel > 0 || stateOutlook == StateMachine.Error) {
                this.ignoreLevel ++; 
                return true;                        // We consumed the event, so pretend it was output.
            } 
 
            switch (this.builder.BeginEvent(stateOutlook, nodeType, prefix, name, nspace, empty, htmlProps, search)) {
            case OutputResult.Continue: 
                this.xsm.Begin(nodeType);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State);
                Debug.Assert(ExecutionResult == ExecResult.Continue);
                return true; 
            case OutputResult.Interrupt:
                this.xsm.Begin(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                ExecutionResult = ExecResult.Interrupt;
                return true; 
            case OutputResult.Overflow:
                ExecutionResult = ExecResult.Interrupt;
                return false;
            case OutputResult.Error: 
                this.ignoreLevel ++;
                return true; 
            case OutputResult.Ignore: 
                return true;
            default: 
                Debug.Fail("Unexpected result of RecordBuilder.BeginEvent()");
                return true;
            }
        } 

        internal bool TextEvent(string text) { 
            return this.TextEvent(text, false); 
        }
 
        internal bool TextEvent(string text, bool disableOutputEscaping) {
            Debug.Assert(this.xsm != null);

            if (this.ignoreLevel > 0) { 
                return true;
            } 
 
            int stateOutlook = this.xsm.BeginOutlook(XPathNodeType.Text);
 
            switch (this.builder.TextEvent(stateOutlook, text, disableOutputEscaping)) {
                case OutputResult.Continue:
                this.xsm.Begin(XPathNodeType.Text);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                Debug.Assert(ExecutionResult == ExecResult.Continue);
                return true; 
            case OutputResult.Interrupt: 
                this.xsm.Begin(XPathNodeType.Text);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                ExecutionResult = ExecResult.Interrupt;
                return true;
            case OutputResult.Overflow:
                ExecutionResult = ExecResult.Interrupt; 
                return false;
            case OutputResult.Error: 
            case OutputResult.Ignore: 
                return true;
            default: 
                Debug.Fail("Unexpected result of RecordBuilder.TextEvent()");
                return true;
            }
        } 

        internal bool EndEvent(XPathNodeType nodeType) { 
            Debug.Assert(this.xsm != null); 

            if (this.ignoreLevel > 0) { 
                this.ignoreLevel --;
                return true;
            }
 
            int stateOutlook = this.xsm.EndOutlook(nodeType);
 
            switch (this.builder.EndEvent(stateOutlook, nodeType)) { 
                case OutputResult.Continue:
                this.xsm.End(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State);
                return true;
            case OutputResult.Interrupt:
                this.xsm.End(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State,
                             "StateMachine.StateOnly(stateOutlook) == this.xsm.State"); 
                ExecutionResult = ExecResult.Interrupt; 
                return true;
            case OutputResult.Overflow: 
                ExecutionResult = ExecResult.Interrupt;
                return false;
            case OutputResult.Error:
            case OutputResult.Ignore: 
            default:
                Debug.Fail("Unexpected result of RecordBuilder.TextEvent()"); 
                return true; 
            }
        } 

        internal bool CopyBeginEvent(XPathNavigator node, bool emptyflag) {
            switch (node.NodeType) {
            case XPathNodeType.Element: 
            case XPathNodeType.Attribute:
            case XPathNodeType.ProcessingInstruction: 
            case XPathNodeType.Comment: 
                return BeginEvent(node.NodeType, node.Prefix, node.LocalName, node.NamespaceURI, emptyflag);
            case XPathNodeType.Namespace: 
                // value instead of namespace here!
                return BeginEvent(XPathNodeType.Namespace, null, node.LocalName, node.Value, false);
            case XPathNodeType.Text:
                // Text will be copied in CopyContents(); 
                break;
 
            case XPathNodeType.Root: 
            case XPathNodeType.Whitespace:
            case XPathNodeType.SignificantWhitespace: 
            case XPathNodeType.All:
                break;

            default: 
                Debug.Fail("Invalid XPathNodeType in CopyBeginEvent");
                break; 
            } 

            return true; 
        }

        internal bool CopyTextEvent(XPathNavigator node) {
            switch (node.NodeType) { 
            case XPathNodeType.Element:
            case XPathNodeType.Namespace: 
                break; 

            case XPathNodeType.Attribute: 
            case XPathNodeType.ProcessingInstruction:
            case XPathNodeType.Comment:
            case XPathNodeType.Text:
            case XPathNodeType.Whitespace: 
            case XPathNodeType.SignificantWhitespace:
                string text = node.Value; 
                return TextEvent(text); 

            case XPathNodeType.Root: 
            case XPathNodeType.All:
                break;

            default: 
                Debug.Fail("Invalid XPathNodeType in CopyTextEvent");
                break; 
            } 

            return true; 
        }

        internal bool CopyEndEvent(XPathNavigator node) {
            switch (node.NodeType) { 
            case XPathNodeType.Element:
            case XPathNodeType.Attribute: 
            case XPathNodeType.ProcessingInstruction: 
            case XPathNodeType.Comment:
            case XPathNodeType.Namespace: 
                return EndEvent(node.NodeType);

            case XPathNodeType.Text:
                // Text was copied in CopyContents(); 
                break;
 
 
            case XPathNodeType.Root:
            case XPathNodeType.Whitespace: 
            case XPathNodeType.SignificantWhitespace:
            case XPathNodeType.All:
                break;
 
            default:
                Debug.Fail("Invalid XPathNodeType in CopyEndEvent"); 
                break; 
            }
 
            return true;
        }

        internal static bool IsRoot(XPathNavigator navigator) { 
            Debug.Assert(navigator != null);
 
            if (navigator.NodeType == XPathNodeType.Root) { 
                return true;
            } 
            else if (navigator.NodeType == XPathNodeType.Element) {
                XPathNavigator clone = navigator.Clone();
                clone.MoveToRoot();
                return clone.IsSamePosition(navigator); 
            }
            else { 
                return false; 
            }
        } 

        //
        // Builder stack
        // 
        internal void PushOutput(RecordOutput output) {
            Debug.Assert(output != null); 
            this.builder.OutputState = this.xsm.State; 
            RecordBuilder lastBuilder = this.builder;
            this.builder      = new RecordBuilder(output, this.nameTable); 
            this.builder.Next = lastBuilder;

            this.xsm.Reset();
        } 

        internal RecordOutput PopOutput() { 
            Debug.Assert(this.builder != null); 

            RecordBuilder topBuilder = this.builder; 
            this.builder              = topBuilder.Next;
            this.xsm.State            = this.builder.OutputState;

            topBuilder.TheEnd(); 

            return topBuilder.Output; 
        } 

        internal bool SetDefaultOutput(XsltOutput.OutputMethod method) { 
            if(Output.Method != method) {
                this.output = this.output.CreateDerivedOutput(method);
                return true;
            } 
            return false;
        } 
 
        internal object GetVariableValue(VariableAction variable) {
            int variablekey = variable.VarKey; 
            if (variable.IsGlobal) {
                ActionFrame rootFrame = (ActionFrame) this.actionStack[0];
                object result = rootFrame.GetVariable(variablekey);
                if (result == VariableAction.BeingComputedMark) { 
                    throw XsltException.Create(Res.Xslt_CircularReference, variable.NameStr);
                } 
                if (result != null) { 
                    return result;
                } 

                // Variable wasn't evaluated yet
                int saveStackSize = this.actionStack.Length;
                ActionFrame varFrame = PushNewFrame(); 
                varFrame.Inherit(rootFrame);
                varFrame.Init(variable, rootFrame.NodeSet); 
                do { 
                    bool endOfFrame = ((ActionFrame) this.actionStack.Peek()).Execute(this);
                    if (endOfFrame) { 
                        this.actionStack.Pop();
                    }
                } while (saveStackSize < this.actionStack.Length);
                Debug.Assert(saveStackSize == this.actionStack.Length); 
                result = rootFrame.GetVariable(variablekey);
                Debug.Assert(result != null, "Variable was just calculated and result can't be null"); 
                return result; 
            } else {
                return ((ActionFrame) this.actionStack.Peek()).GetVariable(variablekey); 
            }
        }

        internal void SetParameter(XmlQualifiedName name, object value) { 
            Debug.Assert(1 < actionStack.Length);
            ActionFrame parentFrame = (ActionFrame) this.actionStack[actionStack.Length - 2]; 
            parentFrame.SetParameter(name, value); 
        }
 
        internal void ResetParams() {
            ActionFrame frame = (ActionFrame) this.actionStack[actionStack.Length - 1];
            frame.ResetParams();
        } 

        internal object GetParameter(XmlQualifiedName name) { 
            Debug.Assert(2 < actionStack.Length); 
            ActionFrame parentFrame = (ActionFrame) this.actionStack[actionStack.Length - 3];
            return parentFrame.GetParameter(name); 
        }

        // ---------------------- Debugger stack -----------------------
 
        internal class DebuggerFrame {
            internal ActionFrame        actionFrame; 
            internal XmlQualifiedName   currentMode; 
        }
 
        internal void PushDebuggerStack() {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            DebuggerFrame dbgFrame = (DebuggerFrame) this.debuggerStack.Push();
            if (dbgFrame == null) { 
                dbgFrame = new DebuggerFrame();
                this.debuggerStack.AddToTop(dbgFrame); 
            } 
            dbgFrame.actionFrame = (ActionFrame) this.actionStack.Peek(); // In a case of next builtIn action.
        } 

        internal void PopDebuggerStack() {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            this.debuggerStack.Pop(); 
        }
 
        internal void OnInstructionExecute() { 
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            DebuggerFrame dbgFrame = (DebuggerFrame) this.debuggerStack.Peek(); 
            Debug.Assert(dbgFrame != null, "PushDebuggerStack() wasn't ever called");
            dbgFrame.actionFrame = (ActionFrame) this.actionStack.Peek();
            this.Debugger.OnInstructionExecute((IXsltProcessor) this);
        } 

        internal XmlQualifiedName GetPrevioseMode() { 
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger"); 
            Debug.Assert(2 <= this.debuggerStack.Length);
            return ((DebuggerFrame) this.debuggerStack[this.debuggerStack.Length - 2]).currentMode; 
        }

        internal void SetCurrentMode(XmlQualifiedName mode) {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger"); 
            ((DebuggerFrame) this.debuggerStack[this.debuggerStack.Length - 1]).currentMode = mode;
        } 
 
        // ----------------------- IXsltProcessor : --------------------
        int IXsltProcessor.StackDepth { 
            get {return this.debuggerStack.Length;}
        }

        IStackFrame IXsltProcessor.GetStackFrame(int depth) { 
            return ((DebuggerFrame) this.debuggerStack[depth]).actionFrame;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Xsl.XsltOld { 
    using Res = System.Xml.Utils.Res;
    using System.Globalization; 
    using System.Diagnostics;
    using System.IO;
    using System.Xml.XPath;
    using MS.Internal.Xml.XPath; 
    using System.Text;
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Xml.Xsl.XsltOld.Debugger;
    using System.Reflection; 
    using System.Security;

    internal sealed class Processor : IXsltProcessor {
        // 
        // Static constants
        // 
 
        const int StackIncrement = 10;
 
        //
        // Execution result
        //
 
        internal enum ExecResult {
            Continue,           // Continues next iteration immediately 
            Interrupt,          // Returns to caller, was processed enough 
            Done                // Execution finished
        } 

        internal enum OutputResult {
            Continue,
            Interrupt, 
            Overflow,
            Error, 
            Ignore 
        }
 
        private ExecResult     execResult;

        //
        // Compiled stylesheet 
        //
 
        private Stylesheet      stylesheet;     // Root of import tree of template managers 
        private RootAction      rootAction;
        private Key[]           keyList; 
        private List  queryStore;
        public  PermissionSet   permissions;   // used by XsltCompiledContext in document and extension functions

        // 
        // Document Being transformed
        // 
 
        private XPathNavigator    document;
 
        //
        // Execution action stack
        //
 
        private HWStack         actionStack;
        private HWStack         debuggerStack; 
 
        //
        // Register for returning value from calling nested action 
        //

        private StringBuilder   sharedStringBuilder;
 
        //
        // Output related member variables 
        // 
        int                     ignoreLevel;
        StateMachine            xsm; 
        RecordBuilder           builder;

        XsltOutput              output;
 
        XmlNameTable            nameTable      = new NameTable();
 
        XmlResolver             resolver; 

#pragma warning disable 618 
        XsltArgumentList        args;
#pragma warning restore 618
        Hashtable               scriptExtensions;
 
        ArrayList               numberList;
        // 
        // Template lookup action 
        //
 
        TemplateLookupAction    templateLookup = new TemplateLookupAction();

        private IXsltDebugger   debugger;
        Query[]                 queryList; 

        private ArrayList sortArray; 
 
        private Hashtable documentCache;
 
        // NOTE: ValueOf() can call Matches() through XsltCompileContext.PreserveWhitespace(),
        // that's why we use two different contexts here, valueOfContext and matchesContext
        private XsltCompileContext  valueOfContext;
        private XsltCompileContext  matchesContext; 

        internal XPathNavigator Current { 
            get { 
                ActionFrame frame = (ActionFrame) this.actionStack.Peek();
                return frame != null ? frame.Node : null; 
            }
        }

        internal ExecResult ExecutionResult { 
            get { return this.execResult; }
 
            set { 
                Debug.Assert(this.execResult == ExecResult.Continue);
                this.execResult = value; 
            }
        }

        internal Stylesheet Stylesheet { 
            get { return this.stylesheet; }
        } 
 
        internal XmlResolver Resolver {
            get { 
                Debug.Assert(this.resolver != null, "Constructor should create it if null passed");
                return this.resolver;
            }
        } 

        internal ArrayList SortArray { 
            get { 
                Debug.Assert(this.sortArray != null, "InitSortArray() wasn't called");
                return this.sortArray; 
            }
        }

        internal Key[] KeyList { 
            get { return this.keyList; }
        } 
 
        internal XPathNavigator GetNavigator(Uri ruri) {
            XPathNavigator result = null; 
            if (documentCache != null) {
                result = documentCache[ruri] as XPathNavigator;
                if (result != null) {
                    return result.Clone(); 
                }
            } 
            else { 
                documentCache = new Hashtable();
            } 

            Object input = resolver.GetEntity(ruri, null, null);
            if (input is Stream) {
                XmlTextReaderImpl tr  = new XmlTextReaderImpl(ruri.ToString(), (Stream) input); { 
                    tr.XmlResolver = this.resolver;
                } 
                // reader is closed by Compiler.LoadDocument() 
                result = ((IXPathNavigable)Compiler.LoadDocument(tr)).CreateNavigator();
            } 
            else if (input is XPathNavigator){
                result = (XPathNavigator) input;
            }
            else { 
                throw XsltException.Create(Res.Xslt_CantResolve, ruri.ToString());
            } 
            documentCache[ruri] = result.Clone(); 
            return result;
        } 

        internal void AddSort(Sort sortinfo) {
            Debug.Assert(this.sortArray != null, "InitSortArray() wasn't called");
            this.sortArray.Add(sortinfo); 
        }
 
        internal void InitSortArray() { 
            if (this.sortArray == null) {
                this.sortArray = new ArrayList(); 
            }
            else {
                this.sortArray.Clear();
            } 
        }
 
        internal object GetGlobalParameter(XmlQualifiedName qname) { 
            object parameter = args.GetParam(qname.Name, qname.Namespace);
            if (parameter == null) { 
                return null;
            }
            //
            if ( 
                parameter is XPathNodeIterator ||
                parameter is XPathNavigator || 
                parameter is Boolean || 
                parameter is Double ||
                parameter is String 
            ) {
                // doing nothing
            } else if (
                parameter is Int16 || parameter is UInt16 || 
                parameter is Int32 || parameter is UInt32 ||
                parameter is Int64 || parameter is UInt64 || 
                parameter is Single || parameter is Decimal 
            ) {
                parameter = XmlConvert.ToXPathDouble(parameter); 
            } else {
                parameter = parameter.ToString();
            }
            return parameter; 
        }
 
        internal object GetExtensionObject(string nsUri) { 
            return args.GetExtensionObject(nsUri);
        } 

        internal object GetScriptObject(string nsUri) {
            return scriptExtensions[nsUri];
        } 

        internal RootAction RootAction { 
            get { return this.rootAction; } 
        }
 
        internal XPathNavigator Document {
            get { return this.document; }
        }
 
#if DEBUG
        private bool stringBuilderLocked = false; 
#endif 

        internal StringBuilder GetSharedStringBuilder() { 
#if DEBUG
            Debug.Assert(! stringBuilderLocked);
#endif
            if (sharedStringBuilder == null) { 
                sharedStringBuilder = new StringBuilder();
            } 
            else { 
                sharedStringBuilder.Length = 0;
            } 
#if DEBUG
            stringBuilderLocked = true;
#endif
            return sharedStringBuilder; 
        }
 
        internal void ReleaseSharedStringBuilder() { 
            // don't clean stringBuilderLocked here. ToString() will happen after this call
#if DEBUG 
            stringBuilderLocked = false;
#endif
        }
 
        internal ArrayList NumberList {
            get { 
                if (this.numberList == null) { 
                    this.numberList = new ArrayList();
                } 
                return this.numberList;
            }
        }
 
        internal IXsltDebugger Debugger {
            get { return this.debugger; } 
        } 

        internal HWStack ActionStack { 
            get { return this.actionStack; }
        }

        internal RecordBuilder Builder { 
            get { return this.builder; }
        } 
 
        internal XsltOutput Output {
            get { return this.output; } 
        }

        //
        // Construction 
        //
        public Processor( 
            XPathNavigator doc, XsltArgumentList args, XmlResolver resolver, 
            Stylesheet stylesheet, List queryStore, RootAction rootAction,
            IXsltDebugger debugger 
        ) {
            this.stylesheet = stylesheet;
            this.queryStore = queryStore;
            this.rootAction = rootAction; 
            this.queryList  = new Query[queryStore.Count]; {
                for(int i = 0; i < queryStore.Count; i ++) { 
                    queryList[i] = Query.Clone(queryStore[i].CompiledQuery.QueryTree); 
                }
            } 

            this.xsm                 = new StateMachine();
            this.document            = doc;
            this.builder             = null; 
            this.actionStack         = new HWStack(StackIncrement);
            this.output              = this.rootAction.Output; 
            this.permissions         = this.rootAction.permissions; 
            this.resolver            = resolver != null ? resolver : new XmlNullResolver();
            this.args                = args     != null ? args     : new XsltArgumentList(); 
            this.debugger            = debugger;
            if (this.debugger != null) {
                this.debuggerStack = new HWStack(StackIncrement, /*limit:*/1000);
                templateLookup     = new TemplateLookupActionDbg(); 
            }
 
            // Clone the compile-time KeyList 
            if (this.rootAction.KeyList != null) {
                this.keyList = new Key[this.rootAction.KeyList.Count]; 
                for (int i = 0; i < this.keyList.Length; i ++) {
                    this.keyList[i] = this.rootAction.KeyList[i].Clone();
                }
            } 

            this.scriptExtensions = new Hashtable(this.stylesheet.ScriptObjectTypes.Count); { 
                foreach(DictionaryEntry entry in this.stylesheet.ScriptObjectTypes) { 
                    string namespaceUri = (string)entry.Key;
                    if (GetExtensionObject(namespaceUri) != null) { 
                        throw XsltException.Create(Res.Xslt_ScriptDub, namespaceUri);
                    }
                    scriptExtensions.Add(namespaceUri, Activator.CreateInstance((Type)entry.Value,
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, null)); 
                }
            } 
 
            this.PushActionFrame(this.rootAction, /*nodeSet:*/null);
        } 

        public ReaderOutput StartReader() {
            ReaderOutput output = new ReaderOutput(this);
            this.builder = new RecordBuilder(output, this.nameTable); 
            return output;
        } 
 
        public void Execute(Stream stream) {
            RecordOutput recOutput = null; 

            switch (this.output.Method) {
            case XsltOutput.OutputMethod.Text:
                recOutput = new TextOnlyOutput(this, stream); 
                break;
            case XsltOutput.OutputMethod.Xml: 
            case XsltOutput.OutputMethod.Html: 
            case XsltOutput.OutputMethod.Other:
            case XsltOutput.OutputMethod.Unknown: 
                recOutput = new TextOutput(this, stream);
                break;
            }
            this.builder = new RecordBuilder(recOutput, this.nameTable); 
            Execute();
        } 
 
        public void Execute(TextWriter writer) {
            RecordOutput recOutput = null; 

            switch (this.output.Method) {
            case XsltOutput.OutputMethod.Text:
                recOutput = new TextOnlyOutput(this, writer); 
                break;
            case XsltOutput.OutputMethod.Xml: 
            case XsltOutput.OutputMethod.Html: 
            case XsltOutput.OutputMethod.Other:
            case XsltOutput.OutputMethod.Unknown: 
                recOutput = new TextOutput(this, writer);
                break;
            }
            this.builder = new RecordBuilder(recOutput, this.nameTable); 
            Execute();
        } 
 
        public void Execute(XmlWriter writer) {
            this.builder = new RecordBuilder(new WriterOutput(this, writer), this.nameTable); 
            Execute();
        }

        // 
        //  Execution part of processor
        // 
        internal void Execute() { 
            Debug.Assert(this.actionStack != null);
 
            while (this.execResult == ExecResult.Continue) {
                ActionFrame frame = (ActionFrame) this.actionStack.Peek();

                if (frame == null) { 
                    Debug.Assert(this.builder != null);
                    this.builder.TheEnd(); 
                    ExecutionResult = ExecResult.Done; 
                    break;
                } 

                // Execute the action which was on the top of the stack
                if (frame.Execute(this)) {
                    this.actionStack.Pop(); 
                }
            } 
 
            if (this.execResult == ExecResult.Interrupt) {
                this.execResult = ExecResult.Continue; 
            }
        }

        // 
        // Action frame support
        // 
 
        internal ActionFrame PushNewFrame() {
            ActionFrame prent = (ActionFrame) this.actionStack.Peek(); 
            ActionFrame frame = (ActionFrame) this.actionStack.Push();
            if (frame == null) {
                frame = new ActionFrame();
                this.actionStack.AddToTop(frame); 
            }
            Debug.Assert(frame != null); 
 
            if (prent != null) {
                frame.Inherit(prent); 
            }

            return frame;
        } 

        internal void PushActionFrame(Action action, XPathNodeIterator nodeSet) { 
            ActionFrame frame = PushNewFrame(); 
            frame.Init(action, nodeSet);
        } 

        internal void PushActionFrame(ActionFrame container) {
            this.PushActionFrame(container, container.NodeSet);
        } 

        internal void PushActionFrame(ActionFrame container, XPathNodeIterator nodeSet) { 
            ActionFrame frame = PushNewFrame(); 
            frame.Init(container, nodeSet);
        } 

        internal void PushTemplateLookup(XPathNodeIterator nodeSet, XmlQualifiedName mode, Stylesheet importsOf) {
            Debug.Assert(this.templateLookup != null);
            this.templateLookup.Initialize(mode, importsOf); 
            PushActionFrame(this.templateLookup, nodeSet);
        } 
 
        internal string GetQueryExpression(int key) {
            Debug.Assert(key != Compiler.InvalidQueryKey); 
            return this.queryStore[key].CompiledQuery.Expression;
        }

        internal Query GetCompiledQuery(int key) { 
            Debug.Assert(key != Compiler.InvalidQueryKey);
            TheQuery theQuery = this.queryStore[key]; 
            theQuery.CompiledQuery.CheckErrors(); 
            Query expr = Query.Clone(this.queryList[key]);
            expr.SetXsltContext(new XsltCompileContext(theQuery._ScopeManager, this)); 
            return expr;
        }

        internal Query GetValueQuery(int key) { 
            return GetValueQuery(key, null);
        } 
 
        internal Query GetValueQuery(int key, XsltCompileContext context) {
            Debug.Assert(key != Compiler.InvalidQueryKey); 
            TheQuery theQuery = this.queryStore[key];
            theQuery.CompiledQuery.CheckErrors();
            Query expr = this.queryList[key];
 
            if (context == null) {
                context = new XsltCompileContext(theQuery._ScopeManager, this); 
            } else { 
                context.Reinitialize(theQuery._ScopeManager, this);
            } 

            expr.SetXsltContext(context);
            return expr;
        } 

        private XsltCompileContext GetValueOfContext() { 
            if (this.valueOfContext == null) { 
                this.valueOfContext = new XsltCompileContext();
            } 
            return this.valueOfContext;
        }

        [Conditional("DEBUG")] 
        private void RecycleValueOfContext() {
            if (this.valueOfContext != null) { 
                this.valueOfContext.Recycle(); 
            }
        } 

        private XsltCompileContext GetMatchesContext() {
            if (this.matchesContext == null) {
                this.matchesContext = new XsltCompileContext(); 
            }
            return this.matchesContext; 
        } 

        [Conditional("DEBUG")] 
        private void RecycleMatchesContext() {
            if (this.matchesContext != null) {
                this.matchesContext.Recycle();
            } 
        }
 
        internal String ValueOf(ActionFrame context, int key) { 
            string result;
 
            Query query = this.GetValueQuery(key, GetValueOfContext());
            object value = query.Evaluate(context.NodeSet);
            if (value is XPathNodeIterator) {
                XPathNavigator n = query.Advance(); 
                result = n != null ? ValueOf(n) : string.Empty;
            } else { 
                result = XmlConvert.ToXPathString(value); 
            }
 
            RecycleValueOfContext();
            return result;
        }
 
        internal String ValueOf(XPathNavigator n) {
            if (this.stylesheet.Whitespace && n.NodeType == XPathNodeType.Element) { 
                StringBuilder builder = this.GetSharedStringBuilder(); 
                ElementValueWithoutWS(n, builder);
                this.ReleaseSharedStringBuilder(); 
                return builder.ToString();
            }
            return n.Value;
        } 

        private void ElementValueWithoutWS(XPathNavigator nav, StringBuilder builder) { 
            Debug.Assert(nav.NodeType == XPathNodeType.Element); 
            bool preserve = this.Stylesheet.PreserveWhiteSpace(this, nav);
            if (nav.MoveToFirstChild()) { 
                do {
                    switch (nav.NodeType) {
                    case XPathNodeType.Text :
                    case XPathNodeType.SignificantWhitespace : 
                        builder.Append(nav.Value);
                        break; 
                    case XPathNodeType.Whitespace : 
                        if (preserve) {
                            builder.Append(nav.Value); 
                        }
                        break;
                    case XPathNodeType.Element :
                        ElementValueWithoutWS(nav, builder); 
                        break;
                    } 
                }while (nav.MoveToNext()); 
                nav.MoveToParent();
            } 
        }

        internal XPathNodeIterator StartQuery(XPathNodeIterator context, int key) {
            Query query = GetCompiledQuery(key); 
            object result = query.Evaluate(context);
            if (result is XPathNodeIterator) { 
                // ToDo: We create XPathSelectionIterator to count positions, but it's better create special query in this case at compile time. 
                return new XPathSelectionIterator(context.Current, query);
            } 
            throw XsltException.Create(Res.XPath_NodeSetExpected);
        }

        internal object Evaluate(ActionFrame context, int key) { 
            return GetValueQuery(key).Evaluate(context.NodeSet);
        } 
 
        internal object RunQuery(ActionFrame context, int key) {
            Query query = GetCompiledQuery(key); 
            object value = query.Evaluate(context.NodeSet);
            XPathNodeIterator it = value as XPathNodeIterator;
            if (it != null) {
                return new XPathArrayIterator(it); 
            }
 
            return value; 
        }
 
        internal string EvaluateString(ActionFrame context, int key) {
            object objValue = Evaluate(context, key);
            string value = null;
            if (objValue != null) 
                value = XmlConvert.ToXPathString(objValue);
            if (value == null) 
                value = string.Empty; 
            return value;
        } 

        internal bool EvaluateBoolean(ActionFrame context, int key) {
            object objValue = Evaluate(context, key);
 
            if (objValue != null) {
                XPathNavigator nav = objValue as XPathNavigator; 
                return nav != null ? Convert.ToBoolean(nav.Value, CultureInfo.InvariantCulture) : Convert.ToBoolean(objValue, CultureInfo.InvariantCulture); 
            }
            else { 
                return false;
            }
        }
 
        internal bool Matches(XPathNavigator context, int key) {
            // We don't use XPathNavigator.Matches() to avoid cloning of Query on each call 
            Query query = this.GetValueQuery(key, GetMatchesContext()); 

            try { 
                bool result = query.MatchNode(context) != null;

                RecycleMatchesContext();
                return result; 
            } catch(XPathException) {
                throw XsltException.Create(Res.Xslt_InvalidPattern, this.GetQueryExpression(key)); 
            } 
        }
 
        //
        // Outputting part of processor
        //
 
        internal XmlNameTable NameTable {
            get { return this.nameTable; } 
        } 

        internal bool CanContinue { 
            get { return this.execResult == ExecResult.Continue; }
        }

        internal bool ExecutionDone { 
            get { return this.execResult == ExecResult.Done; }
        } 
 
        internal void ResetOutput() {
            Debug.Assert(this.builder != null); 
            this.builder.Reset();
        }
        internal bool BeginEvent(XPathNodeType nodeType, string prefix, string name, string nspace, bool empty) {
            return BeginEvent(nodeType, prefix, name,  nspace,  empty, null, true); 
        }
 
        internal bool BeginEvent(XPathNodeType nodeType, string prefix, string name, string nspace, bool empty, Object htmlProps, bool search) { 
            Debug.Assert(this.xsm != null);
 
            int stateOutlook = this.xsm.BeginOutlook(nodeType);

            if (this.ignoreLevel > 0 || stateOutlook == StateMachine.Error) {
                this.ignoreLevel ++; 
                return true;                        // We consumed the event, so pretend it was output.
            } 
 
            switch (this.builder.BeginEvent(stateOutlook, nodeType, prefix, name, nspace, empty, htmlProps, search)) {
            case OutputResult.Continue: 
                this.xsm.Begin(nodeType);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State);
                Debug.Assert(ExecutionResult == ExecResult.Continue);
                return true; 
            case OutputResult.Interrupt:
                this.xsm.Begin(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                ExecutionResult = ExecResult.Interrupt;
                return true; 
            case OutputResult.Overflow:
                ExecutionResult = ExecResult.Interrupt;
                return false;
            case OutputResult.Error: 
                this.ignoreLevel ++;
                return true; 
            case OutputResult.Ignore: 
                return true;
            default: 
                Debug.Fail("Unexpected result of RecordBuilder.BeginEvent()");
                return true;
            }
        } 

        internal bool TextEvent(string text) { 
            return this.TextEvent(text, false); 
        }
 
        internal bool TextEvent(string text, bool disableOutputEscaping) {
            Debug.Assert(this.xsm != null);

            if (this.ignoreLevel > 0) { 
                return true;
            } 
 
            int stateOutlook = this.xsm.BeginOutlook(XPathNodeType.Text);
 
            switch (this.builder.TextEvent(stateOutlook, text, disableOutputEscaping)) {
                case OutputResult.Continue:
                this.xsm.Begin(XPathNodeType.Text);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                Debug.Assert(ExecutionResult == ExecResult.Continue);
                return true; 
            case OutputResult.Interrupt: 
                this.xsm.Begin(XPathNodeType.Text);
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State); 
                ExecutionResult = ExecResult.Interrupt;
                return true;
            case OutputResult.Overflow:
                ExecutionResult = ExecResult.Interrupt; 
                return false;
            case OutputResult.Error: 
            case OutputResult.Ignore: 
                return true;
            default: 
                Debug.Fail("Unexpected result of RecordBuilder.TextEvent()");
                return true;
            }
        } 

        internal bool EndEvent(XPathNodeType nodeType) { 
            Debug.Assert(this.xsm != null); 

            if (this.ignoreLevel > 0) { 
                this.ignoreLevel --;
                return true;
            }
 
            int stateOutlook = this.xsm.EndOutlook(nodeType);
 
            switch (this.builder.EndEvent(stateOutlook, nodeType)) { 
                case OutputResult.Continue:
                this.xsm.End(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State);
                return true;
            case OutputResult.Interrupt:
                this.xsm.End(nodeType); 
                Debug.Assert(StateMachine.StateOnly(stateOutlook) == this.xsm.State,
                             "StateMachine.StateOnly(stateOutlook) == this.xsm.State"); 
                ExecutionResult = ExecResult.Interrupt; 
                return true;
            case OutputResult.Overflow: 
                ExecutionResult = ExecResult.Interrupt;
                return false;
            case OutputResult.Error:
            case OutputResult.Ignore: 
            default:
                Debug.Fail("Unexpected result of RecordBuilder.TextEvent()"); 
                return true; 
            }
        } 

        internal bool CopyBeginEvent(XPathNavigator node, bool emptyflag) {
            switch (node.NodeType) {
            case XPathNodeType.Element: 
            case XPathNodeType.Attribute:
            case XPathNodeType.ProcessingInstruction: 
            case XPathNodeType.Comment: 
                return BeginEvent(node.NodeType, node.Prefix, node.LocalName, node.NamespaceURI, emptyflag);
            case XPathNodeType.Namespace: 
                // value instead of namespace here!
                return BeginEvent(XPathNodeType.Namespace, null, node.LocalName, node.Value, false);
            case XPathNodeType.Text:
                // Text will be copied in CopyContents(); 
                break;
 
            case XPathNodeType.Root: 
            case XPathNodeType.Whitespace:
            case XPathNodeType.SignificantWhitespace: 
            case XPathNodeType.All:
                break;

            default: 
                Debug.Fail("Invalid XPathNodeType in CopyBeginEvent");
                break; 
            } 

            return true; 
        }

        internal bool CopyTextEvent(XPathNavigator node) {
            switch (node.NodeType) { 
            case XPathNodeType.Element:
            case XPathNodeType.Namespace: 
                break; 

            case XPathNodeType.Attribute: 
            case XPathNodeType.ProcessingInstruction:
            case XPathNodeType.Comment:
            case XPathNodeType.Text:
            case XPathNodeType.Whitespace: 
            case XPathNodeType.SignificantWhitespace:
                string text = node.Value; 
                return TextEvent(text); 

            case XPathNodeType.Root: 
            case XPathNodeType.All:
                break;

            default: 
                Debug.Fail("Invalid XPathNodeType in CopyTextEvent");
                break; 
            } 

            return true; 
        }

        internal bool CopyEndEvent(XPathNavigator node) {
            switch (node.NodeType) { 
            case XPathNodeType.Element:
            case XPathNodeType.Attribute: 
            case XPathNodeType.ProcessingInstruction: 
            case XPathNodeType.Comment:
            case XPathNodeType.Namespace: 
                return EndEvent(node.NodeType);

            case XPathNodeType.Text:
                // Text was copied in CopyContents(); 
                break;
 
 
            case XPathNodeType.Root:
            case XPathNodeType.Whitespace: 
            case XPathNodeType.SignificantWhitespace:
            case XPathNodeType.All:
                break;
 
            default:
                Debug.Fail("Invalid XPathNodeType in CopyEndEvent"); 
                break; 
            }
 
            return true;
        }

        internal static bool IsRoot(XPathNavigator navigator) { 
            Debug.Assert(navigator != null);
 
            if (navigator.NodeType == XPathNodeType.Root) { 
                return true;
            } 
            else if (navigator.NodeType == XPathNodeType.Element) {
                XPathNavigator clone = navigator.Clone();
                clone.MoveToRoot();
                return clone.IsSamePosition(navigator); 
            }
            else { 
                return false; 
            }
        } 

        //
        // Builder stack
        // 
        internal void PushOutput(RecordOutput output) {
            Debug.Assert(output != null); 
            this.builder.OutputState = this.xsm.State; 
            RecordBuilder lastBuilder = this.builder;
            this.builder      = new RecordBuilder(output, this.nameTable); 
            this.builder.Next = lastBuilder;

            this.xsm.Reset();
        } 

        internal RecordOutput PopOutput() { 
            Debug.Assert(this.builder != null); 

            RecordBuilder topBuilder = this.builder; 
            this.builder              = topBuilder.Next;
            this.xsm.State            = this.builder.OutputState;

            topBuilder.TheEnd(); 

            return topBuilder.Output; 
        } 

        internal bool SetDefaultOutput(XsltOutput.OutputMethod method) { 
            if(Output.Method != method) {
                this.output = this.output.CreateDerivedOutput(method);
                return true;
            } 
            return false;
        } 
 
        internal object GetVariableValue(VariableAction variable) {
            int variablekey = variable.VarKey; 
            if (variable.IsGlobal) {
                ActionFrame rootFrame = (ActionFrame) this.actionStack[0];
                object result = rootFrame.GetVariable(variablekey);
                if (result == VariableAction.BeingComputedMark) { 
                    throw XsltException.Create(Res.Xslt_CircularReference, variable.NameStr);
                } 
                if (result != null) { 
                    return result;
                } 

                // Variable wasn't evaluated yet
                int saveStackSize = this.actionStack.Length;
                ActionFrame varFrame = PushNewFrame(); 
                varFrame.Inherit(rootFrame);
                varFrame.Init(variable, rootFrame.NodeSet); 
                do { 
                    bool endOfFrame = ((ActionFrame) this.actionStack.Peek()).Execute(this);
                    if (endOfFrame) { 
                        this.actionStack.Pop();
                    }
                } while (saveStackSize < this.actionStack.Length);
                Debug.Assert(saveStackSize == this.actionStack.Length); 
                result = rootFrame.GetVariable(variablekey);
                Debug.Assert(result != null, "Variable was just calculated and result can't be null"); 
                return result; 
            } else {
                return ((ActionFrame) this.actionStack.Peek()).GetVariable(variablekey); 
            }
        }

        internal void SetParameter(XmlQualifiedName name, object value) { 
            Debug.Assert(1 < actionStack.Length);
            ActionFrame parentFrame = (ActionFrame) this.actionStack[actionStack.Length - 2]; 
            parentFrame.SetParameter(name, value); 
        }
 
        internal void ResetParams() {
            ActionFrame frame = (ActionFrame) this.actionStack[actionStack.Length - 1];
            frame.ResetParams();
        } 

        internal object GetParameter(XmlQualifiedName name) { 
            Debug.Assert(2 < actionStack.Length); 
            ActionFrame parentFrame = (ActionFrame) this.actionStack[actionStack.Length - 3];
            return parentFrame.GetParameter(name); 
        }

        // ---------------------- Debugger stack -----------------------
 
        internal class DebuggerFrame {
            internal ActionFrame        actionFrame; 
            internal XmlQualifiedName   currentMode; 
        }
 
        internal void PushDebuggerStack() {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            DebuggerFrame dbgFrame = (DebuggerFrame) this.debuggerStack.Push();
            if (dbgFrame == null) { 
                dbgFrame = new DebuggerFrame();
                this.debuggerStack.AddToTop(dbgFrame); 
            } 
            dbgFrame.actionFrame = (ActionFrame) this.actionStack.Peek(); // In a case of next builtIn action.
        } 

        internal void PopDebuggerStack() {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            this.debuggerStack.Pop(); 
        }
 
        internal void OnInstructionExecute() { 
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger");
            DebuggerFrame dbgFrame = (DebuggerFrame) this.debuggerStack.Peek(); 
            Debug.Assert(dbgFrame != null, "PushDebuggerStack() wasn't ever called");
            dbgFrame.actionFrame = (ActionFrame) this.actionStack.Peek();
            this.Debugger.OnInstructionExecute((IXsltProcessor) this);
        } 

        internal XmlQualifiedName GetPrevioseMode() { 
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger"); 
            Debug.Assert(2 <= this.debuggerStack.Length);
            return ((DebuggerFrame) this.debuggerStack[this.debuggerStack.Length - 2]).currentMode; 
        }

        internal void SetCurrentMode(XmlQualifiedName mode) {
            Debug.Assert(this.Debugger != null, "We don't generate calls this function if ! debugger"); 
            ((DebuggerFrame) this.debuggerStack[this.debuggerStack.Length - 1]).currentMode = mode;
        } 
 
        // ----------------------- IXsltProcessor : --------------------
        int IXsltProcessor.StackDepth { 
            get {return this.debuggerStack.Length;}
        }

        IStackFrame IXsltProcessor.GetStackFrame(int depth) { 
            return ((DebuggerFrame) this.debuggerStack[depth]).actionFrame;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK