Mark tests as not working under TARGET_JVM
[mono.git] / mcs / class / corlib / System / StringComparer.cs
1 //
2 // System.StringComparer
3 //
4 // Authors:
5 //      Marek Safar (marek.safar@seznam.cz)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 #if NET_2_0
31
32 using System.Collections;
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Collections.Generic;
36
37 namespace System
38 {
39         [Serializable, ComVisible(true)]
40         public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
41         {
42                 static StringComparer invariantCultureIgnoreCase = new CultureAwareComparer (CultureInfo.InvariantCulture, true);
43                 static StringComparer invariantCulture = new CultureAwareComparer (CultureInfo.InvariantCulture, false);
44                 static StringComparer ordinalIgnoreCase = new OrdinalComparer (true);
45                 static StringComparer ordinal = new OrdinalComparer (false);
46
47                 // Constructors
48                 protected StringComparer ()
49                 {
50                 }
51
52                 // Properties
53                 public static StringComparer CurrentCulture {
54                         get {
55                                 return new CultureAwareComparer (CultureInfo.CurrentCulture, false);
56                         }
57                 }
58
59                 public static StringComparer CurrentCultureIgnoreCase {
60                         get {
61                                 return new CultureAwareComparer (CultureInfo.CurrentCulture, true);
62                         }
63                 }
64
65                 public static StringComparer InvariantCulture {
66                         get {
67                                 return invariantCulture;
68                         }
69                 }
70
71                 public static StringComparer InvariantCultureIgnoreCase {
72                         get {
73                                 return invariantCultureIgnoreCase;
74                         }
75                 }
76
77                 public static StringComparer Ordinal {
78                         get { return ordinal; }
79                 }
80
81                 public static StringComparer OrdinalIgnoreCase {
82                         get { return ordinalIgnoreCase; }
83                 }
84
85                 // Methods
86                 public static StringComparer Create (CultureInfo culture, bool ignoreCase)
87                 {
88                         return new CultureAwareComparer (culture, ignoreCase);
89                 }
90
91                 public int Compare (object x, object y)
92                 {
93                         if (x == y)
94                                 return 0;
95                         if (x == null)
96                                 return -1;
97                         if (y == null)
98                                 return 1;
99
100                         string s_x = x as string;
101                         if (s_x != null) {
102                                 string s_y = y as string;
103                                 if (s_y != null)
104                                         return Compare (s_x, s_y);
105                         }
106
107                         IComparable ic = x as IComparable;
108                         if (ic == null)
109                                 throw new ArgumentException ();
110
111                         return ic.CompareTo (y);
112                 }
113
114                 public new bool Equals (object x, object y)
115                 {
116                         if (x == y)
117                                 return true;
118                         if (x == null || y == null)
119                                 return false;
120
121                         string s_x = x as string;
122                         if (s_x != null) {
123                                 string s_y = y as string;
124                                 if (s_y != null)
125                                         return Equals (s_x, s_y);
126                         }
127                         return x.Equals (y);
128                 }
129
130                 public int GetHashCode (object o)
131                 {
132                         if (o == null)
133                                 throw new ArgumentNullException("o");
134
135                         string s = o as string;
136                         return s == null ? o.GetHashCode (): GetHashCode(s);
137                 }
138
139                 public abstract int Compare (string x, string y);
140                 public abstract bool Equals (string x, string y);
141                 public abstract int GetHashCode (string s);
142         }
143
144         [Serializable]
145         class CultureAwareComparer : StringComparer
146         {
147                 readonly bool _ignoreCase;
148                 readonly CompareInfo _compareInfo;
149
150                 public CultureAwareComparer (CultureInfo ci, bool ignore_case)
151                 {
152                         _compareInfo = ci.CompareInfo;
153                         _ignoreCase = ignore_case;
154                 }
155
156                 public override int Compare (string x, string y)
157                 {
158                         CompareOptions co = _ignoreCase ? CompareOptions.IgnoreCase : 
159                                 CompareOptions.None;
160                         return _compareInfo.Compare (x, y, co);
161                 }
162
163                 public override bool Equals (string x, string y)
164                 {
165                         return Compare (x, y) == 0;
166                 }
167
168                 public override int GetHashCode (string s)
169                 {
170                         if (s == null)
171                                 throw new ArgumentNullException("s");
172
173                         CompareOptions co = _ignoreCase ? CompareOptions.IgnoreCase : 
174                                 CompareOptions.None;
175                         return _compareInfo.GetSortKey (s, co).GetHashCode ();
176                 }
177         }
178
179         [Serializable]
180         internal class OrdinalComparer : StringComparer
181         {
182                 public OrdinalComparer (bool ignoreCase)
183                 {
184                         _ignoreCase = ignoreCase;
185                 }
186
187                 public override int Compare (string x, string y)
188                 {
189                         if (!_ignoreCase)
190                                 return String.CompareOrdinal (x, y);
191
192                         // copied from String.CompareOrdinal()
193                         if (x == null) {
194                                 if (y == null)
195                                         return 0;
196                                 else
197                                         return -1;
198                         }
199                         else if (y == null) {
200                                 return 1;
201                         }
202
203                         int max = x.Length > y.Length ? y.Length : x.Length;
204                         for (int i = 0; i < max; i++) {
205                                 if (x [i] == y [i])
206                                         continue;
207                                 char xc = Char.ToUpperInvariant (x [i]);
208                                 char yc = Char.ToUpperInvariant (y [i]);
209                                 if (xc != yc)
210                                         return xc - yc;
211                         }
212                         return max < x.Length ? -1 :
213                                 max == y.Length ? 0 : 1;
214                 }
215
216                 public override bool Equals (string x, string y)
217                 {
218                         if (!_ignoreCase)
219                                 return x == y;
220                         return Compare (x, y) == 0;
221                 }
222
223                 public override int GetHashCode (string s)
224                 {
225                         if (!_ignoreCase)
226                                 return s.GetHashCode ();
227
228                         return s.GetCaseInsensitiveHashCode ();
229                 }
230
231                 readonly bool _ignoreCase;
232         }
233 }
234
235 #endif