XmlQuerySequence.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XmlQuerySequence.cs / 1 / XmlQuerySequence.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Collections; 
using System.Collections.Generic;
using System.Xml; 
using System.IO;
using System.Text;
using System.Xml.Schema;
using System.Xml.Xsl; 
using System.Xml.XPath;
using System.Diagnostics; 
using System.ComponentModel; 

namespace System.Xml.Xsl.Runtime { 
    using Res           = System.Xml.Utils.Res;

    /// 
    /// A sequence of Xml values that dynamically expands and allows random access to items. 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public class XmlQuerySequence : IList, System.Collections.IList { 
        public static readonly XmlQuerySequence Empty = new XmlQuerySequence();
 
        private static readonly Type XPathItemType = typeof(XPathItem);

        private T[] items;
        private int size; 

    #if DEBUG 
        private const int DefaultCacheSize = 2; 
    #else
        private const int DefaultCacheSize = 16; 
    #endif

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQuerySequence. 
        /// 
        public static XmlQuerySequence CreateOrReuse(XmlQuerySequence seq) { 
            if (seq != null) { 
                seq.Clear();
                return seq; 
            }

            return new XmlQuerySequence();
        } 

        ///  
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQuerySequence. 
        /// Add "item" to the sequence.
        ///  
        public static XmlQuerySequence CreateOrReuse(XmlQuerySequence seq, T item) {
            if (seq != null) {
                seq.Clear();
                seq.Add(item); 
                return seq;
            } 
 
            return new XmlQuerySequence(item);
        } 

        /// 
        /// Construct new sequence.
        ///  
        public XmlQuerySequence() {
            this.items = new T[DefaultCacheSize]; 
        } 

        ///  
        /// Construct new sequence.
        /// 
        public XmlQuerySequence(int capacity) {
            this.items = new T[capacity]; 
        }
 
        ///  
        /// Construct sequence from the specified array.
        ///  
        public XmlQuerySequence(T[] array, int size) {
            this.items = array;
            this.size = size;
        } 

        ///  
        /// Construct singleton sequence having "value" as its only element. 
        /// 
        public XmlQuerySequence(T value) { 
            this.items = new T[1];
            this.items[0] = value;
            this.size = 1;
        } 

 
        //----------------------------------------------- 
        // IEnumerable implementation
        //----------------------------------------------- 

