SetIterators.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / SetIterators.cs / 1305376 / SetIterators.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Xml; 
using System.Xml.XPath;
using System.Xml.Schema; 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
 
namespace System.Xml.Xsl.Runtime {
 
    ///  
    /// Set iterators (Union, Intersection, Difference) that use containment to control two nested iterators return
    /// one of the following values from MoveNext(). 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)]
    public enum SetIteratorResult {
        NoMoreNodes,                // Iteration is complete; there are no more nodes 
        InitRightIterator,          // Initialize right nested iterator
        NeedLeftNode,               // The next node needs to be fetched from the left nested iterator 
        NeedRightNode,              // The next node needs to be fetched from the right nested iterator 
        HaveCurrentNode,            // This iterator's Current property is set to the next node in the iteration
    }; 


    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates. 
    /// Using a merge sort, this operator returns the union of these sets in document order with no duplicates.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public struct UnionIterator {
        private XmlQueryRuntime runtime; 
        private XPathNavigator navCurr, navOther;
        private IteratorState state;

        private enum IteratorState { 
            InitLeft = 0,
            NeedLeft, 
            NeedRight, 
            LeftIsCurrent,
            RightIsCurrent, 
        };

        /// 
        /// Create SetIterator. 
        /// 
        public void Create(XmlQueryRuntime runtime) { 
            this.runtime = runtime; 
            this.state = IteratorState.InitLeft;
        } 

