// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
//
// (C) Ximian, Inc. http://www.ximian.com
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Collections.Specialized\r
-{\r
- [Serializable]\r
- public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback\r
- {\r
- private Hashtable m_ItemsContainer;\r
- /// <summary>\r
- /// Extends Hashtable based Items container to support storing null-key pairs\r
- /// </summary>\r
- private _Item m_NullKeyItem;\r
- private ArrayList m_ItemsArray;\r
- private IHashCodeProvider m_hashprovider;\r
- private IComparer m_comparer;\r
- private int m_defCapacity;\r
- private bool m_readonly;\r
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Runtime.Serialization;
+
+namespace System.Collections.Specialized
+{
+ [Serializable]
+ public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback
+ {
+ private Hashtable m_ItemsContainer;
+ /// <summary>
+ /// Extends Hashtable based Items container to support storing null-key pairs
+ /// </summary>
+ 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;
-\r
- internal IComparer Comparer {\r
- get {return m_comparer;}\r
- }\r
-\r
- internal IHashCodeProvider HashCodeProvider {\r
- get {return m_hashprovider;}\r
- }\r
-\r
- internal class _Item\r
- {\r
- public string key;\r
- public object value;\r
- public _Item(string key, object value)\r
- {\r
- this.key = key;\r
- this.value = value;\r
- }\r
- } \r
- /// <summary>\r
- /// Implements IEnumerable interface for KeysCollection\r
- /// </summary>\r
- [Serializable]\r
- internal class _KeysEnumerator : IEnumerator\r
- {\r
- private NameObjectCollectionBase m_collection;\r
- private int m_position;\r
- /*private*/internal _KeysEnumerator(NameObjectCollectionBase collection)\r
- {\r
- m_collection = collection;\r
- Reset();\r
- }\r
- public object Current \r
- {\r
- \r
- get{\r
- if ((m_position<m_collection.Count)||(m_position<0))\r
- return m_collection.BaseGetKey(m_position);\r
- else \r
- throw new InvalidOperationException();\r
- }\r
- \r
- }\r
- public bool MoveNext()\r
- {\r
- return ((++m_position)<m_collection.Count)?true:false;\r
- }\r
- public void Reset()\r
- {\r
- m_position = -1;\r
- }\r
- }\r
- \r
- /// <summary>\r
- /// SDK: Represents a collection of the String keys of a collection.\r
+ private KeysCollection keyscoll;
+ private IEqualityComparer equality_comparer;
+
+ internal IEqualityComparer EqualityComparer {
+ get { return equality_comparer; }
+ }
+
+ 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;
+ }
+ }
+ /// <summary>
+ /// Implements IEnumerable interface for KeysCollection
/// </summary>
- [Serializable]\r
- public class KeysCollection : ICollection, IEnumerable\r
- {\r
- private NameObjectCollectionBase m_collection;\r
-\r
- internal/*protected?*/ KeysCollection(NameObjectCollectionBase collection)\r
- {\r
- this.m_collection = collection;\r
- }\r
- public virtual string Get( int index )\r
- {\r
- return m_collection.BaseGetKey(index);\r
- //throw new Exception("Not implemented yet");\r
- }\r
- \r
- // ICollection methods -----------------------------------\r
- void ICollection.CopyTo(Array arr, int index)\r
- {\r
- if (arr==null)\r
- throw new ArgumentNullException("array can't be null");\r
- IEnumerator en = this.GetEnumerator();\r
- int i = index;\r
- while (en.MoveNext())\r
- {\r
- arr.SetValue(en.Current,i);\r
- i++;\r
- } \r
- }\r
-\r
- bool ICollection.IsSynchronized\r
- {\r
- get{\r
- return false;\r
- }\r
- }\r
- object ICollection.SyncRoot\r
- {\r
- get{\r
- return m_collection;\r
- }\r
- }\r
- /// <summary>\r
- /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection\r
- /// </summary>\r
- public int Count \r
- {\r
- get{\r
- return m_collection.Count;\r
- //throw new Exception("Not implemented yet");\r
- }\r
- }\r
-\r
- public string this [int index] {\r
- get { return Get (index); }\r
- }\r
-\r
- // IEnumerable methods --------------------------------\r
- /// <summary>\r
- /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection.\r
- /// </summary>\r
- /// <returns></returns>\r
- public IEnumerator GetEnumerator()\r
- {\r
- return new _KeysEnumerator(m_collection);\r
-// throw new Exception("Not implemented yet");\r
- }\r
- }\r
-\r
-\r
-\r
- //--------------- Protected Instance Constructors --------------\r
- \r
- /// <summary>\r
- /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty.\r
- /// </summary>\r
- [MonoTODO]\r
- protected NameObjectCollectionBase():base()\r
- {\r
- m_readonly = false;\r
- \r
- m_hashprovider = CaseInsensitiveHashCodeProvider.Default;\r
- m_comparer = CaseInsensitiveComparer.Default;\r
- m_defCapacity = 0;\r
- Init();\r
- /*m_ItemsContainer = new Hashtable(m_hashprovider,m_comparer);\r
- m_ItemsArray = new ArrayList();\r
- m_NullKeyItem = null;*/\r
- //TODO: consider common Reset() method\r
- }\r
- \r
- protected NameObjectCollectionBase( int capacity )\r
- {\r
- m_readonly = false;\r
- \r
- m_hashprovider = CaseInsensitiveHashCodeProvider.Default;\r
- m_comparer = CaseInsensitiveComparer.Default;\r
- m_defCapacity = capacity;\r
- Init();\r
- /*m_ItemsContainer = new Hashtable(m_defCapacity, m_hashprovider,m_comparer);\r
- m_ItemsArray = new ArrayList();\r
- m_NullKeyItem = null; */\r
- //throw new Exception("Not implemented yet");\r
- }\r
- protected NameObjectCollectionBase( IHashCodeProvider hashProvider, IComparer comparer )\r
- {\r
- m_readonly = false;\r
- \r
- m_hashprovider = hashProvider;\r
- m_comparer = comparer;\r
- m_defCapacity = 0;\r
- Init();\r
- /*m_ItemsContainer = new Hashtable(m_hashprovider,m_comparer);\r
- m_ItemsArray = new ArrayList();\r
- m_NullKeyItem = null; */\r
- //throw new Exception("Not implemented yet");\r
- }\r
+ [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;
+ }
+ }
+
+ /// <summary>
+ /// SDK: Represents a collection of the String keys of a collection.
+ /// </summary>
+ [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 (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");
+
+ 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;
+ }
+ }
+ /// <summary>
+ /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection
+ /// </summary>
+ public int Count
+ {
+ get{
+ return m_collection.Count;
+ }
+ }
+
+ public string this [int index] {
+ get { return Get (index); }
+ }
+
+ // IEnumerable methods --------------------------------
+ /// <summary>
+ /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection.
+ /// </summary>
+ /// <returns></returns>
+ public IEnumerator GetEnumerator()
+ {
+ return new _KeysEnumerator(m_collection);
+ }
+ }
+
+ //--------------- Protected Instance Constructors --------------
+
+ /// <summary>
+ /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty.
+ /// </summary>
+ protected NameObjectCollectionBase ()
+ {
+ m_readonly = false;
+ m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant;
+ m_comparer = CaseInsensitiveComparer.DefaultInvariant;
+ m_defCapacity = 0;
+ Init();
+ }
+
+ protected NameObjectCollectionBase( int capacity )
+ {
+ m_readonly = false;
+ m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant;
+ m_comparer = CaseInsensitiveComparer.DefaultInvariant;
+ m_defCapacity = capacity;
+ Init();
+ }
+
+ 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)")]
+ 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;
}
- protected NameObjectCollectionBase( int capacity, IHashCodeProvider hashProvider, IComparer comparer )\r
- {\r
- m_readonly = false;\r
- \r
- m_hashprovider = hashProvider;\r
- m_comparer = comparer;\r
- m_defCapacity = capacity;\r
- Init();\r
- /*m_ItemsContainer = new Hashtable(m_defCapacity,m_hashprovider,m_comparer);\r
- m_ItemsArray = new ArrayList();\r
- m_NullKeyItem = null; */\r
-\r
- //throw new Exception("Not implemented yet");\r
- }\r
- \r
- private void Init(){\r
- m_ItemsContainer = new Hashtable(m_defCapacity,m_hashprovider,m_comparer);\r
- m_ItemsArray = new ArrayList();\r
- m_NullKeyItem = null; \r
- }\r
- //--------------- Public Instance Properties -------------------\r
- public virtual NameObjectCollectionBase.KeysCollection Keys \r
- {\r
- get\r
- {\r
- return new KeysCollection(this);\r
- //throw new Exception("Not implemented yet");\r
- }\r
- }\r
- \r
- //--------------- Public Instance Methods ----------------------\r
- // \r
- /// <summary>\r
- /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.\r
- /// \r
- /// <remark>This enumerator returns the keys of the collection as strings.</remark>\r
- /// </summary>\r
- /// <returns></returns>\r
- public IEnumerator GetEnumerator()\r
- {\r
- return new _KeysEnumerator(this);\r
- }\r
- // GetHashCode\r
+ 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)")]
+ 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 (m_ItemsContainer != null) {
+ m_ItemsContainer.Clear ();
+ m_ItemsContainer = null;
+ }
+
+ if (m_ItemsArray != null) {
+ m_ItemsArray.Clear ();
+ m_ItemsArray = null;
+ }
+ if (equality_comparer != null)
+ m_ItemsContainer = new Hashtable (m_defCapacity, equality_comparer);
+ else
+ m_ItemsContainer = new Hashtable (m_defCapacity, m_hashprovider, m_comparer);
+ 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 ----------------------
+ //
+ /// <summary>
+ /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.
+ ///
+ /// <remark>This enumerator returns the keys of the collection as strings.</remark>
+ /// </summary>
+ /// <returns></returns>
+ public virtual IEnumerator GetEnumerator()
+ {
+ return new _KeysEnumerator(this);
+ }
// ISerializable
public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
i++;
}
- info.AddValue ("m_hashprovider", m_hashprovider);
- info.AddValue ("m_comparer", m_comparer);
- info.AddValue ("m_readonly", m_readonly);
- info.AddValue ("keys", keys);
- info.AddValue ("values", values);
- }
-
- // ICollection\r
- public virtual int Count \r
- {\r
- get{\r
- return m_ItemsArray.Count;\r
- //throw new Exception("Not implemented yet");\r
- }\r
- }\r
- bool ICollection.IsSynchronized\r
- {\r
- get { return false; }\r
- }\r
- object ICollection.SyncRoot\r
- {\r
- get { return this; }\r
- }\r
-\r
- void ICollection.CopyTo (Array array, int index)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
+ 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));
+ }
+ 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)
- throw new SerializationException ("The object is not a SerializationInfo");
+ return;
infoCopy = null;
- m_hashprovider = (IHashCodeProvider) info.GetValue ("m_hashprovider",
+ m_hashprovider = (IHashCodeProvider) info.GetValue ("HashProvider",
typeof (IHashCodeProvider));
-
- if (m_hashprovider == null)
- throw new SerializationException ("The hash provider is null");
-
- m_comparer = (IComparer) info.GetValue ("m_comparer", typeof (IComparer));
- if (m_comparer == null)
- throw new SerializationException ("The comparer is null");
-
- m_readonly = info.GetBoolean ("m_readonly");
- string [] keys = (string []) info.GetValue ("keys", typeof (string []));
+ 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");
+ }
+ 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 []));
+ object [] values = (object []) info.GetValue ("Values", typeof (object []));
if (values == null)
throw new SerializationException ("values is null");
for (int i = 0; i < count; i++)
BaseAdd (keys [i], values [i]);
}
- //--------------- Protected Instance Properties ----------------\r
- /// <summary>\r
- /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only.\r
- /// </summary>\r
- protected bool IsReadOnly \r
- {\r
- get{\r
- return m_readonly;\r
- }\r
- set{\r
- m_readonly=value;\r
- }\r
- }\r
- \r
- //--------------- Protected Instance Methods -------------------\r
- /// <summary>\r
- /// Adds an Item with the specified key and value into the <see cref="NameObjectCollectionBase"/>NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <param name="name"></param>\r
- /// <param name="value"></param>\r
- protected void BaseAdd( string name, object value )\r
- {\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- \r
- _Item newitem=new _Item(name, value);\r
-\r
- if (name==null){\r
- //todo: consider nullkey entry\r
- if (m_NullKeyItem==null)\r
- m_NullKeyItem = newitem;\r
- }\r
- else\r
- if (m_ItemsContainer[name]==null){\r
- m_ItemsContainer.Add(name,newitem);\r
- }\r
- m_ItemsArray.Add(newitem);\r
- }
-
- protected void BaseClear()\r
- {\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- Init();\r
- //throw new Exception("Not implemented yet");\r
- }\r
- /// <summary>\r
- /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <returns></returns>\r
- protected object BaseGet( int index )\r
- {\r
- return ((_Item)m_ItemsArray[index]).value;\r
- //throw new Exception("Not implemented yet");\r
- }\r
- /// <summary>\r
- /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <remark>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.</remark>\r
- /// <param name="name"></param>\r
- /// <returns></returns>\r
- protected object BaseGet( string name )\r
- {\r
- _Item item = FindFirstMatchedItem(name);\r
- /// 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.\r
- if (item==null)\r
- return null;\r
- else\r
- return item.value;\r
- }\r
-\r
- /// <summary>\r
- /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <returns>A String array that contains all the keys in the NameObjectCollectionBase instance.</returns>\r
- protected string[] BaseGetAllKeys()\r
- {\r
- int cnt = m_ItemsArray.Count;\r
- string[] allKeys = new string[cnt];\r
- for(int i=0; i<cnt; i++)\r
- allKeys[i] = BaseGetKey(i);//((_Item)m_ItemsArray[i]).key;\r
- \r
- return allKeys;\r
- }\r
-\r
- /// <summary>\r
- /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <returns>An Object array that contains all the values in the NameObjectCollectionBase instance.</returns>\r
- protected object[] BaseGetAllValues()\r
- {\r
- int cnt = m_ItemsArray.Count;\r
- object[] allValues = new object[cnt];\r
- for(int i=0; i<cnt; i++)\r
- allValues[i] = BaseGet(i);\r
- \r
- return allValues;\r
- }
-\r
- protected object[] BaseGetAllValues( Type type )\r
- {\r
- if (type == null)\r
- throw new ArgumentNullException("'type' argument can't be null");\r
- int cnt = m_ItemsArray.Count;\r
- object[] allValues = (object[]) Array.CreateInstance (type, cnt);\r
- for(int i=0; i<cnt; i++)\r
- allValues[i] = BaseGet(i);\r
- \r
- return allValues;\r
- }\r
- \r
- protected string BaseGetKey( int index )\r
- {\r
- return ((_Item)m_ItemsArray[index]).key;\r
- //throw new Exception("Not implemented yet");\r
- }\r
- /// <summary>\r
- /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference \r
- /// </summary>\r
- /// <returns>true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false.</returns>\r
- protected bool BaseHasKeys()\r
- {\r
- return (m_ItemsContainer.Count>0);\r
-// throw new Exception("Not implemented yet");\r
- }\r
-
- protected void BaseRemove( string name )\r
- {\r
- int cnt = 0;\r
- String key;\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- if (name!=null)\r
- {\r
- m_ItemsContainer.Remove(name);\r
- }\r
- else {\r
- m_NullKeyItem = null;\r
- }\r
- \r
- cnt = m_ItemsArray.Count;\r
- for (int i=0 ; i< cnt; ){\r
- key=BaseGetKey(i);\r
- if (m_comparer.Compare (key, name) == 0) {\r
- m_ItemsArray.RemoveAt(i);\r
- cnt--;\r
- }\r
- else \r
- i++;\r
- \r
- }\r
- }
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <LAME>This function implemented the way Microsoft implemented it - \r
- /// 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.\r
- /// E.g. if\r
- /// hashtable is [("Key1","value1")] and array contains [("Key1","value1")("Key1","value2")] then\r
- /// after RemoveAt(1) the collection will be in following state:\r
- /// hashtable:[] \r
- /// array: [("Key1","value1")] \r
- /// It's ok only then the key is uniquely assosiated with the value\r
- /// To fix it a comparsion of objects stored under the same key in the hashtable and in the arraylist should be added \r
- /// </LAME>>\r
- [MonoTODO]\r
- protected void BaseRemoveAt( int index )\r
- {\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- string key = BaseGetKey(index);\r
- if (key!=null){\r
- // TODO: see LAME description above\r
- m_ItemsContainer.Remove(key);\r
- }\r
- else\r
- m_NullKeyItem = null;\r
- m_ItemsArray.RemoveAt(index);\r
-// throw new Exception("Not implemented yet");\r
- }\r
- /// <summary>\r
- /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance.\r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <param name="value"></param>\r
- protected void BaseSet( int index, object value )\r
- {\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- _Item item = (_Item)m_ItemsArray[index];\r
- item.value = value;\r
- //throw new Exception("Not implemented yet");\r
- }\r
- /// <summary>\r
- /// 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.\r
- /// </summary>\r
- /// <param name="name">The String key of the entry to set. The key can be a null reference </param>\r
- /// <param name="value">The Object that represents the new value of the entry to set. The value can be a null reference</param>\r
- protected void BaseSet( string name, object value )\r
- {\r
- if (this.IsReadOnly)\r
- throw new NotSupportedException("Collection is read-only");\r
- _Item item = FindFirstMatchedItem(name);\r
- if (item!=null)\r
- item.value=value;\r
- else \r
- BaseAdd(name, value);\r
-\r
- //throw new Exception("Not implemented yet");\r
- }\r
- [MonoTODO]\r
- private _Item FindFirstMatchedItem(string name)\r
- {\r
- if (name!=null)\r
- return (_Item)m_ItemsContainer[name];\r
- else {\r
- //TODO: consider null key case\r
- return m_NullKeyItem;\r
- //throw new Exception("Not implemented yet");\r
- }\r
-\r
- }\r
- //~Object();\r
- \r
- }\r
-}\r
+
+ //--------------- Protected Instance Properties ----------------
+ /// <summary>
+ /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only.
+ /// </summary>
+ protected bool IsReadOnly
+ {
+ get{
+ return m_readonly;
+ }
+ set{
+ m_readonly=value;
+ }
+ }
+
+ //--------------- Protected Instance Methods -------------------
+ /// <summary>
+ /// Adds an Item with the specified key and value into the <see cref="NameObjectCollectionBase"/>NameObjectCollectionBase instance.
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="value"></param>
+ 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();
+ }
+
+ /// <summary>
+ /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance.
+ /// </summary>
+ /// <param name="index"></param>
+ /// <returns></returns>
+ protected object BaseGet( int index )
+ {
+ return ((_Item)m_ItemsArray[index]).value;
+ }
+
+ /// <summary>
+ /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance.
+ /// </summary>
+ /// <remark>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.</remark>
+ /// <param name="name"></param>
+ /// <returns></returns>
+ 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;
+ }
+
+ /// <summary>
+ /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance.
+ /// </summary>
+ /// <returns>A String array that contains all the keys in the NameObjectCollectionBase instance.</returns>
+ 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;
+ }
+
+ /// <summary>
+ /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance.
+ /// </summary>
+ /// <returns>An Object array that contains all the values in the NameObjectCollectionBase instance.</returns>
+ 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;
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference
+ /// </summary>
+ /// <returns>true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false.</returns>
+ 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++;
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="index"></param>
+ /// <LAME>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
+ /// </LAME>>
+ 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);
+ }
+
+ /// <summary>
+ /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance.
+ /// </summary>
+ /// <param name="index"></param>
+ /// <param name="value"></param>
+ protected void BaseSet( int index, object value )
+ {
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ _Item item = (_Item)m_ItemsArray[index];
+ item.value = value;
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="name">The String key of the entry to set. The key can be a null reference </param>
+ /// <param name="value">The Object that represents the new value of the entry to set. The value can be a null reference</param>
+ protected void BaseSet( string name, object value )
+ {
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ _Item item = FindFirstMatchedItem(name);
+ if (item!=null)
+ item.value=value;
+ else
+ BaseAdd(name, value);
+ }
+
+ [MonoTODO]
+ 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 (m_comparer != null)
+ return (m_comparer.Compare (s1, s2) == 0);
+ else
+ return equality_comparer.Equals (s1, s2);
+ }
+ }
+}