From 94f9c9e1534c1e22c5eebdc507bacd76527750d7 Mon Sep 17 00:00:00 2001 From: jbevain Date: Fri, 23 Apr 2010 12:57:34 +0000 Subject: [PATCH] cleol git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mcs@156004 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- .../Mono.Cecil/NameObjectCollectionBase.cs | 1300 ++++++++++---------- 1 file changed, 650 insertions(+), 650 deletions(-) diff --git a/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs b/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs index 5008cbd151..80b0c11d51 100644 --- a/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs +++ b/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs @@ -1,650 +1,650 @@ -using System; -using System.Collections; -using System.Runtime.Serialization; - -#if NO_SYSTEM_DLL -namespace System.Collections.Specialized -{ - [Serializable] - public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback - { - private Hashtable m_ItemsContainer; - /// - /// Extends Hashtable based Items container to support storing null-key pairs - /// - private _Item m_NullKeyItem; - private ArrayList m_ItemsArray; - private IHashCodeProvider m_hashprovider; - private IComparer m_comparer; - private int m_defCapacity; - private bool m_readonly; - SerializationInfo infoCopy; - private KeysCollection keyscoll; -#if NET_2_0 - private IEqualityComparer equality_comparer; - - internal IEqualityComparer EqualityComparer { - get { return equality_comparer; } - } -#endif - internal IComparer Comparer - { - get { return m_comparer; } - } - - internal IHashCodeProvider HashCodeProvider - { - get { return m_hashprovider; } - } - - internal class _Item - { - public string key; - public object value; - public _Item(string key, object value) - { - this.key = key; - this.value = value; - } - } - /// - /// Implements IEnumerable interface for KeysCollection - /// - [Serializable] - internal class _KeysEnumerator : IEnumerator - { - private NameObjectCollectionBase m_collection; - private int m_position; - - internal _KeysEnumerator(NameObjectCollectionBase collection) - { - m_collection = collection; - Reset(); - } - public object Current - { - - get - { - if ((m_position < m_collection.Count) || (m_position < 0)) - return m_collection.BaseGetKey(m_position); - else - throw new InvalidOperationException(); - } - - } - public bool MoveNext() - { - return ((++m_position) < m_collection.Count); - } - public void Reset() - { - m_position = -1; - } - } - - /// - /// SDK: Represents a collection of the String keys of a collection. - /// - [Serializable] - public class KeysCollection : ICollection, IEnumerable - { - private NameObjectCollectionBase m_collection; - - internal KeysCollection(NameObjectCollectionBase collection) - { - this.m_collection = collection; - } - - public virtual string Get(int index) - { - return m_collection.BaseGetKey(index); - } - - // ICollection methods ----------------------------------- - void ICollection.CopyTo(Array array, int arrayIndex) - { - ArrayList items = m_collection.m_ItemsArray; -#if NET_2_0 - if (null == array) - throw new ArgumentNullException ("array"); - - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException ("arrayIndex"); - - if ((array.Length > 0) && (arrayIndex >= array.Length)) - throw new ArgumentException ("arrayIndex is equal to or greater than array.Length"); - - if (arrayIndex + items.Count > array.Length) - throw new ArgumentException ("Not enough room from arrayIndex to end of array for this KeysCollection"); -#endif - - if (array != null && array.Rank > 1) - throw new ArgumentException("array is multidimensional"); - - object[] objArray = (object[])array; - for (int i = 0; i < items.Count; i++, arrayIndex++) - objArray[arrayIndex] = ((_Item)items[i]).key; - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - object ICollection.SyncRoot - { - get - { - return m_collection; - } - } - /// - /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection - /// - public int Count - { - get - { - return m_collection.Count; - } - } - - public string this[int index] - { - get { return Get(index); } - } - - // IEnumerable methods -------------------------------- - /// - /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection. - /// - /// - public IEnumerator GetEnumerator() - { - return new _KeysEnumerator(m_collection); - } - } - - //--------------- Protected Instance Constructors -------------- - - /// - /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty. - /// - protected NameObjectCollectionBase() - { - m_readonly = false; -#if NET_1_0 - m_hashprovider = CaseInsensitiveHashCodeProvider.Default; - m_comparer = CaseInsensitiveComparer.Default; -#else - m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; - m_comparer = CaseInsensitiveComparer.DefaultInvariant; -#endif - m_defCapacity = 0; - Init(); - } - - protected NameObjectCollectionBase(int capacity) - { - m_readonly = false; -#if NET_1_0 - m_hashprovider = CaseInsensitiveHashCodeProvider.Default; - m_comparer = CaseInsensitiveComparer.Default; -#else - m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; - m_comparer = CaseInsensitiveComparer.DefaultInvariant; -#endif - m_defCapacity = capacity; - Init(); - } - -#if NET_2_0 - - internal NameObjectCollectionBase (IEqualityComparer equalityComparer, IComparer comparer, IHashCodeProvider hcp) - { - equality_comparer = equalityComparer; - m_comparer = comparer; - m_hashprovider = hcp; - m_readonly = false; - m_defCapacity = 0; - Init (); - } - - protected NameObjectCollectionBase (IEqualityComparer equalityComparer) : this( (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer), null, null) - { - } - - [Obsolete ("Use NameObjectCollectionBase(IEqualityComparer)")] -#endif - protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) - { - m_comparer = comparer; - m_hashprovider = hashProvider; - m_readonly = false; - m_defCapacity = 0; - Init(); - } - - protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) - { - infoCopy = info; - } - -#if NET_2_0 - protected NameObjectCollectionBase (int capacity, IEqualityComparer equalityComparer) - { - m_readonly = false; - equality_comparer = (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer); - m_defCapacity = capacity; - Init(); - } - - [Obsolete ("Use NameObjectCollectionBase(int,IEqualityComparer)")] -#endif - protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) - { - m_readonly = false; - - m_hashprovider = hashProvider; - m_comparer = comparer; - m_defCapacity = capacity; - Init(); - } - - private void Init() - { -#if NET_2_0 - if (equality_comparer != null) - m_ItemsContainer = new Hashtable (m_defCapacity, equality_comparer); - else - m_ItemsContainer = new Hashtable (m_defCapacity, m_hashprovider, m_comparer); -#else - m_ItemsContainer = new Hashtable(m_defCapacity, m_hashprovider, m_comparer); -#endif - m_ItemsArray = new ArrayList(); - m_NullKeyItem = null; - } - - //--------------- Public Instance Properties ------------------- - - public virtual NameObjectCollectionBase.KeysCollection Keys - { - get - { - if (keyscoll == null) - keyscoll = new KeysCollection(this); - return keyscoll; - } - } - - //--------------- Public Instance Methods ---------------------- - // - /// - /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase. - /// - /// This enumerator returns the keys of the collection as strings. - /// - /// - public -#if NET_2_0 - virtual -#endif - IEnumerator GetEnumerator() - { - return new _KeysEnumerator(this); - } - - // ISerializable - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - throw new ArgumentNullException("info"); - - int count = Count; - string[] keys = new string[count]; - object[] values = new object[count]; - int i = 0; - foreach (_Item item in m_ItemsArray) - { - keys[i] = item.key; - values[i] = item.value; - i++; - } - -#if NET_2_0 - if (equality_comparer != null) { - info.AddValue ("KeyComparer", equality_comparer, typeof (IEqualityComparer)); - info.AddValue ("Version", 4, typeof (int)); - } else { - info.AddValue ("HashProvider", m_hashprovider, typeof (IHashCodeProvider)); - info.AddValue ("Comparer", m_comparer, typeof (IComparer)); - info.AddValue ("Version", 2, typeof (int)); - } -#else - info.AddValue("HashProvider", m_hashprovider, typeof(IHashCodeProvider)); - info.AddValue("Comparer", m_comparer, typeof(IComparer)); -#endif - info.AddValue("ReadOnly", m_readonly); - info.AddValue("Count", count); - info.AddValue("Keys", keys, typeof(string[])); - info.AddValue("Values", values, typeof(object[])); - } - - // ICollection - public virtual int Count - { - get - { - return m_ItemsArray.Count; - } - } - - bool ICollection.IsSynchronized - { - get { return false; } - } - - object ICollection.SyncRoot - { - get { return this; } - } - - void ICollection.CopyTo(Array array, int index) - { - ((ICollection)Keys).CopyTo(array, index); - } - - // IDeserializationCallback - public virtual void OnDeserialization(object sender) - { - SerializationInfo info = infoCopy; - - // If a subclass overrides the serialization constructor - // and inplements its own serialization process, infoCopy will - // be null and we can ignore this callback. - if (info == null) - return; - - infoCopy = null; - m_hashprovider = (IHashCodeProvider)info.GetValue("HashProvider", - typeof(IHashCodeProvider)); -#if NET_2_0 - if (m_hashprovider == null) { - equality_comparer = (IEqualityComparer) info.GetValue ("KeyComparer", typeof (IEqualityComparer)); - } else { - m_comparer = (IComparer) info.GetValue ("Comparer", typeof (IComparer)); - if (m_comparer == null) - throw new SerializationException ("The comparer is null"); - } -#else - if (m_hashprovider == null) - throw new SerializationException("The hash provider is null"); - - m_comparer = (IComparer)info.GetValue("Comparer", typeof(IComparer)); - if (m_comparer == null) - throw new SerializationException("The comparer is null"); -#endif - m_readonly = info.GetBoolean("ReadOnly"); - string[] keys = (string[])info.GetValue("Keys", typeof(string[])); - if (keys == null) - throw new SerializationException("keys is null"); - - object[] values = (object[])info.GetValue("Values", typeof(object[])); - if (values == null) - throw new SerializationException("values is null"); - - Init(); - int count = keys.Length; - for (int i = 0; i < count; i++) - BaseAdd(keys[i], values[i]); - } - - //--------------- Protected Instance Properties ---------------- - /// - /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only. - /// - protected bool IsReadOnly - { - get - { - return m_readonly; - } - set - { - m_readonly = value; - } - } - - //--------------- Protected Instance Methods ------------------- - /// - /// Adds an Item with the specified key and value into the NameObjectCollectionBase instance. - /// - /// - /// - protected void BaseAdd(string name, object value) - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - - _Item newitem = new _Item(name, value); - - if (name == null) - { - //todo: consider nullkey entry - if (m_NullKeyItem == null) - m_NullKeyItem = newitem; - } - else - if (m_ItemsContainer[name] == null) - { - m_ItemsContainer.Add(name, newitem); - } - m_ItemsArray.Add(newitem); - } - - protected void BaseClear() - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - Init(); - } - - /// - /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance. - /// - /// - /// - protected object BaseGet(int index) - { - return ((_Item)m_ItemsArray[index]).value; - } - - /// - /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance. - /// - /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. - /// - /// - protected object BaseGet(string name) - { - _Item item = FindFirstMatchedItem(name); - /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. - if (item == null) - return null; - else - return item.value; - } - - /// - /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance. - /// - /// A String array that contains all the keys in the NameObjectCollectionBase instance. - protected string[] BaseGetAllKeys() - { - int cnt = m_ItemsArray.Count; - string[] allKeys = new string[cnt]; - for (int i = 0; i < cnt; i++) - allKeys[i] = BaseGetKey(i);//((_Item)m_ItemsArray[i]).key; - - return allKeys; - } - - /// - /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance. - /// - /// An Object array that contains all the values in the NameObjectCollectionBase instance. - protected object[] BaseGetAllValues() - { - int cnt = m_ItemsArray.Count; - object[] allValues = new object[cnt]; - for (int i = 0; i < cnt; i++) - allValues[i] = BaseGet(i); - - return allValues; - } - - protected object[] BaseGetAllValues(Type type) - { - if (type == null) - throw new ArgumentNullException("'type' argument can't be null"); - int cnt = m_ItemsArray.Count; - object[] allValues = (object[])Array.CreateInstance(type, cnt); - for (int i = 0; i < cnt; i++) - allValues[i] = BaseGet(i); - - return allValues; - } - - protected string BaseGetKey(int index) - { - return ((_Item)m_ItemsArray[index]).key; - } - - /// - /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference - /// - /// true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false. - protected bool BaseHasKeys() - { - return (m_ItemsContainer.Count > 0); - } - - protected void BaseRemove(string name) - { - int cnt = 0; - String key; - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - if (name != null) - { - m_ItemsContainer.Remove(name); - } - else - { - m_NullKeyItem = null; - } - - cnt = m_ItemsArray.Count; - for (int i = 0; i < cnt; ) - { - key = BaseGetKey(i); - if (Equals(key, name)) - { - m_ItemsArray.RemoveAt(i); - cnt--; - } - else - i++; - } - } - - /// - /// - /// - /// - /// This function implemented the way Microsoft implemented it - - /// item is removed from hashtable and array without considering the case when there are two items with the same key but different values in array. - /// E.g. if - /// hashtable is [("Key1","value1")] and array contains [("Key1","value1")("Key1","value2")] then - /// after RemoveAt(1) the collection will be in following state: - /// hashtable:[] - /// array: [("Key1","value1")] - /// It's ok only then the key is uniquely assosiated with the value - /// To fix it a comparsion of objects stored under the same key in the hashtable and in the arraylist should be added - /// > - protected void BaseRemoveAt(int index) - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - string key = BaseGetKey(index); - if (key != null) - { - // TODO: see LAME description above - m_ItemsContainer.Remove(key); - } - else - m_NullKeyItem = null; - m_ItemsArray.RemoveAt(index); - } - - /// - /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance. - /// - /// - /// - protected void BaseSet(int index, object value) - { -#if NET_2_0 - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); -#endif - _Item item = (_Item)m_ItemsArray[index]; - item.value = value; - } - - /// - /// Sets the value of the first entry with the specified key in the NameObjectCollectionBase instance, if found; otherwise, adds an entry with the specified key and value into the NameObjectCollectionBase instance. - /// - /// The String key of the entry to set. The key can be a null reference - /// The Object that represents the new value of the entry to set. The value can be a null reference - protected void BaseSet(string name, object value) - { -#if NET_2_0 - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); -#endif - _Item item = FindFirstMatchedItem(name); - if (item != null) - item.value = value; - else - BaseAdd(name, value); - } - - private _Item FindFirstMatchedItem(string name) - { - if (name != null) - return (_Item)m_ItemsContainer[name]; - else - { - //TODO: consider null key case - return m_NullKeyItem; - } - } - - internal bool Equals(string s1, string s2) - { -#if NET_2_0 - if (m_comparer != null) - return (m_comparer.Compare (s1, s2) == 0); - else - return equality_comparer.Equals (s1, s2); -#else - return (m_comparer.Compare(s1, s2) == 0); -#endif - } - } -} -#endif +using System; +using System.Collections; +using System.Runtime.Serialization; + +#if NO_SYSTEM_DLL +namespace System.Collections.Specialized +{ + [Serializable] + public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback + { + private Hashtable m_ItemsContainer; + /// + /// Extends Hashtable based Items container to support storing null-key pairs + /// + private _Item m_NullKeyItem; + private ArrayList m_ItemsArray; + private IHashCodeProvider m_hashprovider; + private IComparer m_comparer; + private int m_defCapacity; + private bool m_readonly; + SerializationInfo infoCopy; + private KeysCollection keyscoll; +#if NET_2_0 + private IEqualityComparer equality_comparer; + + internal IEqualityComparer EqualityComparer { + get { return equality_comparer; } + } +#endif + internal IComparer Comparer + { + get { return m_comparer; } + } + + internal IHashCodeProvider HashCodeProvider + { + get { return m_hashprovider; } + } + + internal class _Item + { + public string key; + public object value; + public _Item(string key, object value) + { + this.key = key; + this.value = value; + } + } + /// + /// Implements IEnumerable interface for KeysCollection + /// + [Serializable] + internal class _KeysEnumerator : IEnumerator + { + private NameObjectCollectionBase m_collection; + private int m_position; + + internal _KeysEnumerator(NameObjectCollectionBase collection) + { + m_collection = collection; + Reset(); + } + public object Current + { + + get + { + if ((m_position < m_collection.Count) || (m_position < 0)) + return m_collection.BaseGetKey(m_position); + else + throw new InvalidOperationException(); + } + + } + public bool MoveNext() + { + return ((++m_position) < m_collection.Count); + } + public void Reset() + { + m_position = -1; + } + } + + /// + /// SDK: Represents a collection of the String keys of a collection. + /// + [Serializable] + public class KeysCollection : ICollection, IEnumerable + { + private NameObjectCollectionBase m_collection; + + internal KeysCollection(NameObjectCollectionBase collection) + { + this.m_collection = collection; + } + + public virtual string Get(int index) + { + return m_collection.BaseGetKey(index); + } + + // ICollection methods ----------------------------------- + void ICollection.CopyTo(Array array, int arrayIndex) + { + ArrayList items = m_collection.m_ItemsArray; +#if NET_2_0 + if (null == array) + throw new ArgumentNullException ("array"); + + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException ("arrayIndex"); + + if ((array.Length > 0) && (arrayIndex >= array.Length)) + throw new ArgumentException ("arrayIndex is equal to or greater than array.Length"); + + if (arrayIndex + items.Count > array.Length) + throw new ArgumentException ("Not enough room from arrayIndex to end of array for this KeysCollection"); +#endif + + if (array != null && array.Rank > 1) + throw new ArgumentException("array is multidimensional"); + + object[] objArray = (object[])array; + for (int i = 0; i < items.Count; i++, arrayIndex++) + objArray[arrayIndex] = ((_Item)items[i]).key; + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + object ICollection.SyncRoot + { + get + { + return m_collection; + } + } + /// + /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection + /// + public int Count + { + get + { + return m_collection.Count; + } + } + + public string this[int index] + { + get { return Get(index); } + } + + // IEnumerable methods -------------------------------- + /// + /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection. + /// + /// + public IEnumerator GetEnumerator() + { + return new _KeysEnumerator(m_collection); + } + } + + //--------------- Protected Instance Constructors -------------- + + /// + /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty. + /// + protected NameObjectCollectionBase() + { + m_readonly = false; +#if NET_1_0 + m_hashprovider = CaseInsensitiveHashCodeProvider.Default; + m_comparer = CaseInsensitiveComparer.Default; +#else + m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; + m_comparer = CaseInsensitiveComparer.DefaultInvariant; +#endif + m_defCapacity = 0; + Init(); + } + + protected NameObjectCollectionBase(int capacity) + { + m_readonly = false; +#if NET_1_0 + m_hashprovider = CaseInsensitiveHashCodeProvider.Default; + m_comparer = CaseInsensitiveComparer.Default; +#else + m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; + m_comparer = CaseInsensitiveComparer.DefaultInvariant; +#endif + m_defCapacity = capacity; + Init(); + } + +#if NET_2_0 + + internal NameObjectCollectionBase (IEqualityComparer equalityComparer, IComparer comparer, IHashCodeProvider hcp) + { + equality_comparer = equalityComparer; + m_comparer = comparer; + m_hashprovider = hcp; + m_readonly = false; + m_defCapacity = 0; + Init (); + } + + protected NameObjectCollectionBase (IEqualityComparer equalityComparer) : this( (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer), null, null) + { + } + + [Obsolete ("Use NameObjectCollectionBase(IEqualityComparer)")] +#endif + protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) + { + m_comparer = comparer; + m_hashprovider = hashProvider; + m_readonly = false; + m_defCapacity = 0; + Init(); + } + + protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) + { + infoCopy = info; + } + +#if NET_2_0 + protected NameObjectCollectionBase (int capacity, IEqualityComparer equalityComparer) + { + m_readonly = false; + equality_comparer = (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer); + m_defCapacity = capacity; + Init(); + } + + [Obsolete ("Use NameObjectCollectionBase(int,IEqualityComparer)")] +#endif + protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) + { + m_readonly = false; + + m_hashprovider = hashProvider; + m_comparer = comparer; + m_defCapacity = capacity; + Init(); + } + + private void Init() + { +#if NET_2_0 + if (equality_comparer != null) + m_ItemsContainer = new Hashtable (m_defCapacity, equality_comparer); + else + m_ItemsContainer = new Hashtable (m_defCapacity, m_hashprovider, m_comparer); +#else + m_ItemsContainer = new Hashtable(m_defCapacity, m_hashprovider, m_comparer); +#endif + m_ItemsArray = new ArrayList(); + m_NullKeyItem = null; + } + + //--------------- Public Instance Properties ------------------- + + public virtual NameObjectCollectionBase.KeysCollection Keys + { + get + { + if (keyscoll == null) + keyscoll = new KeysCollection(this); + return keyscoll; + } + } + + //--------------- Public Instance Methods ---------------------- + // + /// + /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase. + /// + /// This enumerator returns the keys of the collection as strings. + /// + /// + public +#if NET_2_0 + virtual +#endif + IEnumerator GetEnumerator() + { + return new _KeysEnumerator(this); + } + + // ISerializable + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + + int count = Count; + string[] keys = new string[count]; + object[] values = new object[count]; + int i = 0; + foreach (_Item item in m_ItemsArray) + { + keys[i] = item.key; + values[i] = item.value; + i++; + } + +#if NET_2_0 + if (equality_comparer != null) { + info.AddValue ("KeyComparer", equality_comparer, typeof (IEqualityComparer)); + info.AddValue ("Version", 4, typeof (int)); + } else { + info.AddValue ("HashProvider", m_hashprovider, typeof (IHashCodeProvider)); + info.AddValue ("Comparer", m_comparer, typeof (IComparer)); + info.AddValue ("Version", 2, typeof (int)); + } +#else + info.AddValue("HashProvider", m_hashprovider, typeof(IHashCodeProvider)); + info.AddValue("Comparer", m_comparer, typeof(IComparer)); +#endif + info.AddValue("ReadOnly", m_readonly); + info.AddValue("Count", count); + info.AddValue("Keys", keys, typeof(string[])); + info.AddValue("Values", values, typeof(object[])); + } + + // ICollection + public virtual int Count + { + get + { + return m_ItemsArray.Count; + } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return this; } + } + + void ICollection.CopyTo(Array array, int index) + { + ((ICollection)Keys).CopyTo(array, index); + } + + // IDeserializationCallback + public virtual void OnDeserialization(object sender) + { + SerializationInfo info = infoCopy; + + // If a subclass overrides the serialization constructor + // and inplements its own serialization process, infoCopy will + // be null and we can ignore this callback. + if (info == null) + return; + + infoCopy = null; + m_hashprovider = (IHashCodeProvider)info.GetValue("HashProvider", + typeof(IHashCodeProvider)); +#if NET_2_0 + if (m_hashprovider == null) { + equality_comparer = (IEqualityComparer) info.GetValue ("KeyComparer", typeof (IEqualityComparer)); + } else { + m_comparer = (IComparer) info.GetValue ("Comparer", typeof (IComparer)); + if (m_comparer == null) + throw new SerializationException ("The comparer is null"); + } +#else + if (m_hashprovider == null) + throw new SerializationException("The hash provider is null"); + + m_comparer = (IComparer)info.GetValue("Comparer", typeof(IComparer)); + if (m_comparer == null) + throw new SerializationException("The comparer is null"); +#endif + m_readonly = info.GetBoolean("ReadOnly"); + string[] keys = (string[])info.GetValue("Keys", typeof(string[])); + if (keys == null) + throw new SerializationException("keys is null"); + + object[] values = (object[])info.GetValue("Values", typeof(object[])); + if (values == null) + throw new SerializationException("values is null"); + + Init(); + int count = keys.Length; + for (int i = 0; i < count; i++) + BaseAdd(keys[i], values[i]); + } + + //--------------- Protected Instance Properties ---------------- + /// + /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only. + /// + protected bool IsReadOnly + { + get + { + return m_readonly; + } + set + { + m_readonly = value; + } + } + + //--------------- Protected Instance Methods ------------------- + /// + /// Adds an Item with the specified key and value into the NameObjectCollectionBase instance. + /// + /// + /// + protected void BaseAdd(string name, object value) + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + + _Item newitem = new _Item(name, value); + + if (name == null) + { + //todo: consider nullkey entry + if (m_NullKeyItem == null) + m_NullKeyItem = newitem; + } + else + if (m_ItemsContainer[name] == null) + { + m_ItemsContainer.Add(name, newitem); + } + m_ItemsArray.Add(newitem); + } + + protected void BaseClear() + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + Init(); + } + + /// + /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance. + /// + /// + /// + protected object BaseGet(int index) + { + return ((_Item)m_ItemsArray[index]).value; + } + + /// + /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance. + /// + /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. + /// + /// + protected object BaseGet(string name) + { + _Item item = FindFirstMatchedItem(name); + /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. + if (item == null) + return null; + else + return item.value; + } + + /// + /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance. + /// + /// A String array that contains all the keys in the NameObjectCollectionBase instance. + protected string[] BaseGetAllKeys() + { + int cnt = m_ItemsArray.Count; + string[] allKeys = new string[cnt]; + for (int i = 0; i < cnt; i++) + allKeys[i] = BaseGetKey(i);//((_Item)m_ItemsArray[i]).key; + + return allKeys; + } + + /// + /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance. + /// + /// An Object array that contains all the values in the NameObjectCollectionBase instance. + protected object[] BaseGetAllValues() + { + int cnt = m_ItemsArray.Count; + object[] allValues = new object[cnt]; + for (int i = 0; i < cnt; i++) + allValues[i] = BaseGet(i); + + return allValues; + } + + protected object[] BaseGetAllValues(Type type) + { + if (type == null) + throw new ArgumentNullException("'type' argument can't be null"); + int cnt = m_ItemsArray.Count; + object[] allValues = (object[])Array.CreateInstance(type, cnt); + for (int i = 0; i < cnt; i++) + allValues[i] = BaseGet(i); + + return allValues; + } + + protected string BaseGetKey(int index) + { + return ((_Item)m_ItemsArray[index]).key; + } + + /// + /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference + /// + /// true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false. + protected bool BaseHasKeys() + { + return (m_ItemsContainer.Count > 0); + } + + protected void BaseRemove(string name) + { + int cnt = 0; + String key; + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + if (name != null) + { + m_ItemsContainer.Remove(name); + } + else + { + m_NullKeyItem = null; + } + + cnt = m_ItemsArray.Count; + for (int i = 0; i < cnt; ) + { + key = BaseGetKey(i); + if (Equals(key, name)) + { + m_ItemsArray.RemoveAt(i); + cnt--; + } + else + i++; + } + } + + /// + /// + /// + /// + /// This function implemented the way Microsoft implemented it - + /// item is removed from hashtable and array without considering the case when there are two items with the same key but different values in array. + /// E.g. if + /// hashtable is [("Key1","value1")] and array contains [("Key1","value1")("Key1","value2")] then + /// after RemoveAt(1) the collection will be in following state: + /// hashtable:[] + /// array: [("Key1","value1")] + /// It's ok only then the key is uniquely assosiated with the value + /// To fix it a comparsion of objects stored under the same key in the hashtable and in the arraylist should be added + /// > + protected void BaseRemoveAt(int index) + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + string key = BaseGetKey(index); + if (key != null) + { + // TODO: see LAME description above + m_ItemsContainer.Remove(key); + } + else + m_NullKeyItem = null; + m_ItemsArray.RemoveAt(index); + } + + /// + /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance. + /// + /// + /// + protected void BaseSet(int index, object value) + { +#if NET_2_0 + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); +#endif + _Item item = (_Item)m_ItemsArray[index]; + item.value = value; + } + + /// + /// Sets the value of the first entry with the specified key in the NameObjectCollectionBase instance, if found; otherwise, adds an entry with the specified key and value into the NameObjectCollectionBase instance. + /// + /// The String key of the entry to set. The key can be a null reference + /// The Object that represents the new value of the entry to set. The value can be a null reference + protected void BaseSet(string name, object value) + { +#if NET_2_0 + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); +#endif + _Item item = FindFirstMatchedItem(name); + if (item != null) + item.value = value; + else + BaseAdd(name, value); + } + + private _Item FindFirstMatchedItem(string name) + { + if (name != null) + return (_Item)m_ItemsContainer[name]; + else + { + //TODO: consider null key case + return m_NullKeyItem; + } + } + + internal bool Equals(string s1, string s2) + { +#if NET_2_0 + if (m_comparer != null) + return (m_comparer.Compare (s1, s2) == 0); + else + return equality_comparer.Equals (s1, s2); +#else + return (m_comparer.Compare(s1, s2) == 0); +#endif + } + } +} +#endif -- 2.11.4.GIT