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
,
39 IComparable
, IComparable
<UInt64
>
44 public const ulong MaxValue
= 0xffffffffffffffff;
45 public const ulong MinValue
= 0;
47 internal ulong m_value
;
49 public int CompareTo (object value)
54 if (!(value is System
.UInt64
))
55 throw new ArgumentException (Locale
.GetText ("Value is not a System.UInt64."));
57 if (this.m_value
== (ulong) value)
60 if (this.m_value
< (ulong) value)
66 public override bool Equals (object obj
)
68 if (!(obj
is System
.UInt64
))
71 return ((ulong) obj
) == m_value
;
74 public override int GetHashCode ()
76 return (int)(m_value
& 0xffffffff) ^
(int)(m_value
>> 32);
80 public int CompareTo (ulong value)
90 public bool Equals (ulong value)
92 return value == m_value
;
96 [CLSCompliant (false)]
97 public static ulong Parse (string s
)
99 return Parse (s
, NumberStyles
.Integer
, null);
102 [CLSCompliant (false)]
103 public static ulong Parse (string s
, IFormatProvider provider
)
105 return Parse (s
, NumberStyles
.Integer
, provider
);
108 [CLSCompliant (false)]
109 public static ulong Parse (string s
, NumberStyles style
)
111 return Parse (s
, style
, null);
114 internal static bool Parse (string s
, NumberStyles style
, IFormatProvider provider
, bool tryParse
, out ulong result
)
122 throw new ArgumentNullException ("s");
128 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
130 NumberFormatInfo nfi
;
131 if (provider
!= null) {
132 Type typeNFI
= typeof (NumberFormatInfo
);
133 nfi
= (NumberFormatInfo
) provider
.GetFormat (typeNFI
);
136 nfi
= Thread
.CurrentThread
.CurrentCulture
.NumberFormat
;
138 Int32
.CheckStyle (style
);
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
)
153 pos
= Int32
.JumpOverWhite (pos
, s
, true);
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
)
168 pos
= Int32
.JumpOverWhite (pos
, s
, true);
170 if (s
.Substring (pos
, nfi
.NegativeSign
.Length
) == nfi
.NegativeSign
)
174 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
175 if (s
.Substring (pos
, nfi
.PositiveSign
.Length
) == nfi
.PositiveSign
)
179 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
182 if (AllowLeadingSign
&& !foundSign
) {
184 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
186 if (AllowLeadingWhite
)
187 pos
= Int32
.JumpOverWhite (pos
, s
, true);
188 if (AllowCurrencySymbol
) {
189 Int32
.FindCurrency (ref pos
, s
, nfi
,
191 if (foundCurrency
&& AllowLeadingWhite
)
192 pos
= Int32
.JumpOverWhite (pos
, s
, true);
197 if (AllowCurrencySymbol
&& !foundCurrency
) {
199 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
201 if (AllowLeadingWhite
)
202 pos
= Int32
.JumpOverWhite (pos
, s
, true);
204 if (!foundSign
&& AllowLeadingSign
) {
205 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
,
207 if (foundSign
&& AllowLeadingWhite
)
208 pos
= Int32
.JumpOverWhite (pos
, s
, true);
216 bool decimalPointFound
= false;
221 // Just the same as Int32, but this one adds instead of substract
224 if (!Int32
.ValidDigit (s
[pos
], AllowHexSpecifier
)) {
225 if (AllowThousands
&& Int32
.FindOther (ref pos
, s
, nfi
.NumberGroupSeparator
))
228 if (!decimalPointFound
&& AllowDecimalPoint
&&
229 Int32
.FindOther (ref pos
, s
, nfi
.NumberDecimalSeparator
)) {
230 decimalPointFound
= true;
235 else if (AllowHexSpecifier
) {
237 hexDigit
= s
[pos
++];
238 if (Char
.IsDigit (hexDigit
))
239 digitValue
= (ulong) (hexDigit
- '0');
240 else if (Char
.IsLower (hexDigit
))
241 digitValue
= (ulong) (hexDigit
- 'a' + 10);
243 digitValue
= (ulong) (hexDigit
- 'A' + 10);
245 number
= checked (number
* 16 + digitValue
);
247 else if (decimalPointFound
) {
249 // Allows decimal point as long as it's only
250 // followed by zeroes.
251 if (s
[pos
++] != '0')
255 throw new OverflowException (Locale
.GetText ("Value too large or too small."));
261 number
= checked (number
* 10 + (ulong) (s
[pos
++] - '0'));
263 catch (OverflowException
) {
267 throw new OverflowException (Locale
.GetText ("Value too large or too small."));
270 } while (pos
< s
.Length
);
277 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
279 if (AllowTrailingSign
&& !foundSign
) {
281 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
283 if (AllowTrailingWhite
)
284 pos
= Int32
.JumpOverWhite (pos
, s
, true);
285 if (AllowCurrencySymbol
)
286 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
290 if (AllowCurrencySymbol
&& !foundCurrency
) {
292 Int32
.FindCurrency (ref pos
, s
, nfi
, ref foundCurrency
);
294 if (AllowTrailingWhite
)
295 pos
= Int32
.JumpOverWhite (pos
, s
, true);
296 if (!foundSign
&& AllowTrailingSign
)
297 Int32
.FindSign (ref pos
, s
, nfi
, ref foundSign
, ref negative
);
301 if (AllowTrailingWhite
&& pos
< s
.Length
)
302 pos
= Int32
.JumpOverWhite (pos
, s
, false);
304 if (foundOpenParentheses
) {
305 if (pos
>= s
.Length
|| s
[pos
++] != ')')
309 throw new FormatException (Locale
.GetText
310 ("Input string was not in the correct format."));
311 if (AllowTrailingWhite
&& pos
< s
.Length
)
312 pos
= Int32
.JumpOverWhite (pos
, s
, false);
315 if (pos
< s
.Length
&& s
[pos
] != '\u0000')
319 throw new FormatException (Locale
.GetText ("Input string was not in the correct format."));
321 // -0 is legal but other negative values are not
322 if (negative
&& (number
> 0)) {
326 throw new OverflowException (
327 Locale
.GetText ("Negative number"));
334 [CLSCompliant (false)]
335 public static ulong Parse (string s
, NumberStyles style
, IFormatProvider fp
) {
338 Parse (s
, style
, fp
, false, out res
);
345 [CLSCompliant (false)]
346 public static bool TryParse (string s
, out ulong result
) {
348 return Parse (s
, NumberStyles
.Integer
, null, true, out result
);
356 [CLSCompliant (false)]
357 public static bool TryParse (string s
, NumberStyles style
, IFormatProvider provider
, out ulong result
) {
359 return Parse (s
, style
, provider
, true, out result
);
368 public override string ToString ()
370 return ToString (null, null);
373 public string ToString (IFormatProvider provider
)
375 return ToString (null, provider
);
378 public string ToString (string format
)
380 return ToString (format
, null);
383 public string ToString (string format
, IFormatProvider provider
)
385 NumberFormatInfo nfi
= NumberFormatInfo
.GetInstance (provider
);
387 // use "G" when format is null or String.Empty
388 if ((format
== null) || (format
.Length
== 0))
391 return IntegerFormatter
.NumberToString (format
, nfi
, m_value
);
394 // =========== IConvertible Methods =========== //
395 public TypeCode
GetTypeCode ()
397 return TypeCode
.UInt64
;
400 bool IConvertible
.ToBoolean (IFormatProvider provider
)
402 return System
.Convert
.ToBoolean (m_value
);
405 byte IConvertible
.ToByte (IFormatProvider provider
)
407 return System
.Convert
.ToByte (m_value
);
410 char IConvertible
.ToChar (IFormatProvider provider
)
412 return System
.Convert
.ToChar (m_value
);
415 DateTime IConvertible
.ToDateTime (IFormatProvider provider
)
417 return System
.Convert
.ToDateTime (m_value
);
420 decimal IConvertible
.ToDecimal (IFormatProvider provider
)
422 return System
.Convert
.ToDecimal (m_value
);
425 double IConvertible
.ToDouble (IFormatProvider provider
)
427 return System
.Convert
.ToDouble (m_value
);
430 short IConvertible
.ToInt16 (IFormatProvider provider
)
432 return System
.Convert
.ToInt16 (m_value
);
435 int IConvertible
.ToInt32 (IFormatProvider provider
)
437 return System
.Convert
.ToInt32 (m_value
);
440 long IConvertible
.ToInt64 (IFormatProvider provider
)
442 return System
.Convert
.ToInt64 (m_value
);
445 sbyte IConvertible
.ToSByte(IFormatProvider provider
)
447 return System
.Convert
.ToSByte (m_value
);
450 float IConvertible
.ToSingle (IFormatProvider provider
)
452 return System
.Convert
.ToSingle (m_value
);
455 object IConvertible
.ToType (Type conversionType
, IFormatProvider provider
)
457 return System
.Convert
.ToType (m_value
, conversionType
, provider
);
460 ushort IConvertible
.ToUInt16 (IFormatProvider provider
)
462 return System
.Convert
.ToUInt16 (m_value
);
465 uint IConvertible
.ToUInt32 (IFormatProvider provider
)
467 return System
.Convert
.ToUInt32 (m_value
);
470 ulong IConvertible
.ToUInt64 (IFormatProvider provider
)