2 // System.Web.UI.WebControls.OrderedDictionary.cs
\r
5 // Lluis Sanchez Gual (lluis@novell.com)
\r
7 // (C) 2005 Novell, Inc (http://www.novell.com)
\r
11 // Permission is hereby granted, free of charge, to any person obtaining
\r
12 // a copy of this software and associated documentation files (the
\r
13 // "Software"), to deal in the Software without restriction, including
\r
14 // without limitation the rights to use, copy, modify, merge, publish,
\r
15 // distribute, sublicense, and/or sell copies of the Software, and to
\r
16 // permit persons to whom the Software is furnished to do so, subject to
\r
17 // the following conditions:
\r
19 // The above copyright notice and this permission notice shall be
\r
20 // included in all copies or substantial portions of the Software.
\r
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 using System.Runtime.Serialization;
\r
36 namespace System.Collections.Specialized
\r
39 public class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection, IEnumerable, ISerializable
\r
43 IKeyComparer comparer;
\r
45 int initialCapacity;
\r
47 public OrderedDictionary ()
\r
49 list = new ArrayList ();
\r
50 hash = new Hashtable ();
\r
53 [MonoTODO ("Use Hashtable's key comparer constructor")]
\r
54 public OrderedDictionary (IKeyComparer comparer)
\r
56 this.comparer = comparer;
\r
57 list = new ArrayList ();
\r
58 hash = new Hashtable ();
\r
59 // hash = new Hashtable (comparer);
\r
62 public OrderedDictionary (int capacity)
\r
64 initialCapacity = capacity;
\r
65 list = new ArrayList (capacity);
\r
66 hash = new Hashtable (capacity);
\r
69 [MonoTODO ("Use Hashtable's key comparer constructor")]
\r
70 public OrderedDictionary (int capacity, IKeyComparer comparer)
\r
72 this.comparer = comparer;
\r
73 initialCapacity = capacity;
\r
74 list = new ArrayList (capacity);
\r
75 hash = new Hashtable (capacity);
\r
76 // hash = new Hashtable (capacity, comparer);
\r
78 this.comparer = comparer;
\r
81 public OrderedDictionary (SerializationInfo info, StreamingContext context)
\r
83 comparer = (IKeyComparer) info.GetValue ("KeyComparer", typeof(IKeyComparer));
\r
84 readOnly = info.GetBoolean ("ReadOnly");
\r
85 initialCapacity = info.GetInt32 ("InitialCapacity");
\r
86 hash = (Hashtable) info.GetValue ("HashTable", typeof(Hashtable));
\r
87 list = (ArrayList) info.GetValue ("ArrayList", typeof(ArrayList));
\r
90 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
\r
92 info.AddValue ("KeyComparer", comparer, typeof(IKeyComparer));
\r
93 info.AddValue ("ReadOnly", readOnly);
\r
94 info.AddValue ("InitialCapacity", initialCapacity);
\r
95 info.AddValue ("HashTable", hash);
\r
96 info.AddValue ("ArrayList", list);
\r
99 IEnumerator IEnumerable.GetEnumerator()
\r
101 return list.GetEnumerator ();
\r
110 public bool IsSynchronized {
\r
112 return list.IsSynchronized;
\r
116 public object SyncRoot {
\r
118 return list.SyncRoot;
\r
122 public void CopyTo (Array array, int index)
\r
124 list.CopyTo (array, index);
\r
127 public bool IsFixedSize
\r
134 public virtual bool IsReadOnly
\r
141 public virtual object this [object key]
\r
143 get { return hash [key]; }
\r
146 if (hash.Contains (key)) {
\r
147 int i = FindListEntry (key);
\r
148 list [i] = new DictionaryEntry (key, value);
\r
150 list.Add (new DictionaryEntry (key, value));
\r
152 hash [key] = value;
\r
156 public virtual object this [int index]
\r
158 get { return ((DictionaryEntry) list [index]).Value; }
\r
161 DictionaryEntry de = (DictionaryEntry) list [index];
\r
166 public virtual ICollection Keys
\r
169 return new OrderedCollection (list, true);
\r
173 public virtual ICollection Values
\r
176 return new OrderedCollection (list, false);
\r
180 public void Add (object key, object value)
\r
183 hash.Add (key, value);
\r
184 list.Add (new DictionaryEntry (key, value));
\r
187 public void Clear()
\r
194 public bool Contains (object key)
\r
196 return hash.Contains (key);
\r
199 public virtual IDictionaryEnumerator GetEnumerator()
\r
201 return new OrderedEntryCollectionEnumerator (list.GetEnumerator ());
\r
204 public void Remove (object key)
\r
209 int i = FindListEntry (key);
\r
213 int FindListEntry (object key)
\r
215 if (comparer != null) {
\r
216 for (int n=0; n<list.Count; n++) {
\r
217 DictionaryEntry de = (DictionaryEntry) list [n];
\r
218 if (comparer.Equals (de.Key, key))
\r
222 for (int n=0; n<list.Count; n++) {
\r
223 DictionaryEntry de = (DictionaryEntry) list [n];
\r
224 if (de.Key.Equals (key))
\r
234 throw new InvalidOperationException ("Collection is read only");
\r
237 public OrderedDictionary AsReadOnly ()
\r
239 OrderedDictionary od = new OrderedDictionary ();
\r
242 od.comparer = comparer;
\r
243 od.readOnly = true;
\r
247 public void Insert (int index, object key, object value)
\r
250 hash.Add (key, value);
\r
251 list.Insert (index, new DictionaryEntry (key, value));
\r
254 public void RemoveAt (int index)
\r
257 DictionaryEntry entry = (DictionaryEntry) list [index];
\r
258 list.RemoveAt (index);
\r
259 hash.Remove (entry.Key);
\r
262 private class OrderedEntryCollectionEnumerator : IEnumerator, IDictionaryEnumerator
\r
264 IEnumerator listEnumerator;
\r
266 public OrderedEntryCollectionEnumerator (IEnumerator listEnumerator)
\r
268 this.listEnumerator = listEnumerator;
\r
271 public bool MoveNext()
\r
273 return listEnumerator.MoveNext ();
\r
276 public void Reset()
\r
278 listEnumerator.Reset ();
\r
281 public object Current
\r
283 get { return listEnumerator.Current; }
\r
286 public DictionaryEntry Entry
\r
288 get { return (DictionaryEntry) listEnumerator.Current; }
\r
293 get { return Entry.Key; }
\r
296 public object Value
\r
298 get { return Entry.Value; }
\r
302 private class OrderedCollection : ICollection
\r
304 private ArrayList list;
\r
305 private bool isKeyList;
\r
307 public OrderedCollection (ArrayList list, bool isKeyList)
\r
310 this.isKeyList = isKeyList;
\r
319 public bool IsSynchronized
\r
326 public object SyncRoot
\r
329 return list.SyncRoot;
\r
333 public void CopyTo (Array array, int index)
\r
335 for (int n=0; n<list.Count; n++) {
\r
336 DictionaryEntry de = (DictionaryEntry) list [n];
\r
337 if (isKeyList) array.SetValue (de.Key, index + n);
\r
338 else array.SetValue (de.Value, index + n);
\r
342 public IEnumerator GetEnumerator()
\r
344 return new OrderedCollectionEnumerator (list.GetEnumerator (), isKeyList);
\r
347 private class OrderedCollectionEnumerator : IEnumerator
\r
349 private bool isKeyList;
\r
350 IEnumerator listEnumerator;
\r
352 public OrderedCollectionEnumerator (IEnumerator listEnumerator, bool isKeyList)
\r
354 this.listEnumerator = listEnumerator;
\r
355 this.isKeyList = isKeyList;
\r
358 public object Current
\r
361 DictionaryEntry entry = (DictionaryEntry) listEnumerator.Current;
\r
362 return isKeyList ? entry.Key : entry.Value;
\r
366 public bool MoveNext()
\r
368 return listEnumerator.MoveNext ();
\r
371 public void Reset()
\r
373 listEnumerator.Reset ();
\r