5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004 Novell, Inc (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 UInt64 : IFormattable, IConvertible, IComparable
39 , IComparable<UInt64>, IEquatable <UInt64>
42 public const ulong MaxValue = 0xffffffffffffffff;
43 public const ulong MinValue = 0;
45 internal ulong m_value;
47 public int CompareTo (object value)
52 if (!(value is System.UInt64))
53 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt64."));
55 if (this.m_value == (ulong) value)
58 if (this.m_value < (ulong) value)
64 public override bool Equals (object obj)
66 if (!(obj is System.UInt64))
69 return ((ulong) obj) == m_value;
72 public override int GetHashCode ()
74 return (int)(m_value & 0xffffffff) ^ (int)(m_value >> 32);
78 public int CompareTo (ulong value)
88 public bool Equals (ulong value)
90 return value == m_value;
94 [CLSCompliant (false)]
95 public static ulong Parse (string s)
97 return Parse (s, NumberStyles.Integer, null);
100 [CLSCompliant (false)]
101 public static ulong Parse (string s, IFormatProvider provider)
103 return Parse (s, NumberStyles.Integer, provider);
106 [CLSCompliant (false)]
107 public static ulong Parse (string s, NumberStyles style)
109 return Parse (s, style, null);
112 internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out ulong result, out Exception exc)
119 exc = new ArgumentNullException ("s");
125 exc = Int32.GetFormatException ();
129 NumberFormatInfo nfi;
130 if (provider != null) {
131 Type typeNFI = typeof (NumberFormatInfo);
132 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
135 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
137 if (!Int32.CheckStyle (style, tryParse, ref exc))
140 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
141 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
142 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
143 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
144 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
145 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
146 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
147 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
148 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
152 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
155 bool foundOpenParentheses = false;
156 bool negative = false;
157 bool foundSign = false;
158 bool foundCurrency = false;
161 if (AllowParentheses && s [pos] == '(') {
162 foundOpenParentheses = true;
164 negative = true; // MS always make the number negative when there parentheses
165 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
167 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
170 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign) {
172 exc = Int32.GetFormatException ();
175 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) {
177 exc = Int32.GetFormatException ();
182 if (AllowLeadingSign && !foundSign) {
184 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
186 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
188 if (AllowCurrencySymbol) {
189 Int32.FindCurrency (ref pos, s, nfi,
191 if (foundCurrency && AllowLeadingWhite &&
192 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
198 if (AllowCurrencySymbol && !foundCurrency) {
200 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
202 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
205 if (!foundSign && AllowLeadingSign) {
206 Int32.FindSign (ref pos, s, nfi, ref foundSign,
208 if (foundSign && AllowLeadingWhite &&
209 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
218 bool decimalPointFound = false;
223 // Just the same as Int32, but this one adds instead of substract
226 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
227 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
230 if (!decimalPointFound && AllowDecimalPoint &&
231 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
232 decimalPointFound = true;
237 else if (AllowHexSpecifier) {
239 hexDigit = s [pos++];
240 if (Char.IsDigit (hexDigit))
241 digitValue = (ulong) (hexDigit - '0');
242 else if (Char.IsLower (hexDigit))
243 digitValue = (ulong) (hexDigit - 'a' + 10);
245 digitValue = (ulong) (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') {
255 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
263 number = checked (number * 10 + (ulong) (s [pos++] - '0'));
265 catch (OverflowException) {
267 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
271 } while (pos < s.Length);
276 exc = Int32.GetFormatException ();
280 if (AllowTrailingSign && !foundSign) {
282 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
284 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
286 if (AllowCurrencySymbol)
287 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
291 if (AllowCurrencySymbol && !foundCurrency) {
293 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
295 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
297 if (!foundSign && AllowTrailingSign)
298 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
302 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
305 if (foundOpenParentheses) {
306 if (pos >= s.Length || s [pos++] != ')') {
308 exc = Int32.GetFormatException ();
311 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
315 if (pos < s.Length && s [pos] != '\u0000') {
317 exc = Int32.GetFormatException ();
321 // -0 is legal but other negative values are not
322 if (negative && (number > 0)) {
324 exc = new OverflowException (
325 Locale.GetText ("Negative number"));
333 [CLSCompliant (false)]
334 public static ulong Parse (string s, NumberStyles style, IFormatProvider fp)
339 if (!Parse (s, style, fp, false, out res, out exc))
347 [CLSCompliant (false)]
348 public static bool TryParse (string s, out ulong result)
351 if (!Parse (s, NumberStyles.Integer, null, true, out result, out exc)) {
359 [CLSCompliant (false)]
360 public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out ulong result)
363 if (!Parse (s, style, provider, true, out result, out exc)) {
372 public override string ToString ()
374 return NumberFormatter.FormatGeneral (new NumberFormatter.NumberStore (m_value));
377 public string ToString (IFormatProvider provider)
379 return NumberFormatter.FormatGeneral (new NumberFormatter.NumberStore (m_value), provider);
382 public string ToString (string format)
384 return ToString (format, null);
387 public string ToString (string format, IFormatProvider provider)
389 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (provider);
390 return NumberFormatter.NumberToString (format, m_value, nfi);
393 // =========== IConvertible Methods =========== //
394 public TypeCode GetTypeCode ()
396 return TypeCode.UInt64;
399 bool IConvertible.ToBoolean (IFormatProvider provider)
401 return System.Convert.ToBoolean (m_value);
404 byte IConvertible.ToByte (IFormatProvider provider)
406 return System.Convert.ToByte (m_value);
409 char IConvertible.ToChar (IFormatProvider provider)
411 return System.Convert.ToChar (m_value);
414 DateTime IConvertible.ToDateTime (IFormatProvider provider)
416 return System.Convert.ToDateTime (m_value);
419 decimal IConvertible.ToDecimal (IFormatProvider provider)
421 return System.Convert.ToDecimal (m_value);
424 double IConvertible.ToDouble (IFormatProvider provider)
426 return System.Convert.ToDouble (m_value);
429 short IConvertible.ToInt16 (IFormatProvider provider)
431 return System.Convert.ToInt16 (m_value);
434 int IConvertible.ToInt32 (IFormatProvider provider)
436 return System.Convert.ToInt32 (m_value);
439 long IConvertible.ToInt64 (IFormatProvider provider)
441 return System.Convert.ToInt64 (m_value);
444 sbyte IConvertible.ToSByte(IFormatProvider provider)
446 return System.Convert.ToSByte (m_value);
449 float IConvertible.ToSingle (IFormatProvider provider)
451 return System.Convert.ToSingle (m_value);
454 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
456 return System.Convert.ToType (m_value, conversionType, provider);
459 ushort IConvertible.ToUInt16 (IFormatProvider provider)
461 return System.Convert.ToUInt16 (m_value);
464 uint IConvertible.ToUInt32 (IFormatProvider provider)
466 return System.Convert.ToUInt32 (m_value);
469 ulong IConvertible.ToUInt64 (IFormatProvider provider)