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, IComparable
39 , IComparable<UInt32>, IEquatable <UInt32>
42 public const uint MaxValue = 0xffffffff;
43 public const uint MinValue = 0;
45 internal uint m_value;
47 public int CompareTo (object value)
52 if (!(value is System.UInt32))
53 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt32."));
55 if (this.m_value == (uint) value)
58 if (this.m_value < (uint) value)
64 public override bool Equals (object obj)
66 if (!(obj is System.UInt32))
69 return ((uint) obj) == m_value;
72 public override int GetHashCode ()
78 public int CompareTo (uint value)
88 public bool Equals (uint value)
90 return value == m_value;
94 internal static bool Parse (string s, bool tryParse, out uint result, out Exception exc)
99 bool digits_seen = false;
100 bool has_negative_sign = false;
107 exc = new ArgumentNullException ("s");
114 for (i = 0; i < len; i++) {
116 if (!Char.IsWhiteSpace (c))
122 exc = Int32.GetFormatException ();
131 has_negative_sign = true;
134 for (; i < len; i++) {
137 if (c >= '0' && c <= '9') {
138 uint d = (uint) (c - '0');
140 val = checked (val * 10 + d);
144 if (Char.IsWhiteSpace (c)) {
145 for (i++; i < len; i++) {
146 if (!Char.IsWhiteSpace (s [i])) {
148 exc = Int32.GetFormatException ();
155 exc = Int32.GetFormatException ();
162 exc = Int32.GetFormatException ();
166 // -0 is legal but other negative values are not
167 if (has_negative_sign && (val > 0)) {
169 exc = new OverflowException (
170 Locale.GetText ("Negative number"));
178 internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out uint result, out Exception exc)
185 exc = new ArgumentNullException ("s");
191 exc = Int32.GetFormatException ();
195 NumberFormatInfo nfi;
196 if (provider != null) {
197 Type typeNFI = typeof (NumberFormatInfo);
198 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
201 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
203 if (!Int32.CheckStyle (style, tryParse, ref exc))
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 && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
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 && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
236 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign) {
238 exc = Int32.GetFormatException ();
241 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) {
243 exc = Int32.GetFormatException ();
248 if (AllowLeadingSign && !foundSign) {
250 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
252 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
254 if (AllowCurrencySymbol) {
255 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
256 if (foundCurrency && AllowLeadingWhite &&
257 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
263 if (AllowCurrencySymbol && !foundCurrency) {
265 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
267 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
270 if (!foundSign && AllowLeadingSign) {
271 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
272 if (foundSign && AllowLeadingWhite &&
273 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
282 bool decimalPointFound = false;
287 // Just the same as Int32, but this one adds instead of substract
290 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
291 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
294 if (!decimalPointFound && AllowDecimalPoint &&
295 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
296 decimalPointFound = true;
301 else if (AllowHexSpecifier) {
303 hexDigit = s [pos++];
304 if (Char.IsDigit (hexDigit))
305 digitValue = (uint) (hexDigit - '0');
306 else if (Char.IsLower (hexDigit))
307 digitValue = (uint) (hexDigit - 'a' + 10);
309 digitValue = (uint) (hexDigit - 'A' + 10);
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 fp)
416 if (!Parse (s, style, fp, 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.FormatGeneral (new NumberFormatter.NumberStore (m_value));
465 public string ToString (IFormatProvider fp)
467 return NumberFormatter.FormatGeneral (new NumberFormatter.NumberStore (m_value), fp);
470 public string ToString (string format)
472 return ToString (format, null);
475 public string ToString (string format, IFormatProvider fp)
477 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (fp);
478 return NumberFormatter.NumberToString (format, m_value, nfi);
481 // =========== IConvertible Methods =========== //
482 public TypeCode GetTypeCode ()
484 return TypeCode.UInt32;
487 bool IConvertible.ToBoolean (IFormatProvider provider)
489 return System.Convert.ToBoolean (m_value);
492 byte IConvertible.ToByte (IFormatProvider provider)
494 return System.Convert.ToByte (m_value);
497 char IConvertible.ToChar (IFormatProvider provider)
499 return System.Convert.ToChar (m_value);
502 DateTime IConvertible.ToDateTime (IFormatProvider provider)
504 return System.Convert.ToDateTime (m_value);
507 decimal IConvertible.ToDecimal (IFormatProvider provider)
509 return System.Convert.ToDecimal (m_value);
512 double IConvertible.ToDouble (IFormatProvider provider)
514 return System.Convert.ToDouble (m_value);
517 short IConvertible.ToInt16 (IFormatProvider provider)
519 return System.Convert.ToInt16 (m_value);
522 int IConvertible.ToInt32 (IFormatProvider provider)
524 return System.Convert.ToInt32 (m_value);
527 long IConvertible.ToInt64 (IFormatProvider provider)
529 return System.Convert.ToInt64 (m_value);
532 sbyte IConvertible.ToSByte (IFormatProvider provider)
534 return System.Convert.ToSByte (m_value);
537 float IConvertible.ToSingle (IFormatProvider provider)
539 return System.Convert.ToSingle (m_value);
542 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
544 return System.Convert.ToType (m_value, conversionType, provider);
547 ushort IConvertible.ToUInt16 (IFormatProvider provider)
549 return System.Convert.ToUInt16 (m_value);
552 uint IConvertible.ToUInt32 (IFormatProvider provider)
557 ulong IConvertible.ToUInt64 (IFormatProvider provider)
559 return System.Convert.ToUInt64 (m_value);