2009-03-01 Zoltan Varga <vargaz@gmail.com>
[mcs.git] / class / System / System.Collections.Specialized / NameValueCollection.cs
blob27432912015170d929f098d10eaae0ca06e4801c
1 //
2 // System.Collections.Specialized.NameValueCollection.cs
3 //
4 // Author:
5 // Gleb Novodran
6 //
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004-2005 Novell (http://www.novell.com)
9 //
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.
32 using System.Runtime.Serialization;
33 using System.Text;
35 namespace System.Collections.Specialized{
37 [Serializable]
38 public class NameValueCollection : NameObjectCollectionBase
40 string[] cachedAllKeys = null;
41 string[] cachedAll = null;
43 //--------------------- Constructors -----------------------------
45 public NameValueCollection () : base ()
49 public NameValueCollection (int capacity) : base (capacity)
52 #if NET_2_0
53 public NameValueCollection (NameValueCollection col) : base (( col == null ) ? null : col.EqualityComparer ,
54 (col == null) ? null : col.Comparer,
55 (col == null) ? null : col.HashCodeProvider)
57 if (col==null)
58 throw new ArgumentNullException ("col");
59 Add(col);
61 #else
62 public NameValueCollection (NameValueCollection col) : base ((col == null) ? null : col.HashCodeProvider ,
63 (col == null) ? null : col.Comparer)
65 if (col==null)
66 throw new NullReferenceException ();
67 Add(col);
69 #endif
71 #if NET_2_0
72 [Obsolete ("Use NameValueCollection (IEqualityComparer)")]
73 #endif
74 public NameValueCollection (IHashCodeProvider hashProvider, IComparer comparer)
75 : base (hashProvider, comparer)
80 public NameValueCollection (int capacity, NameValueCollection col)
81 : base (capacity, (col == null) ? null : col.HashCodeProvider,
82 (col == null) ? null : col.Comparer)
84 Add (col);
87 protected NameValueCollection (SerializationInfo info, StreamingContext context)
88 :base (info, context)
93 #if NET_2_0
94 [Obsolete ("Use NameValueCollection (IEqualityComparer)")]
95 #endif
96 public NameValueCollection (int capacity, IHashCodeProvider hashProvider, IComparer comparer)
97 :base (capacity, hashProvider, comparer)
102 #if NET_2_0
103 public NameValueCollection (IEqualityComparer equalityComparer)
104 : base (equalityComparer)
108 public NameValueCollection (int capacity, IEqualityComparer equalityComparer)
109 : base (capacity, equalityComparer)
112 #endif
114 public virtual string[] AllKeys
116 get {
117 if (cachedAllKeys == null)
118 cachedAllKeys = BaseGetAllKeys ();
119 return this.cachedAllKeys;
123 public string this [int index]
125 get{
126 return this.Get (index);
130 public string this [string name] {
131 get{
132 return this.Get (name);
134 set{
135 this.Set (name,value);
139 public void Add (NameValueCollection c)
141 if (this.IsReadOnly)
142 throw new NotSupportedException ("Collection is read-only");
143 #if NET_2_0
144 if (c == null)
145 throw new ArgumentNullException ("c");
146 #endif
147 // make sense - but it's not the exception thrown
148 // throw new ArgumentNullException ();
150 InvalidateCachedArrays ();
151 int max = c.Count;
152 for (int i=0; i < max; i++){
153 string key = c.GetKey (i);
154 ArrayList new_values = (ArrayList) c.BaseGet (i);
155 ArrayList values = (ArrayList) BaseGet (key);
156 if (values != null && new_values != null)
157 values.AddRange (new_values);
158 else if (new_values != null)
159 values = new ArrayList (new_values);
160 BaseSet (key, values);
164 /// in SDK doc: If the same value already exists under the same key in the collection,
165 /// it just adds one more value in other words after
166 /// <code>
167 /// NameValueCollection nvc;
168 /// nvc.Add ("LAZY","BASTARD")
169 /// nvc.Add ("LAZY","BASTARD")
170 /// </code>
171 /// nvc.Get ("LAZY") will be "BASTARD,BASTARD" instead of "BASTARD"
173 public virtual void Add (string name, string val)
175 if (this.IsReadOnly)
176 throw new NotSupportedException ("Collection is read-only");
178 InvalidateCachedArrays ();
179 ArrayList values = (ArrayList)BaseGet (name);
180 if (values == null){
181 values = new ArrayList ();
182 if (val != null)
183 values.Add (val);
184 BaseAdd (name, values);
186 else {
187 if (val != null)
188 values.Add (val);
193 #if NET_2_0
194 public virtual void Clear ()
195 #else
196 public void Clear ()
197 #endif
199 if (this.IsReadOnly)
200 throw new NotSupportedException ("Collection is read-only");
201 InvalidateCachedArrays ();
202 BaseClear ();
205 public void CopyTo (Array dest, int index)
207 if (dest == null)
208 throw new ArgumentNullException ("dest", "Null argument - dest");
209 if (index < 0)
210 throw new ArgumentOutOfRangeException ("index", "index is less than 0");
211 if (dest.Rank > 1)
212 throw new ArgumentException ("dest", "multidim");
214 if (cachedAll == null)
215 RefreshCachedAll ();
216 #if NET_2_0
217 try {
218 #endif
219 cachedAll.CopyTo (dest, index);
220 #if NET_2_0
222 catch (ArrayTypeMismatchException)
224 throw new InvalidCastException();
226 #endif
229 private void RefreshCachedAll ()
231 this.cachedAll = null;
232 int max = this.Count;
233 cachedAll = new string [max];
234 for (int i = 0; i < max; i++)
235 cachedAll [i] = this.Get (i);
238 public virtual string Get (int index)
240 ArrayList values = (ArrayList)BaseGet (index);
241 // if index is out of range BaseGet throws an ArgumentOutOfRangeException
243 return AsSingleString (values);
246 public virtual string Get (string name)
248 ArrayList values = (ArrayList)BaseGet (name);
249 return AsSingleString (values);
252 private static string AsSingleString (ArrayList values)
254 const char separator = ',';
256 if (values == null)
257 return null;
258 int max = values.Count;
260 switch (max) {
261 case 0:
262 return null;
263 case 1:
264 return (string)values [0];
265 case 2:
266 return String.Concat ((string)values [0], separator, (string)values [1]);
267 default:
268 int len = max;
269 for (int i = 0; i < max; i++)
270 len += ((string)values [i]).Length;
271 StringBuilder sb = new StringBuilder ((string)values [0], len);
272 for (int i = 1; i < max; i++){
273 sb.Append (separator);
274 sb.Append (values [i]);
277 return sb.ToString ();
282 public virtual string GetKey (int index)
284 return BaseGetKey (index);
288 public virtual string[] GetValues (int index)
290 ArrayList values = (ArrayList)BaseGet (index);
292 return AsStringArray (values);
296 public virtual string[] GetValues (string name)
298 ArrayList values = (ArrayList)BaseGet (name);
300 return AsStringArray (values);
303 private static string[] AsStringArray (ArrayList values)
305 if (values == null)
306 return null;
307 int max = values.Count;//get_Count ();
308 if (max == 0)
309 return null;
311 string[] valArray = new string[max];
312 values.CopyTo (valArray);
313 return valArray;
316 public bool HasKeys ()
318 return BaseHasKeys ();
321 public virtual void Remove (string name)
323 if (this.IsReadOnly)
324 throw new NotSupportedException ("Collection is read-only");
325 InvalidateCachedArrays ();
326 BaseRemove (name);
330 public virtual void Set (string name, string value)
332 if (this.IsReadOnly)
333 throw new NotSupportedException ("Collection is read-only");
335 InvalidateCachedArrays ();
337 ArrayList values = new ArrayList ();
338 if (value != null) {
339 values.Add (value);
340 BaseSet (name,values);
342 else {
343 // remove all entries
344 BaseSet (name, null);
348 protected void InvalidateCachedArrays ()
350 cachedAllKeys = null;
351 cachedAll = null;