        /// 
        /// Return IEnumerator implementation.
        ///  
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return new IListEnumerator(this); 
        } 

 
        //-----------------------------------------------
        // IEnumerable implementation
        //-----------------------------------------------
 
        /// 
        /// Return IEnumerator implementation. 
        ///  
        public IEnumerator GetEnumerator() {
            return new IListEnumerator(this); 
        }


        //----------------------------------------------- 
        // ICollection implementation
        //----------------------------------------------- 
 
        /// 
        /// Return the number of items in the sequence. 
        /// 
        public int Count {
            get { return this.size; }
        } 

        ///  
        /// The XmlQuerySequence is not thread-safe. 
        /// 
        bool System.Collections.ICollection.IsSynchronized { 
            get { return false; }
        }

        ///  
        /// This instance can be used to synchronize access.
        ///  
        object System.Collections.ICollection.SyncRoot { 
            get { return this; }
        } 

        /// 
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        ///  
        void System.Collections.ICollection.CopyTo(Array array, int index) {
            if (this.size == 0) 
                return; 

            Array.Copy(this.items, 0, array, index, this.size); 
        }


        //----------------------------------------------- 
        // ICollection implementation
        //----------------------------------------------- 
 
        /// 
        /// Items may not be added, removed, or modified through the ICollection interface. 
        /// 
        bool ICollection.IsReadOnly {
            get { return true; }
        } 

        ///  
        /// Items may not be added through the ICollection interface. 
        /// 
        void ICollection.Add(T value) { 
            throw new NotSupportedException();
        }

        ///  
        /// Items may not be cleared through the ICollection interface.
        ///  
        void ICollection.Clear() { 
            throw new NotSupportedException();
        } 

        /// 
        /// Returns true if the specified value is in the sequence.
        ///  
        public bool Contains(T value) {
            return IndexOf(value) != -1; 
        } 

        ///  
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        /// 
        public void CopyTo(T[] array, int index) {
            for (int i = 0; i < Count; i++) 
                array[index + i] = this[i];
        } 
 
        /// 
        /// Items may not be removed through the ICollection interface. 
        /// 
        bool ICollection.Remove(T value) {
            throw new NotSupportedException();
        } 

 
        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 

        /// 
        /// Items may not be added, removed, or modified through the IList interface.
        ///  
        bool System.Collections.IList.IsFixedSize {
            get { return true; } 
        } 

        ///  
        /// Items may not be added, removed, or modified through the IList interface.
        /// 
        bool System.Collections.IList.IsReadOnly {
            get { return true; } 
        }
 
        ///  
        /// Return item at the specified index.
        ///  
        object System.Collections.IList.this[int index] {
            get {
                if (index >= this.size)
                    throw new ArgumentOutOfRangeException(); 

                return this.items[index]; 
            } 
            set { throw new NotSupportedException(); }
        } 

        /// 
        /// Items may not be added through the IList interface.
        ///  
        int System.Collections.IList.Add(object value) {
            throw new NotSupportedException(); 
        } 

        ///  
        /// Items may not be cleared through the IList interface.
        /// 
        void System.Collections.IList.Clear() {
            throw new NotSupportedException(); 
        }
 
        ///  
        /// Returns true if the specified value is in the sequence.
        ///  
        bool System.Collections.IList.Contains(object value) {
            return Contains((T) value);
        }
 
        /// 
        /// Returns the index of the specified value in the sequence. 
        ///  
        int System.Collections.IList.IndexOf(object value) {
            return IndexOf((T) value); 
        }

        /// 
        /// Items may not be added through the IList interface. 
        /// 
        void System.Collections.IList.Insert(int index, object value) { 
            throw new NotSupportedException(); 
        }
 
        /// 
        /// Items may not be removed through the IList interface.
        /// 
        void System.Collections.IList.Remove(object value) { 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void System.Collections.IList.RemoveAt(int index) {
            throw new NotSupportedException();
        } 

 
        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 

        /// 
        /// Return item at the specified index.
        ///  
        public T this[int index] {
            get { 
                if (index >= this.size) 
                    throw new ArgumentOutOfRangeException();
 
                return this.items[index];
            }
            set { throw new NotSupportedException(); }
        } 

        ///  
        /// Returns the index of the specified value in the sequence. 
        /// 
        public int IndexOf(T value) { 
            int index = Array.IndexOf(this.items, value);
            return (index < this.size) ? index : -1;
        }
 
        /// 
        /// Items may not be added through the IList interface. 
        ///  
        void IList.Insert(int index, T value) {
            throw new NotSupportedException(); 
        }

        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void IList.RemoveAt(int index) { 
            throw new NotSupportedException(); 
        }
 

        //-----------------------------------------------
        // XmlQuerySequence methods
        //----------------------------------------------- 

        ///  
        /// Clear the cache. 
        /// 
        public void Clear() { 
            this.size = 0;
            OnItemsChanged();
        }
 
        /// 
        /// Add an item to the sequence. 
        ///  
        public void Add(T value) {
            EnsureCache(); 
            this.items[this.size++] = value;
            OnItemsChanged();
        }
 
        /// 
        /// Sort the items in the cache using the keys contained in the provided array. 
        ///  
        public void SortByKeys(Array keys) {
            if (this.size <= 1) 
                return;

            Debug.Assert(keys.Length >= this.size, "Number of keys must be >= number of items.");
            Array.Sort(keys, this.items, 0, this.size); 
            OnItemsChanged();
        } 
 
        /// 
        /// Ensure that an array of the specified type is created and has room for at least one more item. 
        /// 
        private void EnsureCache() {
            T[] cacheNew;
 
            if (this.size >= this.items.Length) {
                cacheNew = new T[this.size * 2]; 
                CopyTo(cacheNew, 0); 
                this.items = cacheNew;
            } 
        }

        /// 
        /// This method is called when one or more items in the cache have been added or removed. 
        /// By default, it does nothing, but subclasses can override it.
        ///  
        protected virtual void OnItemsChanged() { 
        }
    } 

    /// 
    /// A sequence of Xml items that dynamically expands and allows random access to items.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public sealed class XmlQueryItemSequence : XmlQuerySequence { 
        public new static readonly XmlQueryItemSequence Empty = new XmlQueryItemSequence(); 

        ///  
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryItemSequence.
        /// 
        public static XmlQueryItemSequence CreateOrReuse(XmlQueryItemSequence seq) {
            if (seq != null) { 
                seq.Clear();
                return seq; 
            } 

            return new XmlQueryItemSequence(); 
        }

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryItemSequence. 
        /// Add "item" to the sequence.
        ///  
        public static XmlQueryItemSequence CreateOrReuse(XmlQueryItemSequence seq, XPathItem item) { 
            if (seq != null) {
                seq.Clear(); 
                seq.Add(item);
                return seq;
            }
 
            return new XmlQueryItemSequence(item);
        } 
 
        /// 
        /// Construct sequence from the specified array. 
        /// 
        public XmlQueryItemSequence() : base() {
        }
 
        /// 
        /// Construct sequence with the specified initial capacity. 
        ///  
        public XmlQueryItemSequence(int capacity) : base(capacity) {
        } 

        /// 
        /// Construct singleton sequence from a single item.
        ///  
        public XmlQueryItemSequence(XPathItem item) : base(1) {
            AddClone(item); 
        } 

        ///  
        /// Add an item to the sequence; clone the item before doing so if it's a navigator.
        /// 
        public void AddClone(XPathItem item) {
            if (item.IsNode) 
                Add(((XPathNavigator) item).Clone());
            else 
                Add(item); 
        }
    } 

    /// 
    /// A sequence of Xml nodes that dynamically expands and allows random access to items.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public sealed class XmlQueryNodeSequence : XmlQuerySequence, IList { 
        public new static readonly XmlQueryNodeSequence Empty = new XmlQueryNodeSequence(); 

        private XmlQueryNodeSequence docOrderDistinct; 

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryNodeSequence.
        ///  
        public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq) {
            if (seq != null) { 
                seq.Clear(); 
                return seq;
            } 

            return new XmlQueryNodeSequence();
        }
 
        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryNodeSequence. 
        /// Add "nav" to the sequence. 
        /// 
        public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq, XPathNavigator navigator) { 
            if (seq != null) {
                seq.Clear();
                seq.Add(navigator);
                return seq; 
            }
 
            return new XmlQueryNodeSequence(navigator); 
        }
 
        /// 
        /// Construct sequence with the specified initial capacity.
        /// 
        public XmlQueryNodeSequence() : base() { 
        }
 
        ///  
        /// Construct sequence from the specified array.
        ///  
        public XmlQueryNodeSequence(int capacity) : base(capacity) {
        }

        ///  
        /// Construct sequence from the specified array, cloning each navigator before adding it.
        ///  
        public XmlQueryNodeSequence(IList list) : base(list.Count) { 
            for (int idx = 0; idx < list.Count; idx++)
                AddClone(list[idx]); 
        }

        /// 
        /// Construct sequence from the specified array. 
        /// 
        public XmlQueryNodeSequence(XPathNavigator[] array, int size) : base(array, size) { 
        } 

        ///  
        /// Construct singleton sequence from a single navigator.
        /// 
        public XmlQueryNodeSequence(XPathNavigator navigator) : base(1) {
            AddClone(navigator); 
        }
 
        ///  
        /// If this property is true, then the nodes in this cache are already in document order with no duplicates.
        ///  
        public bool IsDocOrderDistinct {
            get { return (this.docOrderDistinct == this) || Count <= 1; }
            set {
    #if DEBUG 
                if (Count > 1) {
                    if (value) { 
                        for (int iNav = 0; iNav < Count - 1; iNav++) { 
                            XmlNodeOrder cmp = this[iNav].ComparePosition(this[iNav + 1]);
                            Debug.Assert(cmp == XmlNodeOrder.Before || cmp == XmlNodeOrder.Unknown); 
                        }
                    }
                }
    #endif 
                this.docOrderDistinct = value ? this : null;
            } 
        } 

        ///  
        /// Return a sequence which contains all distinct nodes in this cache, sorted by document order.
        /// 
        public XmlQueryNodeSequence DocOrderDistinct(IComparer comparer) {
            int iEach, iDistinct; 
            XPathNavigator[] sortArray;
 
            if (this.docOrderDistinct != null) 
                return this.docOrderDistinct;
 
            if (Count <= 1)
                return this;

            // Create a copy of this sequence 
            sortArray = new XPathNavigator[Count];
            for (iEach = 0; iEach < sortArray.Length; iEach++) 
                sortArray[iEach] = this[iEach]; 

            // Sort the navigators using a custom IComparer implementation that uses XPathNavigator.ComparePosition 
            Array.Sort(sortArray, 0, Count, comparer);

            iDistinct = 0;
            for (iEach = 1; iEach < sortArray.Length; iEach++) { 
                if (!sortArray[iDistinct].IsSamePosition(sortArray[iEach])) {
                    // Not a duplicate, so keep it in the cache 
                    iDistinct++; 

                    if (iDistinct != iEach) { 
                        // Fill in "hole" left by duplicate navigators
                        sortArray[iDistinct] = sortArray[iEach];
                    }
                } 
            }
 
            this.docOrderDistinct = new XmlQueryNodeSequence(sortArray, iDistinct + 1); 
            this.docOrderDistinct.docOrderDistinct = this.docOrderDistinct;
 
            return this.docOrderDistinct;
        }

        ///  
        /// Add a node to the sequence; clone the navigator before doing so.
        ///  
        public void AddClone(XPathNavigator navigator) { 
            Add(navigator.Clone());
        } 

        /// 
        /// If any items in the sequence change, then clear docOrderDistinct pointer as well.
        ///  
        protected override void OnItemsChanged() {
            this.docOrderDistinct = null; 
        } 

        //----------------------------------------------- 
        // IEnumerable implementation
        //-----------------------------------------------

        ///  
        /// Return IEnumerator implementation.
        ///  
        IEnumerator IEnumerable.GetEnumerator() { 
            return new IListEnumerator(this);
        } 

        //-----------------------------------------------
        // ICollection implementation
        //----------------------------------------------- 

        ///  
        /// Items may not be added, removed, or modified through the ICollection interface. 
        /// 
        bool ICollection.IsReadOnly { 
            get { return true; }
        }

        ///  
        /// Items may not be added through the ICollection interface.
        ///  
        void ICollection.Add(XPathItem value) { 
            throw new NotSupportedException();
        } 

        /// 
        /// Items may not be cleared through the ICollection interface.
        ///  
        void ICollection.Clear() {
            throw new NotSupportedException(); 
        } 

        ///  
        /// Returns true if the specified value is in the sequence.
        /// 
        bool ICollection.Contains(XPathItem value) {
            return IndexOf((XPathNavigator) value) != -1; 
        }
 
        ///  
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        ///  
        void ICollection.CopyTo(XPathItem[] array, int index) {
            for (int i = 0; i < Count; i++)
                array[index + i] = this[i];
        } 

        ///  
        /// Items may not be removed through the ICollection interface. 
        /// 
        bool ICollection.Remove(XPathItem value) { 
            throw new NotSupportedException();
        }

        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 
 
        /// 
        /// Return item at the specified index. 
        /// 
        XPathItem IList.this[int index] {
            get {
                if (index >= Count) 
                    throw new ArgumentOutOfRangeException();
 
                return base[index]; 
            }
            set { throw new NotSupportedException(); } 
        }

        /// 
        /// Returns the index of the specified value in the sequence. 
        /// 
        int IList.IndexOf(XPathItem value) { 
            return IndexOf((XPathNavigator) value); 
        }
 
        /// 
        /// Items may not be added through the IList interface.
        /// 
        void IList.Insert(int index, XPathItem value) { 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void IList.RemoveAt(int index) {
            throw new NotSupportedException();
        } 
    }
} 
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
using System; 
using System.Collections; 
using System.Collections.Generic;
using System.Xml; 
using System.IO;
using System.Text;
using System.Xml.Schema;
using System.Xml.Xsl; 
using System.Xml.XPath;
using System.Diagnostics; 
using System.ComponentModel; 