        /// 
        /// Position this iterator to the next node in the union.
        ///  
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) {
            switch (this.state) { 
                case IteratorState.InitLeft: 
                    // Fetched node from left iterator, now get initial node from right iterator
                    this.navOther = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft: 
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.LeftIsCurrent; 
                    break; 

                case IteratorState.NeedRight: 
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.RightIsCurrent;
                    break;
 
                case IteratorState.LeftIsCurrent:
                    // Just returned left node as current, so get new left 
                    this.state = IteratorState.NeedLeft; 
                    return SetIteratorResult.NeedLeftNode;
 
                case IteratorState.RightIsCurrent:
                    // Just returned right node as current, so get new right
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
            }
 
            // Merge left and right nodes 
            if (this.navCurr == null) {
                // If both navCurr and navOther are null, then iteration is complete 
                if (this.navOther == null)
                    return SetIteratorResult.NoMoreNodes;

                Swap(); 
            }
            else if (this.navOther != null) { 
                int order = this.runtime.ComparePosition(this.navOther, this.navCurr); 

                // If navCurr is positioned to same node as navOther, 
                if (order == 0) {
                    // Skip navCurr, since it is a duplicate
                    if (this.state == IteratorState.LeftIsCurrent) {
                        this.state = IteratorState.NeedLeft; 
                        return SetIteratorResult.NeedLeftNode;
                    } 
 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
                }

                // If navOther is before navCurr in document order, then swap navCurr with navOther
                if (order < 0) 
                    Swap();
            } 
 
            // Return navCurr
            return SetIteratorResult.HaveCurrentNode; 
        }

        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1. 
        /// 
        public XPathNavigator Current { 
            get { return this.navCurr; } 
        }
 
        /// 
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// 
        private void Swap() { 
            XPathNavigator navTemp = this.navCurr;
            this.navCurr = this.navOther; 
            this.navOther = navTemp; 

            if (this.state == IteratorState.LeftIsCurrent) 
                this.state = IteratorState.RightIsCurrent;
            else
                this.state = IteratorState.LeftIsCurrent;
        } 
    }
 
 
    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates. 
    /// This iterator returns the intersection of these sets in document order with no duplicates.
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct IntersectIterator { 
        private XmlQueryRuntime runtime;
        private XPathNavigator navLeft, navRight; 
        private IteratorState state; 

        private enum IteratorState { 
            InitLeft = 0,
            NeedLeft,
            NeedRight,
            NeedLeftAndRight, 
            HaveCurrent,
        }; 
 
        /// 
        /// Create IntersectIterator. 
        /// 
        public void Create(XmlQueryRuntime runtime) {
            this.runtime = runtime;
            this.state = IteratorState.InitLeft; 
        }
 
        ///  
        /// Position this iterator to the next node in the union.
        ///  
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) {
            int order;

            switch (this.state) { 
                case IteratorState.InitLeft:
                    // Fetched node from left iterator, now get initial node from right iterator 
                    this.navLeft = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator; 

                case IteratorState.NeedLeft:
                    this.navLeft = nestedNavigator;
                    break; 

                case IteratorState.NeedRight: 
                    this.navRight = nestedNavigator; 
                    break;
 
                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    this.navLeft = nestedNavigator;
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.NeedRightNode;
 
                case IteratorState.HaveCurrent: 
                    // Just returned left node as current, so fetch new left and right nodes
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned."); 
                    this.state = IteratorState.NeedLeftAndRight;
                    return SetIteratorResult.NeedLeftNode;
            }
 
            if (this.navLeft == null || this.navRight == null) {
                // No more nodes from either left or right iterator (or both), so iteration is complete 
                return SetIteratorResult.NoMoreNodes; 
            }
 
            // Intersect left and right sets
            order = this.runtime.ComparePosition(this.navLeft, this.navRight);

            if (order < 0) { 
                // If navLeft is positioned to a node that is before navRight, skip left node
                this.state = IteratorState.NeedLeft; 
                return SetIteratorResult.NeedLeftNode; 
            }
            else if (order > 0) { 
                // If navLeft is positioned to a node that is after navRight, so skip right node
                this.state = IteratorState.NeedRight;
                return SetIteratorResult.NeedRightNode;
            } 

            // Otherwise, navLeft is positioned to the same node as navRight, so found one item in the intersection 
            this.state = IteratorState.HaveCurrent; 
            return SetIteratorResult.HaveCurrentNode;
        } 

        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1.
        ///  
        public XPathNavigator Current {
            get { return this.navLeft; } 
        } 
    }
 

    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates.
    /// This iterator returns the difference of these sets (Left - Right) in document order with no duplicates. 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public struct DifferenceIterator { 
        private XmlQueryRuntime runtime;
        private XPathNavigator navLeft, navRight; 
        private IteratorState state;

        private enum IteratorState {
            InitLeft = 0, 
            NeedLeft,
            NeedRight, 
            NeedLeftAndRight, 
            HaveCurrent,
        }; 

        /// 
        /// Create DifferenceIterator.
        ///  
        public void Create(XmlQueryRuntime runtime) {
            this.runtime = runtime; 
            this.state = IteratorState.InitLeft; 
        }
 
        /// 
        /// Position this iterator to the next node in the union.
        /// 
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) { 
            switch (this.state) {
                case IteratorState.InitLeft: 
                    // Fetched node from left iterator, now get initial node from right iterator 
                    this.navLeft = nestedNavigator;
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft:
                    this.navLeft = nestedNavigator; 
                    break;
 
                case IteratorState.NeedRight: 
                    this.navRight = nestedNavigator;
                    break; 

                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    this.navLeft = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
 
                case IteratorState.HaveCurrent:
                    // Just returned left node as current, so fetch new left node 
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                    this.state = IteratorState.NeedLeft;
                    return SetIteratorResult.NeedLeftNode;
            } 

            if (this.navLeft == null) { 
                // If navLeft is null, then difference operation is complete 
                return SetIteratorResult.NoMoreNodes;
            } 
            else if (this.navRight != null) {
                int order = this.runtime.ComparePosition(this.navLeft, this.navRight);

                // If navLeft is positioned to same node as navRight, 
                if (order == 0) {
                    // Skip navLeft and navRight 
                    this.state = IteratorState.NeedLeftAndRight; 
                    return SetIteratorResult.NeedLeftNode;
                } 

                // If navLeft is after navRight in document order, then skip navRight
                if (order > 0) {
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.NeedRightNode;
                } 
            } 

            // Return navLeft 
            this.state = IteratorState.HaveCurrent;
            return SetIteratorResult.HaveCurrentNode;
        }
 
        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1. 
        ///  
        public XPathNavigator Current {
            get { return this.navLeft; } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Xml; 
using System.Xml.XPath;
using System.Xml.Schema; 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
 
namespace System.Xml.Xsl.Runtime {
 
    ///  
    /// Set iterators (Union, Intersection, Difference) that use containment to control two nested iterators return
    /// one of the following values from MoveNext(). 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)]
    public enum SetIteratorResult {
        NoMoreNodes,                // Iteration is complete; there are no more nodes 
        InitRightIterator,          // Initialize right nested iterator
        NeedLeftNode,               // The next node needs to be fetched from the left nested iterator 
        NeedRightNode,              // The next node needs to be fetched from the right nested iterator 
        HaveCurrentNode,            // This iterator's Current property is set to the next node in the iteration
    }; 


    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates. 
    /// Using a merge sort, this operator returns the union of these sets in document order with no duplicates.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public struct UnionIterator {
        private XmlQueryRuntime runtime; 
        private XPathNavigator navCurr, navOther;
        private IteratorState state;

        private enum IteratorState { 
            InitLeft = 0,
            NeedLeft, 
            NeedRight, 
            LeftIsCurrent,
            RightIsCurrent, 
        };

        /// 
        /// Create SetIterator. 
        /// 
        public void Create(XmlQueryRuntime runtime) { 
            this.runtime = runtime; 
            this.state = IteratorState.InitLeft;
        } 

        /// 
        /// Position this iterator to the next node in the union.
        ///  
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) {
            switch (this.state) { 
                case IteratorState.InitLeft: 
                    // Fetched node from left iterator, now get initial node from right iterator
                    this.navOther = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft: 
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.LeftIsCurrent; 
                    break; 

                case IteratorState.NeedRight: 
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.RightIsCurrent;
                    break;
 
                case IteratorState.LeftIsCurrent:
                    // Just returned left node as current, so get new left 
                    this.state = IteratorState.NeedLeft; 
                    return SetIteratorResult.NeedLeftNode;
 
                case IteratorState.RightIsCurrent:
                    // Just returned right node as current, so get new right
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
            }
 
            // Merge left and right nodes 
            if (this.navCurr == null) {
                // If both navCurr and navOther are null, then iteration is complete 
                if (this.navOther == null)
                    return SetIteratorResult.NoMoreNodes;

                Swap(); 
            }
            else if (this.navOther != null) { 
                int order = this.runtime.ComparePosition(this.navOther, this.navCurr); 

                // If navCurr is positioned to same node as navOther, 
                if (order == 0) {
                    // Skip navCurr, since it is a duplicate
                    if (this.state == IteratorState.LeftIsCurrent) {
                        this.state = IteratorState.NeedLeft; 
                        return SetIteratorResult.NeedLeftNode;
                    } 
 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
                }

                // If navOther is before navCurr in document order, then swap navCurr with navOther
                if (order < 0) 
                    Swap();
            } 
 
            // Return navCurr
            return SetIteratorResult.HaveCurrentNode; 
        }

        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1. 
        /// 
        public XPathNavigator Current { 
            get { return this.navCurr; } 
        }
 
        /// 
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// 
        private void Swap() { 
            XPathNavigator navTemp = this.navCurr;
            this.navCurr = this.navOther; 
            this.navOther = navTemp; 

            if (this.state == IteratorState.LeftIsCurrent) 
                this.state = IteratorState.RightIsCurrent;
            else
                this.state = IteratorState.LeftIsCurrent;
        } 
    }
 
 
    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates. 
    /// This iterator returns the intersection of these sets in document order with no duplicates.
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct IntersectIterator { 
        private XmlQueryRuntime runtime;
        private XPathNavigator navLeft, navRight; 
        private IteratorState state; 

        private enum IteratorState { 
            InitLeft = 0,
            NeedLeft,
            NeedRight,
            NeedLeftAndRight, 
            HaveCurrent,
        }; 
 
        /// 
        /// Create IntersectIterator. 
        /// 
        public void Create(XmlQueryRuntime runtime) {
            this.runtime = runtime;
            this.state = IteratorState.InitLeft; 
        }
 
        ///  
        /// Position this iterator to the next node in the union.
        ///  
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) {
            int order;

            switch (this.state) { 
                case IteratorState.InitLeft:
                    // Fetched node from left iterator, now get initial node from right iterator 
                    this.navLeft = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator; 

                case IteratorState.NeedLeft:
                    this.navLeft = nestedNavigator;
                    break; 

                case IteratorState.NeedRight: 
                    this.navRight = nestedNavigator; 
                    break;
 
                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    this.navLeft = nestedNavigator;
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.NeedRightNode;
 
                case IteratorState.HaveCurrent: 
                    // Just returned left node as current, so fetch new left and right nodes
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned."); 
                    this.state = IteratorState.NeedLeftAndRight;
                    return SetIteratorResult.NeedLeftNode;
            }
 
            if (this.navLeft == null || this.navRight == null) {
                // No more nodes from either left or right iterator (or both), so iteration is complete 
                return SetIteratorResult.NoMoreNodes; 
            }
 
            // Intersect left and right sets
            order = this.runtime.ComparePosition(this.navLeft, this.navRight);

            if (order < 0) { 
                // If navLeft is positioned to a node that is before navRight, skip left node
                this.state = IteratorState.NeedLeft; 
                return SetIteratorResult.NeedLeftNode; 
            }
            else if (order > 0) { 
                // If navLeft is positioned to a node that is after navRight, so skip right node
                this.state = IteratorState.NeedRight;
                return SetIteratorResult.NeedRightNode;
            } 

            // Otherwise, navLeft is positioned to the same node as navRight, so found one item in the intersection 
            this.state = IteratorState.HaveCurrent; 
            return SetIteratorResult.HaveCurrentNode;
        } 

        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1.
        ///  
        public XPathNavigator Current {
            get { return this.navLeft; } 
        } 
    }
 

    /// 
    /// This iterator manages two sets of nodes that are already in document order with no duplicates.
    /// This iterator returns the difference of these sets (Left - Right) in document order with no duplicates. 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public struct DifferenceIterator { 
        private XmlQueryRuntime runtime;
        private XPathNavigator navLeft, navRight; 
        private IteratorState state;

        private enum IteratorState {
            InitLeft = 0, 
            NeedLeft,
            NeedRight, 
            NeedLeftAndRight, 
            HaveCurrent,
        }; 

        /// 
        /// Create DifferenceIterator.
        ///  
        public void Create(XmlQueryRuntime runtime) {
            this.runtime = runtime; 
            this.state = IteratorState.InitLeft; 
        }
 
        /// 
        /// Position this iterator to the next node in the union.
        /// 
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) { 
            switch (this.state) {
                case IteratorState.InitLeft: 
                    // Fetched node from left iterator, now get initial node from right iterator 
                    this.navLeft = nestedNavigator;
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft:
                    this.navLeft = nestedNavigator; 
                    break;
 
                case IteratorState.NeedRight: 
                    this.navRight = nestedNavigator;
                    break; 

                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    this.navLeft = nestedNavigator; 
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode; 
 
                case IteratorState.HaveCurrent:
                    // Just returned left node as current, so fetch new left node 
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                    this.state = IteratorState.NeedLeft;
                    return SetIteratorResult.NeedLeftNode;
            } 

            if (this.navLeft == null) { 
                // If navLeft is null, then difference operation is complete 
                return SetIteratorResult.NoMoreNodes;
            } 
            else if (this.navRight != null) {
                int order = this.runtime.ComparePosition(this.navLeft, this.navRight);

                // If navLeft is positioned to same node as navRight, 
                if (order == 0) {
                    // Skip navLeft and navRight 
                    this.state = IteratorState.NeedLeftAndRight; 
                    return SetIteratorResult.NeedLeftNode;
                } 

                // If navLeft is after navRight in document order, then skip navRight
                if (order > 0) {
                    this.state = IteratorState.NeedRight; 
                    return SetIteratorResult.NeedRightNode;
                } 
            } 

            // Return navLeft 
            this.state = IteratorState.HaveCurrent;
            return SetIteratorResult.HaveCurrentNode;
        }
 
        /// 
        /// Return the current result navigator.  This is only defined after MoveNext() has returned -1. 
        ///  
        public XPathNavigator Current {
            get { return this.navLeft; } 
        }
    }
}

// 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