Code:
                         / FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / XPath / Internal / Query.cs / 2 / 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(List buffer, 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.
                          
                        
                        
                        
                    Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataGridViewCellValidatingEventArgs.cs
- PrimitiveType.cs
- ItemCollection.cs
- SecurityException.cs
- diagnosticsswitches.cs
- ValueTable.cs
- SpecialNameAttribute.cs
- FormatVersion.cs
- HMACMD5.cs
- OutputCacheProfileCollection.cs
- ProfileGroupSettings.cs
- WizardForm.cs
- DataGridPagerStyle.cs
- WindowsScrollBar.cs
- ImageFormat.cs
- TextShapeableCharacters.cs
- SequenceFullException.cs
- querybuilder.cs
- XmlBoundElement.cs
- ApplicationTrust.cs
- ConstraintCollection.cs
- ServiceTimeoutsElement.cs
- Random.cs
- StyleModeStack.cs
- HGlobalSafeHandle.cs
- RoleGroupCollectionEditor.cs
- PanelStyle.cs
- OrthographicCamera.cs
- WebPageTraceListener.cs
- CodeMemberProperty.cs
- AmbientValueAttribute.cs
- XmlSchemaSimpleContentRestriction.cs
- SamlAuthorizationDecisionStatement.cs
- DNS.cs
- URLMembershipCondition.cs
- CodePageUtils.cs
- ExpressionContext.cs
- ObjectReaderCompiler.cs
- DesignerSerializerAttribute.cs
- PagerStyle.cs
- AsyncCompletedEventArgs.cs
- HighlightVisual.cs
- GetWinFXPath.cs
- WebPartUserCapability.cs
- BaseDataList.cs
- DirectoryNotFoundException.cs
- CreateUserWizard.cs
- WmpBitmapDecoder.cs
- SafeSecurityHelper.cs
- ErrorCodes.cs
- CompModSwitches.cs
- DefaultPropertyAttribute.cs
- CommandHelper.cs
- DetailsViewPagerRow.cs
- FrameworkElement.cs
- ChangeDirector.cs
- MaskPropertyEditor.cs
- FileLevelControlBuilderAttribute.cs
- TouchesOverProperty.cs
- ClientUriBehavior.cs
- TextEffect.cs
- RefType.cs
- PlainXmlDeserializer.cs
- UserControl.cs
- JsonEncodingStreamWrapper.cs
- AttributeEmitter.cs
- EncodingDataItem.cs
- StructuredTypeInfo.cs
- CounterCreationData.cs
- StyleCollectionEditor.cs
- Variant.cs
- XXXInfos.cs
- HttpWebResponse.cs
- ImageListUtils.cs
- DataBinder.cs
- TimeSpanStorage.cs
- GroupBox.cs
- AccessibilityApplicationManager.cs
- XPathSingletonIterator.cs
- DecimalConstantAttribute.cs
- RefreshPropertiesAttribute.cs
- ServiceProviders.cs
- StrokeNodeData.cs
- MessageQueue.cs
- WebPartDisplayMode.cs
- SoapParser.cs
- XmlSerializerAssemblyAttribute.cs
- Transform.cs
- WindowsGraphics.cs
- ElementUtil.cs
- ResizeGrip.cs
- ResXResourceSet.cs
- Rule.cs
- ProxyWebPartManager.cs
- EntityDataReader.cs
- XmlEntity.cs
- HelpEvent.cs
- LinearKeyFrames.cs
- COM2ExtendedBrowsingHandler.cs
- Nullable.cs