5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004 Novell (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
30 using System
.Globalization
;
31 using System
.Threading
;
36 [CLSCompliant (false)]
37 public struct UInt32
: IFormattable
, IConvertible
,
39 IComparable
, IComparable
<UInt32
>
44 public const uint MaxValue
= 0xffffffff;
45 public const uint MinValue
= 0;
47 internal uint m_value
;
49 public int CompareTo (object value)
54 if (!(value is System
.UInt32
))
55 throw new ArgumentException (Locale
.GetText ("Value is not a System.UInt32."));
57 if (this.m_value
== (uint) value)
60 if (this.m_value
< (uint) value)
66 public override bool Equals (object obj
)
68 if (!(obj
is System
.UInt32
))
71 return ((uint) obj
) == m_value
;
74 public override int GetHashCode ()
80 public int CompareTo (uint value)
90 public bool Equals (uint value)
92 return value == m_value
;
96 internal static bool Parse (string s
, bool tryParse
, out uint result
)
101 bool digits_seen
= false;
102 bool has_negative_sign
= false;
110 throw new ArgumentNullException ("s");
115 for (i
= 0; i
< len
; i
++) {
117 if (!Char
.IsWhiteSpace (c
))
125 throw new FormatException ();
132 has_negative_sign
= true;
135 for (; i
< len
; i
++) {
138 if (c
>= '0' && c
<= '9') {
139 uint d
= (uint) (c
- '0');
141 val
= checked (val
* 10 + d
);
145 if (Char
.IsWhiteSpace (c
)) {
146 for (i
++; i
< len
; i
++) {
147 if (!Char
.IsWhiteSpace (s
[i
]))
151 throw new FormatException ();
158 throw new FormatException ();
165 throw new FormatException ();
167 // -0 is legal but other negative values are not
168 if (has_negative_sign
&& (val
> 0)) {
172 throw new OverflowException (
173 Locale
.GetText ("Negative number"));
180 internal static bool Parse (string s
, NumberStyles style
, IFormatProvider provider
, bool tryParse
, out uint result
)
188 throw new ArgumentNullException ("s");
194 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
196 NumberFormatInfo nfi
;
197 if (provider
!= null) {
198 Type typeNFI
= typeof (NumberFormatInfo
);
199 nfi
= (NumberFormatInfo
) provider
.GetFormat (typeNFI
);
202 nfi
= Thread
.CurrentThread
.CurrentCulture
.NumberFormat
;
204 Int32
.CheckStyle (style
);
206 bool AllowCurrencySymbol
= (style
& NumberStyles
.AllowCurrencySymbol
) != 0;
207 bool AllowHexSpecifier
= (style
& NumberStyles
.AllowHexSpecifier
) != 0;
208 bool AllowThousands
= (style
& NumberStyles
.AllowThousands
) != 0;
209 bool AllowDecimalPoint
= (style
& NumberStyles
.AllowDecimalPoint
) != 0;
210 bool AllowParentheses
= (style
& NumberStyles
.AllowParentheses
) != 0;
211 bool AllowTrailingSign
= (style
& NumberStyles
.AllowTrailingSign
) != 0;
212 bool AllowLeadingSign
= (style
& NumberStyles
.AllowLeadingSign
) != 0;
213 bool AllowTrailingWhite
= (style
& NumberStyles
.AllowTrailingWhite
) != 0;
214 bool AllowLeadingWhite
= (style
& NumberStyles
.AllowLeadingWhite
) != 0;
218 if (AllowLeadingWhite
)
219 pos
= Int32
.JumpOverWhite (pos
, s
, true);
221 bool foundOpenParentheses
= false;
222 bool negative
= false;
223 bool foundSign
= false;
224 bool foundCurrency
= false;
227 if (AllowParentheses
&& s
[pos
] == '(') {
228 foundOpenParentheses
= true;
230 negative
= true; // MS always make the number negative when there parentheses
231 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
233 if (AllowLeadingWhite
)
234 pos
= Int32
.JumpOverWhite (pos
, s
, true);
236 if (s
.Substring (pos
, nfi
.NegativeSign
.Length
) == nfi
.NegativeSign
)
240 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
241 if (s
.Substring (pos
, nfi
.PositiveSign
.Length
) == nfi
.PositiveSign
)
245 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
248 if (AllowLeadingSign
&& !foundSign
) {
250 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
252 if (AllowLeadingWhite
)
253 pos
= Int32
.JumpOverWhite (pos
, s
, true);
254 if (AllowCurrencySymbol
) {
255 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
256 if (foundCurrency
&& AllowLeadingWhite
)
257 pos
= Int32
.JumpOverWhite (pos
, s
, true);
262 if (AllowCurrencySymbol
&& !foundCurrency
) {
264 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
266 if (AllowLeadingWhite
)
267 pos
= Int32
.JumpOverWhite (pos
, s
, true);
269 if (!foundSign
&& AllowLeadingSign
) {
270 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
271 if (foundSign
&& AllowLeadingWhite
)
272 pos
= Int32
.JumpOverWhite (pos
, s
, true);
280 bool decimalPointFound
= false;
285 // Just the same as Int32, but this one adds instead of substract
288 if (!Int32
.ValidDigit (s
[pos
], AllowHexSpecifier
)) {
289 if (AllowThousands
&& Int32
.FindOther (ref pos
, s
, nfi
.NumberGroupSeparator
))
292 if (!decimalPointFound
&& AllowDecimalPoint
&&
293 Int32
.FindOther (ref pos
, s
, nfi
.NumberDecimalSeparator
)) {
294 decimalPointFound
= true;
299 else if (AllowHexSpecifier
) {
301 hexDigit
= s
[pos
++];
302 if (Char
.IsDigit (hexDigit
))
303 digitValue
= (uint) (hexDigit
- '0');
304 else if (Char
.IsLower (hexDigit
))
305 digitValue
= (uint) (hexDigit
- 'a' + 10);
307 digitValue
= (uint) (hexDigit
- 'A' + 10);
309 number
= checked (number
* 16 + digitValue
);
311 else if (decimalPointFound
) {
313 // Allows decimal point as long as it's only
314 // followed by zeroes.
315 if (s
[pos
++] != '0')
319 throw new OverflowException (Locale
.GetText ("Value too large or too small."));
325 number
= checked (number
* 10 + (uint) (s
[pos
++] - '0'));
327 catch (OverflowException
) {
331 throw new OverflowException (Locale
.GetText ("Value too large or too small."));
334 } while (pos
< s
.Length
);
341 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
343 if (AllowTrailingSign
&& !foundSign
) {
345 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
347 if (AllowTrailingWhite
)
348 pos
= Int32
.JumpOverWhite (pos
, s
, true);
349 if (AllowCurrencySymbol
)
350 Int32
. FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
354 if (AllowCurrencySymbol
&& !foundCurrency
) {
356 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
358 if (AllowTrailingWhite
)
359 pos
= Int32
.JumpOverWhite (pos
, s
, true);
360 if (!foundSign
&& AllowTrailingSign
)
361 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
365 if (AllowTrailingWhite
&& pos
< s
.Length
)
366 pos
= Int32
.JumpOverWhite (pos
, s
, false);
368 if (foundOpenParentheses
) {
369 if (pos
>= s
.Length
|| s
[pos
++] != ')')
373 throw new FormatException (Locale
.GetText
374 ("Input string was not in the correct format."));
375 if (AllowTrailingWhite
&& pos
< s
.Length
)
376 pos
= Int32
.JumpOverWhite (pos
, s
, false);
379 if (pos
< s
.Length
&& s
[pos
] != '\u0000')
383 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
385 // -0 is legal but other negative values are not
386 if (negative
&& (number
> 0)) {
390 throw new OverflowException (
391 Locale
.GetText ("Negative number"));
399 [CLSCompliant (false)]
400 public static uint Parse (string s
) {
403 Parse (s
, false, out res
);
408 [CLSCompliant (false)]
409 public static uint Parse (string s
, NumberStyles style
, IFormatProvider fp
) {
412 Parse (s
, style
, fp
, false, out res
);
417 [CLSCompliant (false)]
418 public static uint Parse (string s
, IFormatProvider provider
)
420 return Parse (s
, NumberStyles
.Integer
, provider
);
423 [CLSCompliant (false)]
424 public static uint Parse (string s
, NumberStyles style
)
426 return Parse (s
, style
, null);
430 [CLSCompliant (false)]
431 public static bool TryParse (string s
, out uint result
) {
433 return Parse (s
, true, out result
);
441 [CLSCompliant (false)]
442 public static bool TryParse (string s
, NumberStyles style
, IFormatProvider provider
, out uint result
) {
444 return Parse (s
, style
, provider
, true, out result
);
453 public override string ToString ()
455 return ToString (null, null);
458 public string ToString (IFormatProvider fp
)
460 return ToString (null, fp
);
463 public string ToString (string format
)
465 return ToString (format
, null);
468 public string ToString (string format
, IFormatProvider fp
)
470 NumberFormatInfo nfi
= NumberFormatInfo
.GetInstance (fp
);
472 // use "G" when format is null or String.Empty
473 if ((format
== null) || (format
.Length
== 0))
476 return IntegerFormatter
.NumberToString (format
, nfi
, m_value
);
479 // =========== IConvertible Methods =========== //
480 public TypeCode
GetTypeCode ()
482 return TypeCode
.UInt32
;
485 bool IConvertible
.ToBoolean (IFormatProvider provider
)
487 return System
.Convert
.ToBoolean (m_value
);
490 byte IConvertible
.ToByte (IFormatProvider provider
)
492 return System
.Convert
.ToByte (m_value
);
495 char IConvertible
.ToChar (IFormatProvider provider
)
497 return System
.Convert
.ToChar (m_value
);
500 DateTime IConvertible
.ToDateTime (IFormatProvider provider
)
502 return System
.Convert
.ToDateTime (m_value
);
505 decimal IConvertible
.ToDecimal (IFormatProvider provider
)
507 return System
.Convert
.ToDecimal (m_value
);
510 double IConvertible
.ToDouble (IFormatProvider provider
)
512 return System
.Convert
.ToDouble (m_value
);
515 short IConvertible
.ToInt16 (IFormatProvider provider
)
517 return System
.Convert
.ToInt16 (m_value
);
520 int IConvertible
.ToInt32 (IFormatProvider provider
)
522 return System
.Convert
.ToInt32 (m_value
);
525 long IConvertible
.ToInt64 (IFormatProvider provider
)
527 return System
.Convert
.ToInt64 (m_value
);
530 sbyte IConvertible
.ToSByte (IFormatProvider provider
)
532 return System
.Convert
.ToSByte (m_value
);
535 float IConvertible
.ToSingle (IFormatProvider provider
)
537 return System
.Convert
.ToSingle (m_value
);
540 object IConvertible
.ToType (Type conversionType
, IFormatProvider provider
)
542 return System
.Convert
.ToType (m_value
, conversionType
, provider
);
545 ushort IConvertible
.ToUInt16 (IFormatProvider provider
)
547 return System
.Convert
.ToUInt16 (m_value
);
550 uint IConvertible
.ToUInt32 (IFormatProvider provider
)
555 ulong IConvertible
.ToUInt64 (IFormatProvider provider
)
557 return System
.Convert
.ToUInt64 (m_value
);