namespace System.Xml.Xsl.Runtime { 
    using Res           = System.Xml.Utils.Res;

    /// 
    /// A sequence of Xml values that dynamically expands and allows random access to items. 
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public class XmlQuerySequence : IList, System.Collections.IList { 
        public static readonly XmlQuerySequence Empty = new XmlQuerySequence();
 
        private static readonly Type XPathItemType = typeof(XPathItem);

        private T[] items;
        private int size; 

    #if DEBUG 
        private const int DefaultCacheSize = 2; 
    #else
        private const int DefaultCacheSize = 16; 
    #endif

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQuerySequence. 
        /// 
        public static XmlQuerySequence CreateOrReuse(XmlQuerySequence seq) { 
            if (seq != null) { 
                seq.Clear();
                return seq; 
            }

            return new XmlQuerySequence();
        } 

        ///  
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQuerySequence. 
        /// Add "item" to the sequence.
        ///  
        public static XmlQuerySequence CreateOrReuse(XmlQuerySequence seq, T item) {
            if (seq != null) {
                seq.Clear();
                seq.Add(item); 
                return seq;
            } 
 
            return new XmlQuerySequence(item);
        } 

        /// 
        /// Construct new sequence.
        ///  
        public XmlQuerySequence() {
            this.items = new T[DefaultCacheSize]; 
        } 

        ///  
        /// Construct new sequence.
        /// 
        public XmlQuerySequence(int capacity) {
            this.items = new T[capacity]; 
        }
 
        ///  
        /// Construct sequence from the specified array.
        ///  
        public XmlQuerySequence(T[] array, int size) {
            this.items = array;
            this.size = size;
        } 

        ///  
        /// Construct singleton sequence having "value" as its only element. 
        /// 
        public XmlQuerySequence(T value) { 
            this.items = new T[1];
            this.items[0] = value;
            this.size = 1;
        } 

 
        //----------------------------------------------- 
        // IEnumerable implementation
        //----------------------------------------------- 

        /// 
        /// Return IEnumerator implementation.
        ///  
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return new IListEnumerator(this); 
        } 

 
        //-----------------------------------------------
        // IEnumerable implementation
        //-----------------------------------------------
 
