Merge pull request #4540 from kumpera/android-changes-part1
[mono.git] / mcs / class / System.ServiceModel / System.Collections.Generic / SynchronizedReadOnlyCollection.cs
1 //
2 // System.ServiceModel.SynchronizedReadOnlyCollection.cs
3 //
4 // Author: Duncan Mak (duncan@novell.com)
5 //
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27
28 using System;
29 using System.Collections;
30 using System.Runtime.InteropServices;
31
32 namespace System.Collections.Generic
33 {
34         [ComVisible (false)]
35         public class SynchronizedReadOnlyCollection<T>
36                 : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
37         {
38                 List<T> l;
39                 object sync_root;
40
41                 public SynchronizedReadOnlyCollection ()
42                         : this (new object ())
43                 {
44                 }
45
46                 public SynchronizedReadOnlyCollection (object syncRoot)
47                         : this (syncRoot, new List<T> ())
48                 {
49                 }
50
51                 public SynchronizedReadOnlyCollection (object syncRoot, IEnumerable<T> list)
52                 {
53                         if (syncRoot == null)
54                                 throw new ArgumentNullException ("syncRoot");
55
56                         if (list == null)
57                                 throw new ArgumentNullException ("list");
58
59                         this.sync_root = syncRoot;
60                         this.l = new List<T> (list);
61                 }
62
63                 public SynchronizedReadOnlyCollection (object syncRoot, params T [] list)
64                         : this (syncRoot, (IEnumerable<T>) list)
65                 {
66                 }
67
68                 public SynchronizedReadOnlyCollection (object sync_root, List<T> list, bool make_copy)
69                         : this (sync_root,
70                                 list == null ? null : make_copy ? new List<T> (list) : list)
71                 {
72                 }
73
74                 public bool Contains (T value)
75                 {
76                         bool retval;
77
78                         lock (sync_root) {
79                                 retval = l.Contains (value);
80                         }
81
82                         return retval;
83                 }
84
85                 public void CopyTo (T [] array, int index)
86                 {
87                         lock (sync_root) {
88                                 l.CopyTo (array, index);
89                         }
90                 }
91
92                 public IEnumerator<T> GetEnumerator ()
93                 {
94                         IEnumerator<T> retval;
95
96                         lock (sync_root) {
97                                 retval = l.GetEnumerator ();
98                         }
99
100                         return retval;
101                 }
102
103                 public int IndexOf (T value)
104                 {
105                         int retval;
106
107                         lock (sync_root) {
108                                 retval = l.IndexOf (value);
109                         }
110
111                         return retval;
112                 }
113
114                 void ICollection<T>.Add (T value) { throw new NotSupportedException (); }
115                 void ICollection<T>.Clear () { throw new NotSupportedException (); }
116                 bool ICollection<T>.Remove (T value) { throw new NotSupportedException (); }
117
118                 void IList<T>.Insert (int index, T value) { throw new NotSupportedException (); }
119                 void IList<T>.RemoveAt (int index) { throw new NotSupportedException (); }
120
121                 void ICollection.CopyTo (Array array, int index)
122                 {
123                         ICollection<T> a = array as ICollection<T>;
124
125                         if (a == null)
126                                 throw new ArgumentException ("The array type is not compatible.");
127
128                         lock (sync_root) {
129                                 ((ICollection) l).CopyTo (array, index);
130                         }
131                 }
132
133                 IEnumerator IEnumerable.GetEnumerator ()
134                 {
135                         return GetEnumerator ();
136                 }
137
138                 int IList.Add (object value) { throw new NotSupportedException (); }
139                 void IList.Clear () { throw new NotSupportedException (); }
140
141                 bool IList.Contains (object value)
142                 {
143                         if (typeof (T).IsValueType)
144                                 throw new ArgumentException ("This is a collection of ValueTypes.");
145
146                         // null always gets thru
147                         if (value is T == false && value != null)
148                                 throw new ArgumentException ("value is not of the same type as this collection.");
149
150                         bool retval;
151                         T val = (T) value;
152                         lock (sync_root) {
153                                 retval = l.Contains (val);
154                         }
155
156                         return retval;
157                 }
158
159                 int IList.IndexOf (object value)
160                 {
161                         if (typeof (T).IsValueType)
162                                 throw new ArgumentException ("This is a collection of ValueTypes.");
163
164                         if (value is T == false)
165                                 throw new ArgumentException ("value is not of the same type as this collection.");
166
167                         int retval;
168                         T val = (T) value;
169                         lock (sync_root) {
170                                 retval = l.IndexOf (val);
171                         }
172
173                         return retval;
174                 }
175
176                 void IList.Insert (int index, object value) { throw new NotSupportedException (); }
177                 void IList.Remove (object value) { throw new NotSupportedException (); }
178                 void IList.RemoveAt (int index) { throw new NotSupportedException (); }
179
180                 public int Count {
181                         get {
182                                 int retval;
183                                 lock (sync_root) {
184                                         retval = l.Count;
185                                 }
186                                 return retval;
187                         }
188                 }
189
190                 public T this [int index] {
191                         get {
192                                 T retval;
193                                 lock (sync_root) {
194                                         retval = l [index];
195                                 }
196                                 return retval;
197                         }
198                 }
199
200                 protected IList<T> Items {
201                         get { return l; }
202                 }
203
204
205                 bool ICollection<T>.IsReadOnly { get { return true; }}
206
207                 bool ICollection.IsSynchronized { get { return true; }}
208                 object ICollection.SyncRoot { get { return sync_root; }}
209
210                 bool IList.IsFixedSize { get { return true; }}
211                 bool IList.IsReadOnly { get { return true; }}
212
213                 T IList<T>.this [int index] {
214                         get { return this [index]; }
215                         set { throw new NotSupportedException (); }
216                 }
217
218                 object IList.this [int index] {
219                         get { return this [index]; }
220                         set { throw new NotSupportedException (); }
221                 }
222         }
223 }