Merge pull request #3240 from alexanderkyte/aot_compiler_leaks
[mono.git] / mcs / class / Facades / System.Globalization.Extensions / GlobalizationExtensions.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System;
6 using System.Diagnostics;
7 using System.Diagnostics.Contracts;
8
9 namespace System.Globalization
10 {
11     public static class GlobalizationExtensions
12     {
13         public static StringComparer GetStringComparer(this CompareInfo compareInfo, CompareOptions options)
14         {
15             if (compareInfo == null)
16             {
17                 throw new ArgumentNullException(nameof(compareInfo));
18             }
19
20             if (options == CompareOptions.Ordinal)
21             {
22                 return StringComparer.Ordinal;
23             }
24
25             if (options == CompareOptions.OrdinalIgnoreCase)
26             {
27                 return StringComparer.OrdinalIgnoreCase;
28             }
29
30             if ((options & CultureAwareComparer.ValidCompareMaskOffFlags) != 0)
31             {
32                 throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
33             }
34
35             return new CultureAwareComparer(compareInfo, options);
36         }
37     }
38
39     internal sealed class CultureAwareComparer : StringComparer
40     {
41         internal const CompareOptions ValidCompareMaskOffFlags =
42             ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
43               CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
44
45         private readonly CompareInfo _compareInfo;
46         private readonly CompareOptions _options;
47
48         internal CultureAwareComparer(CompareInfo compareInfo, CompareOptions options)
49         {
50             Debug.Assert((options & ValidCompareMaskOffFlags) == 0);
51             _compareInfo = compareInfo;
52             _options = options;
53         }
54
55         public override int Compare(string x, string y)
56         {
57             if (Object.ReferenceEquals(x, y)) return 0;
58             if (x == null) return -1;
59             if (y == null) return 1;
60             return _compareInfo.Compare(x, y, _options);
61         }
62
63         public override bool Equals(string x, string y)
64         {
65             if (Object.ReferenceEquals(x, y)) return true;
66             if (x == null || y == null) return false;
67
68             return (_compareInfo.Compare(x, y, _options) == 0);
69         }
70
71         public override int GetHashCode(string obj)
72         {
73             if (obj == null)
74             {
75                 throw new ArgumentNullException(nameof(obj));
76             }
77             Contract.EndContractBlock();
78
79             // StringSort used in compare operation and not with the hashing
80             return _compareInfo.GetHashCode(obj, _options & (~CompareOptions.StringSort));
81         }
82
83         // Equals method for the comparer itself. 
84         public override bool Equals(object obj)
85         {
86             CultureAwareComparer comparer = obj as CultureAwareComparer;
87             return
88                 comparer != null &&
89                 _options == comparer._options &&
90                 _compareInfo.Equals(comparer._compareInfo);
91         }
92
93         public override int GetHashCode()
94         {
95             return _compareInfo.GetHashCode() ^ ((int)_options & 0x7FFFFFFF);
96         }
97     }
98 }