        /// 
        /// Return IEnumerator implementation. 
        ///  
        public IEnumerator GetEnumerator() {
            return new IListEnumerator(this); 
        }


        //----------------------------------------------- 
        // ICollection implementation
        //----------------------------------------------- 
 
        /// 
        /// Return the number of items in the sequence. 
        /// 
        public int Count {
            get { return this.size; }
        } 

        ///  
        /// The XmlQuerySequence is not thread-safe. 
        /// 
        bool System.Collections.ICollection.IsSynchronized { 
            get { return false; }
        }

        ///  
        /// This instance can be used to synchronize access.
        ///  
        object System.Collections.ICollection.SyncRoot { 
            get { return this; }
        } 

        /// 
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        ///  
        void System.Collections.ICollection.CopyTo(Array array, int index) {
            if (this.size == 0) 
                return; 

            Array.Copy(this.items, 0, array, index, this.size); 
        }


        //----------------------------------------------- 
        // ICollection implementation
        //----------------------------------------------- 
 
        /// 
        /// Items may not be added, removed, or modified through the ICollection interface. 
        /// 
        bool ICollection.IsReadOnly {
            get { return true; }
        } 

        ///  
        /// Items may not be added through the ICollection interface. 
        /// 
        void ICollection.Add(T value) { 
            throw new NotSupportedException();
        }

