// Authors:\r
// Lluis Sanchez Gual (lluis@novell.com)\r
//\r
-// (C) 2005 Novell, Inc (http://www.novell.com)\r
-//\r
-\r
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)\r
//\r
// Permission is hereby granted, free of charge, to any person obtaining\r
// a copy of this software and associated documentation files (the\r
\r
#if NET_2_0\r
\r
-using System;\r
using System.Runtime.Serialization;\r
-
+\r
namespace System.Collections.Specialized\r
{\r
[Serializable]\r
- public class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection, IEnumerable, ISerializable\r
+ public class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback\r
{\r
ArrayList list;\r
Hashtable hash;\r
- IKeyComparer comparer;\r
bool readOnly;\r
int initialCapacity;\r
+ SerializationInfo serializationInfo;\r
+ IEqualityComparer comparer;\r
\r
public OrderedDictionary ()\r
{\r
hash = new Hashtable ();\r
}\r
\r
- [MonoTODO ("Use Hashtable's key comparer constructor")]\r
- public OrderedDictionary (IKeyComparer comparer)\r
+ public OrderedDictionary (int capacity)\r
{\r
- this.comparer = comparer;\r
- list = new ArrayList ();\r
- hash = new Hashtable ();\r
-// hash = new Hashtable (comparer);\r
+ initialCapacity = (capacity < 0) ? 0 : capacity;\r
+ list = new ArrayList (initialCapacity);\r
+ hash = new Hashtable (initialCapacity);\r
}\r
\r
- public OrderedDictionary (int capacity)\r
+ public OrderedDictionary (IEqualityComparer equalityComparer)\r
{\r
- initialCapacity = capacity;\r
- list = new ArrayList (capacity);\r
- hash = new Hashtable (capacity);\r
+ list = new ArrayList ();\r
+ hash = new Hashtable (equalityComparer);\r
+ comparer = equalityComparer;\r
}\r
- \r
- [MonoTODO ("Use Hashtable's key comparer constructor")]\r
- public OrderedDictionary (int capacity, IKeyComparer comparer)\r
+\r
+ public OrderedDictionary (int capacity, IEqualityComparer equalityComparer)\r
{\r
- this.comparer = comparer;\r
- initialCapacity = capacity;\r
- list = new ArrayList (capacity);\r
- hash = new Hashtable (capacity);\r
-// hash = new Hashtable (capacity, comparer);\r
- \r
- this.comparer = comparer;\r
+ initialCapacity = (capacity < 0) ? 0 : capacity;\r
+ list = new ArrayList (initialCapacity);\r
+ hash = new Hashtable (initialCapacity, equalityComparer);\r
+ comparer = equalityComparer;\r
}\r
- \r
- public OrderedDictionary (SerializationInfo info, StreamingContext context)\r
+\r
+ protected OrderedDictionary (SerializationInfo info, StreamingContext context)\r
+ {\r
+ serializationInfo = info;\r
+ }\r
+\r
+ protected virtual void OnDeserialization (object sender)\r
{\r
- comparer = (IKeyComparer) info.GetValue ("KeyComparer", typeof(IKeyComparer));\r
- readOnly = info.GetBoolean ("ReadOnly");\r
- initialCapacity = info.GetInt32 ("InitialCapacity");\r
- hash = (Hashtable) info.GetValue ("HashTable", typeof(Hashtable));\r
- list = (ArrayList) info.GetValue ("ArrayList", typeof(ArrayList));\r
+ ((IDeserializationCallback) this).OnDeserialization (sender);\r
+ }\r
+\r
+ void IDeserializationCallback.OnDeserialization (object sender)\r
+ {\r
+ if (serializationInfo == null)\r
+ return;\r
+\r
+ comparer = (IEqualityComparer) serializationInfo.GetValue ("KeyComparer", typeof (IEqualityComparer));\r
+ readOnly = serializationInfo.GetBoolean ("ReadOnly");\r
+ initialCapacity = serializationInfo.GetInt32 ("InitialCapacity");\r
+\r
+ if (list == null)\r
+ list = new ArrayList ();\r
+ else\r
+ list.Clear ();\r
+\r
+ hash = new Hashtable (comparer);\r
+ object[] array = (object[]) serializationInfo.GetValue ("ArrayList", typeof(object[]));\r
+ foreach (DictionaryEntry de in array) {\r
+ hash.Add (de.Key, de.Value);\r
+ list.Add (de);\r
+ }\r
}\r
\r
public virtual void GetObjectData (SerializationInfo info, StreamingContext context)\r
{\r
- info.AddValue ("KeyComparer", comparer, typeof(IKeyComparer));\r
+ if (info == null)\r
+ throw new ArgumentNullException ("info");\r
+\r
+ info.AddValue ("KeyComparer", comparer, typeof (IEqualityComparer));\r
info.AddValue ("ReadOnly", readOnly);\r
info.AddValue ("InitialCapacity", initialCapacity);\r
- info.AddValue ("HashTable", hash);\r
- info.AddValue ("ArrayList", list);\r
+\r
+ object[] array = new object [hash.Count];\r
+ hash.CopyTo (array, 0);\r
+ info.AddValue ("ArrayList", array);\r
}\r
- \r
+\r
IEnumerator IEnumerable.GetEnumerator()\r
{\r
return list.GetEnumerator ();\r
return list.Count;\r
}\r
}\r
- \r
- public bool IsSynchronized {\r
+\r
+ bool ICollection.IsSynchronized {\r
get {\r
return list.IsSynchronized;\r
}\r
}\r
- \r
- public object SyncRoot {\r
+\r
+ object ICollection.SyncRoot {\r
get {\r
return list.SyncRoot;\r
}\r
{\r
list.CopyTo (array, index);\r
}\r
- \r
- public bool IsFixedSize\r
- {\r
+\r
+ bool IDictionary.IsFixedSize {\r
get {\r
return false;\r
}\r
}\r
\r
- public virtual bool IsReadOnly\r
+ public bool IsReadOnly\r
{\r
get {\r
return readOnly;\r
}\r
}\r
\r
- public virtual object this [object key]\r
+ public object this [object key]\r
{\r
get { return hash [key]; }\r
set {\r
WriteCheck ();\r
if (hash.Contains (key)) {\r
int i = FindListEntry (key);\r
- list [i] = value;\r
+ list [i] = new DictionaryEntry (key, value);\r
} else\r
list.Add (new DictionaryEntry (key, value));\r
\r
}\r
}\r
\r
- public virtual object this [int index]\r
+ public object this [int index]\r
{\r
get { return ((DictionaryEntry) list [index]).Value; }\r
set {\r
WriteCheck ();\r
DictionaryEntry de = (DictionaryEntry) list [index];\r
de.Value = value;\r
+ // update (even on the list) isn't automatic\r
+ list [index] = de;\r
+ hash [de.Key] = value;\r
}\r
}\r
\r
- public virtual ICollection Keys\r
+ public ICollection Keys\r
{\r
get {\r
return new OrderedCollection (list, true);\r
}\r
}\r
\r
- public virtual ICollection Values\r
+ public ICollection Values\r
{\r
get {\r
return new OrderedCollection (list, false);\r
{\r
WriteCheck ();\r
\r
- hash.Remove (key);\r
- int i = FindListEntry (key);\r
- list.RemoveAt (i);\r
+ if (hash.Contains (key)) {\r
+ hash.Remove (key);\r
+ int i = FindListEntry (key);\r
+ list.RemoveAt (i);\r
+ }\r
}\r
\r
int FindListEntry (object key)\r
{\r
- if (comparer != null) {\r
- for (int n=0; n<list.Count; n++) {\r
- DictionaryEntry de = (DictionaryEntry) list [n];\r
- if (comparer.Equals (de.Key, key))\r
- return n;\r
- }\r
- } else {\r
- for (int n=0; n<list.Count; n++) {\r
- DictionaryEntry de = (DictionaryEntry) list [n];\r
- if (de.Key.Equals (key))\r
- return n;\r
- }\r
+ for (int n=0; n<list.Count; n++) {\r
+ DictionaryEntry de = (DictionaryEntry) list [n];\r
+ if (comparer != null ? comparer.Equals(de.Key, key) : de.Key.Equals(key))\r
+ return n;\r
}\r
return -1;\r
}\r
void WriteCheck ()\r
{\r
if (readOnly)\r
- throw new InvalidOperationException ("Collection is read only");\r
+ throw new NotSupportedException ("Collection is read only");\r
}\r
\r
public OrderedDictionary AsReadOnly ()\r