5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
10 using System.Globalization;
11 using System.Threading;
17 public struct UInt32 : IComparable, IFormattable, IConvertible {
19 public const uint MaxValue = 0xffffffff;
20 public const uint MinValue = 0;
24 public int CompareTo (object v)
29 if (!(v is System.UInt32))
30 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt32"));
32 if (value == (uint) v)
41 public override bool Equals (object o)
43 if (!(o is System.UInt32))
46 return ((uint) o) == value;
49 public override int GetHashCode ()
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;
89 if (c >= '0' && c <= '9'){
90 uint d = (uint) (c - '0');
92 val = checked (val * 10 + d);
95 if (Char.IsWhiteSpace (c)){
96 for (i++; i < len; i++){
97 if (!Char.IsWhiteSpace (s [i]))
98 throw new FormatException ();
102 throw new FormatException ();
106 throw new FormatException ();
108 if (has_negative_sign)
109 throw new OverflowException ();
114 [CLSCompliant(false)]
115 public static uint Parse (string s, IFormatProvider fp)
117 return Parse (s, NumberStyles.Integer, fp);
120 [CLSCompliant(false)]
121 public static uint Parse (string s, NumberStyles style)
123 return Parse (s, style, null);
126 [CLSCompliant(false)]
127 public static uint Parse (string s, NumberStyles style, IFormatProvider fp)
130 throw new ArgumentNullException ();
133 throw new FormatException ("Input string was not in the correct format.");
135 NumberFormatInfo nfi;
137 Type typeNFI = typeof (System.Globalization.NumberFormatInfo);
138 nfi = (NumberFormatInfo) fp.GetFormat (typeNFI);
141 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
143 Int32.CheckStyle (style);
145 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
146 bool AllowExponent = (style & NumberStyles.AllowExponent) != 0;
147 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
148 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
149 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
150 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
151 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
152 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
153 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
154 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
158 if (AllowLeadingWhite)
159 pos = Int32.JumpOverWhite (pos, s, true);
161 bool foundOpenParentheses = false;
162 bool negative = false;
163 bool foundSign = false;
164 bool foundCurrency = false;
167 if (AllowParentheses && s [pos] == '(') {
168 foundOpenParentheses = true;
170 negative = true; // MS always make the number negative when there parentheses
171 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
173 if (AllowLeadingWhite)
174 pos = Int32.JumpOverWhite (pos, s, true);
176 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
177 throw new FormatException ("Input string was not in the correct format.");
178 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
179 throw new FormatException ("Input string was not in the correct format.");
182 if (AllowLeadingSign && !foundSign) {
184 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
186 if (AllowLeadingWhite)
187 pos = Int32.JumpOverWhite (pos, s, true);
188 if (AllowCurrencySymbol) {
189 Int32.FindCurrency (ref pos, s, nfi,
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,
207 if (foundSign && AllowLeadingWhite)
208 pos = Int32.JumpOverWhite (pos, s, true);
216 bool decimalPointFound = false;
221 // Just the same as Int32, but this one adds instead of substract
224 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
225 if (AllowThousands &&
226 Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
229 if (!decimalPointFound && AllowDecimalPoint &&
230 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
231 decimalPointFound = true;
237 else if (AllowHexSpecifier) {
239 hexDigit = s [pos++];
240 if (Char.IsDigit (hexDigit))
241 digitValue = (uint) (hexDigit - '0');
242 else if (Char.IsLower (hexDigit))
243 digitValue = (uint) (hexDigit - 'a' + 10);
245 digitValue = (uint) (hexDigit - 'A' + 10);
247 number = checked (number * 16 + digitValue);
249 else if (decimalPointFound) {
251 // Allows decimal point as long as it's only
252 // followed by zeroes.
253 if (s [pos++] != '0')
254 throw new OverflowException ("Value too large or too small.");
262 (uint) (s [pos++] - '0')
264 } catch (OverflowException) {
265 throw new OverflowException ("Value too large or too small.");
268 } while (pos < s.Length);
272 throw new FormatException ("Input string was not in the correct format.");
274 if (AllowTrailingSign && !foundSign) {
276 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
278 if (AllowTrailingWhite)
279 pos = Int32.JumpOverWhite (pos, s, true);
280 if (AllowCurrencySymbol)
281 Int32. FindCurrency (ref pos, s, nfi,
286 if (AllowCurrencySymbol && !foundCurrency) {
288 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
290 if (AllowTrailingWhite)
291 pos = Int32.JumpOverWhite (pos, s, true);
292 if (!foundSign && AllowTrailingSign)
293 Int32.FindSign (ref pos, s, nfi, ref foundSign,
298 if (AllowTrailingWhite && pos < s.Length)
299 pos = Int32.JumpOverWhite (pos, s, false);
301 if (foundOpenParentheses) {
302 if (pos >= s.Length || s [pos++] != ')')
303 throw new FormatException ("Input string was not in the correct " +
305 if (AllowTrailingWhite && pos < s.Length)
306 pos = Int32.JumpOverWhite (pos, s, false);
310 throw new FormatException ("Input string was not in the correct format.");
313 throw new OverflowException ( "Value too large or too small.");
318 public override string ToString ()
320 return ToString (null, null);
323 public string ToString (IFormatProvider fp)
325 return ToString (null, fp);
328 public string ToString (string format)
330 return ToString (format, null);
333 public string ToString (string format, IFormatProvider fp)
335 NumberFormatInfo nfi = NumberFormatInfo.GetInstance( fp );
337 if ( format == null )
340 return IntegerFormatter.NumberToString(format, nfi, value);
343 // =========== IConvertible Methods =========== //
345 public TypeCode GetTypeCode ()
347 return TypeCode.UInt32;
350 bool IConvertible.ToBoolean (IFormatProvider provider)
352 return System.Convert.ToBoolean (value);
355 byte IConvertible.ToByte (IFormatProvider provider)
357 return System.Convert.ToByte (value);
360 char IConvertible.ToChar (IFormatProvider provider)
362 return System.Convert.ToChar (value);
365 DateTime IConvertible.ToDateTime (IFormatProvider provider)
367 return System.Convert.ToDateTime (value);
370 decimal IConvertible.ToDecimal (IFormatProvider provider)
372 return System.Convert.ToDecimal (value);
375 double IConvertible.ToDouble (IFormatProvider provider)
377 return System.Convert.ToDouble (value);
380 short IConvertible.ToInt16 (IFormatProvider provider)
382 return System.Convert.ToInt16 (value);
385 int IConvertible.ToInt32 (IFormatProvider provider)
387 return System.Convert.ToInt32 (value);
390 long IConvertible.ToInt64 (IFormatProvider provider)
392 return System.Convert.ToInt64 (value);
395 [CLSCompliant (false)]
396 sbyte IConvertible.ToSByte (IFormatProvider provider)
398 return System.Convert.ToSByte (value);
401 float IConvertible.ToSingle (IFormatProvider provider)
403 return System.Convert.ToSingle (value);
406 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
408 return System.Convert.ToType (value, conversionType, provider);
411 [CLSCompliant (false)]
412 ushort IConvertible.ToUInt16 (IFormatProvider provider)
414 return System.Convert.ToUInt16 (value);
417 [CLSCompliant (false)]
418 uint IConvertible.ToUInt32 (IFormatProvider provider)
420 return System.Convert.ToUInt32 (value);
423 [CLSCompliant (false)]
424 ulong IConvertible.ToUInt64 (IFormatProvider provider)
426 return System.Convert.ToUInt64 (value);