        ///  
        /// Items may not be cleared through the ICollection interface.
        ///  
        void ICollection.Clear() { 
            throw new NotSupportedException();
        } 

        /// 
        /// Returns true if the specified value is in the sequence.
        ///  
        public bool Contains(T value) {
            return IndexOf(value) != -1; 
        } 

        ///  
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        /// 
        public void CopyTo(T[] array, int index) {
            for (int i = 0; i < Count; i++) 
                array[index + i] = this[i];
        } 
 
        /// 
        /// Items may not be removed through the ICollection interface. 
        /// 
        bool ICollection.Remove(T value) {
            throw new NotSupportedException();
        } 

 
        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 

        /// 
        /// Items may not be added, removed, or modified through the IList interface.
        ///  
        bool System.Collections.IList.IsFixedSize {
            get { return true; } 
        } 

        ///  
        /// Items may not be added, removed, or modified through the IList interface.
        /// 
        bool System.Collections.IList.IsReadOnly {
            get { return true; } 
        }
 
        ///  
        /// Return item at the specified index.
        ///  
        object System.Collections.IList.this[int index] {
            get {
                if (index >= this.size)
                    throw new ArgumentOutOfRangeException(); 

                return this.items[index]; 
            } 
            set { throw new NotSupportedException(); }
        } 

