5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
10 using System.Globalization;
11 using System.Threading;
16 [CLSCompliant (false)]
17 public struct UInt32 : IComparable, IFormattable, IConvertible
19 public const uint MaxValue = 0xffffffff;
20 public const uint MinValue = 0;
24 public int CompareTo (object value)
29 if (!(value is System.UInt32))
30 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt32."));
32 if (this.value == (uint) value)
35 if (this.value < (uint) value)
41 public override bool Equals (object obj)
43 if (!(obj is System.UInt32))
46 return ((uint) obj) == value;
49 public override int GetHashCode ()
54 [CLSCompliant (false)]
55 public static uint Parse (string s)
60 bool digits_seen = false;
61 bool has_negative_sign = false;
64 throw new ArgumentNullException (Locale.GetText ("s is null"));
69 for (i = 0; i < len; i++) {
71 if (!Char.IsWhiteSpace (c))
76 throw new FormatException ();
83 has_negative_sign = true;
86 for (; i < len; i++) {
89 if (c >= '0' && c <= '9') {
90 uint d = (uint) (c - '0');
92 val = checked (val * 10 + d);
96 if (Char.IsWhiteSpace (c)) {
97 for (i++; i < len; i++) {
98 if (!Char.IsWhiteSpace (s [i]))
99 throw new FormatException ();
103 throw new FormatException ();
107 throw new FormatException ();
109 if (has_negative_sign)
110 throw new OverflowException ();
115 [CLSCompliant (false)]
116 public static uint Parse (string s, IFormatProvider provider)
118 return Parse (s, NumberStyles.Integer, provider);
121 [CLSCompliant (false)]
122 public static uint Parse (string s, NumberStyles style)
124 return Parse (s, style, null);
127 [CLSCompliant (false)]
128 public static uint Parse (string s, NumberStyles style, IFormatProvider provider)
131 throw new ArgumentNullException ();
134 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
136 NumberFormatInfo nfi;
137 if (provider != null) {
138 Type typeNFI = typeof (NumberFormatInfo);
139 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
142 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
144 Int32.CheckStyle (style);
146 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
147 bool AllowExponent = (style & NumberStyles.AllowExponent) != 0;
148 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
149 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
150 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
151 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
152 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
153 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
154 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
155 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
159 if (AllowLeadingWhite)
160 pos = Int32.JumpOverWhite (pos, s, true);
162 bool foundOpenParentheses = false;
163 bool negative = false;
164 bool foundSign = false;
165 bool foundCurrency = false;
168 if (AllowParentheses && s [pos] == '(') {
169 foundOpenParentheses = true;
171 negative = true; // MS always make the number negative when there parentheses
172 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
174 if (AllowLeadingWhite)
175 pos = Int32.JumpOverWhite (pos, s, true);
177 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
178 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
179 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
180 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
183 if (AllowLeadingSign && !foundSign) {
185 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
187 if (AllowLeadingWhite)
188 pos = Int32.JumpOverWhite (pos, s, true);
189 if (AllowCurrencySymbol) {
190 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
191 if (foundCurrency && AllowLeadingWhite)
192 pos = Int32.JumpOverWhite (pos, s, true);
197 if (AllowCurrencySymbol && !foundCurrency) {
199 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
201 if (AllowLeadingWhite)
202 pos = Int32.JumpOverWhite (pos, s, true);
204 if (!foundSign && AllowLeadingSign) {
205 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
206 if (foundSign && AllowLeadingWhite)
207 pos = Int32.JumpOverWhite (pos, s, true);
215 bool decimalPointFound = false;
220 // Just the same as Int32, but this one adds instead of substract
223 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
224 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
227 if (!decimalPointFound && AllowDecimalPoint &&
228 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
229 decimalPointFound = true;
234 else if (AllowHexSpecifier) {
236 hexDigit = s [pos++];
237 if (Char.IsDigit (hexDigit))
238 digitValue = (uint) (hexDigit - '0');
239 else if (Char.IsLower (hexDigit))
240 digitValue = (uint) (hexDigit - 'a' + 10);
242 digitValue = (uint) (hexDigit - 'A' + 10);
244 number = checked (number * 16 + digitValue);
246 else if (decimalPointFound) {
248 // Allows decimal point as long as it's only
249 // followed by zeroes.
250 if (s [pos++] != '0')
251 throw new OverflowException (Locale.GetText ("Value too large or too small."));
257 number = checked (number * 10 + (uint) (s [pos++] - '0'));
259 catch (OverflowException) {
260 throw new OverflowException (Locale.GetText ("Value too large or too small."));
263 } while (pos < s.Length);
267 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
269 if (AllowTrailingSign && !foundSign) {
271 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
273 if (AllowTrailingWhite)
274 pos = Int32.JumpOverWhite (pos, s, true);
275 if (AllowCurrencySymbol)
276 Int32. FindCurrency (ref pos, s, nfi, ref foundCurrency);
280 if (AllowCurrencySymbol && !foundCurrency) {
282 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
284 if (AllowTrailingWhite)
285 pos = Int32.JumpOverWhite (pos, s, true);
286 if (!foundSign && AllowTrailingSign)
287 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
291 if (AllowTrailingWhite && pos < s.Length)
292 pos = Int32.JumpOverWhite (pos, s, false);
294 if (foundOpenParentheses) {
295 if (pos >= s.Length || s [pos++] != ')')
296 throw new FormatException (Locale.GetText
297 ("Input string was not in the correct format."));
298 if (AllowTrailingWhite && pos < s.Length)
299 pos = Int32.JumpOverWhite (pos, s, false);
302 if (pos < s.Length && s [pos] != '\u0000')
303 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
306 throw new OverflowException (Locale.GetText ("Value too large or too small."));
311 public override string ToString ()
313 return ToString (null, null);
316 public string ToString (IFormatProvider fp)
318 return ToString (null, fp);
321 public string ToString (string format)
323 return ToString (format, null);
326 public string ToString (string format, IFormatProvider fp)
328 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (fp);
333 return IntegerFormatter.NumberToString (format, nfi, value);
336 // =========== IConvertible Methods =========== //
337 public TypeCode GetTypeCode ()
339 return TypeCode.UInt32;
342 bool IConvertible.ToBoolean (IFormatProvider provider)
344 return System.Convert.ToBoolean (value);
347 byte IConvertible.ToByte (IFormatProvider provider)
349 return System.Convert.ToByte (value);
352 char IConvertible.ToChar (IFormatProvider provider)
354 return System.Convert.ToChar (value);
357 DateTime IConvertible.ToDateTime (IFormatProvider provider)
359 return System.Convert.ToDateTime (value);
362 decimal IConvertible.ToDecimal (IFormatProvider provider)
364 return System.Convert.ToDecimal (value);
367 double IConvertible.ToDouble (IFormatProvider provider)
369 return System.Convert.ToDouble (value);
372 short IConvertible.ToInt16 (IFormatProvider provider)
374 return System.Convert.ToInt16 (value);
377 int IConvertible.ToInt32 (IFormatProvider provider)
379 return System.Convert.ToInt32 (value);
382 long IConvertible.ToInt64 (IFormatProvider provider)
384 return System.Convert.ToInt64 (value);
387 [CLSCompliant (false)]
388 sbyte IConvertible.ToSByte (IFormatProvider provider)
390 return System.Convert.ToSByte (value);
393 float IConvertible.ToSingle (IFormatProvider provider)
395 return System.Convert.ToSingle (value);
398 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
400 return System.Convert.ToType (value, conversionType, provider);
403 [CLSCompliant (false)]
404 ushort IConvertible.ToUInt16 (IFormatProvider provider)
406 return System.Convert.ToUInt16 (value);
409 [CLSCompliant (false)]
410 uint IConvertible.ToUInt32 (IFormatProvider provider)
412 return System.Convert.ToUInt32 (value);
415 [CLSCompliant (false)]
416 ulong IConvertible.ToUInt64 (IFormatProvider provider)
418 return System.Convert.ToUInt64 (value);