NameObjectCollectionBase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / CompMod / System / Collections / Specialized / NameObjectCollectionBase.cs / 1 / NameObjectCollectionBase.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Ordered String/Object collection of name/value pairs with support for null key 
 *
 * This class is intended to be used as a base class 
 *
 * Copyright (c) 2000 Microsoft Corporation
 */
 
namespace System.Collections.Specialized {
 
    using Microsoft.Win32; 
    using System.Collections;
    using System.Runtime.Serialization; 
    using System.Globalization;
    using System.Security.Permissions;

    ///  
    /// Provides the base class for a sorted collection of associated  keys
    ///    and  values that can be accessed either with the hash code of 
    ///    the key or with the index. 
    /// 
    [Serializable()] 
    public abstract class NameObjectCollectionBase : ICollection, ISerializable, IDeserializationCallback {
        // const names used for serialization
        private const String ReadOnlyName = "ReadOnly";
        private const String CountName = "Count"; 
        private const String ComparerName = "Comparer";
        private const String HashCodeProviderName = "HashProvider"; 
        private const String KeysName = "Keys"; 
        private const String ValuesName = "Values";
        private const String KeyComparerName = "KeyComparer"; 
        private const String VersionName = "Version";

        private bool _readOnly = false;
        private ArrayList _entriesArray; 
        private IEqualityComparer _keyComparer;
        private Hashtable _entriesTable; 
        private NameObjectEntry _nullKeyEntry; 
        private KeysCollection _keys;
        private SerializationInfo _serializationInfo; 
        private int _version;
        [NonSerialized]
        private Object _syncRoot;
 
        private static StringComparer defaultComparer = StringComparer.InvariantCultureIgnoreCase;
 
        ///  
        ///  Creates an empty  instance with the default initial capacity and using the default case-insensitive hash
        ///    code provider and the default case-insensitive comparer. 
        /// 
        protected NameObjectCollectionBase() :this(defaultComparer) {
        }
 
        protected NameObjectCollectionBase(IEqualityComparer equalityComparer)
        { 
           _keyComparer = (equalityComparer == null) ? defaultComparer : equalityComparer; 
           Reset();
        } 

        protected NameObjectCollectionBase(Int32 capacity, IEqualityComparer equalityComparer) : this (equalityComparer)
        {
            Reset(capacity); 
        }
 
 
        /// 
        /// Creates an empty  instance with 
        ///    the default initial capacity and using the specified case-insensitive hash code provider and the
        ///    specified case-insensitive comparer.
        /// 
 
#pragma warning disable 618
        [Obsolete("Please use NameObjectCollectionBase(IEqualityComparer) instead.")] 
        protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) { 
            _keyComparer = new CompatibleComparer( comparer, hashProvider);
            Reset(); 
        }
#pragma warning restore 618

        ///  
        /// Creates an empty  instance with the specified
        ///    initial capacity and using the specified case-insensitive hash code provider 
        ///    and the specified case-insensitive comparer. 
        /// 
#pragma warning disable 618 
        [Obsolete("Please use NameObjectCollectionBase(Int32, IEqualityComparer) instead.")]
        protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) {
            _keyComparer = new CompatibleComparer( comparer, hashProvider);
            Reset(capacity); 
        }
#pragma warning restore 618 
 
        /// 
        /// Creates an empty  instance with the specified 
        ///    initial capacity and using the default case-insensitive hash code provider
        ///    and the default case-insensitive comparer.
        /// 
        protected NameObjectCollectionBase(int capacity) { 
            _keyComparer = StringComparer.InvariantCultureIgnoreCase;
            Reset(capacity); 
        } 

        // Allow internal extenders to avoid creating the hashtable/arraylist. 
        internal NameObjectCollectionBase(DBNull dummy)
        {
        }
 
        //
        // Serialization support 
        // 

        ///  
        ///    [To be supplied.]
        /// 
        protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) {
            _serializationInfo = info; 
        }
 
        ///  
        ///    [To be supplied.]
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)] 		
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
            if (info == null)
                throw new ArgumentNullException("info"); 

            info.AddValue(ReadOnlyName, _readOnly); 
 
