(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / System / Int64.cs
blobe2dd9be2af0b000c39845a9980ad02b9a57afd69
1 //
2 // System.Int64.cs
3 //
4 // Author:
5 // Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) Ximian, Inc. http://www.ximian.com
8 //
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Globalization;
32 using System.Threading;
34 namespace System {
36 [Serializable]
37 public struct Int64 : IFormattable, IConvertible,
38 #if NET_2_0
39 IComparable, IComparable<Int64>
40 #else
41 IComparable
42 #endif
45 public const long MaxValue = 0x7fffffffffffffff;
46 public const long MinValue = -9223372036854775808;
48 internal long m_value;
50 public int CompareTo (object v)
52 if (v == null)
53 return 1;
55 if (!(v is System.Int64))
56 throw new ArgumentException (Locale.GetText ("Value is not a System.Int64"));
58 if (m_value == (long) v)
59 return 0;
61 if (m_value < (long) v)
62 return -1;
64 return 1;
67 public override bool Equals (object o)
69 if (!(o is System.Int64))
70 return false;
72 return ((long) o) == m_value;
75 public override int GetHashCode ()
77 return (int)(m_value & 0xffffffff) ^ (int)(m_value >> 32);
80 #if NET_2_0
81 public int CompareTo (long value)
83 if (m_value == value)
84 return 0;
85 if (m_value > value)
86 return 1;
87 else
88 return -1;
91 public bool Equals (long value)
93 return value == m_value;
95 #endif
97 internal static bool Parse (string s, bool tryParse, out long result)
99 long val = 0;
100 int len;
101 int i;
102 int sign = 1;
103 bool digits_seen = false;
105 result = 0;
107 if (s == null)
108 if (tryParse)
109 return false;
110 else
111 throw new ArgumentNullException ("s");
113 len = s.Length;
115 char c;
116 for (i = 0; i < len; i++){
117 c = s [i];
118 if (!Char.IsWhiteSpace (c))
119 break;
122 if (i == len)
123 if (tryParse)
124 return false;
125 else
126 throw new FormatException ();
128 c = s [i];
129 if (c == '+')
130 i++;
131 else if (c == '-'){
132 sign = -1;
133 i++;
136 for (; i < len; i++){
137 c = s [i];
139 if (c >= '0' && c <= '9'){
140 val = checked (val * 10 + (c - '0') * sign);
141 digits_seen = true;
142 } else {
143 if (Char.IsWhiteSpace (c)){
144 for (i++; i < len; i++){
145 if (!Char.IsWhiteSpace (s [i]))
146 if (tryParse)
147 return false;
148 else
149 throw new FormatException ();
151 break;
152 } else
153 if (tryParse)
154 return false;
155 else
156 throw new FormatException ();
159 if (!digits_seen)
160 if (tryParse)
161 return false;
162 else
163 throw new FormatException ();
165 result = val;
166 return true;
169 public static long Parse (string s, IFormatProvider fp)
171 return Parse (s, NumberStyles.Integer, fp);
174 public static long Parse (string s, NumberStyles style)
176 return Parse (s, style, null);
179 internal static bool Parse (string s, NumberStyles style, IFormatProvider fp, bool tryParse, out long result)
181 result = 0;
183 if (s == null)
184 if (tryParse)
185 return false;
186 else
187 throw new ArgumentNullException ();
189 if (s.Length == 0)
190 if (tryParse)
191 return false;
192 else
193 throw new FormatException ("Input string was not " +
194 "in the correct format: s.Length==0.");
196 NumberFormatInfo nfi;
197 if (fp != null) {
198 Type typeNFI = typeof (System.Globalization.NumberFormatInfo);
199 nfi = (NumberFormatInfo) fp.GetFormat (typeNFI);
201 else
202 nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
204 Int32.CheckStyle (style);
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;
216 int pos = 0;
218 if (AllowLeadingWhite)
219 pos = Int32.JumpOverWhite (pos, s, true);
221 bool foundOpenParentheses = false;
222 bool negative = false;
223 bool foundSign = false;
224 bool foundCurrency = false;
226 // Pre-number stuff
227 if (AllowParentheses && s [pos] == '(') {
228 foundOpenParentheses = true;
229 foundSign = true;
230 negative = true; // MS always make the number negative when there parentheses
231 // even when NumberFormatInfo.NumberNegativePattern != 0!!!
232 pos++;
233 if (AllowLeadingWhite)
234 pos = Int32.JumpOverWhite (pos, s, true);
236 if (s.Substring (pos, nfi.NegativeSign.Length) == nfi.NegativeSign)
237 if (tryParse)
238 return false;
239 else
240 throw new FormatException ("Input string was not in the correct " +
241 "format: Has Negative Sign.");
242 if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign)
243 if (tryParse)
244 return false;
245 else
246 throw new FormatException ("Input string was not in the correct " +
247 "format: Has Positive Sign.");
250 if (AllowLeadingSign && !foundSign) {
251 // Sign + Currency
252 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
253 if (foundSign) {
254 if (AllowLeadingWhite)
255 pos = Int32.JumpOverWhite (pos, s, true);
256 if (AllowCurrencySymbol) {
257 Int32.FindCurrency (ref pos, s, nfi,
258 ref foundCurrency);
259 if (foundCurrency && AllowLeadingWhite)
260 pos = Int32.JumpOverWhite (pos, s, true);
265 if (AllowCurrencySymbol && !foundCurrency) {
266 // Currency + sign
267 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
268 if (foundCurrency) {
269 if (AllowLeadingWhite)
270 pos = Int32.JumpOverWhite (pos, s, true);
271 if (foundCurrency) {
272 if (!foundSign && AllowLeadingSign) {
273 Int32.FindSign (ref pos, s, nfi, ref foundSign,
274 ref negative);
275 if (foundSign && AllowLeadingWhite)
276 pos = Int32.JumpOverWhite (pos, s, true);
282 long number = 0;
283 int nDigits = 0;
284 bool decimalPointFound = false;
285 int digitValue;
286 char hexDigit;
288 // Number stuff
289 do {
291 if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
292 if (AllowThousands &&
293 (Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)
294 || Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
295 continue;
296 else
297 if (!decimalPointFound && AllowDecimalPoint &&
298 (Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)
299 || Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
300 decimalPointFound = true;
301 continue;
304 break;
306 else if (AllowHexSpecifier) {
307 nDigits++;
308 hexDigit = s [pos++];
309 if (Char.IsDigit (hexDigit))
310 digitValue = (int) (hexDigit - '0');
311 else if (Char.IsLower (hexDigit))
312 digitValue = (int) (hexDigit - 'a' + 10);
313 else
314 digitValue = (int) (hexDigit - 'A' + 10);
316 ulong unumber = (ulong)number;
317 number = (long)checked(unumber * 16ul + (ulong)digitValue);
319 else if (decimalPointFound) {
320 nDigits++;
321 // Allows decimal point as long as it's only
322 // followed by zeroes.
323 if (s [pos++] != '0')
324 if (tryParse)
325 return false;
326 else
327 throw new OverflowException ("Value too large or too " +
328 "small.");
330 else {
331 nDigits++;
333 try {
334 // Calculations done as negative
335 // (abs (MinValue) > abs (MaxValue))
336 number = checked (
337 number * 10 -
338 (long) (s [pos++] - '0')
340 } catch (OverflowException) {
341 if (tryParse)
342 return false;
343 else
344 throw new OverflowException ("Value too large or too " +
345 "small.");
348 } while (pos < s.Length);
350 // Post number stuff
351 if (nDigits == 0)
352 if (tryParse)
353 return false;
354 else
355 throw new FormatException ("Input string was not in the correct format: nDigits == 0.");
357 if (AllowTrailingSign && !foundSign) {
358 // Sign + Currency
359 Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative);
360 if (foundSign) {
361 if (AllowTrailingWhite)
362 pos = Int32.JumpOverWhite (pos, s, true);
363 if (AllowCurrencySymbol)
364 Int32.FindCurrency (ref pos, s, nfi,
365 ref foundCurrency);
369 if (AllowCurrencySymbol && !foundCurrency) {
370 // Currency + sign
371 if (nfi.CurrencyPositivePattern == 3 && s[pos++] != ' ')
372 if (tryParse)
373 return false;
374 else
375 throw new FormatException ("Input string was not in the correct format: no space between number and currency symbol.");
377 Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency);
378 if (foundCurrency && pos < s.Length) {
379 if (AllowTrailingWhite)
380 pos = Int32.JumpOverWhite (pos, s, true);
381 if (!foundSign && AllowTrailingSign)
382 Int32.FindSign (ref pos, s, nfi, ref foundSign,
383 ref negative);
387 if (AllowTrailingWhite && pos < s.Length)
388 pos = Int32.JumpOverWhite (pos, s, false);
390 if (foundOpenParentheses) {
391 if (pos >= s.Length || s [pos++] != ')')
392 if (tryParse)
393 return false;
394 else
395 throw new FormatException ("Input string was not in the correct " +
396 "format: No room for close parens.");
397 if (AllowTrailingWhite && pos < s.Length)
398 pos = Int32.JumpOverWhite (pos, s, false);
401 if (pos < s.Length && s [pos] != '\u0000')
402 if (tryParse)
403 return false;
404 else
405 throw new FormatException ("Input string was not in the correct format: Did not parse entire string. pos = "
406 + pos + " s.Length = " + s.Length);
409 if (!negative && !AllowHexSpecifier)
410 number = -number;
412 result = number;
413 return true;
416 public static long Parse (string s) {
417 long res;
419 Parse (s, false, out res);
421 return res;
424 public static long Parse (string s, NumberStyles style, IFormatProvider fp) {
425 long res;
427 Parse (s, style, fp, false, out res);
429 return res;
432 #if NET_2_0
433 public static bool TryParse (string s, out long result) {
434 try {
435 return Parse (s, true, out result);
437 catch (Exception) {
438 result = 0;
439 return false;
443 public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out long result) {
444 try {
445 return Parse (s, style, provider, true, out result);
447 catch (Exception) {
448 result = 0;
449 return false;
452 #endif
454 public override string ToString ()
456 return ToString (null, null);
459 public string ToString (IFormatProvider fp)
461 return ToString (null, fp);
464 public string ToString (string format)
466 return ToString (format, null);
469 public string ToString (string format, IFormatProvider fp)
471 NumberFormatInfo nfi = NumberFormatInfo.GetInstance( fp );
473 // use "G" when format is null or String.Empty
474 if ((format == null) || (format.Length == 0))
475 format = "G";
477 return IntegerFormatter.NumberToString (format, nfi, m_value);
480 // =========== IConvertible Methods =========== //
482 public TypeCode GetTypeCode ()
484 return TypeCode.Int64;
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)
554 return System.Convert.ToUInt32 (m_value);
557 ulong IConvertible.ToUInt64 (IFormatProvider provider)
559 return System.Convert.ToUInt64 (m_value);