Add locking to EventWaitHandle.Set/Reset to avoid crashes when another thread dispose...
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Channels / AggregateDictionary.cs
1 //
2 // System.Runtime.Remoting.Channels.AggregateDictionary.cs
3 //
4 // Author: Lluis Sanchez Gual (lluis@ximian.com)
5 //
6 // 2002 (C) Copyright, Novell, Inc.
7 //
8
9 //
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections;
33
34 namespace System.Runtime.Remoting.Channels
35 {
36         [System.Runtime.InteropServices.ComVisible (true)]
37         internal class AggregateDictionary: IDictionary
38         {
39                 IDictionary[] dictionaries;
40                 ArrayList _values;
41                 ArrayList _keys;
42                 
43                 public AggregateDictionary (IDictionary[] dics)
44                 {
45                         dictionaries = dics;
46                 }
47                 
48                 public bool IsFixedSize 
49                 { 
50                         get { return true; }
51                 }               
52                 
53                 public bool IsReadOnly 
54                 { 
55                         get { return true; }
56                 } 
57                 
58                 public object this [object key]
59                 { 
60                         get 
61                         {
62                                 foreach (IDictionary dic in dictionaries)
63                                         if (dic.Contains (key)) return dic [key];
64                                 return null;
65                         }
66                         
67                         set
68                         {
69                                 throw new NotSupportedException ();
70                         }
71                 }
72                 
73                 public ICollection Keys 
74                 { 
75                         get
76                         {
77                                 if (_keys != null) return _keys;
78                                 
79                                 _keys = new ArrayList ();
80                                 foreach (IDictionary dic in dictionaries)
81                                         _keys.AddRange (dic.Keys);
82                                 return _keys;
83                         }
84                 } 
85                 
86                 public ICollection Values 
87                 { 
88                         get
89                         {
90                                 if (_values != null) return _values;
91                                 
92                                 _values = new ArrayList ();
93                                 foreach (IDictionary dic in dictionaries)
94                                         _values.AddRange (dic.Values);
95                                 return _values;
96                         }
97                 }
98                 
99                 public void Add (object key, object value)
100                 {
101                         throw new NotSupportedException ();
102                 }
103                 
104                 public void Clear ()
105                 {
106                         throw new NotSupportedException ();
107                 }
108                 
109                 public bool Contains (object ob)
110                 {
111                         foreach (IDictionary dic in dictionaries)
112                                 if (dic.Contains (ob)) return true;
113                         return false;
114                 }
115                 
116                 public IDictionaryEnumerator GetEnumerator ()
117                 {
118                         return new AggregateEnumerator (dictionaries);
119                 }
120                 
121                 IEnumerator IEnumerable.GetEnumerator ()
122                 {
123                         return new AggregateEnumerator (dictionaries);
124                 }
125                 
126                 public void Remove (object ob)
127                 {
128                         throw new NotSupportedException ();
129                 }
130                 
131                 public void CopyTo (Array array, int index)
132                 {
133                         foreach (object ob in this)
134                                 array.SetValue (ob, index++);
135                 }
136                 
137                 public int Count 
138                 { 
139                         get
140                         {
141                                 int c = 0;
142                                 foreach (IDictionary dic in dictionaries)
143                                         c += dic.Count;
144                                 return c;
145                         }
146                 }
147                 
148                 public bool IsSynchronized 
149                 { 
150                         get { return false; }
151                 }
152                 
153                 public object SyncRoot 
154                 { 
155                         get { return this; }
156                 } 
157         }
158         
159         internal class AggregateEnumerator: IDictionaryEnumerator
160         {
161                 IDictionary[] dictionaries;
162                 int pos = 0;
163                 IDictionaryEnumerator currente;
164                 
165                 public AggregateEnumerator (IDictionary[] dics)
166                 {
167                         dictionaries = dics;
168                         Reset ();
169                 }
170                 
171                 public DictionaryEntry Entry 
172                 { 
173                         get { return currente.Entry; }
174                 }
175                 
176                 public object Key 
177                 {
178                         get { return currente.Key; }
179                 }
180                 
181                 public object Value 
182                 { 
183                         get { return currente.Value; }
184                 }
185                 
186                 public object Current 
187                 { 
188                         get { return currente.Current; }
189                 }
190                 
191                 public bool MoveNext ()
192                 {
193                         if (pos >= dictionaries.Length) return false;
194
195                         if (!currente.MoveNext()) 
196                         {
197                                 pos++;
198                                 if (pos >= dictionaries.Length) return false;
199                                 currente = dictionaries [pos].GetEnumerator ();
200                                 return MoveNext ();
201                         }
202                         
203                         return true;
204                 }
205                 
206                 public void Reset ()
207                 {
208                         pos = 0;
209                         if (dictionaries.Length > 0)
210                                 currente = dictionaries [0].GetEnumerator ();
211                 }
212         }
213 }