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);