Add StrinEnumerator.cs and StringCollection.cs
[mono.git] / mcs / class / System / System.Collections.Specialized / StringCollection.cs
1 /* System.Collections.Specialized.StringCollection.cs\r
2  * Authors:\r
3  *   John Barnette (jbarn@httcb.net)\r
4  *   Sean MacIsaac (macisaac@ximian.com)\r
5  *\r
6  *  Copyright (C) 2001 John Barnette\r
7  * (C) Ximian, Inc.  http://www.ximian.com\r
8  *\r
9  * NOTES:\r
10  * I bet Microsoft uses ArrayList as a backing store for this; I wonder what\r
11  * the performance difference will be.\r
12 */\r
13 \r
14 using System;\r
15 \r
16 namespace System.Collections.Specialized {\r
17         public class StringCollection : IList, ICollection, IEnumerable {\r
18                 private static int   InitialCapacity    = 11;\r
19                 private static float CapacityMultiplier = 2.0f;\r
20                 \r
21                 private int count;\r
22                 private int modCount;\r
23                 \r
24                 private string[] entries;\r
25                 \r
26                 // Public Constructor\r
27                 public StringCollection() {\r
28                         entries  = new string[InitialCapacity];\r
29                         count    = 0;\r
30                         modCount = 0;\r
31                 }\r
32                 \r
33                 // Public Instance Properties\r
34                 public int Count {\r
35                         get { return count; }\r
36                 }\r
37                 \r
38                 public bool IsFixedSize {\r
39                         get { return false; }\r
40                 }\r
41                 \r
42                 public bool IsReadOnly {\r
43                         get { return false; }\r
44                 }\r
45                 \r
46                 public bool IsSynchronized {\r
47                         get { return false; }\r
48                 }\r
49                 \r
50                 object IList.this[int index] {\r
51                         get { return this[index]; }\r
52                         set { this[index] = value.ToString(); } \r
53                 }\r
54                 \r
55                 public string this[int index] {\r
56                         get {\r
57                                 if (index < 0 || index >= count) {\r
58                                         throw new ArgumentOutOfRangeException("index");\r
59                                 }\r
60                                 \r
61                                 return entries[index];\r
62                         }\r
63                         \r
64                         set {\r
65                                 if (index < 0 || index >= count) {\r
66                                         throw new ArgumentOutOfRangeException("index");\r
67                                 }\r
68                                 \r
69                                 modCount++;\r
70                                 entries[index] = value;\r
71                         }\r
72                 }\r
73                 \r
74                 public object SyncRoot {\r
75                         get { return this; }\r
76                 }\r
77                 \r
78                 \r
79                 // Public Instance Methods\r
80                 \r
81                 int IList.Add(object value) {\r
82                         return Add(value.ToString());\r
83                 }\r
84                 \r
85                 public int Add(string value) {\r
86                         modCount++;\r
87                         Resize(count + 1);\r
88                         int index = count++;\r
89                         entries[index] = value;\r
90                         \r
91                         return index;\r
92                 }\r
93                 \r
94                 public void AddRange(string[] value) {\r
95                         int numEntries = value.Length;\r
96                         \r
97                         modCount++;\r
98                         Resize(count + numEntries);\r
99                         Array.Copy(value, 0, entries, count, numEntries);\r
100                         count += numEntries;\r
101                 }\r
102                 \r
103                 public void Clear() {\r
104                         modCount++;\r
105                         count = 0;\r
106                 }\r
107                 \r
108                 bool IList.Contains(object value) {\r
109                         return Contains(value.ToString());\r
110                 }\r
111                 \r
112                 public bool Contains(string value) {\r
113                         foreach (string entry in entries) {\r
114                                 if (value.Equals(entry)) {\r
115                                         return true;\r
116                                 }\r
117                         }\r
118                         \r
119                         return false;\r
120                 }\r
121                 \r
122                 void ICollection.CopyTo(Array array, int index) {\r
123                         if (array == null) {\r
124                                 throw new ArgumentNullException("array");\r
125                         } else if (index < 0) {\r
126                                 throw new ArgumentOutOfRangeException("index");\r
127                         } else if (array.Rank > 1) {\r
128                                 throw new ArgumentException("array");\r
129                         } else if (index >= array.Length) {\r
130                                 throw new ArgumentException("index");\r
131                         } else if (array.Length - index < count) {\r
132                                 throw new ArgumentException("array");\r
133                         }\r
134                         \r
135                         Array.Copy(entries, 0, array, index, count);\r
136                 }\r
137                 \r
138                 public void CopyTo(string[] array, int index) {\r
139                         if (array == null) {\r
140                                 throw new ArgumentNullException("array");\r
141                         } else if (index < 0) {\r
142                                 throw new ArgumentOutOfRangeException("index");\r
143                         } else if (array.Rank > 1) {\r
144                                 throw new ArgumentException("array");\r
145                         } else if (index >= array.Length) {\r
146                                 throw new ArgumentException("index");\r
147                         } else if (array.Length - index < count) {\r
148                                 throw new ArgumentException("array");\r
149                         }\r
150                         \r
151                         Array.Copy(entries, 0, array, index, count);\r
152                 }\r
153                 \r
154                 IEnumerator IEnumerable.GetEnumerator() {\r
155                         return new InternalEnumerator(this);\r
156                 }\r
157                 \r
158                 public StringEnumerator GetEnumerator() {\r
159                         return new StringEnumerator(this);\r
160                 }\r
161                 \r
162                 int IList.IndexOf(object value) {\r
163                         return IndexOf(value.ToString());\r
164                 }\r
165                 \r
166                 public int IndexOf(string value) {\r
167                         for (int i = 0; i < count; i++) {\r
168                                 if (value.Equals(entries[i])) {\r
169                                         return i;\r
170                                 }\r
171                         }\r
172                         \r
173                         return -1;\r
174                 }\r
175                 \r
176                 void IList.Insert(int index, object value) {\r
177                         Insert(index, value.ToString());\r
178                 }\r
179                 \r
180                 public void Insert(int index, string value) {\r
181                         if (index < 0 || index > count) {\r
182                                 throw new ArgumentOutOfRangeException("index");\r
183                         }\r
184                         \r
185                         modCount++;\r
186                         Resize(count + 1);\r
187                         Array.Copy(entries, index, entries, index + 1, count - index);\r
188                         entries[index] = value;\r
189                         count++;\r
190                 }\r
191 \r
192                 \r
193                 void IList.Remove(object value) {\r
194                         Remove(value.ToString());\r
195                 }\r
196                 \r
197                 public void Remove(string value) {\r
198                         for (int i = 0; i < count; i++) {\r
199                                 if (value.Equals(entries[i])) {\r
200                                         RemoveAt(i);\r
201                                         return;\r
202                                 }\r
203                         }\r
204                 }\r
205                 \r
206                 public void RemoveAt(int index) {\r
207                         if (index < 0 || index >= count) {\r
208                                 throw new ArgumentOutOfRangeException("index");\r
209                         }\r
210                         \r
211                         int remaining = count - index - 1;\r
212                         \r
213                         modCount++;\r
214                         \r
215                         if (remaining > 0) {\r
216                                 Array.Copy(entries, index + 1, entries, index, remaining);\r
217                         }\r
218                         \r
219                         count--;\r
220                         entries[count] = null;\r
221                 }\r
222                 \r
223                 \r
224                 // Private Instance Methods\r
225                 \r
226                 private void Resize(int minSize) {\r
227                         int oldSize = entries.Length;\r
228                         \r
229                         if (minSize > oldSize) {\r
230                                 string[] oldEntries = entries;\r
231                                 int newSize = (int) (oldEntries.Length * CapacityMultiplier);\r
232                                 \r
233                                 if (newSize < minSize) newSize = minSize;\r
234                                 entries = new string[newSize];\r
235                                 Array.Copy(oldEntries, 0, entries, 0, count);\r
236                         }\r
237                 }\r
238                 \r
239                 \r
240                 // Private classes\r
241                 \r
242                 private class InternalEnumerator : IEnumerator {\r
243                         private StringCollection data;\r
244                         private int index;\r
245                         private int myModCount;\r
246                         \r
247                         public InternalEnumerator(StringCollection data) {\r
248                                 this.data  = data;\r
249                                 myModCount = data.modCount;\r
250                                 index      = -1;\r
251                         }\r
252                         \r
253                         \r
254                         // Public Instance Properties\r
255                         \r
256                         public object Current {\r
257                                 get {\r
258                                         if (myModCount != data.modCount) {\r
259                                                 throw new InvalidOperationException();\r
260                                         } else if (index < 0 || index > data.count - 1) {\r
261                                                 throw new InvalidOperationException();\r
262                                         }\r
263                                         \r
264                                         return data[index];\r
265                                 }\r
266                         }\r
267                         \r
268                         \r
269                         // Public Instance Methods\r
270                         \r
271                         public bool MoveNext() {\r
272                                 if (myModCount != data.modCount) {\r
273                                         throw new InvalidOperationException();\r
274                                 }\r
275                                 \r
276                                 if (++index >= data.count - 1) {\r
277                                         return false;\r
278                                 }\r
279                                 \r
280                                 return true;\r
281                         }\r
282                         \r
283                         public void Reset() {\r
284                                 if (myModCount != data.modCount) {\r
285                                         throw new InvalidOperationException();\r
286                                 }\r
287                                 \r
288                                 index = -1;\r
289                         }\r
290                 }\r
291         }\r
292 }\r