Merge remote-tracking branch 'local/msvc-updates' into msvc-updates
[mono.git] / mcs / class / corlib / System.Globalization / RegionInfo.cs
1 //
2 // System.Globalization.RegionInfo.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7
8 //
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System.Runtime.CompilerServices;
31 using System.Runtime.InteropServices;
32
33 namespace System.Globalization
34 {
35         [System.Runtime.InteropServices.ComVisible(true)]
36         [Serializable]
37         [StructLayout (LayoutKind.Sequential)]
38         public partial class RegionInfo
39         {
40                 static RegionInfo currentRegion;
41
42                 // This property is not synchronized with CurrentCulture, so
43                 // we need to use bootstrap CurrentCulture LCID.
44                 public static RegionInfo CurrentRegion {
45                         get {
46                                 if (currentRegion == null) {
47                                         // make sure to fill BootstrapCultureID.
48                                         CultureInfo ci = CultureInfo.CurrentCulture;
49                                         // If current culture is invariant then region is not available.
50                                         if (ci != null && CultureInfo.BootstrapCultureID != 0x7F)
51                                                 currentRegion = new RegionInfo (CultureInfo.BootstrapCultureID);
52                                         else
53 #if MONOTOUCH
54                                                 currentRegion = CreateFromNSLocale ();
55 #else
56                                                 currentRegion = null;
57 #endif
58                                 }
59                                 return currentRegion;
60                         }
61                 }
62                 
63                 // the following (instance) fields must be _first_ and stay synchronized
64                 // with the mono's MonoRegionInfo defined in mono/metadata/object-internals.h
65 #pragma warning disable 649
66                 int regionId;
67                 string iso2Name;
68                 string iso3Name;
69                 string win3Name;
70                 string englishName;
71                 string currencySymbol;
72                 string isoCurrencySymbol;
73                 string currencyEnglishName;
74 #pragma warning restore 649
75                 
76                 // new (instance) fields should be added here (and do not have to be duplicated in the runtime)
77                 
78                 int lcid; // it is used only for Equals() (not even used in GetHashCode()).
79                 
80                 public RegionInfo (int culture)
81                 {
82                         if (!GetByTerritory (CultureInfo.GetCultureInfo (culture)))
83                                 throw new ArgumentException (
84                                         String.Format ("Region ID {0} (0x{0:X4}) is not a supported region.", culture), "culture");
85                 }
86
87                 public RegionInfo (string name)
88                 {
89                         if (name == null)
90                                 throw new ArgumentNullException ();
91
92                         if (construct_internal_region_from_name (name.ToUpperInvariant ())) {
93                                 lcid = name.GetHashCode (); // random-ish
94                                 return;
95                         }
96                         if (!GetByTerritory (CultureInfo.GetCultureInfo (name)))
97                                 throw new ArgumentException (String.Format ("Region name {0} is not supported.", name), "name");
98                 }
99
100                 bool GetByTerritory (CultureInfo ci)
101                 {
102                         if (ci == null)
103                                 throw new Exception ("INTERNAL ERROR: should not happen.");
104                         if (ci.IsNeutralCulture || ci.Territory == null)
105                                 return false;
106                         this.lcid = ci.LCID;
107                         return construct_internal_region_from_name (ci.Territory.ToUpperInvariant ());
108                 }
109
110                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
111                 private extern bool construct_internal_region_from_name (string name);
112
113                 [System.Runtime.InteropServices.ComVisible(false)]
114                 public virtual string CurrencyEnglishName {
115                         get { return currencyEnglishName; }
116                 }
117
118                 public virtual string CurrencySymbol {
119                         get { return currencySymbol; }
120                 }
121
122                 [MonoTODO ("DisplayName currently only returns the EnglishName")]
123                 public virtual string DisplayName {
124                         get { return englishName; }
125                 }
126
127                 public virtual string EnglishName {
128                         get { return englishName; }
129                 }
130
131                 [System.Runtime.InteropServices.ComVisible(false)]
132                 public virtual int GeoId {
133                         get { return regionId; }
134                 }
135
136                 public virtual bool IsMetric {
137                         get {
138                                 switch (iso2Name) {
139                                 case "US":
140                                 case "UK":
141                                         return false;
142                                 default:
143                                         return true;
144                                 }
145                         }
146                 }
147
148                 public virtual string ISOCurrencySymbol {
149                         get { return isoCurrencySymbol; }
150                 }
151
152                 [System.Runtime.InteropServices.ComVisible(false)]
153                 public virtual string NativeName {
154                         get { return DisplayName; }
155                 }
156
157                 [MonoTODO ("Not implemented")]
158                 [System.Runtime.InteropServices.ComVisible(false)]
159                 public virtual string CurrencyNativeName {
160                         get { throw new NotImplementedException (); }
161                 }
162
163                 public virtual string Name {
164                         get { return iso2Name; }
165                 }
166
167                 public virtual string ThreeLetterISORegionName {
168                         get { return iso3Name; }
169                 }
170
171                 public virtual string ThreeLetterWindowsRegionName {
172                         get { return win3Name; }
173                 }
174                 
175                 public virtual string TwoLetterISORegionName {
176                         get { return iso2Name; }
177                 }
178
179                 //
180                 // methods
181
182                 public override bool Equals (object value)
183                 {
184                         RegionInfo other = value as RegionInfo;
185                         return other != null && lcid == other.lcid;
186                 }
187
188                 public override int GetHashCode ()
189                 {
190                         return (int) (0x80000000 + (regionId << 3) + regionId); // it i still based on regionId
191                 }
192
193                 public override string ToString ()
194                 {
195                         return Name;
196                 }
197         }
198 }