        /// 
        /// Items may not be added through the IList interface.
        ///  
        int System.Collections.IList.Add(object value) {
            throw new NotSupportedException(); 
        } 

        ///  
        /// Items may not be cleared through the IList interface.
        /// 
        void System.Collections.IList.Clear() {
            throw new NotSupportedException(); 
        }
 
        ///  
        /// Returns true if the specified value is in the sequence.
        ///  
        bool System.Collections.IList.Contains(object value) {
            return Contains((T) value);
        }
 
        /// 
        /// Returns the index of the specified value in the sequence. 
        ///  
        int System.Collections.IList.IndexOf(object value) {
            return IndexOf((T) value); 
        }

        /// 
        /// Items may not be added through the IList interface. 
        /// 
        void System.Collections.IList.Insert(int index, object value) { 
            throw new NotSupportedException(); 
        }
 
        /// 
        /// Items may not be removed through the IList interface.
        /// 
        void System.Collections.IList.Remove(object value) { 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void System.Collections.IList.RemoveAt(int index) {
            throw new NotSupportedException();
        } 

 
        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 

        /// 
        /// Return item at the specified index.
        ///  
        public T this[int index] {
            get { 
                if (index >= this.size) 
                    throw new ArgumentOutOfRangeException();
 
                return this.items[index];
            }
            set { throw new NotSupportedException(); }
        } 

        ///  
        /// Returns the index of the specified value in the sequence. 
        /// 
        public int IndexOf(T value) { 
            int index = Array.IndexOf(this.items, value);
            return (index < this.size) ? index : -1;
        }
 
        /// 
        /// Items may not be added through the IList interface. 
        ///  
        void IList.Insert(int index, T value) {
            throw new NotSupportedException(); 
        }

        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void IList.RemoveAt(int index) { 
            throw new NotSupportedException(); 
        }
 

        //-----------------------------------------------
        // XmlQuerySequence methods
        //----------------------------------------------- 

        ///  
        /// Clear the cache. 
        /// 
        public void Clear() { 
            this.size = 0;
            OnItemsChanged();
        }
 
        /// 
        /// Add an item to the sequence. 
        ///  
        public void Add(T value) {
            EnsureCache(); 
            this.items[this.size++] = value;
            OnItemsChanged();
        }
 
        /// 
        /// Sort the items in the cache using the keys contained in the provided array. 
        ///  
        public void SortByKeys(Array keys) {
            if (this.size <= 1) 
                return;

            Debug.Assert(keys.Length >= this.size, "Number of keys must be >= number of items.");
            Array.Sort(keys, this.items, 0, this.size); 
            OnItemsChanged();
        } 
 
        /// 
        /// Ensure that an array of the specified type is created and has room for at least one more item. 
        /// 
        private void EnsureCache() {
            T[] cacheNew;
 
            if (this.size >= this.items.Length) {
                cacheNew = new T[this.size * 2]; 
                CopyTo(cacheNew, 0); 
                this.items = cacheNew;
            } 
        }

        /// 
        /// This method is called when one or more items in the cache have been added or removed. 
        /// By default, it does nothing, but subclasses can override it.
        ///  
        protected virtual void OnItemsChanged() { 
        }
    } 

    /// 
    /// A sequence of Xml items that dynamically expands and allows random access to items.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public sealed class XmlQueryItemSequence : XmlQuerySequence { 
        public new static readonly XmlQueryItemSequence Empty = new XmlQueryItemSequence(); 

