Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Xml / System / Xml / XPath / Internal / Query.cs / 5 / Query.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace MS.Internal.Xml.XPath { using System; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; using System.Diagnostics; using System.Collections.Generic; // See comments to QueryBuilder.Props // Not all of them are used currently internal enum QueryProps { None = 0x00, Position = 0x01, Count = 0x02, Cached = 0x04, Reverse = 0x08, Merge = 0x10, }; // Turn off DebuggerDisplayAttribute. in subclasses of Query. // Calls to Current in the XPathNavigator.DebuggerDisplayProxy may change state or throw [DebuggerDisplay("{ToString()}")] internal abstract class Query : ResetableIterator { public Query() { } protected Query(Query other) : base(other) { } // -- XPathNodeIterator -- //public abstract XPathNodeIterator Clone(); //public abstract XPathNavigator Current { get; } //public abstract int CurrentPosition { get; } public override bool MoveNext() { return Advance() != null; } public override int Count { get { // Query can be ordered in reverse order. So we can't assume like base.Count that last node has greatest position. if (count == -1) { Query clone = (Query)this.Clone(); clone.Reset(); count = 0; while (clone.MoveNext()) count ++; } return count; } } // ------------- ResetableIterator ----------- // It's importent that Query is resetable. This fact is used in several plases: // 1. In LogicalExpr: "foo = bar" // 2. In SelectionOperator.Reset(). // In all this cases Reset() means restart iterate through the same nodes. // So reset shouldn't clean bufferes in query. This should be done in set context. //public abstract void Reset(); // -------------------- Query ------------------ public virtual void SetXsltContext(XsltContext context) { } public abstract object Evaluate(XPathNodeIterator nodeIterator); public abstract XPathNavigator Advance(); public virtual XPathNavigator MatchNode(XPathNavigator current) { throw XPathException.Create(Res.Xp_InvalidPattern); } public virtual double XsltDefaultPriority { get { return 0.5; } } public abstract XPathResultType StaticType { get; } public virtual QueryProps Properties { get { return QueryProps.Merge; } } // ----------------- Helper methods ------------- public static Query Clone(Query input) { if (input != null) { return (Query)input.Clone(); } return null; } protected static XPathNodeIterator Clone(XPathNodeIterator input) { if (input != null) { return input.Clone(); } return null; } protected static XPathNavigator Clone(XPathNavigator input) { if (input != null) { return input.Clone(); } return null; } // ----------------------------------------------------- // Set of methods to support insertion to sorted buffer. // buffer is always sorted here public bool Insert(Listbuffer, XPathNavigator nav) { int l = 0; int r = buffer.Count; // In most cases nodes are already sorted. // This means that nav often will be equal or after then last item in the buffer // So let's check this first. if (r != 0) { switch (CompareNodes(buffer[r - 1], nav)) { case XmlNodeOrder.Same: return false; case XmlNodeOrder.Before: buffer.Add(nav.Clone()); return true; default: r --; break; } } while (l < r) { int m = GetMedian(l, r); switch (CompareNodes(buffer[m], nav)) { case XmlNodeOrder.Same: return false; case XmlNodeOrder.Before: l = m + 1; break; default: r = m; break; } } AssertDOD(buffer, nav, l); buffer.Insert(l, nav.Clone()); return true; } private static int GetMedian(int l, int r) { Debug.Assert(0 <= l && l < r); return (int) (((uint) l + (uint) r) >> 1); } public static XmlNodeOrder CompareNodes(XPathNavigator l, XPathNavigator r) { XmlNodeOrder cmp = l.ComparePosition(r); if (cmp == XmlNodeOrder.Unknown) { XPathNavigator copy = l.Clone(); copy.MoveToRoot(); string baseUriL = copy.BaseURI; if (! copy.MoveTo(r)) { copy = r.Clone(); } copy.MoveToRoot(); string baseUriR = copy.BaseURI; int cmpBase = string.CompareOrdinal(baseUriL, baseUriR); cmp = ( cmpBase < 0 ? XmlNodeOrder.Before : cmpBase > 0 ? XmlNodeOrder.After : /*default*/ XmlNodeOrder.Unknown ); } return cmp; } [Conditional("DEBUG")] private void AssertDOD(List buffer, XPathNavigator nav, int pos) { if (nav.GetType().ToString() == "Microsoft.VisualStudio.Modeling.StoreNavigator") return; if (nav.GetType().ToString() == "System.Xml.DataDocumentXPathNavigator") return; Debug.Assert(0 <= pos && pos <= buffer.Count, "Algorithm error: Insert()"); XmlNodeOrder cmp; if (0 < pos) { cmp = CompareNodes(buffer[pos - 1], nav); Debug.Assert(cmp == XmlNodeOrder.Before, "Algorithm error: Insert()"); } if (pos < buffer.Count) { cmp = CompareNodes(nav, buffer[pos]); Debug.Assert(cmp == XmlNodeOrder.Before, "Algorithm error: Insert()"); } } [Conditional("DEBUG")] public static void AssertQuery(Query query) { Debug.Assert(query != null, "AssertQuery(): query == null"); if (query is FunctionQuery) return; // Temp Fix. Functions (as document()) return now unordered sequences query = Clone(query); XPathNavigator last = null; XPathNavigator curr; int querySize = query.Clone().Count; int actualSize = 0; while ((curr = query.Advance()) != null) { if (curr.GetType().ToString() == "Microsoft.VisualStudio.Modeling.StoreNavigator") return; if (curr.GetType().ToString() == "System.Xml.DataDocumentXPathNavigator") return; Debug.Assert(curr == query.Current, "AssertQuery(): query.Advance() != query.Current"); if (last != null) { if (last.NodeType == XPathNodeType.Namespace && curr.NodeType == XPathNodeType.Namespace) { // NamespaceQuery reports namsespaces in mixed order. // Ignore this for now. // It seams that this doesn't breake other queries becasue NS can't have children } else { XmlNodeOrder cmp = CompareNodes(last, curr); Debug.Assert(cmp == XmlNodeOrder.Before, "AssertQuery(): Wrong node order"); } } last = curr.Clone(); actualSize++; } Debug.Assert(actualSize == querySize, "AssertQuery(): actualSize != querySize"); } // =================== XPathResultType_Navigator ====================== // In v.1.0 and v.1.1 XPathResultType.Navigator is defined == to XPathResultType.String // This is source for multiple bugs or additional type casts. // To fix all of them in one change in v.2 we internaly use one more value: public const XPathResultType XPathResultType_Navigator = (XPathResultType) 4; // The biggest challenge in this change is preserve backward compatibility with v.1.1 // To achive this in all places where we accept from or report to user XPathResultType. // On my best knowledge this happens only in XsltContext.ResolveFunction() / IXsltContextFunction.ReturnType protected XPathResultType GetXPathType(object value) { if (value is XPathNodeIterator) return XPathResultType.NodeSet; if (value is string ) return XPathResultType.String; if (value is double ) return XPathResultType.Number; if (value is bool ) return XPathResultType.Boolean; Debug.Assert(value is XPathNavigator, "Unknown value type"); return XPathResultType_Navigator; } // =================== Serialization ====================== public virtual void PrintQuery(XmlWriter w) { w.WriteElementString(this.GetType().Name, string.Empty); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace MS.Internal.Xml.XPath { using System; using System.Xml; using System.Xml.XPath; using System.Xml.Xsl; using System.Diagnostics; using System.Collections.Generic; // See comments to QueryBuilder.Props // Not all of them are used currently internal enum QueryProps { None = 0x00, Position = 0x01, Count = 0x02, Cached = 0x04, Reverse = 0x08, Merge = 0x10, }; // Turn off DebuggerDisplayAttribute. in subclasses of Query. // Calls to Current in the XPathNavigator.DebuggerDisplayProxy may change state or throw [DebuggerDisplay("{ToString()}")] internal abstract class Query : ResetableIterator { public Query() { } protected Query(Query other) : base(other) { } // -- XPathNodeIterator -- //public abstract XPathNodeIterator Clone(); //public abstract XPathNavigator Current { get; } //public abstract int CurrentPosition { get; } public override bool MoveNext() { return Advance() != null; } public override int Count { get { // Query can be ordered in reverse order. So we can't assume like base.Count that last node has greatest position. if (count == -1) { Query clone = (Query)this.Clone(); clone.Reset(); count = 0; while (clone.MoveNext()) count ++; } return count; } } // ------------- ResetableIterator ----------- // It's importent that Query is resetable. This fact is used in several plases: // 1. In LogicalExpr: "foo = bar" // 2. In SelectionOperator.Reset(). // In all this cases Reset() means restart iterate through the same nodes. // So reset shouldn't clean bufferes in query. This should be done in set context. //public abstract void Reset(); // -------------------- Query ------------------ public virtual void SetXsltContext(XsltContext context) { } public abstract object Evaluate(XPathNodeIterator nodeIterator); public abstract XPathNavigator Advance(); public virtual XPathNavigator MatchNode(XPathNavigator current) { throw XPathException.Create(Res.Xp_InvalidPattern); } public virtual double XsltDefaultPriority { get { return 0.5; } } public abstract XPathResultType StaticType { get; } public virtual QueryProps Properties { get { return QueryProps.Merge; } } // ----------------- Helper methods ------------- public static Query Clone(Query input) { if (input != null) { return (Query)input.Clone(); } return null; } protected static XPathNodeIterator Clone(XPathNodeIterator input) { if (input != null) { return input.Clone(); } return null; } protected static XPathNavigator Clone(XPathNavigator input) { if (input != null) { return input.Clone(); } return null; } // ----------------------------------------------------- // Set of methods to support insertion to sorted buffer. // buffer is always sorted here public bool Insert(Listbuffer, XPathNavigator nav) { int l = 0; int r = buffer.Count; // In most cases nodes are already sorted. // This means that nav often will be equal or after then last item in the buffer // So let's check this first. if (r != 0) { switch (CompareNodes(buffer[r - 1], nav)) { case XmlNodeOrder.Same: return false; case XmlNodeOrder.Before: buffer.Add(nav.Clone()); return true; default: r --; break; } } while (l < r) { int m = GetMedian(l, r); switch (CompareNodes(buffer[m], nav)) { case XmlNodeOrder.Same: return false; case XmlNodeOrder.Before: l = m + 1; break; default: r = m; break; } } AssertDOD(buffer, nav, l); buffer.Insert(l, nav.Clone()); return true; } private static int GetMedian(int l, int r) { Debug.Assert(0 <= l && l < r); return (int) (((uint) l + (uint) r) >> 1); } public static XmlNodeOrder CompareNodes(XPathNavigator l, XPathNavigator r) { XmlNodeOrder cmp = l.ComparePosition(r); if (cmp == XmlNodeOrder.Unknown) { XPathNavigator copy = l.Clone(); copy.MoveToRoot(); string baseUriL = copy.BaseURI; if (! copy.MoveTo(r)) { copy = r.Clone(); } copy.MoveToRoot(); string baseUriR = copy.BaseURI; int cmpBase = string.CompareOrdinal(baseUriL, baseUriR); cmp = ( cmpBase < 0 ? XmlNodeOrder.Before : cmpBase > 0 ? XmlNodeOrder.After : /*default*/ XmlNodeOrder.Unknown ); } return cmp; } [Conditional("DEBUG")] private void AssertDOD(List buffer, XPathNavigator nav, int pos) { if (nav.GetType().ToString() == "Microsoft.VisualStudio.Modeling.StoreNavigator") return; if (nav.GetType().ToString() == "System.Xml.DataDocumentXPathNavigator") return; Debug.Assert(0 <= pos && pos <= buffer.Count, "Algorithm error: Insert()"); XmlNodeOrder cmp; if (0 < pos) { cmp = CompareNodes(buffer[pos - 1], nav); Debug.Assert(cmp == XmlNodeOrder.Before, "Algorithm error: Insert()"); } if (pos < buffer.Count) { cmp = CompareNodes(nav, buffer[pos]); Debug.Assert(cmp == XmlNodeOrder.Before, "Algorithm error: Insert()"); } } [Conditional("DEBUG")] public static void AssertQuery(Query query) { Debug.Assert(query != null, "AssertQuery(): query == null"); if (query is FunctionQuery) return; // Temp Fix. Functions (as document()) return now unordered sequences query = Clone(query); XPathNavigator last = null; XPathNavigator curr; int querySize = query.Clone().Count; int actualSize = 0; while ((curr = query.Advance()) != null) { if (curr.GetType().ToString() == "Microsoft.VisualStudio.Modeling.StoreNavigator") return; if (curr.GetType().ToString() == "System.Xml.DataDocumentXPathNavigator") return; Debug.Assert(curr == query.Current, "AssertQuery(): query.Advance() != query.Current"); if (last != null) { if (last.NodeType == XPathNodeType.Namespace && curr.NodeType == XPathNodeType.Namespace) { // NamespaceQuery reports namsespaces in mixed order. // Ignore this for now. // It seams that this doesn't breake other queries becasue NS can't have children } else { XmlNodeOrder cmp = CompareNodes(last, curr); Debug.Assert(cmp == XmlNodeOrder.Before, "AssertQuery(): Wrong node order"); } } last = curr.Clone(); actualSize++; } Debug.Assert(actualSize == querySize, "AssertQuery(): actualSize != querySize"); } // =================== XPathResultType_Navigator ====================== // In v.1.0 and v.1.1 XPathResultType.Navigator is defined == to XPathResultType.String // This is source for multiple bugs or additional type casts. // To fix all of them in one change in v.2 we internaly use one more value: public const XPathResultType XPathResultType_Navigator = (XPathResultType) 4; // The biggest challenge in this change is preserve backward compatibility with v.1.1 // To achive this in all places where we accept from or report to user XPathResultType. // On my best knowledge this happens only in XsltContext.ResolveFunction() / IXsltContextFunction.ReturnType protected XPathResultType GetXPathType(object value) { if (value is XPathNodeIterator) return XPathResultType.NodeSet; if (value is string ) return XPathResultType.String; if (value is double ) return XPathResultType.Number; if (value is bool ) return XPathResultType.Boolean; Debug.Assert(value is XPathNavigator, "Unknown value type"); return XPathResultType_Navigator; } // =================== Serialization ====================== public virtual void PrintQuery(XmlWriter w) { w.WriteElementString(this.GetType().Name, string.Empty); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WinInetCache.cs
- DbDeleteCommandTree.cs
- Animatable.cs
- controlskin.cs
- MatrixStack.cs
- ChildTable.cs
- ProcessRequestArgs.cs
- DiagnosticStrings.cs
- UserControl.cs
- HtmlInputText.cs
- BufferedStream.cs
- SiteMapNodeCollection.cs
- StringFreezingAttribute.cs
- ParserHooks.cs
- PageVisual.cs
- SafeArrayRankMismatchException.cs
- LoopExpression.cs
- TextServicesCompartment.cs
- InputScopeConverter.cs
- ToolBarButton.cs
- OletxVolatileEnlistment.cs
- ReadWriteObjectLock.cs
- XmlParserContext.cs
- ToolBarButton.cs
- KeyConverter.cs
- DataAdapter.cs
- VerificationException.cs
- SystemKeyConverter.cs
- InnerItemCollectionView.cs
- OutputWindow.cs
- XmlDictionary.cs
- DomainConstraint.cs
- EventMappingSettingsCollection.cs
- PrefixQName.cs
- HttpPostServerProtocol.cs
- AssertFilter.cs
- FloaterBaseParagraph.cs
- TagPrefixAttribute.cs
- NameScopePropertyAttribute.cs
- EncryptedXml.cs
- ObjectSecurity.cs
- AppDomainGrammarProxy.cs
- WeakKeyDictionary.cs
- XpsS0ValidatingLoader.cs
- WinFormsSecurity.cs
- AnnotationStore.cs
- SizeAnimationClockResource.cs
- SystemGatewayIPAddressInformation.cs
- SrgsElementList.cs
- ContextMenuService.cs
- QuestionEventArgs.cs
- XPathAxisIterator.cs
- HttpCacheVary.cs
- GestureRecognizer.cs
- VectorCollectionConverter.cs
- DataListItemCollection.cs
- CustomError.cs
- DateTimeOffsetAdapter.cs
- TextRenderer.cs
- XamlSerializationHelper.cs
- Condition.cs
- FlowPanelDesigner.cs
- DefaultValueConverter.cs
- XmlUtil.cs
- CodeParameterDeclarationExpressionCollection.cs
- IODescriptionAttribute.cs
- Double.cs
- PointCollectionConverter.cs
- TextTreeInsertUndoUnit.cs
- WebServiceReceive.cs
- InvokeMethod.cs
- FilteredXmlReader.cs
- Int64Converter.cs
- OleDbDataAdapter.cs
- PrePostDescendentsWalker.cs
- GridViewRowCollection.cs
- SmtpFailedRecipientsException.cs
- ToolStripTextBox.cs
- Page.cs
- WizardPanel.cs
- Point3DAnimation.cs
- NameValueCollection.cs
- CheckBoxList.cs
- DurableEnlistmentState.cs
- DetailsViewInsertedEventArgs.cs
- TrackingRecord.cs
- LambdaCompiler.Binary.cs
- SqlWriter.cs
- SystemResourceHost.cs
- Socket.cs
- StickyNoteContentControl.cs
- ParentQuery.cs
- DrawingBrush.cs
- CatalogPart.cs
- DocumentViewerAutomationPeer.cs
- XmlSerializerAssemblyAttribute.cs
- QilInvoke.cs
- ParallelEnumerable.cs
- XmlEntity.cs
- XmlStreamNodeWriter.cs