5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004 Novell (http://www.novell.com)
11 using System.Globalization;
12 using System.Threading;
17 [CLSCompliant (false)]
18 public struct UInt64 : IComparable, IFormattable, IConvertible
20 public const ulong MaxValue = 0xffffffffffffffff;
21 public const ulong MinValue = 0;
23 internal ulong m_value;
25 public int CompareTo (object value)
30 if (!(value is System.UInt64))
31 throw new ArgumentException (Locale.GetText ("Value is not a System.UInt64."));
33 if (this.m_value == (ulong) value)
36 if (this.m_value < (ulong) value)
42 public override bool Equals (object obj)
44 if (!(obj is System.UInt64))
47 return ((ulong) obj) == m_value;
50 public override int GetHashCode ()
52 return (int)(m_value & 0xffffffff) ^ (int)(m_value >> 32);
55 [CLSCompliant (false)]
56 public static ulong Parse (string s)
58 return Parse (s, NumberStyles.Integer, null);
61 [CLSCompliant (false)]
62 public static ulong Parse (string s, IFormatProvider provider)
64 return Parse (s, NumberStyles.Integer, provider);
67 [CLSCompliant (false)]
68 public static ulong Parse (string s, NumberStyles style)
70 return Parse (s, style, null);
73 [CLSCompliant (false)]
74 public static ulong Parse (string s, NumberStyles style, IFormatProvider provider)
77 throw new ArgumentNullException ("s");
80 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
83 if (provider != null) {
84 Type typeNFI = typeof (NumberFormatInfo);
85 nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
88 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
90 Int32.CheckStyle (style);
92 bool AllowCurrencySymbol = (style & NumberStyles.AllowCurrencySymbol) != 0;
93 bool AllowExponent = (style & NumberStyles.AllowExponent) != 0;
94 bool AllowHexSpecifier = (style & NumberStyles.AllowHexSpecifier) != 0;
95 bool AllowThousands = (style & NumberStyles.AllowThousands) != 0;
96 bool AllowDecimalPoint = (style & NumberStyles.AllowDecimalPoint) != 0;
97 bool AllowParentheses = (style & NumberStyles.AllowParentheses) != 0;
98 bool AllowTrailingSign = (style & NumberStyles.AllowTrailingSign) != 0;
99 bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0;
100 bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0;
101 bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0;
105 if (AllowLeadingWhite)
106 pos = Int32.JumpOverWhite (pos, s, true);
108 bool foundOpenParentheses = false;
109 bool negative = false;
110 bool foundSign = false;
111 bool foundCurrency = false;
114 if (AllowParentheses && s [pos] == '(') {
115 foundOpenParentheses = true;
117 negative = true; // MS always make the number negative when there parentheses
118 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
120 if (AllowLeadingWhite)
121 pos = Int32.JumpOverWhite (pos, s, true);
123 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
124 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
125 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
126 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
129 if (AllowLeadingSign && !foundSign) {
131 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
133 if (AllowLeadingWhite)
134 pos = Int32.JumpOverWhite (pos, s, true);
135 if (AllowCurrencySymbol) {
136 Int32.FindCurrency (ref pos, s, nfi,
138 if (foundCurrency && AllowLeadingWhite)
139 pos = Int32.JumpOverWhite (pos, s, true);
144 if (AllowCurrencySymbol && !foundCurrency) {
146 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
148 if (AllowLeadingWhite)
149 pos = Int32.JumpOverWhite (pos, s, true);
151 if (!foundSign && AllowLeadingSign) {
152 Int32.FindSign (ref pos, s, nfi, ref foundSign,
154 if (foundSign && AllowLeadingWhite)
155 pos = Int32.JumpOverWhite (pos, s, true);
163 bool decimalPointFound = false;
168 // Just the same as Int32, but this one adds instead of substract
171 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
172 if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator))
175 if (!decimalPointFound && AllowDecimalPoint &&
176 Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) {
177 decimalPointFound = true;
182 else if (AllowHexSpecifier) {
184 hexDigit = s [pos++];
185 if (Char.IsDigit (hexDigit))
186 digitValue = (ulong) (hexDigit - '0');
187 else if (Char.IsLower (hexDigit))
188 digitValue = (ulong) (hexDigit - 'a' + 10);
190 digitValue = (ulong) (hexDigit - 'A' + 10);
192 number = checked (number * 16 + digitValue);
194 else if (decimalPointFound) {
196 // Allows decimal point as long as it's only
197 // followed by zeroes.
198 if (s [pos++] != '0')
199 throw new OverflowException (Locale.GetText ("Value too large or too small."));
205 number = checked (number * 10 + (ulong) (s [pos++] - '0'));
207 catch (OverflowException) {
208 throw new OverflowException (Locale.GetText ("Value too large or too small."));
211 } while (pos < s.Length);
215 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
217 if (AllowTrailingSign && !foundSign) {
219 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
221 if (AllowTrailingWhite)
222 pos = Int32.JumpOverWhite (pos, s, true);
223 if (AllowCurrencySymbol)
224 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
228 if (AllowCurrencySymbol && !foundCurrency) {
230 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
232 if (AllowTrailingWhite)
233 pos = Int32.JumpOverWhite (pos, s, true);
234 if (!foundSign && AllowTrailingSign)
235 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
239 if (AllowTrailingWhite && pos < s.Length)
240 pos = Int32.JumpOverWhite (pos, s, false);
242 if (foundOpenParentheses) {
243 if (pos >= s.Length || s [pos++] != ')')
244 throw new FormatException (Locale.GetText
245 ("Input string was not in the correct format."));
246 if (AllowTrailingWhite && pos < s.Length)
247 pos = Int32.JumpOverWhite (pos, s, false);
250 if (pos < s.Length && s [pos] != '\u0000')
251 throw new FormatException (Locale.GetText ("Input string was not in the correct format."));
253 // -0 is legal but other negative values are not
254 if (negative && (number > 0)) {
255 throw new OverflowException (
256 Locale.GetText ("Negative number"));
262 public override string ToString ()
264 return ToString (null, null);
267 public string ToString (IFormatProvider provider)
269 return ToString (null, provider);
272 public string ToString (string format)
274 return ToString (format, null);
277 public string ToString (string format, IFormatProvider provider)
279 NumberFormatInfo nfi = NumberFormatInfo.GetInstance (provider);
281 // use "G" when format is null or String.Empty
282 if ((format == null) || (format.Length == 0))
285 return IntegerFormatter.NumberToString (format, nfi, m_value);
288 // =========== IConvertible Methods =========== //
289 public TypeCode GetTypeCode ()
291 return TypeCode.UInt64;
294 bool IConvertible.ToBoolean (IFormatProvider provider)
296 return System.Convert.ToBoolean (m_value);
299 byte IConvertible.ToByte (IFormatProvider provider)
301 return System.Convert.ToByte (m_value);
304 char IConvertible.ToChar (IFormatProvider provider)
306 return System.Convert.ToChar (m_value);
309 DateTime IConvertible.ToDateTime (IFormatProvider provider)
311 return System.Convert.ToDateTime (m_value);
314 decimal IConvertible.ToDecimal (IFormatProvider provider)
316 return System.Convert.ToDecimal (m_value);
319 double IConvertible.ToDouble (IFormatProvider provider)
321 return System.Convert.ToDouble (m_value);
324 short IConvertible.ToInt16 (IFormatProvider provider)
326 return System.Convert.ToInt16 (m_value);
329 int IConvertible.ToInt32 (IFormatProvider provider)
331 return System.Convert.ToInt32 (m_value);
334 long IConvertible.ToInt64 (IFormatProvider provider)
336 return System.Convert.ToInt64 (m_value);
339 sbyte IConvertible.ToSByte(IFormatProvider provider)
341 return System.Convert.ToSByte (m_value);
344 float IConvertible.ToSingle (IFormatProvider provider)
346 return System.Convert.ToSingle (m_value);
349 object IConvertible.ToType (Type conversionType, IFormatProvider provider)
351 return System.Convert.ToType (m_value, conversionType, provider);
354 ushort IConvertible.ToUInt16 (IFormatProvider provider)
356 return System.Convert.ToUInt16 (m_value);
359 uint IConvertible.ToUInt32 (IFormatProvider provider)
361 return System.Convert.ToUInt32 (m_value);
364 ulong IConvertible.ToUInt64 (IFormatProvider provider)