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)]
38 [System.Runtime.InteropServices.ComVisible (true)]
40 public struct UInt64 : IFormattable, IConvertible, IComparable
42 , IComparable<UInt64>, IEquatable <UInt64>
45 public const ulong MaxValue = 0xffffffffffffffff;
46 public const ulong MinValue = 0;
48 internal ulong m_value;
50 public int CompareTo (object value)
55 if (!(value is System.UInt64))
56 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt64."));
58 if (this.m_value == (ulong) value)
61 if (this.m_value < (ulong) value)
67 public override bool Equals (object obj)
69 if (!(obj is System.UInt64))
72 return ((ulong) obj) == m_value;
75 public override int GetHashCode ()
77 return (int)(m_value & 0xffffffff) ^ (int)(m_value >> 32);
81 public int CompareTo (ulong value)
91 public bool Equals (ulong value)
93 return value == m_value;
97 [CLSCompliant (false)]
98 public static ulong Parse (string s)
100 return Parse (s, NumberStyles.Integer, null);
103 [CLSCompliant (false)]
104 public static ulong Parse (string s, IFormatProvider provider)
106 return Parse (s, NumberStyles.Integer, provider);
109 [CLSCompliant (false)]
110 public static ulong Parse (string s, NumberStyles style)
112 return Parse (s, style, null);
115 internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out ulong result, out Exception exc)
122 exc = new ArgumentNullException ("s");
128 exc = Int32.GetFormatException ();
132 NumberFormatInfo nfi;
133 if (provider != null) {
134 Type typeNFI = typeof (NumberFormatInfo);
135 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
138 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
140 if (!Int32.CheckStyle (style, tryParse, ref exc))
143 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
144 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
145 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
146 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
147 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
148 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
149 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
150 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
151 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
155 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
158 bool foundOpenParentheses = false;
159 bool negative = false;
160 bool foundSign = false;
161 bool foundCurrency = false;
164 if (AllowParentheses && s [pos] == '(') {
165 foundOpenParentheses = true;
167 negative = true; // MS always make the number negative when there parentheses
168 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
170 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
173 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign) {
175 exc = Int32.GetFormatException ();
178 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) {
180 exc = Int32.GetFormatException ();
185 if (AllowLeadingSign && !foundSign) {
187 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
189 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
191 if (AllowCurrencySymbol) {
192 Int32.FindCurrency (ref pos, s, nfi,
194 if (foundCurrency && AllowLeadingWhite &&
195 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
201 if (AllowCurrencySymbol && !foundCurrency) {
203 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
205 if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
208 if (!foundSign && AllowLeadingSign) {
209 Int32.FindSign (ref pos, s, nfi, ref foundSign,
211 if (foundSign && AllowLeadingWhite &&
212 !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
221 bool decimalPointFound = false;
226 // Just the same as Int32, but this one adds instead of substract
229 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
230 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
233 if (!decimalPointFound && AllowDecimalPoint &&
234 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
235 decimalPointFound = true;
240 else if (AllowHexSpecifier) {
242 hexDigit = s [pos++];
243 if (Char.IsDigit (hexDigit))
244 digitValue = (ulong) (hexDigit - '0');
245 else if (Char.IsLower (hexDigit))
246 digitValue = (ulong) (hexDigit - 'a' + 10);
248 digitValue = (ulong) (hexDigit - 'A' + 10);
251 // Any number above 32 will do
252 bool can_overflow = number > 0xffff;
254 number = number * 16 + digitValue;
256 if (can_overflow && number < 16)
259 number = checked (number * 16 + digitValue);
261 else if (decimalPointFound) {
263 // Allows decimal point as long as it's only
264 // followed by zeroes.
265 if (s [pos++] != '0') {
267 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
275 number = checked (number * 10 + (ulong) (s [pos++] - '0'));
277 catch (OverflowException) {
279 exc = new OverflowException (Locale.GetText ("Value too large or too small."));
283 } while (pos < s.Length);
288 exc = Int32.GetFormatException ();
292 if (AllowTrailingSign && !foundSign) {
294 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
296 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
298 if (AllowCurrencySymbol)
299 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
303 if (AllowCurrencySymbol && !foundCurrency) {
305 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
307 if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc))
309 if (!foundSign && AllowTrailingSign)
310 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
314 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
317 if (foundOpenParentheses) {
318 if (pos >= s.Length || s [pos++] != ')') {
320 exc = Int32.GetFormatException ();
323 if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc))
327 if (pos < s.Length && s [pos] != '\u0000') {
329 exc = Int32.GetFormatException ();
333 // -0 is legal but other negative values are not
334 if (negative && (number > 0)) {
336 exc = new OverflowException (
337 Locale.GetText ("Negative number"));
345 [CLSCompliant (false)]
346 public static ulong Parse (string s, NumberStyles style, IFormatProvider fp)
351 if (!Parse (s, style, fp, false, out res, out exc))
359 [CLSCompliant (false)]
360 public static bool TryParse (string s, out ulong result)
363 if (!Parse (s, NumberStyles.Integer, null, true, out result, out exc)) {
371 [CLSCompliant (false)]
372 public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out ulong result)
375 if (!Parse (s, style, provider, true, out result, out exc)) {
384 public override string ToString ()
386 return new NumberFormatter(null, m_value).FormatDecimal(-1, null);
389 public string ToString (IFormatProvider provider)
391 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (provider);
392 return new NumberFormatter(null, m_value).FormatDecimal(-1, nfi);
395 public string ToString (string format)
397 return ToString (format, null);
400 public string ToString (string format, IFormatProvider provider)
402 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (provider);
403 return NumberFormatter.NumberToString (format, m_value, nfi);
406 // =========== IConvertible Methods =========== //
407 public TypeCode GetTypeCode ()
409 return TypeCode.UInt64;
412 bool IConvertible.ToBoolean (IFormatProvider provider)
414 return System.Convert.ToBoolean (m_value);
417 byte IConvertible.ToByte (IFormatProvider provider)
419 return System.Convert.ToByte (m_value);
422 char IConvertible.ToChar (IFormatProvider provider)
424 return System.Convert.ToChar (m_value);
427 DateTime IConvertible.ToDateTime (IFormatProvider provider)
429 return System.Convert.ToDateTime (m_value);
432 decimal IConvertible.ToDecimal (IFormatProvider provider)
434 return System.Convert.ToDecimal (m_value);
437 double IConvertible.ToDouble (IFormatProvider provider)
439 return System.Convert.ToDouble (m_value);
442 short IConvertible.ToInt16 (IFormatProvider provider)
444 return System.Convert.ToInt16 (m_value);
447 int IConvertible.ToInt32 (IFormatProvider provider)
449 return System.Convert.ToInt32 (m_value);
452 long IConvertible.ToInt64 (IFormatProvider provider)
454 return System.Convert.ToInt64 (m_value);
457 sbyte IConvertible.ToSByte(IFormatProvider provider)
459 return System.Convert.ToSByte (m_value);
462 float IConvertible.ToSingle (IFormatProvider provider)
464 return System.Convert.ToSingle (m_value);
467 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
469 return System.Convert.ToType (m_value, conversionType, provider);
472 ushort IConvertible.ToUInt16 (IFormatProvider provider)
474 return System.Convert.ToUInt16 (m_value);
477 uint IConvertible.ToUInt32 (IFormatProvider provider)
479 return System.Convert.ToUInt32 (m_value);
482 ulong IConvertible.ToUInt64 (IFormatProvider provider)