        ///  
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryItemSequence.
        /// 
        public static XmlQueryItemSequence CreateOrReuse(XmlQueryItemSequence seq) {
            if (seq != null) { 
                seq.Clear();
                return seq; 
            } 

            return new XmlQueryItemSequence(); 
        }

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryItemSequence. 
        /// Add "item" to the sequence.
        ///  
        public static XmlQueryItemSequence CreateOrReuse(XmlQueryItemSequence seq, XPathItem item) { 
            if (seq != null) {
                seq.Clear(); 
                seq.Add(item);
                return seq;
            }
 
            return new XmlQueryItemSequence(item);
        } 
 
        /// 
        /// Construct sequence from the specified array. 
        /// 
        public XmlQueryItemSequence() : base() {
        }
 
        /// 
        /// Construct sequence with the specified initial capacity. 
        ///  
        public XmlQueryItemSequence(int capacity) : base(capacity) {
        } 

        /// 
        /// Construct singleton sequence from a single item.
        ///  
        public XmlQueryItemSequence(XPathItem item) : base(1) {
            AddClone(item); 
        } 

        ///  
        /// Add an item to the sequence; clone the item before doing so if it's a navigator.
        /// 
        public void AddClone(XPathItem item) {
            if (item.IsNode) 
                Add(((XPathNavigator) item).Clone());
            else 
                Add(item); 
        }
    } 

    /// 
    /// A sequence of Xml nodes that dynamically expands and allows random access to items.
    ///  
    [EditorBrowsable(EditorBrowsableState.Never)]
    public sealed class XmlQueryNodeSequence : XmlQuerySequence, IList { 
        public new static readonly XmlQueryNodeSequence Empty = new XmlQueryNodeSequence(); 

        private XmlQueryNodeSequence docOrderDistinct; 

        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryNodeSequence.
        ///  
        public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq) {
            if (seq != null) { 
                seq.Clear(); 
                return seq;
            } 

            return new XmlQueryNodeSequence();
        }
 
        /// 
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryNodeSequence. 
        /// Add "nav" to the sequence. 
        /// 
        public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq, XPathNavigator navigator) { 
            if (seq != null) {
                seq.Clear();
                seq.Add(navigator);
                return seq; 
            }
 
            return new XmlQueryNodeSequence(navigator); 
        }
 
        /// 
        /// Construct sequence with the specified initial capacity.
        /// 
        public XmlQueryNodeSequence() : base() { 
        }
 
        ///  
        /// Construct sequence from the specified array.
        ///  
        public XmlQueryNodeSequence(int capacity) : base(capacity) {
        }

        ///  
        /// Construct sequence from the specified array, cloning each navigator before adding it.
        ///  
        public XmlQueryNodeSequence(IList list) : base(list.Count) { 
            for (int idx = 0; idx < list.Count; idx++)
                AddClone(list[idx]); 
        }

        /// 
        /// Construct sequence from the specified array. 
        /// 
        public XmlQueryNodeSequence(XPathNavigator[] array, int size) : base(array, size) { 
        } 

        ///  
        /// Construct singleton sequence from a single navigator.
        /// 
        public XmlQueryNodeSequence(XPathNavigator navigator) : base(1) {
            AddClone(navigator); 
        }
 
        ///  
        /// If this property is true, then the nodes in this cache are already in document order with no duplicates.
        ///  
        public bool IsDocOrderDistinct {
            get { return (this.docOrderDistinct == this) || Count <= 1; }
            set {
    #if DEBUG 
                if (Count > 1) {
                    if (value) { 
                        for (int iNav = 0; iNav < Count - 1; iNav++) { 
                            XmlNodeOrder cmp = this[iNav].ComparePosition(this[iNav + 1]);
                            Debug.Assert(cmp == XmlNodeOrder.Before || cmp == XmlNodeOrder.Unknown); 
                        }
                    }
                }
    #endif 
                this.docOrderDistinct = value ? this : null;
            } 
        } 

        ///  
        /// Return a sequence which contains all distinct nodes in this cache, sorted by document order.
        /// 
        public XmlQueryNodeSequence DocOrderDistinct(IComparer comparer) {
            int iEach, iDistinct; 
            XPathNavigator[] sortArray;
 
            if (this.docOrderDistinct != null) 
                return this.docOrderDistinct;
 
            if (Count <= 1)
                return this;

            // Create a copy of this sequence 
            sortArray = new XPathNavigator[Count];
            for (iEach = 0; iEach < sortArray.Length; iEach++) 
                sortArray[iEach] = this[iEach]; 

            // Sort the navigators using a custom IComparer implementation that uses XPathNavigator.ComparePosition 
            Array.Sort(sortArray, 0, Count, comparer);

            iDistinct = 0;
            for (iEach = 1; iEach < sortArray.Length; iEach++) { 
                if (!sortArray[iDistinct].IsSamePosition(sortArray[iEach])) {
                    // Not a duplicate, so keep it in the cache 
                    iDistinct++; 

                    if (iDistinct != iEach) { 
                        // Fill in "hole" left by duplicate navigators
                        sortArray[iDistinct] = sortArray[iEach];
                    }
                } 
            }
 
            this.docOrderDistinct = new XmlQueryNodeSequence(sortArray, iDistinct + 1); 
            this.docOrderDistinct.docOrderDistinct = this.docOrderDistinct;
 
            return this.docOrderDistinct;
        }

        ///  
        /// Add a node to the sequence; clone the navigator before doing so.
        ///  
        public void AddClone(XPathNavigator navigator) { 
            Add(navigator.Clone());
        } 

        /// 
        /// If any items in the sequence change, then clear docOrderDistinct pointer as well.
        ///  
        protected override void OnItemsChanged() {
            this.docOrderDistinct = null; 
        } 

        //----------------------------------------------- 
        // IEnumerable implementation
        //-----------------------------------------------

        ///  
        /// Return IEnumerator implementation.
        ///  
        IEnumerator IEnumerable.GetEnumerator() { 
            return new IListEnumerator(this);
        } 

        //-----------------------------------------------
        // ICollection implementation
        //----------------------------------------------- 

        ///  
        /// Items may not be added, removed, or modified through the ICollection interface. 
        /// 
        bool ICollection.IsReadOnly { 
            get { return true; }
        }

        ///  
        /// Items may not be added through the ICollection interface.
        ///  
        void ICollection.Add(XPathItem value) { 
            throw new NotSupportedException();
        } 

        /// 
        /// Items may not be cleared through the ICollection interface.
        ///  
        void ICollection.Clear() {
            throw new NotSupportedException(); 
        } 

        ///  
        /// Returns true if the specified value is in the sequence.
        /// 
        bool ICollection.Contains(XPathItem value) {
            return IndexOf((XPathNavigator) value) != -1; 
        }
 
        ///  
        /// Copy contents of this sequence to the specified Array, starting at the specified index in the target array.
        ///  
        void ICollection.CopyTo(XPathItem[] array, int index) {
            for (int i = 0; i < Count; i++)
                array[index + i] = this[i];
        } 

        ///  
        /// Items may not be removed through the ICollection interface. 
        /// 
        bool ICollection.Remove(XPathItem value) { 
            throw new NotSupportedException();
        }

        //----------------------------------------------- 
        // IList implementation
        //----------------------------------------------- 
 
        /// 
        /// Return item at the specified index. 
        /// 
        XPathItem IList.this[int index] {
            get {
                if (index >= Count) 
                    throw new ArgumentOutOfRangeException();
 
                return base[index]; 
            }
            set { throw new NotSupportedException(); } 
        }

        /// 
        /// Returns the index of the specified value in the sequence. 
        /// 
        int IList.IndexOf(XPathItem value) { 
            return IndexOf((XPathNavigator) value); 
        }
 
        /// 
        /// Items may not be added through the IList interface.
        /// 
        void IList.Insert(int index, XPathItem value) { 
            throw new NotSupportedException();
        } 
 
        /// 
        /// Items may not be removed through the IList interface. 
        /// 
        void IList.RemoveAt(int index) {
            throw new NotSupportedException();
        } 
    }
} 
 

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