/// <summary> /// Compile this xpath to run on an external (fx) xpath engine /// </summary> internal void CompileForExternal(string xpath, XmlNamespaceManager names) { Opcode op = QueryMatcher.CompileForExternalEngine(xpath, names, null, this.match).First; this.query = op; this.flags |= XPathFilterFlags.IsFxFilter; }
internal QueryMatcher(QueryMatcher matcher) { this.processorPool = new WeakReference(null); this.maxNodes = matcher.maxNodes; this.query = matcher.query; this.subExprVars = matcher.subExprVars; }
internal void CompileForInternal(string xpath, XmlNamespaceManager names) { base.query = null; xpath = xpath.Trim(); if (xpath.Length == 0) { base.query = matchAlwaysFilter; this.flags |= XPathFilterFlags.AlwaysMatch; } else if ((1 == xpath.Length) && ('/' == xpath[0])) { base.query = rootFilter.First; this.flags |= XPathFilterFlags.AlwaysMatch; } else { ValueDataType type; OpcodeBlock block = QueryMatcher.CompileForInternalEngine(xpath, names, QueryCompilerFlags.None, out type); if (this.match) { block.Append(new MatchResultOpcode()); } else { block.Append(new QueryResultOpcode()); } base.query = block.First; } this.flags &= ~XPathFilterFlags.IsFxFilter; }
static XPathQueryMatcher() { ValueDataType type; matchAlwaysFilter = new PushBooleanOpcode(true); rootFilter = QueryMatcher.CompileForInternalEngine("/", null, QueryCompilerFlags.None, out type); rootFilter.Append(new MatchResultOpcode()); }
internal void Add(string expression, XmlNamespaceManager names, object item, bool forceExternal) { Fx.Assert(null != item, ""); // Compile the new filter bool compiled = false; OpcodeBlock codeBlock = new OpcodeBlock(); codeBlock.Append(new NoOpOpcode(OpcodeID.QueryTree)); if (!forceExternal) { try { ValueDataType returnType = ValueDataType.None; // Try to compile and merge the compiled query into the query tree codeBlock.Append(QueryMatcher.CompileForInternalEngine(expression, names, QueryCompilerFlags.InverseQuery, out returnType)); MultipleResultOpcode opcode; if (!this.match) { opcode = new QueryMultipleResultOpcode(); } else { opcode = new MatchMultipleResultOpcode(); } opcode.AddItem(item); codeBlock.Append(opcode); compiled = true; // Perform SubExpression Elimination codeBlock = new OpcodeBlock(this.elim.Add(item, codeBlock.First)); this.subExprVars = this.elim.VariableCount; } catch (QueryCompileException) { // If the filter couldn't be compiled, we drop down to the framework engine } } if (!compiled) { codeBlock.Append(QueryMatcher.CompileForExternalEngine(expression, names, item, this.match)); } // Merge the compiled query into the query tree QueryTreeBuilder builder = new QueryTreeBuilder(); this.query = builder.Build(this.query, codeBlock); // To de-merge this filter from the tree, we'll have to walk backwards up the tree... so we // have to remember the last opcode that is executed on behalf of this filter this.lastLookup[item] = builder.LastOpcode; }
internal QueryProcessor(QueryMatcher matcher) { base.Processor = this; this.matcher = matcher; this.flags = QueryProcessingFlags.Match; this.messageAction = null; this.messageId = null; this.messageSoapUri = null; this.messageTo = null; if (matcher.SubExprVarCount > 0) { this.subExprVars = new SubExprVariable[matcher.SubExprVarCount]; } }
internal QueryProcessor(QueryMatcher matcher) : base() { this.Processor = this; this.matcher = matcher; this.flags = QueryProcessingFlags.Match; // PERF, Microsoft, see if we can just let these to their default init this.messageAction = null; //this.messageAddress = null; //this.messageVia = null; this.messageId = null; this.messageSoapUri = null; this.messageTo = null; if (matcher.SubExprVarCount > 0) { this.subExprVars = new SubExprVariable[matcher.SubExprVarCount]; } }
internal void Add(string expression, XmlNamespaceManager names, object item, bool forceExternal) { bool flag = false; OpcodeBlock newBlock = new OpcodeBlock(); newBlock.Append(new NoOpOpcode(OpcodeID.QueryTree)); if (!forceExternal) { try { MultipleResultOpcode opcode; ValueDataType none = ValueDataType.None; newBlock.Append(QueryMatcher.CompileForInternalEngine(expression, names, QueryCompilerFlags.InverseQuery, out none)); if (!this.match) { opcode = new QueryMultipleResultOpcode(); } else { opcode = new MatchMultipleResultOpcode(); } opcode.AddItem(item); newBlock.Append(opcode); flag = true; newBlock = new OpcodeBlock(this.elim.Add(item, newBlock.First)); base.subExprVars = this.elim.VariableCount; } catch (QueryCompileException) { } } if (!flag) { newBlock.Append(QueryMatcher.CompileForExternalEngine(expression, names, item, this.match)); } QueryTreeBuilder builder = new QueryTreeBuilder(); base.query = builder.Build(base.query, newBlock); this.lastLookup[item] = builder.LastOpcode; }
/// <summary> /// Compile for the internal engine with default flags /// By defalt, we compile an xpath to run stand alone, with standard optimizations /// </summary> internal void CompileForInternal(string xpath, XmlNamespaceManager names) { this.query = null; xpath = xpath.Trim(); if (0 == xpath.Length) { // Empty xpaths always match. Same for xpaths that refer to the root only // We will evaluate such filters with minimal overhead. However, we // don't want a null value for this.query, so we stick a dummy value in there this.query = XPathQueryMatcher.matchAlwaysFilter; this.flags |= (XPathFilterFlags.AlwaysMatch); } else if (1 == xpath.Length && '/' == xpath[0]) { this.query = XPathQueryMatcher.rootFilter.First; this.flags |= (XPathFilterFlags.AlwaysMatch); } else { ValueDataType returnType; OpcodeBlock codeBlock = QueryMatcher.CompileForInternalEngine(xpath, names, QueryCompilerFlags.None, out returnType); // Inject a final opcode that will place the query result on the query context // This query is now ready for execution STAND ALONE if (this.match) { codeBlock.Append(new MatchResultOpcode()); } else { codeBlock.Append(new QueryResultOpcode()); } this.query = codeBlock.First; } this.flags &= ~XPathFilterFlags.IsFxFilter; }
internal QueryResult(QueryMatcher matcher, Message message, bool evalBody) { this.matcher = matcher; this.message = message; this.evalBody = evalBody; }
internal static OpcodeBlock CompileForInternalEngine(string xpath, XmlNamespaceManager ns, QueryCompilerFlags flags, out ValueDataType returnType) { return(QueryMatcher.CompileForInternalEngine(xpath, ns, flags, QueryMatcher.defaultFunctionLibs, out returnType)); }
/// <summary> /// Compile the given filter for evaluation using the internal engine. /// </summary> /// <param name="flags">Caller customizes optimizations via the flags parameter</param> /// <param name="returnType">Every xpath expression has a return type</param> /// <returns>The opcode block we execute to evaluate</returns> internal static OpcodeBlock CompileForInternalEngine(XPathMessageFilter filter, QueryCompilerFlags flags, IFunctionLibrary[] functionLibs, out ValueDataType returnType) { return(QueryMatcher.CompileForInternalEngine(filter.XPath.Trim(), filter.namespaces, flags, functionLibs, out returnType)); }