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)]
38 [System.Runtime.InteropServices.ComVisible (true)]
40 public struct UInt32 : IFormattable, IConvertible, IComparable
42 , IComparable<UInt32>, IEquatable <UInt32>
45 public const uint MaxValue = 0xffffffff;
46 public const uint MinValue = 0;
48 internal uint m_value;
50 public int CompareTo (object value)
55 if (!(value is System.UInt32))
56 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt32."));
58 uint val = (uint) value;
63 return (m_value < val) ? -1 : 1;
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 obj)
92 return obj == m_value;
96 internal static bool Parse (string s, bool tryParse, out uint result, out Exception exc)
101 bool digits_seen = false;
102 bool has_negative_sign = false;
109 exc = new ArgumentNullException ("s");
116 for (i = 0; i < len; i++) {
118 if (!Char.IsWhiteSpace (c))
124 exc = Int32.GetFormatException ();
133 has_negative_sign = true;
136 for (; i < len; i++) {
139 if (c >= '0' && c <= '9') {
140 uint d = (uint) (c - '0');
142 if ((val > MaxValue/10) || (val == (MaxValue / 10) && d > (MaxValue % 10))){
144 exc = new OverflowException (Locale.GetText ("Value is too large"));
147 val = (val * 10) + d;
149 } else if (!Int32.ProcessTrailingWhitespace (tryParse, s, i, ref exc)){
155 exc = Int32.GetFormatException ();
159 // -0 is legal but other negative values are not
160 if (has_negative_sign && (val > 0)) {
162 exc = new OverflowException (
163 Locale.GetText ("Negative number"));
171 internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out uint result, out Exception exc)
178 exc = new ArgumentNullException ("s");
184 exc = Int32.GetFormatException ();
188 NumberFormatInfo nfi;
189 if (provider != null) {
190 Type typeNFI = typeof (NumberFormatInfo);
191 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
194 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
196 if (!Int32.CheckStyle (style, tryParse, ref exc))
199 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
200 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
201 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
202 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
203 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
204 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
205 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
206 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
207 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
211 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
214 bool foundOpenParentheses = false;
215 bool negative = false;
216 bool foundSign = false;
217 bool foundCurrency = false;
220 if (AllowParentheses && s [pos] == '(') {
221 foundOpenParentheses = true;
223 negative = true; // MS always make the number negative when there parentheses
224 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
226 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
229 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign) {
231 exc = Int32.GetFormatException ();
234 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) {
236 exc = Int32.GetFormatException ();
241 if (AllowLeadingSign && !foundSign) {
243 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
245 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
247 if (AllowCurrencySymbol) {
248 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
249 if (foundCurrency && AllowLeadingWhite &&
250 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
256 if (AllowCurrencySymbol && !foundCurrency) {
258 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
260 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
263 if (!foundSign && AllowLeadingSign) {
264 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
265 if (foundSign && AllowLeadingWhite &&
266 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
275 bool decimalPointFound = false;
280 // Just the same as Int32, but this one adds instead of substract
283 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
284 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
287 if (!decimalPointFound && AllowDecimalPoint &&
288 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
289 decimalPointFound = true;
294 else if (AllowHexSpecifier) {
296 hexDigit = s [pos++];
297 if (Char.IsDigit (hexDigit))
298 digitValue = (uint) (hexDigit - '0');
299 else if (Char.IsLower (hexDigit))
300 digitValue = (uint) (hexDigit - 'a' + 10);
302 digitValue = (uint) (hexDigit - 'A' + 10);
305 ulong l = number * 16 + digitValue;
311 number = checked (number * 16 + digitValue);
313 else if (decimalPointFound) {
315 // Allows decimal point as long as it's only
316 // followed by zeroes.
317 if (s [pos++] != '0') {
319 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
327 number = checked (number * 10 + (uint) (s [pos++] - '0'));
329 catch (OverflowException) {
331 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
335 } while (pos < s.Length);
340 exc = Int32.GetFormatException ();
344 if (AllowTrailingSign && !foundSign) {
346 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
348 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
350 if (AllowCurrencySymbol)
351 Int32. FindCurrency (ref pos, s, nfi, ref foundCurrency);
355 if (AllowCurrencySymbol && !foundCurrency) {
357 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
359 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
361 if (!foundSign && AllowTrailingSign)
362 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
366 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
369 if (foundOpenParentheses) {
370 if (pos >= s.Length || s [pos++] != ')') {
372 exc = Int32.GetFormatException ();
375 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
379 if (pos < s.Length && s [pos] != '\u0000') {
381 exc = Int32.GetFormatException ();
385 // -0 is legal but other negative values are not
386 if (negative && (number > 0)) {
388 exc = new OverflowException (
389 Locale.GetText ("Negative number"));
398 [CLSCompliant (false)]
399 public static uint Parse (string s)
404 if (!Parse (s, false, out res, out exc))
410 [CLSCompliant (false)]
411 public static uint Parse (string s, NumberStyles style, IFormatProvider provider)
416 if (!Parse (s, style, provider, false, out res, out exc))
422 [CLSCompliant (false)]
423 public static uint Parse (string s, IFormatProvider provider)
425 return Parse (s, NumberStyles.Integer, provider);
428 [CLSCompliant (false)]
429 public static uint Parse (string s, NumberStyles style)
431 return Parse (s, style, null);
435 [CLSCompliant (false)]
436 public static bool TryParse (string s, out uint result)
439 if (!Parse (s, true, out result, out exc)) {
447 [CLSCompliant (false)]
448 public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out uint result)
451 if (!Parse (s, style, provider, true, out result, out exc)) {
460 public override string ToString ()
462 return NumberFormatter.NumberToString (m_value, null);
465 public string ToString (IFormatProvider provider)
467 return NumberFormatter.NumberToString (m_value, provider);
470 public string ToString (string format)
472 return ToString (format, null);
475 public string ToString (string format, IFormatProvider provider)
477 return NumberFormatter.NumberToString (format, m_value, provider);
480 // =========== IConvertible Methods =========== //
481 public TypeCode GetTypeCode ()
483 return TypeCode.UInt32;
486 bool IConvertible.ToBoolean (IFormatProvider provider)
488 return System.Convert.ToBoolean (m_value);
491 byte IConvertible.ToByte (IFormatProvider provider)
493 return System.Convert.ToByte (m_value);
496 char IConvertible.ToChar (IFormatProvider provider)
498 return System.Convert.ToChar (m_value);
501 DateTime IConvertible.ToDateTime (IFormatProvider provider)
503 return System.Convert.ToDateTime (m_value);
506 decimal IConvertible.ToDecimal (IFormatProvider provider)
508 return System.Convert.ToDecimal (m_value);
511 double IConvertible.ToDouble (IFormatProvider provider)
513 return System.Convert.ToDouble (m_value);
516 short IConvertible.ToInt16 (IFormatProvider provider)
518 return System.Convert.ToInt16 (m_value);
521 int IConvertible.ToInt32 (IFormatProvider provider)
523 return System.Convert.ToInt32 (m_value);
526 long IConvertible.ToInt64 (IFormatProvider provider)
528 return System.Convert.ToInt64 (m_value);
531 sbyte IConvertible.ToSByte (IFormatProvider provider)
533 return System.Convert.ToSByte (m_value);
536 float IConvertible.ToSingle (IFormatProvider provider)
538 return System.Convert.ToSingle (m_value);
541 object IConvertible.ToType (Type type, IFormatProvider provider)
543 return System.Convert.ToType (m_value, type, provider);
546 ushort IConvertible.ToUInt16 (IFormatProvider provider)
548 return System.Convert.ToUInt16 (m_value);
551 uint IConvertible.ToUInt32 (IFormatProvider provider)
556 ulong IConvertible.ToUInt64 (IFormatProvider provider)
558 return System.Convert.ToUInt64 (m_value);