2 // System.Web.UI.WebControls.OrderedDictionary.cs
\r
5 // Lluis Sanchez Gual (lluis@novell.com)
\r
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
\r
10 // a copy of this software and associated documentation files (the
\r
11 // "Software"), to deal in the Software without restriction, including
\r
12 // without limitation the rights to use, copy, modify, merge, publish,
\r
13 // distribute, sublicense, and/or sell copies of the Software, and to
\r
14 // permit persons to whom the Software is furnished to do so, subject to
\r
15 // the following conditions:
\r
17 // The above copyright notice and this permission notice shall be
\r
18 // included in all copies or substantial portions of the Software.
\r
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
31 using System.Runtime.Serialization;
\r
33 namespace System.Collections.Specialized
\r
36 public class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback
\r
42 SerializationInfo serializationInfo;
43 IEqualityComparer comparer;
\r
45 public OrderedDictionary ()
\r
47 list = new ArrayList ();
\r
48 hash = new Hashtable ();
\r
51 public OrderedDictionary (int capacity)
\r
53 initialCapacity = (capacity < 0) ? 0 : capacity;
\r
54 list = new ArrayList (initialCapacity);
\r
55 hash = new Hashtable (initialCapacity);
\r
58 public OrderedDictionary (IEqualityComparer equalityComparer)
60 list = new ArrayList ();
\r
61 hash = new Hashtable (equalityComparer);
62 comparer = equalityComparer;
\r
65 public OrderedDictionary (int capacity, IEqualityComparer equalityComparer)
67 initialCapacity = (capacity < 0) ? 0 : capacity;
\r
68 list = new ArrayList (initialCapacity);
\r
69 hash = new Hashtable (initialCapacity, equalityComparer);
\r
70 comparer = equalityComparer;
\r
73 protected OrderedDictionary (SerializationInfo info, StreamingContext context)
\r
75 serializationInfo = info;
\r
78 protected virtual void OnDeserialization (object sender)
80 if (serializationInfo == null)
83 comparer = (IEqualityComparer) serializationInfo.GetValue ("KeyComparer", typeof (IEqualityComparer));
84 readOnly = serializationInfo.GetBoolean ("ReadOnly");
\r
85 initialCapacity = serializationInfo.GetInt32 ("InitialCapacity");
88 list = new ArrayList ();
92 hash = new Hashtable (comparer);
93 object[] array = (object[]) serializationInfo.GetValue ("ArrayList", typeof(object[]));
94 foreach (DictionaryEntry de in array) {
95 hash.Add (de.Key, de.Value);
\r
100 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
\r
103 throw new ArgumentNullException ("info");
105 info.AddValue ("KeyComparer", comparer, typeof (IEqualityComparer));
106 info.AddValue ("ReadOnly", readOnly);
\r
107 info.AddValue ("InitialCapacity", initialCapacity);
\r
109 object[] array = new object [hash.Count];
110 hash.CopyTo (array, 0);
\r
111 info.AddValue ("ArrayList", array);
\r
114 IEnumerator IEnumerable.GetEnumerator()
\r
116 return list.GetEnumerator ();
\r
125 bool ICollection.IsSynchronized {
127 return list.IsSynchronized;
131 object ICollection.SyncRoot {
133 return list.SyncRoot;
137 public void CopyTo (Array array, int index)
\r
139 list.CopyTo (array, index);
\r
142 bool IDictionary.IsFixedSize {
148 public virtual bool IsReadOnly
\r
155 public virtual object this [object key]
\r
157 get { return hash [key]; }
\r
160 if (hash.Contains (key)) {
\r
161 int i = FindListEntry (key);
\r
162 list [i] = new DictionaryEntry (key, value);
\r
164 list.Add (new DictionaryEntry (key, value));
\r
166 hash [key] = value;
\r
170 public virtual object this [int index]
\r
172 get { return ((DictionaryEntry) list [index]).Value; }
\r
175 DictionaryEntry de = (DictionaryEntry) list [index];
\r
177 // update (even on the list) isn't automatic
179 hash [de.Key] = value;
\r
183 public virtual ICollection Keys
\r
186 return new OrderedCollection (list, true);
\r
190 public virtual ICollection Values
\r
193 return new OrderedCollection (list, false);
\r
197 public void Add (object key, object value)
\r
200 hash.Add (key, value);
\r
201 list.Add (new DictionaryEntry (key, value));
\r
204 public void Clear()
\r
211 public bool Contains (object key)
\r
213 return hash.Contains (key);
\r
216 public virtual IDictionaryEnumerator GetEnumerator()
\r
218 return new OrderedEntryCollectionEnumerator (list.GetEnumerator ());
\r
221 public void Remove (object key)
\r
225 if (hash.Contains (key)) {
\r
227 int i = FindListEntry (key);
\r
232 int FindListEntry (object key)
\r
234 for (int n=0; n<list.Count; n++) {
\r
235 DictionaryEntry de = (DictionaryEntry) list [n];
\r
236 if (de.Key.Equals (key))
\r
245 throw new NotSupportedException ("Collection is read only");
\r
248 public OrderedDictionary AsReadOnly ()
\r
250 OrderedDictionary od = new OrderedDictionary ();
\r
253 od.comparer = comparer;
\r
258 public void Insert (int index, object key, object value)
\r
261 hash.Add (key, value);
\r
262 list.Insert (index, new DictionaryEntry (key, value));
\r
265 public void RemoveAt (int index)
\r
268 DictionaryEntry entry = (DictionaryEntry) list [index];
\r
269 list.RemoveAt (index);
\r
270 hash.Remove (entry.Key);
\r
273 private class OrderedEntryCollectionEnumerator : IEnumerator, IDictionaryEnumerator
\r
275 IEnumerator listEnumerator;
\r
277 public OrderedEntryCollectionEnumerator (IEnumerator listEnumerator)
\r
279 this.listEnumerator = listEnumerator;
\r
282 public bool MoveNext()
\r
284 return listEnumerator.MoveNext ();
\r
287 public void Reset()
\r
289 listEnumerator.Reset ();
\r
292 public object Current
\r
294 get { return listEnumerator.Current; }
\r
297 public DictionaryEntry Entry
\r
299 get { return (DictionaryEntry) listEnumerator.Current; }
\r
304 get { return Entry.Key; }
\r
307 public object Value
\r
309 get { return Entry.Value; }
\r
313 private class OrderedCollection : ICollection
\r
315 private ArrayList list;
\r
316 private bool isKeyList;
\r
318 public OrderedCollection (ArrayList list, bool isKeyList)
\r
321 this.isKeyList = isKeyList;
\r
330 public bool IsSynchronized
\r
337 public object SyncRoot
\r
340 return list.SyncRoot;
\r
344 public void CopyTo (Array array, int index)
\r
346 for (int n=0; n<list.Count; n++) {
\r
347 DictionaryEntry de = (DictionaryEntry) list [n];
\r
348 if (isKeyList) array.SetValue (de.Key, index + n);
\r
349 else array.SetValue (de.Value, index + n);
\r
353 public IEnumerator GetEnumerator()
\r
355 return new OrderedCollectionEnumerator (list.GetEnumerator (), isKeyList);
\r
358 private class OrderedCollectionEnumerator : IEnumerator
\r
360 private bool isKeyList;
\r
361 IEnumerator listEnumerator;
\r
363 public OrderedCollectionEnumerator (IEnumerator listEnumerator, bool isKeyList)
\r
365 this.listEnumerator = listEnumerator;
\r
366 this.isKeyList = isKeyList;
\r
369 public object Current
\r
372 DictionaryEntry entry = (DictionaryEntry) listEnumerator.Current;
\r
373 return isKeyList ? entry.Key : entry.Value;
\r
377 public bool MoveNext()
\r
379 return listEnumerator.MoveNext ();
\r
382 public void Reset()
\r
384 listEnumerator.Reset ();
\r