merge -r 58784:58785
[mono.git] / mcs / class / System / System.Collections.Specialized / OrderedDictionary.cs
1 //\r
2 // System.Web.UI.WebControls.OrderedDictionary.cs\r
3 //\r
4 // Authors:\r
5 //      Lluis Sanchez Gual (lluis@novell.com)\r
6 //\r
7 // (C) 2005 Novell, Inc (http://www.novell.com)\r
8 //\r
9 \r
10 //\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
18 // \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
21 // \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
29 //\r
30 \r
31 #if NET_2_0\r
32 \r
33 using System;\r
34 using System.Runtime.Serialization;\r
35 \r
36 namespace System.Collections.Specialized\r
37 {\r
38         [Serializable]\r
39         public class OrderedDictionary : IOrderedDictionary, IDictionary, ICollection, IEnumerable, ISerializable\r
40         {\r
41                 ArrayList list;\r
42                 Hashtable hash;\r
43                 bool readOnly;\r
44                 int initialCapacity;\r
45                 \r
46                 public OrderedDictionary ()\r
47                 {\r
48                         list = new ArrayList ();\r
49                         hash = new Hashtable ();\r
50                 }\r
51                 \r
52                 public OrderedDictionary (int capacity)\r
53                 {\r
54                         initialCapacity = capacity;\r
55                         list = new ArrayList (capacity);\r
56                         hash = new Hashtable (capacity);\r
57                 }\r
58                 \r
59                 public OrderedDictionary (SerializationInfo info, StreamingContext context)\r
60                 {\r
61                         readOnly = info.GetBoolean ("ReadOnly");\r
62                         initialCapacity = info.GetInt32 ("InitialCapacity");\r
63                         hash = (Hashtable) info.GetValue ("HashTable", typeof(Hashtable));\r
64                         list = (ArrayList) info.GetValue ("ArrayList", typeof(ArrayList));\r
65                 }\r
66                 \r
67                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)\r
68                 {\r
69                         info.AddValue ("ReadOnly", readOnly);\r
70                         info.AddValue ("InitialCapacity", initialCapacity);\r
71                         info.AddValue ("HashTable", hash);\r
72                         info.AddValue ("ArrayList", list);\r
73                 }\r
74                 \r
75                 IEnumerator IEnumerable.GetEnumerator()\r
76                 {\r
77                         return list.GetEnumerator ();\r
78                 }\r
79                 \r
80                 public int Count {\r
81                         get {\r
82                                 return list.Count;\r
83                         }\r
84                 }\r
85                 \r
86                 public bool IsSynchronized {\r
87                         get {\r
88                                 return list.IsSynchronized;\r
89                         }\r
90                 }\r
91                 \r
92                 public object SyncRoot {\r
93                         get {\r
94                                 return list.SyncRoot;\r
95                         }\r
96                 }\r
97 \r
98                 public void CopyTo (Array array, int index)\r
99                 {\r
100                         list.CopyTo (array, index);\r
101                 }\r
102                 \r
103                 public bool IsFixedSize\r
104                 {\r
105                         get {\r
106                                 return false;\r
107                         }\r
108                 }\r
109                 \r
110                 public virtual bool IsReadOnly\r
111                 {\r
112                         get {\r
113                                 return readOnly;\r
114                         }\r
115                 }\r
116                 \r
117                 public virtual object this [object key]\r
118                 {\r
119                         get { return hash [key]; }\r
120                         set {\r
121                                 WriteCheck ();\r
122                                 if (hash.Contains (key)) {\r
123                                         int i = FindListEntry (key);\r
124                                         list [i] = new DictionaryEntry (key, value);\r
125                                 } else\r
126                                         list.Add (new DictionaryEntry (key, value));\r
127                                 \r
128                                 hash [key] = value;\r
129                         }\r
130                 }\r
131                 \r
132                 public virtual object this [int index]\r
133                 {\r
134                         get { return ((DictionaryEntry) list [index]).Value; }\r
135                         set {\r
136                                 WriteCheck ();\r
137                                 DictionaryEntry de = (DictionaryEntry) list [index];\r
138                                 de.Value = value;\r
139                         }\r
140                 }\r
141                 \r
142                 public virtual ICollection Keys\r
143                 {\r
144                         get {\r
145                                 return new OrderedCollection (list, true);\r
146                         }\r
147                 }\r
148                 \r
149                 public virtual ICollection Values\r
150                 {\r
151                         get {\r
152                                 return new OrderedCollection (list, false);\r
153                         }\r
154                 }\r
155 \r
156                 public void Add (object key, object value)\r
157                 {\r
158                         WriteCheck ();\r
159                         hash.Add (key, value);\r
160                         list.Add (new DictionaryEntry (key, value));\r
161                 }\r
162                 \r
163                 public void Clear()\r
164                 {\r
165                         WriteCheck ();\r
166                         hash.Clear ();\r
167                         list.Clear ();\r
168                 }\r
169                 \r
170                 public bool Contains (object key)\r
171                 {\r
172                         return hash.Contains (key);\r
173                 }\r
174                 \r
175                 public virtual IDictionaryEnumerator GetEnumerator()\r
176                 {\r
177                         return new OrderedEntryCollectionEnumerator (list.GetEnumerator ());\r
178                 }\r
179                 \r
180                 public void Remove (object key)\r
181                 {\r
182                         WriteCheck ();\r
183 \r
184                         if (hash.Contains (key)) {\r
185                                 hash.Remove (key);\r
186                                 int i = FindListEntry (key);\r
187                                 list.RemoveAt (i);\r
188                         }\r
189                 }\r
190                 \r
191                 int FindListEntry (object key)\r
192                 {\r
193                         for (int n=0; n<list.Count; n++) {\r
194                                 DictionaryEntry de = (DictionaryEntry) list [n];\r
195                                 if (de.Key.Equals (key))\r
196                                         return n;\r
197                         }\r
198                         return -1;\r
199                 }\r
200                 \r
201                 void WriteCheck ()\r
202                 {\r
203                         if (readOnly)\r
204                                 throw new InvalidOperationException ("Collection is read only");\r
205                 }\r
206                 \r
207                 public OrderedDictionary AsReadOnly ()\r
208                 {\r
209                         OrderedDictionary od = new OrderedDictionary ();\r
210                         od.list = list;\r
211                         od.hash = hash;\r
212                         od.readOnly = true;\r
213                         return od;\r
214                 }\r
215                 \r
216                 public void Insert (int index, object key, object value)\r
217                 {\r
218                         WriteCheck ();\r
219                         hash.Add (key, value);\r
220                         list.Insert (index, new DictionaryEntry (key, value));\r
221                 }\r
222                 \r
223                 public void RemoveAt (int index)\r
224                 {\r
225                         WriteCheck ();\r
226                         DictionaryEntry entry = (DictionaryEntry) list [index];\r
227                         list.RemoveAt (index);\r
228                         hash.Remove (entry.Key);\r
229                 }\r
230                 \r
231                 private class OrderedEntryCollectionEnumerator : IEnumerator, IDictionaryEnumerator\r
232                 {\r
233                         IEnumerator listEnumerator;\r
234                         \r
235                         public OrderedEntryCollectionEnumerator (IEnumerator listEnumerator)\r
236                         {\r
237                                 this.listEnumerator = listEnumerator;\r
238                         }\r
239 \r
240                         public bool MoveNext()\r
241                         {\r
242                                 return listEnumerator.MoveNext ();\r
243                         }\r
244                         \r
245                         public void Reset()\r
246                         {\r
247                                 listEnumerator.Reset ();\r
248                         }\r
249                         \r
250                         public object Current\r
251                         {\r
252                                 get { return listEnumerator.Current; }\r
253                         }\r
254                         \r
255                         public DictionaryEntry Entry\r
256                         {\r
257                                 get { return (DictionaryEntry) listEnumerator.Current; }\r
258                         }\r
259                         \r
260                         public object Key\r
261                         {\r
262                                 get { return Entry.Key; }\r
263                         }\r
264                         \r
265                         public object Value\r
266                         {\r
267                                 get { return Entry.Value; }\r
268                         }\r
269                 }\r
270                 \r
271                 private class OrderedCollection : ICollection\r
272                 {\r
273                         private ArrayList list;\r
274                         private bool isKeyList;\r
275                                 \r
276                         public OrderedCollection (ArrayList list, bool isKeyList)\r
277                         {\r
278                                 this.list = list;\r
279                                 this.isKeyList = isKeyList;\r
280                         }\r
281 \r
282                         public int Count {\r
283                                 get {\r
284                                         return list.Count;\r
285                                 }\r
286                         }\r
287                         \r
288                         public bool IsSynchronized\r
289                         {\r
290                                 get {\r
291                                         return false;\r
292                                 }\r
293                         }\r
294                         \r
295                         public object SyncRoot\r
296                         {\r
297                                 get {\r
298                                         return list.SyncRoot;\r
299                                 }\r
300                         }\r
301 \r
302                         public void CopyTo (Array array, int index)\r
303                         {\r
304                                 for (int n=0; n<list.Count; n++) {\r
305                                         DictionaryEntry de = (DictionaryEntry) list [n];\r
306                                         if (isKeyList) array.SetValue (de.Key, index + n);\r
307                                         else array.SetValue (de.Value, index + n);\r
308                                 }\r
309                         }\r
310                         \r
311                         public IEnumerator GetEnumerator()\r
312                         {\r
313                                 return new OrderedCollectionEnumerator (list.GetEnumerator (), isKeyList);\r
314                         }\r
315                         \r
316                         private class OrderedCollectionEnumerator : IEnumerator\r
317                         {\r
318                                 private bool isKeyList;\r
319                                 IEnumerator listEnumerator;\r
320                                         \r
321                                 public OrderedCollectionEnumerator (IEnumerator listEnumerator, bool isKeyList)\r
322                                 {\r
323                                         this.listEnumerator = listEnumerator;\r
324                                         this.isKeyList = isKeyList;\r
325                                 }\r
326 \r
327                                 public object Current\r
328                                 {\r
329                                         get {\r
330                                                 DictionaryEntry entry = (DictionaryEntry) listEnumerator.Current;\r
331                                                 return isKeyList ? entry.Key : entry.Value;\r
332                                         }\r
333                                 }\r
334                                 \r
335                                 public bool MoveNext()\r
336                                 {\r
337                                         return listEnumerator.MoveNext ();\r
338                                 }\r
339                                 \r
340                                 public void Reset()\r
341                                 {\r
342                                         listEnumerator.Reset ();\r
343                                 }\r
344                         }\r
345                 }\r
346         }\r
347 }\r
348 \r
349 #endif\r