5 // Derek Holden (dholden@draper.com)
6 // Duncan Mak (duncan@ximian.com)
7 // Marek Safar (marek.safar@gmail.com)
9 // (C) Ximian, Inc. http://www.ximian.com
10 // Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
12 // System.Convert class. This was written word for word off the
13 // Library specification for System.Convert in the ECMA TC39 TG2
14 // and TG3 working documents. The first page of which has a table
15 // for all legal conversion scenerios.
17 // This header and the one above it can be formatted however, just trying
18 // to keep it consistent w/ the existing mcs headers.
20 // This Convert class could be written another way, with each type
21 // implementing IConvertible and defining their own conversion functions,
22 // and this class just calling the type's implementation. Or, they can
23 // be defined here and the implementing type can use these functions when
24 // defining their IConvertible interface. Byte's ToBoolean() calls
25 // Convert.ToBoolean(byte), or Convert.ToBoolean(byte) calls
26 // byte.ToBoolean(). The first case is what is done here.
28 // See http://lists.ximian.com/archives/public/mono-list/2001-July/000525.html
30 // There are also conversion functions that are not defined in
31 // the ECMA draft, such as there is no bool ToBoolean(DateTime value),
32 // and placing that somewhere won't compile w/ this Convert since the
33 // function doesn't exist. However calling that when using Microsoft's
34 // System.Convert doesn't produce any compiler errors, it just throws
35 // an InvalidCastException at runtime.
37 // Whenever a decimal, double, or single is converted to an integer
38 // based type, it is even rounded. This uses Math.Round which only
39 // has Round(decimal) and Round(double), so in the Convert from
40 // single cases the value is passed to Math as a double. This
41 // may not be completely necessary.
43 // The .NET Framework SDK lists DBNull as a member of this class
44 // as 'public static readonly object DBNull;'.
46 // It should also be decided if all the cast return values should be
47 // returned as unchecked or not.
49 // All the XML function comments were auto generated which is why they
50 // sound someone redundant.
52 // TYPE | BOOL BYTE CHAR DT DEC DBL I16 I32 I64 SBYT SNGL STR UI16 UI32 UI64
53 // -----+--------------------------------------------------------------------
54 // BOOL | X X X X X X X X X X X X X
55 // BYTE | X X X X X X X X X X X X X X
56 // CHAR | X X X X X X X X X X
58 // DEC | X X X X X X X X X X X X X
59 // DBL | X X X X X X X X X X X X X
60 // I16 | X X X X X X X X X X X X X X
61 // I32 | X X X X X X X X X X X X X X
62 // I64 | X X X X X X X X X X X X X X
63 // SBYT | X X X X X X X X X X X X X X
64 // SNGL | X X X X X X X X X X X X X
65 // STR | X X X X X X X X X X X X X X X
66 // UI16 | X X X X X X X X X X X X X X
67 // UI32 | X X X X X X X X X X X X X X
68 // UI64 | X X X X X X X X X X X X X X
72 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
74 // Permission is hereby granted, free of charge, to any person obtaining
75 // a copy of this software and associated documentation files (the
76 // "Software"), to deal in the Software without restriction, including
77 // without limitation the rights to use, copy, modify, merge, publish,
78 // distribute, sublicense, and/or sell copies of the Software, and to
79 // permit persons to whom the Software is furnished to do so, subject to
80 // the following conditions:
82 // The above copyright notice and this permission notice shall be
83 // included in all copies or substantial portions of the Software.
85 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
87 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
88 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
89 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
90 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
91 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
94 using System.Globalization;
96 using System.Security.Cryptography;
98 using System.Runtime.CompilerServices;
99 using System.Runtime.InteropServices;
103 // [CLSCompliant(false)]
104 public static class Convert {
107 public static readonly object DBNull = System.DBNull.Value;
109 [MethodImplAttribute (MethodImplOptions.InternalCall)]
110 extern static byte [] InternalFromBase64String (string str, bool allowWhitespaceOnly);
112 [MethodImplAttribute (MethodImplOptions.InternalCall)]
113 extern static byte [] InternalFromBase64CharArray (char [] arr, int offset, int length);
115 public static byte[] FromBase64CharArray (char[] inArray, int offset, int length)
118 throw new ArgumentNullException ("inArray");
120 throw new ArgumentOutOfRangeException ("offset < 0");
122 throw new ArgumentOutOfRangeException ("length < 0");
123 // avoid integer overflow
124 if (offset > inArray.Length - length)
125 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
127 return InternalFromBase64CharArray (inArray, offset, length);
130 public static byte[] FromBase64String (string s)
133 throw new ArgumentNullException ("s");
136 return EmptyArray<byte>.Value;
139 return InternalFromBase64String (s, true);
142 public static TypeCode GetTypeCode (object value)
145 return TypeCode.Empty;
147 return Type.GetTypeCode (value.GetType ());
150 public static bool IsDBNull (object value)
158 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length,
159 char[] outArray, int offsetOut)
162 throw new ArgumentNullException ("inArray");
163 if (outArray == null)
164 throw new ArgumentNullException ("outArray");
165 if (offsetIn < 0 || length < 0 || offsetOut < 0)
166 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
167 // avoid integer overflow
168 if (offsetIn > inArray.Length - length)
169 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
171 // note: normally ToBase64Transform doesn't support multiple block processing
172 byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offsetIn, length);
174 char[] cOutArr = new ASCIIEncoding ().GetChars (outArr);
176 // avoid integer overflow
177 if (offsetOut > outArray.Length - cOutArr.Length)
178 throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
180 Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
182 return cOutArr.Length;
185 public static string ToBase64String (byte[] inArray)
188 throw new ArgumentNullException ("inArray");
190 return ToBase64String (inArray, 0, inArray.Length);
193 public static string ToBase64String (byte[] inArray, int offset, int length)
196 throw new ArgumentNullException ("inArray");
197 if (offset < 0 || length < 0)
198 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
199 // avoid integer overflow
200 if (offset > inArray.Length - length)
201 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
203 // note: normally ToBase64Transform doesn't support multiple block processing
204 byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offset, length);
206 return (new ASCIIEncoding ().GetString (outArr));
210 public static string ToBase64String (byte[] inArray, Base64FormattingOptions options)
213 throw new ArgumentNullException ("inArray");
214 return ToBase64String (inArray, 0, inArray.Length, options);
218 public static string ToBase64String (byte[] inArray, int offset, int length, Base64FormattingOptions options)
221 throw new ArgumentNullException ("inArray");
222 if (offset < 0 || length < 0)
223 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
224 // avoid integer overflow
225 if (offset > inArray.Length - length)
226 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
231 if (options == Base64FormattingOptions.InsertLineBreaks)
232 return ToBase64StringBuilderWithLine (inArray, offset, length).ToString ();
234 return Encoding.ASCII.GetString (Base64Helper.TransformFinalBlock (inArray, offset, length));
238 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length,
239 char[] outArray, int offsetOut, Base64FormattingOptions options)
242 throw new ArgumentNullException ("inArray");
243 if (outArray == null)
244 throw new ArgumentNullException ("outArray");
245 if (offsetIn < 0 || length < 0 || offsetOut < 0)
246 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
247 // avoid integer overflow
248 if (offsetIn > inArray.Length - length)
249 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
254 // note: normally ToBase64Transform doesn't support multiple block processing
255 if (options == Base64FormattingOptions.InsertLineBreaks) {
256 StringBuilder sb = ToBase64StringBuilderWithLine (inArray, offsetIn, length);
257 sb.CopyTo (0, outArray, offsetOut, sb.Length);
260 byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offsetIn, length);
262 char[] cOutArr = Encoding.ASCII.GetChars (outArr);
264 // avoid integer overflow
265 if (offsetOut > outArray.Length - cOutArr.Length)
266 throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
268 Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
269 return cOutArr.Length;
273 private const int MaxBytesPerLine = 57;
275 static StringBuilder ToBase64StringBuilderWithLine (byte [] inArray, int offset, int length)
277 StringBuilder sb = new StringBuilder ();
280 int full = Math.DivRem (length, MaxBytesPerLine, out remainder);
281 for (int i = 0; i < full; i ++) {
282 byte[] data = Base64Helper.TransformFinalBlock (inArray, offset, MaxBytesPerLine);
283 sb.AppendLine (Encoding.ASCII.GetString (data));
284 offset += MaxBytesPerLine;
286 // we never complete (i.e. the last line) with a new line
287 if (remainder == 0) {
288 int nll = Environment.NewLine.Length;
289 sb.Remove (sb.Length - nll, nll);
291 byte[] data = Base64Helper.TransformFinalBlock (inArray, offset, remainder);
292 sb.Append (Encoding.ASCII.GetString (data));
297 // ========== Boolean Conversions ========== //
299 public static bool ToBoolean (bool value)
304 public static bool ToBoolean (byte value)
309 public static bool ToBoolean (char value)
311 throw new InvalidCastException (Locale.GetText ("Can't convert char to bool"));
314 public static bool ToBoolean (DateTime value)
316 throw new InvalidCastException (Locale.GetText ("Can't convert date to bool"));
319 public static bool ToBoolean (decimal value)
321 return (value != 0M);
324 public static bool ToBoolean (double value)
329 public static bool ToBoolean (float value)
331 return (value != 0f);
334 public static bool ToBoolean (int value)
339 public static bool ToBoolean (long value)
344 [CLSCompliant (false)]
345 public static bool ToBoolean (sbyte value)
350 public static bool ToBoolean (short value)
355 public static bool ToBoolean (string value)
358 return false; // LAMESPEC: Spec says throw ArgumentNullException
359 return Boolean.Parse (value);
362 public static bool ToBoolean (string value, IFormatProvider provider)
365 return false; // LAMESPEC: Spec says throw ArgumentNullException
366 return Boolean.Parse (value); // provider is ignored.
369 [CLSCompliant (false)]
370 public static bool ToBoolean (uint value)
375 [CLSCompliant (false)]
376 public static bool ToBoolean (ulong value)
381 [CLSCompliant (false)]
382 public static bool ToBoolean (ushort value)
389 public static bool ToBoolean (object value)
393 return ToBoolean (value, null);
396 public static bool ToBoolean (object value, IFormatProvider provider)
400 return ((IConvertible) value).ToBoolean (provider);
403 // ========== Byte Conversions ========== //
405 public static byte ToByte (bool value)
407 return (byte)(value ? 1 : 0);
410 public static byte ToByte (byte value)
415 public static byte ToByte (char value)
417 return checked ((byte) value);
420 public static byte ToByte (DateTime value)
422 throw new InvalidCastException ("This conversion is not supported.");
425 public static byte ToByte (decimal value)
427 // Returned Even-Rounded
428 return checked ((byte) Math.Round (value));
431 public static byte ToByte (double value)
433 // Returned Even-Rounded
434 return checked ((byte) Math.Round (value));
437 public static byte ToByte (float value)
439 // Returned Even-Rounded, pass it as a double, could have this
440 // method just call Convert.ToByte ( (double)value)
441 return checked ((byte) Math.Round (value));
444 public static byte ToByte (int value)
446 return checked ((byte) value);
449 public static byte ToByte (long value)
451 return checked ((byte) value);
454 [CLSCompliant (false)]
455 public static byte ToByte (sbyte value)
457 return checked ((byte) value);
460 public static byte ToByte (short value)
462 return checked ((byte) value);
465 public static byte ToByte (string value)
468 return 0; // LAMESPEC: Spec says throw ArgumentNullException
469 return Byte.Parse (value);
472 public static byte ToByte (string value, IFormatProvider provider)
475 return 0; // LAMESPEC: Spec says throw ArgumentNullException
476 return Byte.Parse (value, provider);
479 public static byte ToByte (string value, int fromBase)
481 int retVal = ConvertFromBase (value, fromBase, true);
483 return checked ((byte) retVal);
486 [CLSCompliant (false)]
487 public static byte ToByte (uint value)
489 return checked ((byte) value);
492 [CLSCompliant (false)]
493 public static byte ToByte (ulong value)
495 return checked ((byte) value);
498 [CLSCompliant (false)]
499 public static byte ToByte (ushort value)
501 return checked ((byte) value);
504 public static byte ToByte (object value)
508 return ToByte (value, null);
511 public static byte ToByte (object value, IFormatProvider provider)
515 return ((IConvertible) value).ToByte (provider);
518 // ========== Char Conversions ========== //
520 public static char ToChar (bool value)
522 throw new InvalidCastException ("This conversion is not supported.");
525 public static char ToChar (byte value)
530 public static char ToChar (char value)
535 public static char ToChar (DateTime value)
537 throw new InvalidCastException ("This conversion is not supported.");
540 public static char ToChar (decimal value)
542 throw new InvalidCastException ("This conversion is not supported.");
545 public static char ToChar (double value)
547 throw new InvalidCastException ("This conversion is not supported.");
550 public static char ToChar (int value)
552 return checked ((char) value);
555 public static char ToChar (long value)
557 return checked ((char) value);
560 public static char ToChar (float value)
562 throw new InvalidCastException ("This conversion is not supported.");
565 [CLSCompliant (false)]
566 public static char ToChar (sbyte value)
568 return checked ((char) value);
571 public static char ToChar (short value)
573 return checked ((char) value);
576 public static char ToChar (string value)
578 return Char.Parse (value);
581 public static char ToChar (string value, IFormatProvider provider)
583 return Char.Parse (value); // provider is ignored.
586 [CLSCompliant (false)]
587 public static char ToChar (uint value)
589 return checked ((char) value);
592 [CLSCompliant (false)]
593 public static char ToChar (ulong value)
595 return checked ((char) value);
598 [CLSCompliant (false)]
599 public static char ToChar (ushort value)
604 public static char ToChar (object value)
608 return ToChar (value, null);
611 public static char ToChar (object value, IFormatProvider provider)
615 return ((IConvertible) value).ToChar (provider);
618 // ========== DateTime Conversions ========== //
620 public static DateTime ToDateTime (string value)
623 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
624 return DateTime.Parse (value);
627 public static DateTime ToDateTime (string value, IFormatProvider provider)
630 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
631 return DateTime.Parse (value, provider);
634 public static DateTime ToDateTime (bool value)
636 throw new InvalidCastException ("This conversion is not supported.");
639 public static DateTime ToDateTime (byte value)
641 throw new InvalidCastException ("This conversion is not supported.");
644 public static DateTime ToDateTime (char value)
646 throw new InvalidCastException ("This conversion is not supported.");
649 public static DateTime ToDateTime (DateTime value)
654 public static DateTime ToDateTime (decimal value)
656 throw new InvalidCastException ("This conversion is not supported.");
659 public static DateTime ToDateTime (double value)
661 throw new InvalidCastException ("This conversion is not supported.");
664 public static DateTime ToDateTime (short value)
666 throw new InvalidCastException ("This conversion is not supported.");
669 public static DateTime ToDateTime (int value)
671 throw new InvalidCastException ("This conversion is not supported.");
674 public static DateTime ToDateTime (long value)
676 throw new InvalidCastException ("This conversion is not supported.");
679 public static DateTime ToDateTime (float value)
681 throw new InvalidCastException ("This conversion is not supported.");
684 public static DateTime ToDateTime (object value)
687 return DateTime.MinValue;
688 return ToDateTime (value, null);
691 public static DateTime ToDateTime (object value, IFormatProvider provider)
694 return DateTime.MinValue;
695 return ((IConvertible) value).ToDateTime (provider);
698 [CLSCompliant (false)]
699 public static DateTime ToDateTime (sbyte value)
701 throw new InvalidCastException ("This conversion is not supported.");
703 [CLSCompliant (false)]
704 public static DateTime ToDateTime (ushort value)
706 throw new InvalidCastException ("This conversion is not supported.");
709 [CLSCompliant (false)]
710 public static DateTime ToDateTime (uint value)
712 throw new InvalidCastException ("This conversion is not supported.");
715 [CLSCompliant (false)]
716 public static DateTime ToDateTime (ulong value)
718 throw new InvalidCastException ("This conversion is not supported.");
721 // ========== Decimal Conversions ========== //
723 public static decimal ToDecimal (bool value)
725 return value ? 1 : 0;
728 public static decimal ToDecimal (byte value)
730 return (decimal)value;
733 public static decimal ToDecimal (char value)
735 throw new InvalidCastException ("This conversion is not supported.");
738 public static decimal ToDecimal (DateTime value)
740 throw new InvalidCastException ("This conversion is not supported.");
743 public static decimal ToDecimal (decimal value)
748 public static decimal ToDecimal (double value)
750 return (decimal) value;
753 public static decimal ToDecimal (float value)
755 return (decimal) value;
758 public static decimal ToDecimal (int value)
760 return (decimal)value;
763 public static decimal ToDecimal (long value)
765 return (decimal)value;
768 [CLSCompliant (false)]
769 public static decimal ToDecimal (sbyte value)
771 return (decimal)value;
774 public static decimal ToDecimal (short value)
776 return (decimal)value;
779 public static decimal ToDecimal (string value)
782 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
783 return Decimal.Parse (value);
786 public static decimal ToDecimal (string value, IFormatProvider provider)
789 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
790 return Decimal.Parse (value, provider);
793 [CLSCompliant (false)]
794 public static decimal ToDecimal (uint value)
796 return (decimal)value;
799 [CLSCompliant (false)]
800 public static decimal ToDecimal (ulong value)
802 return (decimal)value;
805 [CLSCompliant (false)]
806 public static decimal ToDecimal (ushort value)
808 return (decimal)value;
811 public static decimal ToDecimal (object value)
814 return new Decimal (0);
815 return ToDecimal (value, null);
818 public static decimal ToDecimal (object value, IFormatProvider provider)
821 return new Decimal (0);
822 return ((IConvertible) value).ToDecimal (provider);
826 // ========== Double Conversions ========== //
828 public static double ToDouble (bool value)
830 return value ? 1 : 0;
833 public static double ToDouble (byte value)
835 return (double) value;
838 public static double ToDouble (char value)
840 throw new InvalidCastException ("This conversion is not supported.");
843 public static double ToDouble (DateTime value)
845 throw new InvalidCastException ("This conversion is not supported.");
848 public static double ToDouble (decimal value)
850 return (double)value;
853 public static double ToDouble (double value)
858 public static double ToDouble (float value)
860 return (double) value;
863 public static double ToDouble (int value)
865 return (double)value;
868 public static double ToDouble (long value)
870 return (double)value;
873 [CLSCompliant (false)]
874 public static double ToDouble (sbyte value)
876 return (double)value;
879 public static double ToDouble (short value)
881 return (double)value;
884 public static double ToDouble (string value)
887 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
888 return Double.Parse (value);
891 public static double ToDouble (string value, IFormatProvider provider)
894 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
895 return Double.Parse (value, provider);
898 [CLSCompliant (false)]
899 public static double ToDouble (uint value)
901 return (double)value;
904 [CLSCompliant (false)]
905 public static double ToDouble (ulong value)
907 return (double)value;
910 [CLSCompliant (false)]
911 public static double ToDouble (ushort value)
913 return (double)value;
916 public static double ToDouble (object value)
920 return ToDouble (value, null);
923 public static double ToDouble (object value, IFormatProvider provider)
927 return ((IConvertible) value).ToDouble (provider);
930 // ========== Int16 Conversions ========== //
932 public static short ToInt16 (bool value)
934 return (short)(value ? 1 : 0);
937 public static short ToInt16 (byte value)
942 public static short ToInt16 (char value)
944 return checked ((short) value);
947 public static short ToInt16 (DateTime value)
949 throw new InvalidCastException ("This conversion is not supported.");
952 public static short ToInt16 (decimal value)
954 // Returned Even-Rounded
955 return checked ((short) Math.Round (value));
958 public static short ToInt16 (double value)
960 // Returned Even-Rounded
961 return checked ((short) Math.Round (value));
964 public static short ToInt16 (float value)
966 // Returned Even-Rounded, use Math.Round pass as a double.
967 return checked ((short) Math.Round (value));
970 public static short ToInt16 (int value)
972 return checked ((short) value);
975 public static short ToInt16 (long value)
977 return checked ((short) value);
980 [CLSCompliant (false)]
981 public static short ToInt16 (sbyte value)
986 public static short ToInt16 (short value)
991 public static short ToInt16 (string value)
994 return 0; // LAMESPEC: Spec says throw ArgumentNullException
995 return Int16.Parse (value);
998 public static short ToInt16 (string value, IFormatProvider provider)
1001 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1002 return Int16.Parse (value, provider);
1005 public static short ToInt16 (string value, int fromBase)
1007 int result = ConvertFromBase (value, fromBase, false);
1008 if (fromBase != 10) {
1009 if (result > ushort.MaxValue) {
1010 throw new OverflowException ("Value was either too large or too small for an Int16.");
1013 // note: no sign are available to detect negatives
1014 if (result > Int16.MaxValue) {
1015 // return negative 2's complement
1016 return Convert.ToInt16 (-(65536 - result));
1019 return Convert.ToInt16 (result);
1022 [CLSCompliant (false)]
1023 public static short ToInt16 (uint value)
1025 return checked ((short) value);
1028 [CLSCompliant (false)]
1029 public static short ToInt16 (ulong value)
1031 return checked ((short) value);
1034 [CLSCompliant (false)]
1035 public static short ToInt16 (ushort value)
1037 return checked ((short) value);
1040 public static short ToInt16 (object value)
1044 return ToInt16 (value, null);
1047 public static short ToInt16 (object value, IFormatProvider provider)
1051 return ((IConvertible) value).ToInt16 (provider);
1054 // ========== Int32 Conversions ========== //
1056 public static int ToInt32 (bool value)
1058 return value ? 1 : 0;
1061 public static int ToInt32 (byte value)
1066 public static int ToInt32 (char value)
1071 public static int ToInt32 (DateTime value)
1073 throw new InvalidCastException ("This conversion is not supported.");
1076 public static int ToInt32 (decimal value)
1078 // Returned Even-Rounded
1079 return checked ((int) Math.Round (value));
1082 public static int ToInt32 (double value)
1084 // Returned Even-Rounded
1086 return (int)(Math.Round (value));
1090 public static int ToInt32 (float value)
1092 if (value > Int32.MaxValue || value < Int32.MinValue)
1093 throw new OverflowException (Locale.GetText (
1094 "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
1096 // Returned Even-Rounded, pass as a double, could just call
1097 // Convert.ToInt32 ( (double)value);
1099 return (int)(Math.Round ( (double)value));
1103 public static int ToInt32 (int value)
1108 public static int ToInt32 (long value)
1110 return checked ((int) value);
1113 [CLSCompliant (false)]
1114 public static int ToInt32 (sbyte value)
1119 public static int ToInt32 (short value)
1124 public static int ToInt32 (string value)
1127 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1128 return Int32.Parse (value);
1131 public static int ToInt32 (string value, IFormatProvider provider)
1134 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1135 return Int32.Parse (value, provider);
1139 public static int ToInt32 (string value, int fromBase)
1141 return ConvertFromBase (value, fromBase, false);
1144 [CLSCompliant (false)]
1145 public static int ToInt32 (uint value)
1147 return checked ((int) value);
1150 [CLSCompliant (false)]
1151 public static int ToInt32 (ulong value)
1153 return checked ((int) value);
1156 [CLSCompliant (false)]
1157 public static int ToInt32 (ushort value)
1162 public static int ToInt32 (object value)
1166 return ToInt32 (value, null);
1169 public static int ToInt32 (object value, IFormatProvider provider)
1173 return ((IConvertible) value).ToInt32 (provider);
1176 // ========== Int64 Conversions ========== //
1178 public static long ToInt64 (bool value)
1180 return value ? 1 : 0;
1183 public static long ToInt64 (byte value)
1185 return (long)(ulong)value;
1188 public static long ToInt64 (char value)
1193 public static long ToInt64 (DateTime value)
1195 throw new InvalidCastException ("This conversion is not supported.");
1198 public static long ToInt64 (decimal value)
1200 // Returned Even-Rounded
1201 return checked ((long) Math.Round (value));
1204 public static long ToInt64 (double value)
1206 // Returned Even-Rounded
1207 return checked ((long) Math.Round (value));
1210 public static long ToInt64 (float value)
1212 // Returned Even-Rounded, pass to Math as a double, could
1213 // just call Convert.ToInt64 ( (double)value);
1214 return checked ((long) Math.Round (value));
1217 public static long ToInt64 (int value)
1222 public static long ToInt64 (long value)
1227 [CLSCompliant (false)]
1228 public static long ToInt64 (sbyte value)
1233 public static long ToInt64 (short value)
1238 public static long ToInt64 (string value)
1241 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1242 return Int64.Parse (value);
1245 public static long ToInt64 (string value, IFormatProvider provider)
1248 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1249 return Int64.Parse (value, provider);
1252 public static long ToInt64 (string value, int fromBase)
1254 return ConvertFromBase64 (value, fromBase, false);
1257 [CLSCompliant (false)]
1258 public static long ToInt64 (uint value)
1260 return (long)(ulong)value;
1263 [CLSCompliant (false)]
1264 public static long ToInt64 (ulong value)
1266 return checked ((long) value);
1269 [CLSCompliant (false)]
1270 public static long ToInt64 (ushort value)
1272 return (long)(ulong)value;
1275 public static long ToInt64 (object value)
1279 return ToInt64 (value, null);
1282 public static long ToInt64 (object value, IFormatProvider provider)
1286 return ((IConvertible) value).ToInt64 (provider);
1289 // ========== SByte Conversions ========== //
1291 [CLSCompliant (false)]
1292 public static sbyte ToSByte (bool value)
1294 return (sbyte)(value ? 1 : 0);
1297 [CLSCompliant (false)]
1298 public static sbyte ToSByte (byte value)
1300 return checked ((sbyte) value);
1303 [CLSCompliant (false)]
1304 public static sbyte ToSByte (char value)
1306 return checked ((sbyte) value);
1309 [CLSCompliant (false)]
1310 public static sbyte ToSByte (DateTime value)
1312 throw new InvalidCastException ("This conversion is not supported.");
1315 [CLSCompliant (false)]
1316 public static sbyte ToSByte (decimal value)
1318 // Returned Even-Rounded
1319 return checked ((sbyte) Math.Round (value));
1322 [CLSCompliant (false)]
1323 public static sbyte ToSByte (double value)
1325 // Returned Even-Rounded
1326 return checked ((sbyte) Math.Round (value));
1329 [CLSCompliant (false)]
1330 public static sbyte ToSByte (float value)
1332 // Returned Even-Rounded, pass as double to Math
1333 return checked ((sbyte) Math.Round (value));
1336 [CLSCompliant (false)]
1337 public static sbyte ToSByte (int value)
1339 return checked ((sbyte) value);
1342 [CLSCompliant (false)]
1343 public static sbyte ToSByte (long value)
1345 return checked ((sbyte) value);
1348 [CLSCompliant (false)]
1349 public static sbyte ToSByte (sbyte value)
1354 [CLSCompliant (false)]
1355 public static sbyte ToSByte (short value)
1357 return checked ((sbyte) value);
1360 [CLSCompliant (false)]
1361 public static sbyte ToSByte (string value)
1364 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1365 return SByte.Parse (value);
1368 [CLSCompliant (false)]
1369 public static sbyte ToSByte (string value, IFormatProvider provider)
1372 throw new ArgumentNullException ("value");
1373 return SByte.Parse (value, provider);
1376 [CLSCompliant (false)]
1377 public static sbyte ToSByte (string value, int fromBase)
1379 int result = ConvertFromBase (value, fromBase, false);
1380 if (fromBase != 10) {
1381 // note: no sign are available to detect negatives
1382 if (result > SByte.MaxValue) {
1383 // return negative 2's complement
1384 return Convert.ToSByte (-(256 - result));
1387 return Convert.ToSByte (result);
1390 [CLSCompliant (false)]
1391 public static sbyte ToSByte (uint value)
1393 return checked ((sbyte) value);
1396 [CLSCompliant (false)]
1397 public static sbyte ToSByte (ulong value)
1399 return checked ((sbyte) value);
1402 [CLSCompliant (false)]
1403 public static sbyte ToSByte (ushort value)
1405 return checked ((sbyte) value);
1408 [CLSCompliant (false)]
1409 public static sbyte ToSByte (object value)
1413 return ToSByte (value, null);
1416 [CLSCompliant (false)]
1417 public static sbyte ToSByte (object value, IFormatProvider provider)
1421 return ((IConvertible) value).ToSByte (provider);
1424 // ========== Single Conversions ========== //
1426 public static float ToSingle (bool value)
1428 return value ? 1 : 0;
1431 public static float ToSingle (byte value)
1433 return (float)value;
1436 public static float ToSingle (Char value)
1438 throw new InvalidCastException ("This conversion is not supported.");
1441 public static float ToSingle (DateTime value)
1443 throw new InvalidCastException ("This conversion is not supported.");
1446 public static float ToSingle (decimal value)
1448 return (float)value;
1451 public static float ToSingle (double value)
1453 return (float)value;
1456 public static float ToSingle (float value)
1461 public static float ToSingle (int value)
1463 return (float)value;
1466 public static float ToSingle (long value)
1468 return (float)value;
1471 [CLSCompliant (false)]
1472 public static float ToSingle (sbyte value)
1474 return (float)value;
1477 public static float ToSingle (short value)
1479 return (float)value;
1482 public static float ToSingle (string value)
1485 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1486 return Single.Parse (value);
1489 public static float ToSingle (string value, IFormatProvider provider)
1492 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1493 return Single.Parse (value, provider);
1496 [CLSCompliant (false)]
1497 public static float ToSingle (uint value)
1499 return (float)value;
1502 [CLSCompliant (false)]
1503 public static float ToSingle (ulong value)
1505 return (float)value;
1508 [CLSCompliant (false)]
1509 public static float ToSingle (ushort value)
1511 return (float)value;
1514 public static float ToSingle (object value)
1518 return ToSingle (value, null);
1521 // [CLSCompliant (false)]
1522 public static float ToSingle (object value, IFormatProvider provider)
1526 return ((IConvertible) value).ToSingle (provider);
1529 // ========== String Conversions ========== //
1531 public static string ToString (bool value)
1533 return value.ToString ();
1536 public static string ToString (bool value, IFormatProvider provider)
1538 return value.ToString (); // the same as ToString (bool).
1541 public static string ToString (byte value)
1543 return value.ToString ();
1546 public static string ToString (byte value, IFormatProvider provider)
1548 return value.ToString (provider);
1551 public static string ToString (byte value, int toBase)
1556 return value.ToString ();
1558 byte[] val = BitConverter.GetBytes (value);
1562 return ConvertToBase2 (val);
1564 return ConvertToBase8 (val);
1566 return ConvertToBase16 (val);
1568 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1572 public static string ToString (char value)
1574 return value.ToString ();
1577 public static string ToString (char value, IFormatProvider provider)
1579 return value.ToString (); // the same as ToString (char)
1582 public static string ToString (DateTime value)
1584 return value.ToString ();
1587 public static string ToString (DateTime value, IFormatProvider provider)
1589 return value.ToString (provider);
1592 public static string ToString (decimal value)
1594 return value.ToString ();
1597 public static string ToString (decimal value, IFormatProvider provider)
1599 return value.ToString (provider);
1602 public static string ToString (double value)
1604 return value.ToString ();
1607 public static string ToString (double value, IFormatProvider provider)
1609 return value.ToString (provider);
1612 public static string ToString (float value)
1614 return value.ToString ();
1617 public static string ToString (float value, IFormatProvider provider)
1619 return value.ToString (provider);
1622 public static string ToString (int value)
1624 return value.ToString ();
1627 public static string ToString (int value, int toBase)
1632 return value.ToString ();
1634 byte[] val = BitConverter.GetBytes (value);
1638 return ConvertToBase2 (val);
1640 return ConvertToBase8 (val);
1642 return ConvertToBase16 (val);
1644 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1648 public static string ToString (int value, IFormatProvider provider)
1650 return value.ToString (provider);
1653 public static string ToString (long value)
1655 return value.ToString ();
1658 public static string ToString (long value, int toBase)
1663 return value.ToString ();
1665 byte[] val = BitConverter.GetBytes (value);
1669 return ConvertToBase2 (val);
1671 return ConvertToBase8 (val);
1673 return ConvertToBase16 (val);
1675 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1679 public static string ToString (long value, IFormatProvider provider)
1681 return value.ToString (provider);
1684 public static string ToString (object value)
1686 return ToString (value, null);
1689 public static string ToString (object value, IFormatProvider provider)
1691 if (value is IConvertible)
1692 return ((IConvertible) value).ToString (provider);
1693 else if (value != null)
1694 return value.ToString ();
1695 return String.Empty;
1698 [CLSCompliant (false)]
1699 public static string ToString (sbyte value)
1701 return value.ToString ();
1704 [CLSCompliant (false)]
1705 public static string ToString (sbyte value, IFormatProvider provider)
1707 return value.ToString (provider);
1710 public static string ToString (short value)
1712 return value.ToString ();
1715 public static string ToString (short value, int toBase)
1720 return value.ToString ();
1722 byte[] val = BitConverter.GetBytes (value);
1726 return ConvertToBase2 (val);
1728 return ConvertToBase8 (val);
1730 return ConvertToBase16 (val);
1732 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1736 public static string ToString (short value, IFormatProvider provider)
1738 return value.ToString (provider);
1741 public static string ToString (string value)
1746 public static string ToString (string value, IFormatProvider provider)
1748 return value; // provider is ignored.
1751 [CLSCompliant (false)]
1752 public static string ToString (uint value)
1754 return value.ToString ();
1757 [CLSCompliant (false)]
1758 public static string ToString (uint value, IFormatProvider provider)
1760 return value.ToString (provider);
1763 [CLSCompliant (false)]
1764 public static string ToString (ulong value)
1766 return value.ToString ();
1769 [CLSCompliant (false)]
1770 public static string ToString (ulong value, IFormatProvider provider)
1772 return value.ToString (provider);
1775 [CLSCompliant (false)]
1776 public static string ToString (ushort value)
1778 return value.ToString ();
1781 [CLSCompliant (false)]
1782 public static string ToString (ushort value, IFormatProvider provider)
1784 return value.ToString (provider);
1787 // ========== UInt16 Conversions ========== //
1789 [CLSCompliant (false)]
1790 public static ushort ToUInt16 (bool value)
1792 return (ushort)(value ? 1 : 0);
1795 [CLSCompliant (false)]
1796 public static ushort ToUInt16 (byte value)
1798 return (ushort)value;
1801 [CLSCompliant (false)]
1802 public static ushort ToUInt16 (char value)
1804 return (ushort)value;
1807 [CLSCompliant (false)]
1808 public static ushort ToUInt16 (DateTime value)
1810 throw new InvalidCastException ("This conversion is not supported.");
1813 [CLSCompliant (false)]
1814 public static ushort ToUInt16 (decimal value)
1816 // Returned Even-Rounded
1817 return checked ((ushort) Math.Round (value));
1820 [CLSCompliant (false)]
1821 public static ushort ToUInt16 (double value)
1823 // Returned Even-Rounded
1824 return checked ((ushort) Math.Round (value));
1827 [CLSCompliant (false)]
1828 public static ushort ToUInt16 (float value)
1830 // Returned Even-Rounded, pass as double to Math
1831 return checked ((ushort) Math.Round (value));
1834 [CLSCompliant (false)]
1835 public static ushort ToUInt16 (int value)
1837 return checked ((ushort) value);
1840 [CLSCompliant (false)]
1841 public static ushort ToUInt16 (long value)
1843 return checked ((ushort) value);
1846 [CLSCompliant (false)]
1847 public static ushort ToUInt16 (sbyte value)
1849 return checked ((ushort) value);
1852 [CLSCompliant (false)]
1853 public static ushort ToUInt16 (short value)
1855 return checked ((ushort) value);
1858 [CLSCompliant (false)]
1859 public static ushort ToUInt16 (string value)
1862 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1863 return UInt16.Parse (value);
1866 [CLSCompliant (false)]
1867 public static ushort ToUInt16 (string value, IFormatProvider provider)
1870 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1871 return UInt16.Parse (value, provider);
1874 [CLSCompliant (false)]
1875 public static ushort ToUInt16 (string value, int fromBase)
1877 return ToUInt16 (ConvertFromBase (value, fromBase, true));
1880 [CLSCompliant (false)]
1881 public static ushort ToUInt16 (uint value)
1883 return checked ((ushort) value);
1886 [CLSCompliant (false)]
1887 public static ushort ToUInt16 (ulong value)
1889 return checked ((ushort) value);
1892 [CLSCompliant (false)]
1893 public static ushort ToUInt16 (ushort value)
1898 [CLSCompliant (false)]
1899 public static ushort ToUInt16 (object value)
1903 return ToUInt16 (value, null);
1906 [CLSCompliant (false)]
1907 public static ushort ToUInt16 (object value, IFormatProvider provider)
1911 return ((IConvertible) value).ToUInt16 (provider);
1914 // ========== UInt32 Conversions ========== //
1916 [CLSCompliant (false)]
1917 public static uint ToUInt32 (bool value)
1919 return (uint)(value ? 1 : 0);
1922 [CLSCompliant (false)]
1923 public static uint ToUInt32 (byte value)
1928 [CLSCompliant (false)]
1929 public static uint ToUInt32 (char value)
1934 [CLSCompliant (false)]
1935 public static uint ToUInt32 (DateTime value)
1937 throw new InvalidCastException ("This conversion is not supported.");
1940 [CLSCompliant (false)]
1941 public static uint ToUInt32 (decimal value)
1943 // Returned Even-Rounded
1944 return checked ((uint) Math.Round (value));
1947 [CLSCompliant (false)]
1948 public static uint ToUInt32 (double value)
1950 // Returned Even-Rounded
1951 return checked ((uint) Math.Round (value));
1954 [CLSCompliant (false)]
1955 public static uint ToUInt32 (float value)
1957 // Returned Even-Rounded, pass as double to Math
1958 return checked ((uint) Math.Round (value));
1961 [CLSCompliant (false)]
1962 public static uint ToUInt32 (int value)
1964 return checked ((uint) value);
1967 [CLSCompliant (false)]
1968 public static uint ToUInt32 (long value)
1970 return checked ((uint) value);
1973 [CLSCompliant (false)]
1974 public static uint ToUInt32 (sbyte value)
1976 return checked ((uint) value);
1979 [CLSCompliant (false)]
1980 public static uint ToUInt32 (short value)
1982 return checked ((uint) value);
1985 [CLSCompliant (false)]
1986 public static uint ToUInt32 (string value)
1989 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1990 return UInt32.Parse (value);
1993 [CLSCompliant (false)]
1994 public static uint ToUInt32 (string value, IFormatProvider provider)
1997 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1998 return UInt32.Parse (value, provider);
2001 [CLSCompliant (false)]
2002 public static uint ToUInt32 (string value, int fromBase)
2004 return (uint) ConvertFromBase (value, fromBase, true);
2007 [CLSCompliant (false)]
2008 public static uint ToUInt32 (uint value)
2013 [CLSCompliant (false)]
2014 public static uint ToUInt32 (ulong value)
2016 return checked ((uint) value);
2019 [CLSCompliant (false)]
2020 public static uint ToUInt32 (ushort value)
2025 [CLSCompliant (false)]
2026 public static uint ToUInt32 (object value)
2030 return ToUInt32 (value, null);
2033 [CLSCompliant (false)]
2034 public static uint ToUInt32 (object value, IFormatProvider provider)
2038 return ((IConvertible) value).ToUInt32 (provider);
2042 // ========== UInt64 Conversions ========== //
2044 [CLSCompliant (false)]
2045 public static ulong ToUInt64 (bool value)
2047 return (ulong)(value ? 1 : 0);
2050 [CLSCompliant (false)]
2051 public static ulong ToUInt64 (byte value)
2053 return (ulong)value;
2056 [CLSCompliant (false)]
2057 public static ulong ToUInt64 (char value)
2059 return (ulong)value;
2062 [CLSCompliant (false)]
2063 public static ulong ToUInt64 (DateTime value)
2065 throw new InvalidCastException ("The conversion is not supported.");
2068 [CLSCompliant (false)]
2069 public static ulong ToUInt64 (decimal value)
2071 // Returned Even-Rounded
2072 return checked ((ulong) Math.Round (value));
2075 [CLSCompliant (false)]
2076 public static ulong ToUInt64 (double value)
2078 // Returned Even-Rounded
2079 return checked ((ulong) Math.Round (value));
2082 [CLSCompliant (false)]
2083 public static ulong ToUInt64 (float value)
2085 // Returned Even-Rounded, pass as a double to Math
2086 return checked ((ulong) Math.Round (value));
2089 [CLSCompliant (false)]
2090 public static ulong ToUInt64 (int value)
2092 return checked ((ulong) value);
2095 [CLSCompliant (false)]
2096 public static ulong ToUInt64 (long value)
2098 return checked ((ulong) value);
2101 [CLSCompliant (false)]
2102 public static ulong ToUInt64 (sbyte value)
2104 return checked ((ulong) value);
2107 [CLSCompliant (false)]
2108 public static ulong ToUInt64 (short value)
2110 return checked ((ulong) value);
2113 [CLSCompliant (false)]
2114 public static ulong ToUInt64 (string value)
2117 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2118 return UInt64.Parse (value);
2121 [CLSCompliant (false)]
2122 public static ulong ToUInt64 (string value, IFormatProvider provider)
2125 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2126 return UInt64.Parse (value, provider);
2129 [CLSCompliant (false)]
2130 public static ulong ToUInt64 (string value, int fromBase)
2132 return (ulong) ConvertFromBase64 (value, fromBase, true);
2135 [CLSCompliant (false)]
2136 public static ulong ToUInt64 (uint value)
2138 return (ulong)value;
2141 [CLSCompliant (false)]
2142 public static ulong ToUInt64 (ulong value)
2147 [CLSCompliant (false)]
2148 public static ulong ToUInt64 (ushort value)
2150 return (ulong)value;
2153 [CLSCompliant (false)]
2154 public static ulong ToUInt64 (object value)
2158 return ToUInt64 (value, null);
2161 [CLSCompliant (false)]
2162 public static ulong ToUInt64 (object value, IFormatProvider provider)
2166 return ((IConvertible) value).ToUInt64 (provider);
2170 // ========== Conversion / Helper Functions ========== //
2172 public static object ChangeType (object value, Type conversionType)
2174 if ((value != null) && (conversionType == null))
2175 throw new ArgumentNullException ("conversionType");
2176 CultureInfo ci = CultureInfo.CurrentCulture;
2177 IFormatProvider provider;
2178 if (conversionType == typeof(DateTime)) {
2179 provider = ci.DateTimeFormat;
2182 provider = ci.NumberFormat;
2184 return ToType (value, conversionType, provider, true);
2187 public static object ChangeType (object value, TypeCode typeCode)
2189 CultureInfo ci = CultureInfo.CurrentCulture;
2190 Type conversionType = conversionTable [(int) typeCode];
2191 IFormatProvider provider;
2192 if (conversionType == typeof(DateTime)) {
2193 provider = ci.DateTimeFormat;
2196 provider = ci.NumberFormat;
2198 return ToType (value, conversionType, provider, true);
2201 public static object ChangeType (object value, Type conversionType, IFormatProvider provider)
2203 if ((value != null) && (conversionType == null))
2204 throw new ArgumentNullException ("conversionType");
2205 return ToType (value, conversionType, provider, true);
2208 public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider)
2210 Type conversionType = conversionTable [(int)typeCode];
2211 return ToType (value, conversionType, provider, true);
2214 private static bool NotValidBase (int value)
2216 if ((value == 2) || (value == 8) ||
2217 (value == 10) || (value == 16))
2223 private static int ConvertFromBase (string value, int fromBase, bool unsigned)
2225 if (NotValidBase (fromBase))
2226 throw new ArgumentException ("fromBase is not valid.");
2235 int len = value.Length;
2236 bool negative = false;
2238 // special processing for some bases
2241 if (value.Substring (i, 1) == "-") {
2243 throw new OverflowException (
2244 Locale.GetText ("The string was being parsed as"
2245 + " an unsigned number and could not have a"
2246 + " negative sign."));
2253 if (value.Substring (i, 1) == "-") {
2254 throw new ArgumentException ("String cannot contain a "
2255 + "minus sign if the base is not 10.");
2259 if ((value[i] == '0') && ((value [i+1] == 'x') || (value [i+1] == 'X'))) {
2265 if (value.Substring (i, 1) == "-") {
2266 throw new ArgumentException ("String cannot contain a "
2267 + "minus sign if the base is not 10.");
2273 throw new FormatException ("Could not find any parsable digits.");
2276 if (value[i] == '+') {
2281 char c = value[i++];
2282 if (Char.IsNumber (c)) {
2283 digitValue = c - '0';
2284 } else if (Char.IsLetter (c)) {
2285 digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2288 throw new FormatException ("Additional unparsable "
2289 + "characters are at the end of the string.");
2291 throw new FormatException ("Could not find any parsable"
2296 if (digitValue >= fromBase) {
2298 throw new FormatException ("Additional unparsable "
2299 + "characters are at the end of the string.");
2301 throw new FormatException ("Could not find any parsable"
2306 result = (fromBase) * result + digitValue;
2311 throw new FormatException ("Could not find any parsable digits.");
2319 // note: this has nothing to do with base64 encoding (just base and Int64)
2320 private static long ConvertFromBase64 (string value, int fromBase, bool unsigned)
2322 if (NotValidBase (fromBase))
2323 throw new ArgumentException ("fromBase is not valid.");
2328 int digitValue = -1;
2330 bool negative = false;
2333 int len = value.Length;
2335 // special processing for some bases
2338 if (value.Substring(i, 1) == "-") {
2340 throw new OverflowException (
2341 Locale.GetText ("The string was being parsed as"
2342 + " an unsigned number and could not have a"
2343 + " negative sign."));
2350 if (value.Substring (i, 1) == "-") {
2351 throw new ArgumentException ("String cannot contain a "
2352 + "minus sign if the base is not 10.");
2356 if ((value[i] == '0') && ((value[i + 1] == 'x') || (value[i + 1] == 'X'))) {
2362 if (value.Substring (i, 1) == "-") {
2363 throw new ArgumentException ("String cannot contain a "
2364 + "minus sign if the base is not 10.");
2370 throw new FormatException ("Could not find any parsable digits.");
2373 if (value[i] == '+') {
2378 char c = value[i++];
2379 if (Char.IsNumber (c)) {
2380 digitValue = c - '0';
2381 } else if (Char.IsLetter (c)) {
2382 digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2385 throw new FormatException ("Additional unparsable "
2386 + "characters are at the end of the string.");
2388 throw new FormatException ("Could not find any parsable"
2393 if (digitValue >= fromBase) {
2395 throw new FormatException ("Additional unparsable "
2396 + "characters are at the end of the string.");
2398 throw new FormatException ("Could not find any parsable"
2403 result = (fromBase * result + digitValue);
2408 throw new FormatException ("Could not find any parsable digits.");
2416 private static void EndianSwap (ref byte[] value)
2418 byte[] buf = new byte[value.Length];
2419 for (int i = 0; i < value.Length; i++)
2420 buf[i] = value[value.Length-1-i];
2424 private static string ConvertToBase2 (byte[] value)
2426 if (!BitConverter.IsLittleEndian)
2427 EndianSwap (ref value);
2428 StringBuilder sb = new StringBuilder ();
2429 for (int i = value.Length - 1; i >= 0; i--) {
2431 for (int j = 0; j < 8; j++) {
2432 if ((b & 0x80) == 0x80) {
2442 return sb.ToString ();
2445 private static string ConvertToBase8 (byte[] value)
2448 switch (value.Length) {
2450 l = (ulong) value [0];
2453 l = (ulong) BitConverter.ToUInt16 (value, 0);
2456 l = (ulong) BitConverter.ToUInt32 (value, 0);
2459 l = BitConverter.ToUInt64 (value, 0);
2462 throw new ArgumentException ("value");
2465 StringBuilder sb = new StringBuilder ();
2466 for (int i = 21; i >= 0; i--) {
2467 // 3 bits at the time
2468 char val = (char) ((l >> i * 3) & 0x7);
2469 if ((val != 0) || (sb.Length > 0)) {
2474 return sb.ToString ();
2477 private static string ConvertToBase16 (byte[] value)
2479 if (!BitConverter.IsLittleEndian)
2480 EndianSwap (ref value);
2481 StringBuilder sb = new StringBuilder ();
2482 for (int i = value.Length - 1; i >= 0; i--) {
2483 char high = (char)((value[i] >> 4) & 0x0f);
2484 if ((high != 0) || (sb.Length > 0)) {
2494 char low = (char)(value[i] & 0x0f);
2495 if ((low != 0) || (sb.Length > 0)) {
2505 return sb.ToString ();
2508 // Lookup table for the conversion ToType method. Order
2509 // is important! Used by ToType for comparing the target
2510 // type, and uses hardcoded array indexes.
2511 private static readonly Type[] conversionTable = {
2512 // Valid ICovnertible Types
2514 typeof (object), // 1 TypeCode.Object
2515 typeof (DBNull), // 2 TypeCode.DBNull
2516 typeof (Boolean), // 3 TypeCode.Boolean
2517 typeof (Char), // 4 TypeCode.Char
2518 typeof (SByte), // 5 TypeCode.SByte
2519 typeof (Byte), // 6 TypeCode.Byte
2520 typeof (Int16), // 7 TypeCode.Int16
2521 typeof (UInt16), // 8 TypeCode.UInt16
2522 typeof (Int32), // 9 TypeCode.Int32
2523 typeof (UInt32), // 10 TypeCode.UInt32
2524 typeof (Int64), // 11 TypeCode.Int64
2525 typeof (UInt64), // 12 TypeCode.UInt64
2526 typeof (Single), // 13 TypeCode.Single
2527 typeof (Double), // 14 TypeCode.Double
2528 typeof (Decimal), // 15 TypeCode.Decimal
2529 typeof (DateTime), // 16 TypeCode.DateTime
2531 typeof (String), // 18 TypeCode.String
2535 // Function to convert an object to another type and return
2536 // it as an object. In place for the core data types to use
2537 // when implementing IConvertible. Uses hardcoded indexes in
2538 // the conversionTypes array, so if modify carefully.
2541 // The `try_target_to_type' boolean indicates if the code
2542 // should try to call the IConvertible.ToType method if everything
2545 // This should be true for invocations from Convert.cs, and
2546 // false from the mscorlib types that implement IConvertible that
2547 // all into this internal function.
2549 // This was added to keep the fix for #481687 working and to avoid
2550 // the regression that the simple fix introduced (485377)
2551 internal static object ToType (object value, Type conversionType, IFormatProvider provider, bool try_target_to_type)
2553 if (value == null) {
2554 if ((conversionType != null) && conversionType.IsValueType){
2555 throw new InvalidCastException ("Null object can not be converted to a value type.");
2560 if (conversionType == null)
2561 throw new InvalidCastException ("Cannot cast to destination type.");
2563 if (value.GetType () == conversionType)
2566 IConvertible convertValue = value as IConvertible;
2567 if (convertValue != null) {
2569 if (conversionType == conversionTable[0]) // 0 Empty
2570 throw new ArgumentNullException ();
2572 if (conversionType == conversionTable[1]) // 1 TypeCode.Object
2575 if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull
2576 throw new InvalidCastException (
2577 "Cannot cast to DBNull, it's not IConvertible");
2579 if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean
2580 return convertValue.ToBoolean (provider);
2582 if (conversionType == conversionTable[4]) // 4 TypeCode.Char
2583 return convertValue.ToChar (provider);
2585 if (conversionType == conversionTable[5]) // 5 TypeCode.SByte
2586 return convertValue.ToSByte (provider);
2588 if (conversionType == conversionTable[6]) // 6 TypeCode.Byte
2589 return convertValue.ToByte (provider);
2591 if (conversionType == conversionTable[7]) // 7 TypeCode.Int16
2592 return convertValue.ToInt16 (provider);
2594 if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16
2595 return convertValue.ToUInt16 (provider);
2597 if (conversionType == conversionTable[9]) // 9 TypeCode.Int32
2598 return convertValue.ToInt32 (provider);
2600 if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32
2601 return convertValue.ToUInt32 (provider);
2603 if (conversionType == conversionTable[11]) // 11 TypeCode.Int64
2604 return convertValue.ToInt64 (provider);
2606 if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64
2607 return convertValue.ToUInt64 (provider);
2609 if (conversionType == conversionTable[13]) // 13 TypeCode.Single
2610 return convertValue.ToSingle (provider);
2612 if (conversionType == conversionTable[14]) // 14 TypeCode.Double
2613 return convertValue.ToDouble (provider);
2615 if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal
2616 return convertValue.ToDecimal (provider);
2618 if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime
2619 return convertValue.ToDateTime (provider);
2621 if (conversionType == conversionTable[18]) // 18 TypeCode.String
2622 return convertValue.ToString (provider);
2624 if (conversionType == conversionTable[19] && value is Enum) // System.Enum
2627 if (try_target_to_type)
2628 return convertValue.ToType (conversionType, provider);
2630 // Not in the conversion table
2631 throw new InvalidCastException ((Locale.GetText (
2632 "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));