#pragma warning disable 618
            // Maintain backward serialization compatibility if new APIs are not used. 
            if( _keyComparer == defaultComparer) {
                info.AddValue(HashCodeProviderName, CompatibleComparer.DefaultHashCodeProvider, typeof(IHashCodeProvider));
                info.AddValue(ComparerName, CompatibleComparer.DefaultComparer, typeof(IComparer));
            } 
            else if(_keyComparer == null) {
                info.AddValue(HashCodeProviderName, null, typeof(IHashCodeProvider)); 
                info.AddValue(ComparerName, null, typeof(IComparer)); 
            }
            else if(_keyComparer is CompatibleComparer) { 
                CompatibleComparer c = (CompatibleComparer)_keyComparer;
                info.AddValue(HashCodeProviderName, c.HashCodeProvider, typeof(IHashCodeProvider));
                info.AddValue(ComparerName, c.Comparer, typeof(IComparer));
            } 
            else {
                info.AddValue(KeyComparerName, _keyComparer, typeof(IEqualityComparer)); 
            } 
#pragma warning restore 618
 
            int count = _entriesArray.Count;
            info.AddValue(CountName, count);

            String[] keys = new String[count]; 
            Object[] values = new Object[count];
 
            for (int i = 0; i < count; i++) { 
                NameObjectEntry entry = (NameObjectEntry)_entriesArray[i];
                keys[i] = entry.Key; 
                values[i] = entry.Value;
            }

            info.AddValue(KeysName, keys, typeof(String[])); 
            info.AddValue(ValuesName, values, typeof(Object[]));
            info.AddValue(VersionName, _version); 
        } 

        ///  
        ///    [To be supplied.]
        /// 
        public virtual void OnDeserialization(Object sender) {
            if (_keyComparer != null) { 
                return;//Somebody had a dependency on this hashtable and fixed us up before the ObjectManager got to it.
            } 
 
            if (_serializationInfo == null)
                throw new SerializationException(); 

            SerializationInfo info = _serializationInfo;
            _serializationInfo = null;
 
            bool readOnly = false;
            int count = 0; 
            String[] keys = null; 
            Object[] values = null;
#pragma warning disable 618 
            IHashCodeProvider hashProvider = null;
#pragma warning restore 618
            IComparer comparer = null;
            bool hasVersion = false; 
            int serializedVersion = 0;
 
            SerializationInfoEnumerator enumerator = info.GetEnumerator(); 
            while( enumerator.MoveNext())
            { 
                switch( enumerator.Name)
                {
                    case ReadOnlyName:
                        readOnly = info.GetBoolean(ReadOnlyName);; 
                        break;
                    case HashCodeProviderName: 
#pragma warning disable 618 
                        hashProvider = (IHashCodeProvider)info.GetValue(HashCodeProviderName, typeof(IHashCodeProvider));;
#pragma warning restore 618 
                        break;
                    case ComparerName:
                        comparer = (IComparer)info.GetValue(ComparerName, typeof(IComparer));
                        break; 
                    case KeyComparerName:
                        _keyComparer = (IEqualityComparer)info.GetValue(KeyComparerName, typeof(IEqualityComparer)); 
                        break; 
                    case CountName:
                        count = info.GetInt32(CountName); 
                        break;
                    case KeysName:
                        keys = (String[])info.GetValue(KeysName, typeof(String[]));
                        break; 
                    case ValuesName:
                        values = (Object[])info.GetValue(ValuesName, typeof(Object[])); 
                        break; 
                    case VersionName:
                        hasVersion = true; 
                        serializedVersion = info.GetInt32(VersionName);
                        break;
                }
            } 

            if( _keyComparer == null) { 
                if(comparer == null || hashProvider == null) 
                {
                    throw new SerializationException(); 
                }
                else {
                    // create a new key comparer for V1 Object
                    _keyComparer = new CompatibleComparer(comparer, hashProvider); 
                }
            } 
 
            if ( keys == null || values == null)
                throw new SerializationException(); 

            Reset(count);

            for (int i = 0; i < count; i++) 
                BaseAdd(keys[i], values[i]);
 
            _readOnly = readOnly;  // after collection populated 
            if(hasVersion) {
                _version = serializedVersion; 
            }
        }

        // 
        // Private helpers
        // 
 
        private void Reset() {
            _entriesArray = new ArrayList(); 
            _entriesTable = new Hashtable(_keyComparer);
            _nullKeyEntry = null;
            _version++;
        } 

        private void Reset(int capacity) { 
            _entriesArray = new ArrayList(capacity); 
            _entriesTable = new Hashtable(capacity, _keyComparer);
            _nullKeyEntry = null; 
            _version++;
        }

        private NameObjectEntry FindEntry(String key) { 
            if (key != null)
                return (NameObjectEntry)_entriesTable[key]; 
            else 
                return _nullKeyEntry;
        } 

        internal IEqualityComparer Comparer
        {
            get 
            {
                return _keyComparer; 
            } 
            set
            { 
                _keyComparer = value;
            }

        } 

 
        ///  
        /// Gets or sets a value indicating whether the  instance is read-only.
        ///  
        protected bool IsReadOnly {
            get { return _readOnly; }
            set { _readOnly = value; }
        } 

        ///  
        /// Gets a value indicating whether the  instance contains entries whose 
        ///    keys are not .
        ///  
        protected bool BaseHasKeys() {
            return (_entriesTable.Count > 0);  // any entries with keys?
        }
 
        //
        // Methods to add / remove entries 
        // 

        ///  
        ///    Adds an entry with the specified key and value into the
        ///     instance.
        /// 
        protected void BaseAdd(String name, Object value) { 
            if (_readOnly)
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly)); 
 
            NameObjectEntry entry = new NameObjectEntry(name, value);
 
            // insert entry into hashtable
            if (name != null) {
                if (_entriesTable[name] == null)
                    _entriesTable.Add(name, entry); 
            }
            else { // null key -- special case -- hashtable doesn't like null keys 
                if (_nullKeyEntry == null) 
                    _nullKeyEntry = entry;
            } 

            // add entry to the list
            _entriesArray.Add(entry);
 
            _version++;
        } 
 
        /// 
        ///    Removes the entries with the specified key from the 
        ///     instance.
        /// 
        protected void BaseRemove(String name) {
            if (_readOnly) 
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly));
 
            if (name != null) { 
                // remove from hashtable
                _entriesTable.Remove(name); 

                // remove from array
                for (int i = _entriesArray.Count-1; i >= 0; i--) {
                    if (_keyComparer.Equals(name, BaseGetKey(i))) 
                        _entriesArray.RemoveAt(i);
                } 
            } 
            else { // null key -- special case
                // null out special 'null key' entry 
                _nullKeyEntry = null;

                // remove from array
                for (int i = _entriesArray.Count-1; i >= 0; i--) { 
                    if (BaseGetKey(i) == null)
                        _entriesArray.RemoveAt(i); 
                } 
            }
 
            _version++;
        }

        ///  
        ///     Removes the entry at the specified index of the
        ///     instance. 
        ///  
        protected void BaseRemoveAt(int index) {
            if (_readOnly) 
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly));

            String key = BaseGetKey(index);
 
            if (key != null) {
                // remove from hashtable 
                _entriesTable.Remove(key); 
            }
            else { // null key -- special case 
                // null out special 'null key' entry
                _nullKeyEntry = null;
            }
 
            // remove from array
            _entriesArray.RemoveAt(index); 
 
            _version++;
        } 

        /// 
        /// Removes all entries from the  instance.
        ///  
        protected void BaseClear() {
            if (_readOnly) 
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly)); 

            Reset(); 
        }

        //
        // Access by name 
        //
 
        ///  
        ///    Gets the value of the first entry with the specified key from
        ///       the  instance. 
        /// 
        protected Object BaseGet(String name) {
            NameObjectEntry e = FindEntry(name);
            return (e != null) ? e.Value : null; 
        }
 
        ///  
        /// Sets the value of the first entry with the specified key in the 
        /// instance, if found; otherwise, adds an entry with the specified key and value 
        /// into the 
        /// instance.
        /// 
        protected void BaseSet(String name, Object value) { 
            if (_readOnly)
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly)); 
 
            NameObjectEntry entry = FindEntry(name);
            if (entry != null) { 
                entry.Value = value;
                _version++;
            }
            else { 
                BaseAdd(name, value);
            } 
        } 

        // 
        // Access by index
        //

        ///  
        ///    Gets the value of the entry at the specified index of
        ///       the  instance. 
        ///  
        protected Object BaseGet(int index) {
            NameObjectEntry entry = (NameObjectEntry)_entriesArray[index]; 
            return entry.Value;
        }

        ///  
        ///    Gets the key of the entry at the specified index of the
        ///     
        ///    instance. 
        /// 
        protected String BaseGetKey(int index) { 
            NameObjectEntry entry = (NameObjectEntry)_entriesArray[index];
            return entry.Key;
        }
 
        /// 
        ///    Sets the value of the entry at the specified index of 
        ///       the  instance. 
        /// 
        protected void BaseSet(int index, Object value) { 
            if (_readOnly)
                throw new NotSupportedException(SR.GetString(SR.CollectionReadOnly));

            NameObjectEntry entry = (NameObjectEntry)_entriesArray[index]; 
            entry.Value = value;
            _version++; 
        } 

        // 
        // ICollection implementation
        //

        ///  
        /// Returns an enumerator that can iterate through the .
        ///  
        public virtual IEnumerator GetEnumerator() { 
            return new NameObjectKeysEnumerator(this);
        } 

        /// 
        /// Gets the number of key-and-value pairs in the  instance.
        ///  
        public virtual int Count {
            get { 
                return _entriesArray.Count; 
            }
        } 

        void ICollection.CopyTo(Array array, int index) {
            if (array==null) {
                throw new ArgumentNullException("array"); 
            }
 
            if (array.Rank != 1) { 
                throw new ArgumentException(SR.GetString(SR.Arg_MultiRank));
            } 

            if (index < 0) {
                throw new ArgumentOutOfRangeException("index",SR.GetString(SR.IndexOutOfRange, index.ToString(CultureInfo.CurrentCulture)) );
            } 

            if (array.Length - index < _entriesArray.Count) { 
                throw new ArgumentException(SR.GetString(SR.Arg_InsufficientSpace)); 
            }
 
            for (IEnumerator e = this.GetEnumerator(); e.MoveNext();)
                array.SetValue(e.Current, index++);
        }
 
        Object ICollection.SyncRoot {
            get { 
                if( _syncRoot == null) { 
                    System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null);
                } 
                return _syncRoot;
            }
        }
 
        bool ICollection.IsSynchronized {
            get { return false; } 
        } 

        // 
        //  Helper methods to get arrays of keys and values
        //

        ///  
        /// Returns a  array containing all the keys in the
        ///  instance. 
        ///  
        protected String[] BaseGetAllKeys() {
            int n = _entriesArray.Count; 
            String[] allKeys = new String[n];

            for (int i = 0; i < n; i++)
                allKeys[i] = BaseGetKey(i); 

            return allKeys; 
        } 

        ///  
        /// Returns an  array containing all the values in the
        ///  instance.
        /// 
        protected Object[] BaseGetAllValues() { 
            int n = _entriesArray.Count;
            Object[] allValues = new Object[n]; 
 
            for (int i = 0; i < n; i++)
                allValues[i] = BaseGet(i); 

            return allValues;
        }
 
        /// 
        ///    Returns an array of the specified type containing 
        ///       all the values in the  instance. 
        /// 
        protected object[] BaseGetAllValues(Type type) { 
            int n = _entriesArray.Count;
            object[] allValues = (object[]) Array.CreateInstance(type, n);

            for (int i = 0; i < n; i++) { 
                allValues[i] = BaseGet(i);
            } 
 
            return allValues;
        } 

        //
        // Keys propetry
        // 

        ///  
        /// Returns a  instance containing 
        ///    all the keys in the  instance.
        ///  
        public virtual KeysCollection Keys {
            get {
                if (_keys == null)
                    _keys = new KeysCollection(this); 
                return _keys;
            } 
        } 

        // 
        // Simple entry class to allow substitution of values and indexed access to keys
        //

        internal class NameObjectEntry { 

            internal NameObjectEntry(String name, Object value) { 
                Key = name; 
                Value = value;
            } 

            internal String Key;
            internal Object Value;
        } 

        // 
        // Enumerator over keys of NameObjectCollection 
        //
 
        [Serializable()]
        internal class NameObjectKeysEnumerator : IEnumerator {
            private int _pos;
            private NameObjectCollectionBase _coll; 
            private int _version;
 
            internal NameObjectKeysEnumerator(NameObjectCollectionBase coll) { 
                _coll = coll;
                _version = _coll._version; 
                _pos = -1;
            }

            public bool MoveNext() { 
                if ( _version != _coll._version)
                    throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumFailedVersion)); 
 
                if( _pos < _coll.Count - 1) {
                    _pos++; 
                    return true;
                }
                else {
                    _pos = _coll.Count; 
                    return false;
                } 
 
            }
 
            public void Reset() {
                if (_version != _coll._version)
                    throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumFailedVersion));
                _pos = -1; 
            }
 
            public Object Current { 
                get {
                    if(_pos >= 0 && _pos < _coll.Count) { 
                        return _coll.BaseGetKey(_pos);
                    }
                    else {
                        throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_EnumOpCantHappen)); 
                    }
                } 
            } 
        }
 
        //
        // Keys collection
        //
 
        /// 
        /// Represents a collection of the  keys of a collection. 
        ///  
        [Serializable()]
        public class KeysCollection : ICollection { 

            private NameObjectCollectionBase _coll;

            internal KeysCollection(NameObjectCollectionBase coll) { 
                _coll = coll;
            } 
 
            // Indexed access
 
            /// 
            ///     Gets the key at the specified index of the collection.
            /// 
            public virtual String Get(int index) { 
                return _coll.BaseGetKey(index);
            } 
 
            /// 
            ///    Represents the entry at the specified index of the collection. 
            /// 
            public String this[int index] {
                get {
                    return Get(index); 
                }
            } 
 
            // ICollection implementation
 
            /// 
            ///    Returns an enumerator that can iterate through the
            ///    .
            ///  
            public IEnumerator GetEnumerator() {
                return new NameObjectKeysEnumerator(_coll); 
            } 

            ///  
            /// Gets the number of keys in the .
            /// 
            public int Count {
                get { 
                    return _coll.Count;
                } 
            } 

            void ICollection.CopyTo(Array array, int index) { 
                if (array==null) {
                    throw new ArgumentNullException("array");
                }
 
                if (array.Rank != 1) {
                    throw new ArgumentException(SR.GetString(SR.Arg_MultiRank)); 
                } 

                if (index < 0) { 
                    throw new ArgumentOutOfRangeException("index",SR.GetString(SR.IndexOutOfRange, index.ToString(CultureInfo.CurrentCulture)) );
                }

                if (array.Length - index < _coll.Count) { 
                    throw new ArgumentException(SR.GetString(SR.Arg_InsufficientSpace));
                } 
 
                for (IEnumerator e = this.GetEnumerator(); e.MoveNext();)
                    array.SetValue(e.Current, index++); 
            }

            Object ICollection.SyncRoot {
                get { return ((ICollection)_coll).SyncRoot; } 
            }
 
 
            bool ICollection.IsSynchronized {
                get { return false; } 
            }
        }
    }
 
    [Serializable()]
    internal class CompatibleComparer: IEqualityComparer  { 
        IComparer _comparer; 
        static IComparer defaultComparer;
        // Needed for compatability 
#pragma warning disable 618
        IHashCodeProvider _hcp;

        static IHashCodeProvider defaultHashProvider; 

        internal CompatibleComparer(IComparer comparer, IHashCodeProvider hashCodeProvider) { 
            _comparer = comparer; 
            _hcp = hashCodeProvider;
        } 
#pragma warning restore 618

        public new bool Equals(Object a, Object b) {
            if (a == b) return true; 
            if (a == null || b == null) return false;
 
            // We must call Compare or CompareTo method 
            // to make sure everything is fine, but the
            // guideline is that Equals should never throw. 
            // So we need to catch ArgumentException (note this
            // is the exception we should get if two objects are not
            // comparable.)
 
            try {
                if (_comparer != null) 
                    return (_comparer.Compare(a,b) == 0); 

                IComparable ia = a as IComparable; 
                if (ia != null)
                    return (ia.CompareTo(b) ==0);
            }
            catch(ArgumentException) { 
                return false;
            } 
 
            return a.Equals(b);
        } 

        public int GetHashCode(Object obj) {
            if( obj == null) {
                throw new ArgumentNullException("obj"); 
            }
 
            if (_hcp != null) 
                return _hcp.GetHashCode(obj);
            return obj.GetHashCode(); 
        }

        public IComparer Comparer {
            get { 
                return _comparer;
            } 
        } 

#pragma warning disable 618 
        public IHashCodeProvider HashCodeProvider {
            get {
                return _hcp;
            } 
        }
#pragma warning restore 618 
 
        public static IComparer DefaultComparer {
            get { 
                if( defaultComparer == null) {
                    defaultComparer = new CaseInsensitiveComparer(CultureInfo.InvariantCulture);
                }
                return defaultComparer; 
            }
        } 
 
#pragma warning disable 618
        public static IHashCodeProvider DefaultHashCodeProvider { 
            get {
                if( defaultHashProvider == null) {
                    defaultHashProvider = new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture);
                } 
                return defaultHashProvider;
            } 
        } 
#pragma warning restore 618
    } 
}


                        

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