5 // Derek Holden (dholden@draper.com)
6 // Duncan Mak (duncan@ximian.com)
8 // (C) Ximian, Inc. http://www.ximian.com
11 // System.Convert class. This was written word for word off the
12 // Library specification for System.Convert in the ECMA TC39 TG2
13 // and TG3 working documents. The first page of which has a table
14 // for all legal conversion scenerios.
16 // This header and the one above it can be formatted however, just trying
17 // to keep it consistent w/ the existing mcs headers.
19 // This Convert class could be written another way, with each type
20 // implementing IConvertible and defining their own conversion functions,
21 // and this class just calling the type's implementation. Or, they can
22 // be defined here and the implementing type can use these functions when
23 // defining their IConvertible interface. Byte's ToBoolean() calls
24 // Convert.ToBoolean(byte), or Convert.ToBoolean(byte) calls
25 // byte.ToBoolean(). The first case is what is done here.
27 // See http://lists.ximian.com/archives/public/mono-list/2001-July/000525.html
29 // There are also conversion functions that are not defined in
30 // the ECMA draft, such as there is no bool ToBoolean(DateTime value),
31 // and placing that somewhere won't compile w/ this Convert since the
32 // function doesn't exist. However calling that when using Microsoft's
33 // System.Convert doesn't produce any compiler errors, it just throws
34 // an InvalidCastException at runtime.
36 // Whenever a decimal, double, or single is converted to an integer
37 // based type, it is even rounded. This uses Math.Round which only
38 // has Round(decimal) and Round(double), so in the Convert from
39 // single cases the value is passed to Math as a double. This
40 // may not be completely necessary.
42 // The .NET Framework SDK lists DBNull as a member of this class
43 // as 'public static readonly object DBNull;'.
45 // It should also be decided if all the cast return values should be
46 // returned as unchecked or not.
48 // All the XML function comments were auto generated which is why they
49 // sound someone redundant.
51 // TYPE | BOOL BYTE CHAR DT DEC DBL I16 I32 I64 SBYT SNGL STR UI16 UI32 UI64
52 // -----+--------------------------------------------------------------------
53 // BOOL | X X X X X X X X X X X X X
54 // BYTE | X X X X X X X X X X X X X X
55 // CHAR | X X X X X X X X X X
57 // DEC | X X X X X X X X X X X X X
58 // DBL | X X X X X X X X X X X X X
59 // I16 | X X X X X X X X X X X X X X
60 // I32 | X X X X X X X X X X X X X X
61 // I64 | X X X X X X X X X X X X X X
62 // SBYT | X X X X X X X X X X X X X X
63 // SNGL | X X X X X X X X X X X X X
64 // STR | X X X X X X X X X X X X X X X
65 // UI16 | X X X X X X X X X X X X X X
66 // UI32 | X X X X X X X X X X X X X X
67 // UI64 | X X X X X X X X X X X X X X
71 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
73 // Permission is hereby granted, free of charge, to any person obtaining
74 // a copy of this software and associated documentation files (the
75 // "Software"), to deal in the Software without restriction, including
76 // without limitation the rights to use, copy, modify, merge, publish,
77 // distribute, sublicense, and/or sell copies of the Software, and to
78 // permit persons to whom the Software is furnished to do so, subject to
79 // the following conditions:
81 // The above copyright notice and this permission notice shall be
82 // included in all copies or substantial portions of the Software.
84 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
86 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
87 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
88 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
89 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
90 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93 using System.Globalization;
95 using System.Security.Cryptography;
97 using System.Runtime.CompilerServices;
98 using System.Runtime.InteropServices;
102 // [CLSCompliant(false)]
103 public static class Convert {
106 public static readonly object DBNull = System.DBNull.Value;
108 [MethodImplAttribute (MethodImplOptions.InternalCall)]
109 extern static byte [] InternalFromBase64String (string str, bool allowWhitespaceOnly);
111 [MethodImplAttribute (MethodImplOptions.InternalCall)]
112 extern static byte [] InternalFromBase64CharArray (char [] arr, int offset, int length);
114 public static byte[] FromBase64CharArray (char[] inArray, int offset, int length)
117 throw new ArgumentNullException ("inArray");
119 throw new ArgumentOutOfRangeException ("offset < 0");
121 throw new ArgumentOutOfRangeException ("length < 0");
122 // avoid integer overflow
123 if (offset > inArray.Length - length)
124 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
126 return InternalFromBase64CharArray (inArray, offset, length);
129 public static byte[] FromBase64String (string s)
132 throw new ArgumentNullException ("s");
135 return EmptyArray<byte>.Value;
138 return InternalFromBase64String (s, true);
141 public static TypeCode GetTypeCode (object value)
144 return TypeCode.Empty;
146 return Type.GetTypeCode (value.GetType ());
149 public static bool IsDBNull (object value)
157 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length,
158 char[] outArray, int offsetOut)
161 throw new ArgumentNullException ("inArray");
162 if (outArray == null)
163 throw new ArgumentNullException ("outArray");
164 if (offsetIn < 0 || length < 0 || offsetOut < 0)
165 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
166 // avoid integer overflow
167 if (offsetIn > inArray.Length - length)
168 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
170 // note: normally ToBase64Transform doesn't support multiple block processing
171 byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
173 char[] cOutArr = new ASCIIEncoding ().GetChars (outArr);
175 // avoid integer overflow
176 if (offsetOut > outArray.Length - cOutArr.Length)
177 throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
179 Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
181 return cOutArr.Length;
184 public static string ToBase64String (byte[] inArray)
187 throw new ArgumentNullException ("inArray");
189 return ToBase64String (inArray, 0, inArray.Length);
192 public static string ToBase64String (byte[] inArray, int offset, int length)
195 throw new ArgumentNullException ("inArray");
196 if (offset < 0 || length < 0)
197 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
198 // avoid integer overflow
199 if (offset > inArray.Length - length)
200 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
202 // note: normally ToBase64Transform doesn't support multiple block processing
203 byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, length);
205 return (new ASCIIEncoding ().GetString (outArr));
209 public static string ToBase64String (byte[] inArray, Base64FormattingOptions options)
212 throw new ArgumentNullException ("inArray");
213 return ToBase64String (inArray, 0, inArray.Length, options);
217 public static string ToBase64String (byte[] inArray, int offset, int length, Base64FormattingOptions options)
220 throw new ArgumentNullException ("inArray");
221 if (offset < 0 || length < 0)
222 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
223 // avoid integer overflow
224 if (offset > inArray.Length - length)
225 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
230 if (options == Base64FormattingOptions.InsertLineBreaks)
231 return ToBase64StringBuilderWithLine (inArray, offset, length).ToString ();
233 return Encoding.ASCII.GetString (ToBase64Transform.InternalTransformFinalBlock (inArray, offset, length));
237 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length,
238 char[] outArray, int offsetOut, Base64FormattingOptions options)
241 throw new ArgumentNullException ("inArray");
242 if (outArray == null)
243 throw new ArgumentNullException ("outArray");
244 if (offsetIn < 0 || length < 0 || offsetOut < 0)
245 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
246 // avoid integer overflow
247 if (offsetIn > inArray.Length - length)
248 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
253 // note: normally ToBase64Transform doesn't support multiple block processing
254 if (options == Base64FormattingOptions.InsertLineBreaks) {
255 StringBuilder sb = ToBase64StringBuilderWithLine (inArray, offsetIn, length);
256 sb.CopyTo (0, outArray, offsetOut, sb.Length);
259 byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
261 char[] cOutArr = Encoding.ASCII.GetChars (outArr);
263 // avoid integer overflow
264 if (offsetOut > outArray.Length - cOutArr.Length)
265 throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
267 Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
268 return cOutArr.Length;
272 private const int MaxBytesPerLine = 57;
274 static StringBuilder ToBase64StringBuilderWithLine (byte [] inArray, int offset, int length)
276 StringBuilder sb = new StringBuilder ();
279 int full = Math.DivRem (length, MaxBytesPerLine, out remainder);
280 for (int i = 0; i < full; i ++) {
281 byte[] data = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, MaxBytesPerLine);
282 sb.AppendLine (Encoding.ASCII.GetString (data));
283 offset += MaxBytesPerLine;
285 // we never complete (i.e. the last line) with a new line
286 if (remainder == 0) {
287 int nll = Environment.NewLine.Length;
288 sb.Remove (sb.Length - nll, nll);
290 byte[] data = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, remainder);
291 sb.Append (Encoding.ASCII.GetString (data));
296 // ========== Boolean Conversions ========== //
298 public static bool ToBoolean (bool value)
303 public static bool ToBoolean (byte value)
308 public static bool ToBoolean (char value)
310 throw new InvalidCastException (Locale.GetText ("Can't convert char to bool"));
313 public static bool ToBoolean (DateTime value)
315 throw new InvalidCastException (Locale.GetText ("Can't convert date to bool"));
318 public static bool ToBoolean (decimal value)
320 return (value != 0M);
323 public static bool ToBoolean (double value)
328 public static bool ToBoolean (float value)
330 return (value != 0f);
333 public static bool ToBoolean (int value)
338 public static bool ToBoolean (long value)
343 [CLSCompliant (false)]
344 public static bool ToBoolean (sbyte value)
349 public static bool ToBoolean (short value)
354 public static bool ToBoolean (string value)
357 return false; // LAMESPEC: Spec says throw ArgumentNullException
358 return Boolean.Parse (value);
361 public static bool ToBoolean (string value, IFormatProvider provider)
364 return false; // LAMESPEC: Spec says throw ArgumentNullException
365 return Boolean.Parse (value); // provider is ignored.
368 [CLSCompliant (false)]
369 public static bool ToBoolean (uint value)
374 [CLSCompliant (false)]
375 public static bool ToBoolean (ulong value)
380 [CLSCompliant (false)]
381 public static bool ToBoolean (ushort value)
388 public static bool ToBoolean (object value)
392 return ToBoolean (value, null);
395 public static bool ToBoolean (object value, IFormatProvider provider)
399 return ((IConvertible) value).ToBoolean (provider);
402 // ========== Byte Conversions ========== //
404 public static byte ToByte (bool value)
406 return (byte)(value ? 1 : 0);
409 public static byte ToByte (byte value)
414 public static byte ToByte (char value)
416 return checked ((byte) value);
419 public static byte ToByte (DateTime value)
421 throw new InvalidCastException ("This conversion is not supported.");
424 public static byte ToByte (decimal value)
426 // Returned Even-Rounded
427 return checked ((byte) Math.Round (value));
430 public static byte ToByte (double value)
432 // Returned Even-Rounded
433 return checked ((byte) Math.Round (value));
436 public static byte ToByte (float value)
438 // Returned Even-Rounded, pass it as a double, could have this
439 // method just call Convert.ToByte ( (double)value)
440 return checked ((byte) Math.Round (value));
443 public static byte ToByte (int value)
445 return checked ((byte) value);
448 public static byte ToByte (long value)
450 return checked ((byte) value);
453 [CLSCompliant (false)]
454 public static byte ToByte (sbyte value)
456 return checked ((byte) value);
459 public static byte ToByte (short value)
461 return checked ((byte) value);
464 public static byte ToByte (string value)
467 return 0; // LAMESPEC: Spec says throw ArgumentNullException
468 return Byte.Parse (value);
471 public static byte ToByte (string value, IFormatProvider provider)
474 return 0; // LAMESPEC: Spec says throw ArgumentNullException
475 return Byte.Parse (value, provider);
478 public static byte ToByte (string value, int fromBase)
480 int retVal = ConvertFromBase (value, fromBase, true);
482 return checked ((byte) retVal);
485 [CLSCompliant (false)]
486 public static byte ToByte (uint value)
488 return checked ((byte) value);
491 [CLSCompliant (false)]
492 public static byte ToByte (ulong value)
494 return checked ((byte) value);
497 [CLSCompliant (false)]
498 public static byte ToByte (ushort value)
500 return checked ((byte) value);
503 public static byte ToByte (object value)
507 return ToByte (value, null);
510 public static byte ToByte (object value, IFormatProvider provider)
514 return ((IConvertible) value).ToByte (provider);
517 // ========== Char Conversions ========== //
519 public static char ToChar (bool value)
521 throw new InvalidCastException ("This conversion is not supported.");
524 public static char ToChar (byte value)
529 public static char ToChar (char value)
534 public static char ToChar (DateTime value)
536 throw new InvalidCastException ("This conversion is not supported.");
539 public static char ToChar (decimal value)
541 throw new InvalidCastException ("This conversion is not supported.");
544 public static char ToChar (double value)
546 throw new InvalidCastException ("This conversion is not supported.");
549 public static char ToChar (int value)
551 return checked ((char) value);
554 public static char ToChar (long value)
556 return checked ((char) value);
559 public static char ToChar (float value)
561 throw new InvalidCastException ("This conversion is not supported.");
564 [CLSCompliant (false)]
565 public static char ToChar (sbyte value)
567 return checked ((char) value);
570 public static char ToChar (short value)
572 return checked ((char) value);
575 public static char ToChar (string value)
577 return Char.Parse (value);
580 public static char ToChar (string value, IFormatProvider provider)
582 return Char.Parse (value); // provider is ignored.
585 [CLSCompliant (false)]
586 public static char ToChar (uint value)
588 return checked ((char) value);
591 [CLSCompliant (false)]
592 public static char ToChar (ulong value)
594 return checked ((char) value);
597 [CLSCompliant (false)]
598 public static char ToChar (ushort value)
603 public static char ToChar (object value)
607 return ToChar (value, null);
610 public static char ToChar (object value, IFormatProvider provider)
614 return ((IConvertible) value).ToChar (provider);
617 // ========== DateTime Conversions ========== //
619 public static DateTime ToDateTime (string value)
622 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
623 return DateTime.Parse (value);
626 public static DateTime ToDateTime (string value, IFormatProvider provider)
629 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
630 return DateTime.Parse (value, provider);
633 public static DateTime ToDateTime (bool value)
635 throw new InvalidCastException ("This conversion is not supported.");
638 public static DateTime ToDateTime (byte value)
640 throw new InvalidCastException ("This conversion is not supported.");
643 public static DateTime ToDateTime (char value)
645 throw new InvalidCastException ("This conversion is not supported.");
648 public static DateTime ToDateTime (DateTime value)
653 public static DateTime ToDateTime (decimal value)
655 throw new InvalidCastException ("This conversion is not supported.");
658 public static DateTime ToDateTime (double value)
660 throw new InvalidCastException ("This conversion is not supported.");
663 public static DateTime ToDateTime (short value)
665 throw new InvalidCastException ("This conversion is not supported.");
668 public static DateTime ToDateTime (int value)
670 throw new InvalidCastException ("This conversion is not supported.");
673 public static DateTime ToDateTime (long value)
675 throw new InvalidCastException ("This conversion is not supported.");
678 public static DateTime ToDateTime (float value)
680 throw new InvalidCastException ("This conversion is not supported.");
683 public static DateTime ToDateTime (object value)
686 return DateTime.MinValue;
687 return ToDateTime (value, null);
690 public static DateTime ToDateTime (object value, IFormatProvider provider)
693 return DateTime.MinValue;
694 return ((IConvertible) value).ToDateTime (provider);
697 [CLSCompliant (false)]
698 public static DateTime ToDateTime (sbyte value)
700 throw new InvalidCastException ("This conversion is not supported.");
702 [CLSCompliant (false)]
703 public static DateTime ToDateTime (ushort value)
705 throw new InvalidCastException ("This conversion is not supported.");
708 [CLSCompliant (false)]
709 public static DateTime ToDateTime (uint value)
711 throw new InvalidCastException ("This conversion is not supported.");
714 [CLSCompliant (false)]
715 public static DateTime ToDateTime (ulong value)
717 throw new InvalidCastException ("This conversion is not supported.");
720 // ========== Decimal Conversions ========== //
722 public static decimal ToDecimal (bool value)
724 return value ? 1 : 0;
727 public static decimal ToDecimal (byte value)
729 return (decimal)value;
732 public static decimal ToDecimal (char value)
734 throw new InvalidCastException ("This conversion is not supported.");
737 public static decimal ToDecimal (DateTime value)
739 throw new InvalidCastException ("This conversion is not supported.");
742 public static decimal ToDecimal (decimal value)
747 public static decimal ToDecimal (double value)
749 return (decimal) value;
752 public static decimal ToDecimal (float value)
754 return (decimal) value;
757 public static decimal ToDecimal (int value)
759 return (decimal)value;
762 public static decimal ToDecimal (long value)
764 return (decimal)value;
767 [CLSCompliant (false)]
768 public static decimal ToDecimal (sbyte value)
770 return (decimal)value;
773 public static decimal ToDecimal (short value)
775 return (decimal)value;
778 public static decimal ToDecimal (string value)
781 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
782 return Decimal.Parse (value);
785 public static decimal ToDecimal (string value, IFormatProvider provider)
788 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
789 return Decimal.Parse (value, provider);
792 [CLSCompliant (false)]
793 public static decimal ToDecimal (uint value)
795 return (decimal)value;
798 [CLSCompliant (false)]
799 public static decimal ToDecimal (ulong value)
801 return (decimal)value;
804 [CLSCompliant (false)]
805 public static decimal ToDecimal (ushort value)
807 return (decimal)value;
810 public static decimal ToDecimal (object value)
813 return new Decimal (0);
814 return ToDecimal (value, null);
817 public static decimal ToDecimal (object value, IFormatProvider provider)
820 return new Decimal (0);
821 return ((IConvertible) value).ToDecimal (provider);
825 // ========== Double Conversions ========== //
827 public static double ToDouble (bool value)
829 return value ? 1 : 0;
832 public static double ToDouble (byte value)
834 return (double) value;
837 public static double ToDouble (char value)
839 throw new InvalidCastException ("This conversion is not supported.");
842 public static double ToDouble (DateTime value)
844 throw new InvalidCastException ("This conversion is not supported.");
847 public static double ToDouble (decimal value)
849 return (double)value;
852 public static double ToDouble (double value)
857 public static double ToDouble (float value)
859 return (double) value;
862 public static double ToDouble (int value)
864 return (double)value;
867 public static double ToDouble (long value)
869 return (double)value;
872 [CLSCompliant (false)]
873 public static double ToDouble (sbyte value)
875 return (double)value;
878 public static double ToDouble (short value)
880 return (double)value;
883 public static double ToDouble (string value)
886 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
887 return Double.Parse (value);
890 public static double ToDouble (string value, IFormatProvider provider)
893 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
894 return Double.Parse (value, provider);
897 [CLSCompliant (false)]
898 public static double ToDouble (uint value)
900 return (double)value;
903 [CLSCompliant (false)]
904 public static double ToDouble (ulong value)
906 return (double)value;
909 [CLSCompliant (false)]
910 public static double ToDouble (ushort value)
912 return (double)value;
915 public static double ToDouble (object value)
919 return ToDouble (value, null);
922 public static double ToDouble (object value, IFormatProvider provider)
926 return ((IConvertible) value).ToDouble (provider);
929 // ========== Int16 Conversions ========== //
931 public static short ToInt16 (bool value)
933 return (short)(value ? 1 : 0);
936 public static short ToInt16 (byte value)
941 public static short ToInt16 (char value)
943 return checked ((short) value);
946 public static short ToInt16 (DateTime value)
948 throw new InvalidCastException ("This conversion is not supported.");
951 public static short ToInt16 (decimal value)
953 // Returned Even-Rounded
954 return checked ((short) Math.Round (value));
957 public static short ToInt16 (double value)
959 // Returned Even-Rounded
960 return checked ((short) Math.Round (value));
963 public static short ToInt16 (float value)
965 // Returned Even-Rounded, use Math.Round pass as a double.
966 return checked ((short) Math.Round (value));
969 public static short ToInt16 (int value)
971 return checked ((short) value);
974 public static short ToInt16 (long value)
976 return checked ((short) value);
979 [CLSCompliant (false)]
980 public static short ToInt16 (sbyte value)
985 public static short ToInt16 (short value)
990 public static short ToInt16 (string value)
993 return 0; // LAMESPEC: Spec says throw ArgumentNullException
994 return Int16.Parse (value);
997 public static short ToInt16 (string value, IFormatProvider provider)
1000 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1001 return Int16.Parse (value, provider);
1004 public static short ToInt16 (string value, int fromBase)
1006 int result = ConvertFromBase (value, fromBase, false);
1007 if (fromBase != 10) {
1008 if (result > ushort.MaxValue) {
1009 throw new OverflowException ("Value was either too large or too small for an Int16.");
1012 // note: no sign are available to detect negatives
1013 if (result > Int16.MaxValue) {
1014 // return negative 2's complement
1015 return Convert.ToInt16 (-(65536 - result));
1018 return Convert.ToInt16 (result);
1021 [CLSCompliant (false)]
1022 public static short ToInt16 (uint value)
1024 return checked ((short) value);
1027 [CLSCompliant (false)]
1028 public static short ToInt16 (ulong value)
1030 return checked ((short) value);
1033 [CLSCompliant (false)]
1034 public static short ToInt16 (ushort value)
1036 return checked ((short) value);
1039 public static short ToInt16 (object value)
1043 return ToInt16 (value, null);
1046 public static short ToInt16 (object value, IFormatProvider provider)
1050 return ((IConvertible) value).ToInt16 (provider);
1053 // ========== Int32 Conversions ========== //
1055 public static int ToInt32 (bool value)
1057 return value ? 1 : 0;
1060 public static int ToInt32 (byte value)
1065 public static int ToInt32 (char value)
1070 public static int ToInt32 (DateTime value)
1072 throw new InvalidCastException ("This conversion is not supported.");
1075 public static int ToInt32 (decimal value)
1077 // Returned Even-Rounded
1078 return checked ((int) Math.Round (value));
1081 public static int ToInt32 (double value)
1083 // Returned Even-Rounded
1085 return (int)(Math.Round (value));
1089 public static int ToInt32 (float value)
1091 if (value > Int32.MaxValue || value < Int32.MinValue)
1092 throw new OverflowException (Locale.GetText (
1093 "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
1095 // Returned Even-Rounded, pass as a double, could just call
1096 // Convert.ToInt32 ( (double)value);
1098 return (int)(Math.Round ( (double)value));
1102 public static int ToInt32 (int value)
1107 public static int ToInt32 (long value)
1109 return checked ((int) value);
1112 [CLSCompliant (false)]
1113 public static int ToInt32 (sbyte value)
1118 public static int ToInt32 (short value)
1123 public static int ToInt32 (string value)
1126 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1127 return Int32.Parse (value);
1130 public static int ToInt32 (string value, IFormatProvider provider)
1133 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1134 return Int32.Parse (value, provider);
1138 public static int ToInt32 (string value, int fromBase)
1140 return ConvertFromBase (value, fromBase, false);
1143 [CLSCompliant (false)]
1144 public static int ToInt32 (uint value)
1146 return checked ((int) value);
1149 [CLSCompliant (false)]
1150 public static int ToInt32 (ulong value)
1152 return checked ((int) value);
1155 [CLSCompliant (false)]
1156 public static int ToInt32 (ushort value)
1161 public static int ToInt32 (object value)
1165 return ToInt32 (value, null);
1168 public static int ToInt32 (object value, IFormatProvider provider)
1172 return ((IConvertible) value).ToInt32 (provider);
1175 // ========== Int64 Conversions ========== //
1177 public static long ToInt64 (bool value)
1179 return value ? 1 : 0;
1182 public static long ToInt64 (byte value)
1184 return (long)(ulong)value;
1187 public static long ToInt64 (char value)
1192 public static long ToInt64 (DateTime value)
1194 throw new InvalidCastException ("This conversion is not supported.");
1197 public static long ToInt64 (decimal value)
1199 // Returned Even-Rounded
1200 return checked ((long) Math.Round (value));
1203 public static long ToInt64 (double value)
1205 // Returned Even-Rounded
1206 return checked ((long) Math.Round (value));
1209 public static long ToInt64 (float value)
1211 // Returned Even-Rounded, pass to Math as a double, could
1212 // just call Convert.ToInt64 ( (double)value);
1213 return checked ((long) Math.Round (value));
1216 public static long ToInt64 (int value)
1221 public static long ToInt64 (long value)
1226 [CLSCompliant (false)]
1227 public static long ToInt64 (sbyte value)
1232 public static long ToInt64 (short value)
1237 public static long ToInt64 (string value)
1240 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1241 return Int64.Parse (value);
1244 public static long ToInt64 (string value, IFormatProvider provider)
1247 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1248 return Int64.Parse (value, provider);
1251 public static long ToInt64 (string value, int fromBase)
1253 return ConvertFromBase64 (value, fromBase, false);
1256 [CLSCompliant (false)]
1257 public static long ToInt64 (uint value)
1259 return (long)(ulong)value;
1262 [CLSCompliant (false)]
1263 public static long ToInt64 (ulong value)
1265 return checked ((long) value);
1268 [CLSCompliant (false)]
1269 public static long ToInt64 (ushort value)
1271 return (long)(ulong)value;
1274 public static long ToInt64 (object value)
1278 return ToInt64 (value, null);
1281 public static long ToInt64 (object value, IFormatProvider provider)
1285 return ((IConvertible) value).ToInt64 (provider);
1288 // ========== SByte Conversions ========== //
1290 [CLSCompliant (false)]
1291 public static sbyte ToSByte (bool value)
1293 return (sbyte)(value ? 1 : 0);
1296 [CLSCompliant (false)]
1297 public static sbyte ToSByte (byte value)
1299 return checked ((sbyte) value);
1302 [CLSCompliant (false)]
1303 public static sbyte ToSByte (char value)
1305 return checked ((sbyte) value);
1308 [CLSCompliant (false)]
1309 public static sbyte ToSByte (DateTime value)
1311 throw new InvalidCastException ("This conversion is not supported.");
1314 [CLSCompliant (false)]
1315 public static sbyte ToSByte (decimal value)
1317 // Returned Even-Rounded
1318 return checked ((sbyte) Math.Round (value));
1321 [CLSCompliant (false)]
1322 public static sbyte ToSByte (double value)
1324 // Returned Even-Rounded
1325 return checked ((sbyte) Math.Round (value));
1328 [CLSCompliant (false)]
1329 public static sbyte ToSByte (float value)
1331 // Returned Even-Rounded, pass as double to Math
1332 return checked ((sbyte) Math.Round (value));
1335 [CLSCompliant (false)]
1336 public static sbyte ToSByte (int value)
1338 return checked ((sbyte) value);
1341 [CLSCompliant (false)]
1342 public static sbyte ToSByte (long value)
1344 return checked ((sbyte) value);
1347 [CLSCompliant (false)]
1348 public static sbyte ToSByte (sbyte value)
1353 [CLSCompliant (false)]
1354 public static sbyte ToSByte (short value)
1356 return checked ((sbyte) value);
1359 [CLSCompliant (false)]
1360 public static sbyte ToSByte (string value)
1363 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1364 return SByte.Parse (value);
1367 [CLSCompliant (false)]
1368 public static sbyte ToSByte (string value, IFormatProvider provider)
1371 throw new ArgumentNullException ("value");
1372 return SByte.Parse (value, provider);
1375 [CLSCompliant (false)]
1376 public static sbyte ToSByte (string value, int fromBase)
1378 int result = ConvertFromBase (value, fromBase, false);
1379 if (fromBase != 10) {
1380 // note: no sign are available to detect negatives
1381 if (result > SByte.MaxValue) {
1382 // return negative 2's complement
1383 return Convert.ToSByte (-(256 - result));
1386 return Convert.ToSByte (result);
1389 [CLSCompliant (false)]
1390 public static sbyte ToSByte (uint value)
1392 return checked ((sbyte) value);
1395 [CLSCompliant (false)]
1396 public static sbyte ToSByte (ulong value)
1398 return checked ((sbyte) value);
1401 [CLSCompliant (false)]
1402 public static sbyte ToSByte (ushort value)
1404 return checked ((sbyte) value);
1407 [CLSCompliant (false)]
1408 public static sbyte ToSByte (object value)
1412 return ToSByte (value, null);
1415 [CLSCompliant (false)]
1416 public static sbyte ToSByte (object value, IFormatProvider provider)
1420 return ((IConvertible) value).ToSByte (provider);
1423 // ========== Single Conversions ========== //
1425 public static float ToSingle (bool value)
1427 return value ? 1 : 0;
1430 public static float ToSingle (byte value)
1432 return (float)value;
1435 public static float ToSingle (Char value)
1437 throw new InvalidCastException ("This conversion is not supported.");
1440 public static float ToSingle (DateTime value)
1442 throw new InvalidCastException ("This conversion is not supported.");
1445 public static float ToSingle (decimal value)
1447 return (float)value;
1450 public static float ToSingle (double value)
1452 return (float)value;
1455 public static float ToSingle (float value)
1460 public static float ToSingle (int value)
1462 return (float)value;
1465 public static float ToSingle (long value)
1467 return (float)value;
1470 [CLSCompliant (false)]
1471 public static float ToSingle (sbyte value)
1473 return (float)value;
1476 public static float ToSingle (short value)
1478 return (float)value;
1481 public static float ToSingle (string value)
1484 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1485 return Single.Parse (value);
1488 public static float ToSingle (string value, IFormatProvider provider)
1491 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1492 return Single.Parse (value, provider);
1495 [CLSCompliant (false)]
1496 public static float ToSingle (uint value)
1498 return (float)value;
1501 [CLSCompliant (false)]
1502 public static float ToSingle (ulong value)
1504 return (float)value;
1507 [CLSCompliant (false)]
1508 public static float ToSingle (ushort value)
1510 return (float)value;
1513 public static float ToSingle (object value)
1517 return ToSingle (value, null);
1520 // [CLSCompliant (false)]
1521 public static float ToSingle (object value, IFormatProvider provider)
1525 return ((IConvertible) value).ToSingle (provider);
1528 // ========== String Conversions ========== //
1530 public static string ToString (bool value)
1532 return value.ToString ();
1535 public static string ToString (bool value, IFormatProvider provider)
1537 return value.ToString (); // the same as ToString (bool).
1540 public static string ToString (byte value)
1542 return value.ToString ();
1545 public static string ToString (byte value, IFormatProvider provider)
1547 return value.ToString (provider);
1550 public static string ToString (byte value, int toBase)
1555 return value.ToString ();
1557 byte[] val = BitConverter.GetBytes (value);
1561 return ConvertToBase2 (val);
1563 return ConvertToBase8 (val);
1565 return ConvertToBase16 (val);
1567 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1571 public static string ToString (char value)
1573 return value.ToString ();
1576 public static string ToString (char value, IFormatProvider provider)
1578 return value.ToString (); // the same as ToString (char)
1581 public static string ToString (DateTime value)
1583 return value.ToString ();
1586 public static string ToString (DateTime value, IFormatProvider provider)
1588 return value.ToString (provider);
1591 public static string ToString (decimal value)
1593 return value.ToString ();
1596 public static string ToString (decimal value, IFormatProvider provider)
1598 return value.ToString (provider);
1601 public static string ToString (double value)
1603 return value.ToString ();
1606 public static string ToString (double value, IFormatProvider provider)
1608 return value.ToString (provider);
1611 public static string ToString (float value)
1613 return value.ToString ();
1616 public static string ToString (float value, IFormatProvider provider)
1618 return value.ToString (provider);
1621 public static string ToString (int value)
1623 return value.ToString ();
1626 public static string ToString (int value, int toBase)
1631 return value.ToString ();
1633 byte[] val = BitConverter.GetBytes (value);
1637 return ConvertToBase2 (val);
1639 return ConvertToBase8 (val);
1641 return ConvertToBase16 (val);
1643 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1647 public static string ToString (int value, IFormatProvider provider)
1649 return value.ToString (provider);
1652 public static string ToString (long value)
1654 return value.ToString ();
1657 public static string ToString (long value, int toBase)
1662 return value.ToString ();
1664 byte[] val = BitConverter.GetBytes (value);
1668 return ConvertToBase2 (val);
1670 return ConvertToBase8 (val);
1672 return ConvertToBase16 (val);
1674 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1678 public static string ToString (long value, IFormatProvider provider)
1680 return value.ToString (provider);
1683 public static string ToString (object value)
1685 return ToString (value, null);
1688 public static string ToString (object value, IFormatProvider provider)
1690 if (value is IConvertible)
1691 return ((IConvertible) value).ToString (provider);
1692 else if (value != null)
1693 return value.ToString ();
1694 return String.Empty;
1697 [CLSCompliant (false)]
1698 public static string ToString (sbyte value)
1700 return value.ToString ();
1703 [CLSCompliant (false)]
1704 public static string ToString (sbyte value, IFormatProvider provider)
1706 return value.ToString (provider);
1709 public static string ToString (short value)
1711 return value.ToString ();
1714 public static string ToString (short value, int toBase)
1719 return value.ToString ();
1721 byte[] val = BitConverter.GetBytes (value);
1725 return ConvertToBase2 (val);
1727 return ConvertToBase8 (val);
1729 return ConvertToBase16 (val);
1731 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1735 public static string ToString (short value, IFormatProvider provider)
1737 return value.ToString (provider);
1740 public static string ToString (string value)
1745 public static string ToString (string value, IFormatProvider provider)
1747 return value; // provider is ignored.
1750 [CLSCompliant (false)]
1751 public static string ToString (uint value)
1753 return value.ToString ();
1756 [CLSCompliant (false)]
1757 public static string ToString (uint value, IFormatProvider provider)
1759 return value.ToString (provider);
1762 [CLSCompliant (false)]
1763 public static string ToString (ulong value)
1765 return value.ToString ();
1768 [CLSCompliant (false)]
1769 public static string ToString (ulong value, IFormatProvider provider)
1771 return value.ToString (provider);
1774 [CLSCompliant (false)]
1775 public static string ToString (ushort value)
1777 return value.ToString ();
1780 [CLSCompliant (false)]
1781 public static string ToString (ushort value, IFormatProvider provider)
1783 return value.ToString (provider);
1786 // ========== UInt16 Conversions ========== //
1788 [CLSCompliant (false)]
1789 public static ushort ToUInt16 (bool value)
1791 return (ushort)(value ? 1 : 0);
1794 [CLSCompliant (false)]
1795 public static ushort ToUInt16 (byte value)
1797 return (ushort)value;
1800 [CLSCompliant (false)]
1801 public static ushort ToUInt16 (char value)
1803 return (ushort)value;
1806 [CLSCompliant (false)]
1807 public static ushort ToUInt16 (DateTime value)
1809 throw new InvalidCastException ("This conversion is not supported.");
1812 [CLSCompliant (false)]
1813 public static ushort ToUInt16 (decimal value)
1815 // Returned Even-Rounded
1816 return checked ((ushort) Math.Round (value));
1819 [CLSCompliant (false)]
1820 public static ushort ToUInt16 (double value)
1822 // Returned Even-Rounded
1823 return checked ((ushort) Math.Round (value));
1826 [CLSCompliant (false)]
1827 public static ushort ToUInt16 (float value)
1829 // Returned Even-Rounded, pass as double to Math
1830 return checked ((ushort) Math.Round (value));
1833 [CLSCompliant (false)]
1834 public static ushort ToUInt16 (int value)
1836 return checked ((ushort) value);
1839 [CLSCompliant (false)]
1840 public static ushort ToUInt16 (long value)
1842 return checked ((ushort) value);
1845 [CLSCompliant (false)]
1846 public static ushort ToUInt16 (sbyte value)
1848 return checked ((ushort) value);
1851 [CLSCompliant (false)]
1852 public static ushort ToUInt16 (short value)
1854 return checked ((ushort) value);
1857 [CLSCompliant (false)]
1858 public static ushort ToUInt16 (string value)
1861 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1862 return UInt16.Parse (value);
1865 [CLSCompliant (false)]
1866 public static ushort ToUInt16 (string value, IFormatProvider provider)
1869 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1870 return UInt16.Parse (value, provider);
1873 [CLSCompliant (false)]
1874 public static ushort ToUInt16 (string value, int fromBase)
1876 return ToUInt16 (ConvertFromBase (value, fromBase, true));
1879 [CLSCompliant (false)]
1880 public static ushort ToUInt16 (uint value)
1882 return checked ((ushort) value);
1885 [CLSCompliant (false)]
1886 public static ushort ToUInt16 (ulong value)
1888 return checked ((ushort) value);
1891 [CLSCompliant (false)]
1892 public static ushort ToUInt16 (ushort value)
1897 [CLSCompliant (false)]
1898 public static ushort ToUInt16 (object value)
1902 return ToUInt16 (value, null);
1905 [CLSCompliant (false)]
1906 public static ushort ToUInt16 (object value, IFormatProvider provider)
1910 return ((IConvertible) value).ToUInt16 (provider);
1913 // ========== UInt32 Conversions ========== //
1915 [CLSCompliant (false)]
1916 public static uint ToUInt32 (bool value)
1918 return (uint)(value ? 1 : 0);
1921 [CLSCompliant (false)]
1922 public static uint ToUInt32 (byte value)
1927 [CLSCompliant (false)]
1928 public static uint ToUInt32 (char value)
1933 [CLSCompliant (false)]
1934 public static uint ToUInt32 (DateTime value)
1936 throw new InvalidCastException ("This conversion is not supported.");
1939 [CLSCompliant (false)]
1940 public static uint ToUInt32 (decimal value)
1942 // Returned Even-Rounded
1943 return checked ((uint) Math.Round (value));
1946 [CLSCompliant (false)]
1947 public static uint ToUInt32 (double value)
1949 // Returned Even-Rounded
1950 return checked ((uint) Math.Round (value));
1953 [CLSCompliant (false)]
1954 public static uint ToUInt32 (float value)
1956 // Returned Even-Rounded, pass as double to Math
1957 return checked ((uint) Math.Round (value));
1960 [CLSCompliant (false)]
1961 public static uint ToUInt32 (int value)
1963 return checked ((uint) value);
1966 [CLSCompliant (false)]
1967 public static uint ToUInt32 (long value)
1969 return checked ((uint) value);
1972 [CLSCompliant (false)]
1973 public static uint ToUInt32 (sbyte value)
1975 return checked ((uint) value);
1978 [CLSCompliant (false)]
1979 public static uint ToUInt32 (short value)
1981 return checked ((uint) value);
1984 [CLSCompliant (false)]
1985 public static uint ToUInt32 (string value)
1988 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1989 return UInt32.Parse (value);
1992 [CLSCompliant (false)]
1993 public static uint ToUInt32 (string value, IFormatProvider provider)
1996 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1997 return UInt32.Parse (value, provider);
2000 [CLSCompliant (false)]
2001 public static uint ToUInt32 (string value, int fromBase)
2003 return (uint) ConvertFromBase (value, fromBase, true);
2006 [CLSCompliant (false)]
2007 public static uint ToUInt32 (uint value)
2012 [CLSCompliant (false)]
2013 public static uint ToUInt32 (ulong value)
2015 return checked ((uint) value);
2018 [CLSCompliant (false)]
2019 public static uint ToUInt32 (ushort value)
2024 [CLSCompliant (false)]
2025 public static uint ToUInt32 (object value)
2029 return ToUInt32 (value, null);
2032 [CLSCompliant (false)]
2033 public static uint ToUInt32 (object value, IFormatProvider provider)
2037 return ((IConvertible) value).ToUInt32 (provider);
2041 // ========== UInt64 Conversions ========== //
2043 [CLSCompliant (false)]
2044 public static ulong ToUInt64 (bool value)
2046 return (ulong)(value ? 1 : 0);
2049 [CLSCompliant (false)]
2050 public static ulong ToUInt64 (byte value)
2052 return (ulong)value;
2055 [CLSCompliant (false)]
2056 public static ulong ToUInt64 (char value)
2058 return (ulong)value;
2061 [CLSCompliant (false)]
2062 public static ulong ToUInt64 (DateTime value)
2064 throw new InvalidCastException ("The conversion is not supported.");
2067 [CLSCompliant (false)]
2068 public static ulong ToUInt64 (decimal value)
2070 // Returned Even-Rounded
2071 return checked ((ulong) Math.Round (value));
2074 [CLSCompliant (false)]
2075 public static ulong ToUInt64 (double value)
2077 // Returned Even-Rounded
2078 return checked ((ulong) Math.Round (value));
2081 [CLSCompliant (false)]
2082 public static ulong ToUInt64 (float value)
2084 // Returned Even-Rounded, pass as a double to Math
2085 return checked ((ulong) Math.Round (value));
2088 [CLSCompliant (false)]
2089 public static ulong ToUInt64 (int value)
2091 return checked ((ulong) value);
2094 [CLSCompliant (false)]
2095 public static ulong ToUInt64 (long value)
2097 return checked ((ulong) value);
2100 [CLSCompliant (false)]
2101 public static ulong ToUInt64 (sbyte value)
2103 return checked ((ulong) value);
2106 [CLSCompliant (false)]
2107 public static ulong ToUInt64 (short value)
2109 return checked ((ulong) value);
2112 [CLSCompliant (false)]
2113 public static ulong ToUInt64 (string value)
2116 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2117 return UInt64.Parse (value);
2120 [CLSCompliant (false)]
2121 public static ulong ToUInt64 (string value, IFormatProvider provider)
2124 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2125 return UInt64.Parse (value, provider);
2128 [CLSCompliant (false)]
2129 public static ulong ToUInt64 (string value, int fromBase)
2131 return (ulong) ConvertFromBase64 (value, fromBase, true);
2134 [CLSCompliant (false)]
2135 public static ulong ToUInt64 (uint value)
2137 return (ulong)value;
2140 [CLSCompliant (false)]
2141 public static ulong ToUInt64 (ulong value)
2146 [CLSCompliant (false)]
2147 public static ulong ToUInt64 (ushort value)
2149 return (ulong)value;
2152 [CLSCompliant (false)]
2153 public static ulong ToUInt64 (object value)
2157 return ToUInt64 (value, null);
2160 [CLSCompliant (false)]
2161 public static ulong ToUInt64 (object value, IFormatProvider provider)
2165 return ((IConvertible) value).ToUInt64 (provider);
2169 // ========== Conversion / Helper Functions ========== //
2171 public static object ChangeType (object value, Type conversionType)
2173 if ((value != null) && (conversionType == null))
2174 throw new ArgumentNullException ("conversionType");
2175 CultureInfo ci = CultureInfo.CurrentCulture;
2176 IFormatProvider provider;
2177 if (conversionType == typeof(DateTime)) {
2178 provider = ci.DateTimeFormat;
2181 provider = ci.NumberFormat;
2183 return ToType (value, conversionType, provider, true);
2186 public static object ChangeType (object value, TypeCode typeCode)
2188 CultureInfo ci = CultureInfo.CurrentCulture;
2189 Type conversionType = conversionTable [(int) typeCode];
2190 IFormatProvider provider;
2191 if (conversionType == typeof(DateTime)) {
2192 provider = ci.DateTimeFormat;
2195 provider = ci.NumberFormat;
2197 return ToType (value, conversionType, provider, true);
2200 public static object ChangeType (object value, Type conversionType, IFormatProvider provider)
2202 if ((value != null) && (conversionType == null))
2203 throw new ArgumentNullException ("conversionType");
2204 return ToType (value, conversionType, provider, true);
2207 public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider)
2209 Type conversionType = conversionTable [(int)typeCode];
2210 return ToType (value, conversionType, provider, true);
2213 private static bool NotValidBase (int value)
2215 if ((value == 2) || (value == 8) ||
2216 (value == 10) || (value == 16))
2222 private static int ConvertFromBase (string value, int fromBase, bool unsigned)
2224 if (NotValidBase (fromBase))
2225 throw new ArgumentException ("fromBase is not valid.");
2234 int len = value.Length;
2235 bool negative = false;
2237 // special processing for some bases
2240 if (value.Substring (i, 1) == "-") {
2242 throw new OverflowException (
2243 Locale.GetText ("The string was being parsed as"
2244 + " an unsigned number and could not have a"
2245 + " negative sign."));
2252 if (value.Substring (i, 1) == "-") {
2253 throw new ArgumentException ("String cannot contain a "
2254 + "minus sign if the base is not 10.");
2258 if ((value[i] == '0') && ((value [i+1] == 'x') || (value [i+1] == 'X'))) {
2264 if (value.Substring (i, 1) == "-") {
2265 throw new ArgumentException ("String cannot contain a "
2266 + "minus sign if the base is not 10.");
2272 throw new FormatException ("Could not find any parsable digits.");
2275 if (value[i] == '+') {
2280 char c = value[i++];
2281 if (Char.IsNumber (c)) {
2282 digitValue = c - '0';
2283 } else if (Char.IsLetter (c)) {
2284 digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2287 throw new FormatException ("Additional unparsable "
2288 + "characters are at the end of the string.");
2290 throw new FormatException ("Could not find any parsable"
2295 if (digitValue >= fromBase) {
2297 throw new FormatException ("Additional unparsable "
2298 + "characters are at the end of the string.");
2300 throw new FormatException ("Could not find any parsable"
2305 result = (fromBase) * result + digitValue;
2310 throw new FormatException ("Could not find any parsable digits.");
2318 // note: this has nothing to do with base64 encoding (just base and Int64)
2319 private static long ConvertFromBase64 (string value, int fromBase, bool unsigned)
2321 if (NotValidBase (fromBase))
2322 throw new ArgumentException ("fromBase is not valid.");
2327 int digitValue = -1;
2329 bool negative = false;
2332 int len = value.Length;
2334 // special processing for some bases
2337 if (value.Substring(i, 1) == "-") {
2339 throw new OverflowException (
2340 Locale.GetText ("The string was being parsed as"
2341 + " an unsigned number and could not have a"
2342 + " negative sign."));
2349 if (value.Substring (i, 1) == "-") {
2350 throw new ArgumentException ("String cannot contain a "
2351 + "minus sign if the base is not 10.");
2355 if ((value[i] == '0') && ((value[i + 1] == 'x') || (value[i + 1] == 'X'))) {
2361 if (value.Substring (i, 1) == "-") {
2362 throw new ArgumentException ("String cannot contain a "
2363 + "minus sign if the base is not 10.");
2369 throw new FormatException ("Could not find any parsable digits.");
2372 if (value[i] == '+') {
2377 char c = value[i++];
2378 if (Char.IsNumber (c)) {
2379 digitValue = c - '0';
2380 } else if (Char.IsLetter (c)) {
2381 digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2384 throw new FormatException ("Additional unparsable "
2385 + "characters are at the end of the string.");
2387 throw new FormatException ("Could not find any parsable"
2392 if (digitValue >= fromBase) {
2394 throw new FormatException ("Additional unparsable "
2395 + "characters are at the end of the string.");
2397 throw new FormatException ("Could not find any parsable"
2402 result = (fromBase * result + digitValue);
2407 throw new FormatException ("Could not find any parsable digits.");
2415 private static void EndianSwap (ref byte[] value)
2417 byte[] buf = new byte[value.Length];
2418 for (int i = 0; i < value.Length; i++)
2419 buf[i] = value[value.Length-1-i];
2423 private static string ConvertToBase2 (byte[] value)
2425 if (!BitConverter.IsLittleEndian)
2426 EndianSwap (ref value);
2427 StringBuilder sb = new StringBuilder ();
2428 for (int i = value.Length - 1; i >= 0; i--) {
2430 for (int j = 0; j < 8; j++) {
2431 if ((b & 0x80) == 0x80) {
2441 return sb.ToString ();
2444 private static string ConvertToBase8 (byte[] value)
2447 switch (value.Length) {
2449 l = (ulong) value [0];
2452 l = (ulong) BitConverter.ToUInt16 (value, 0);
2455 l = (ulong) BitConverter.ToUInt32 (value, 0);
2458 l = BitConverter.ToUInt64 (value, 0);
2461 throw new ArgumentException ("value");
2464 StringBuilder sb = new StringBuilder ();
2465 for (int i = 21; i >= 0; i--) {
2466 // 3 bits at the time
2467 char val = (char) ((l >> i * 3) & 0x7);
2468 if ((val != 0) || (sb.Length > 0)) {
2473 return sb.ToString ();
2476 private static string ConvertToBase16 (byte[] value)
2478 if (!BitConverter.IsLittleEndian)
2479 EndianSwap (ref value);
2480 StringBuilder sb = new StringBuilder ();
2481 for (int i = value.Length - 1; i >= 0; i--) {
2482 char high = (char)((value[i] >> 4) & 0x0f);
2483 if ((high != 0) || (sb.Length > 0)) {
2493 char low = (char)(value[i] & 0x0f);
2494 if ((low != 0) || (sb.Length > 0)) {
2504 return sb.ToString ();
2507 // Lookup table for the conversion ToType method. Order
2508 // is important! Used by ToType for comparing the target
2509 // type, and uses hardcoded array indexes.
2510 private static readonly Type[] conversionTable = {
2511 // Valid ICovnertible Types
2513 typeof (object), // 1 TypeCode.Object
2514 typeof (DBNull), // 2 TypeCode.DBNull
2515 typeof (Boolean), // 3 TypeCode.Boolean
2516 typeof (Char), // 4 TypeCode.Char
2517 typeof (SByte), // 5 TypeCode.SByte
2518 typeof (Byte), // 6 TypeCode.Byte
2519 typeof (Int16), // 7 TypeCode.Int16
2520 typeof (UInt16), // 8 TypeCode.UInt16
2521 typeof (Int32), // 9 TypeCode.Int32
2522 typeof (UInt32), // 10 TypeCode.UInt32
2523 typeof (Int64), // 11 TypeCode.Int64
2524 typeof (UInt64), // 12 TypeCode.UInt64
2525 typeof (Single), // 13 TypeCode.Single
2526 typeof (Double), // 14 TypeCode.Double
2527 typeof (Decimal), // 15 TypeCode.Decimal
2528 typeof (DateTime), // 16 TypeCode.DateTime
2530 typeof (String), // 18 TypeCode.String
2533 // Function to convert an object to another type and return
2534 // it as an object. In place for the core data types to use
2535 // when implementing IConvertible. Uses hardcoded indexes in
2536 // the conversionTypes array, so if modify carefully.
2539 // The `try_target_to_type' boolean indicates if the code
2540 // should try to call the IConvertible.ToType method if everything
2543 // This should be true for invocations from Convert.cs, and
2544 // false from the mscorlib types that implement IConvertible that
2545 // all into this internal function.
2547 // This was added to keep the fix for #481687 working and to avoid
2548 // the regression that the simple fix introduced (485377)
2549 internal static object ToType (object value, Type conversionType, IFormatProvider provider, bool try_target_to_type)
2551 if (value == null) {
2552 if ((conversionType != null) && conversionType.IsValueType){
2553 throw new InvalidCastException ("Null object can not be converted to a value type.");
2558 if (conversionType == null)
2559 throw new InvalidCastException ("Cannot cast to destination type.");
2561 if (value.GetType () == conversionType)
2564 if (value is IConvertible) {
2565 IConvertible convertValue = (IConvertible) value;
2567 if (conversionType == conversionTable[0]) // 0 Empty
2568 throw new ArgumentNullException ();
2570 else if (conversionType == conversionTable[1]) // 1 TypeCode.Object
2571 return (object) value;
2573 else if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull
2574 throw new InvalidCastException (
2575 "Cannot cast to DBNull, it's not IConvertible");
2577 else if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean
2578 return (object) convertValue.ToBoolean (provider);
2580 else if (conversionType == conversionTable[4]) // 4 TypeCode.Char
2581 return (object) convertValue.ToChar (provider);
2583 else if (conversionType == conversionTable[5]) // 5 TypeCode.SByte
2584 return (object) convertValue.ToSByte (provider);
2586 else if (conversionType == conversionTable[6]) // 6 TypeCode.Byte
2587 return (object) convertValue.ToByte (provider);
2589 else if (conversionType == conversionTable[7]) // 7 TypeCode.Int16
2590 return (object) convertValue.ToInt16 (provider);
2592 else if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16
2593 return (object) convertValue.ToUInt16 (provider);
2595 else if (conversionType == conversionTable[9]) // 9 TypeCode.Int32
2596 return (object) convertValue.ToInt32 (provider);
2598 else if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32
2599 return (object) convertValue.ToUInt32 (provider);
2601 else if (conversionType == conversionTable[11]) // 11 TypeCode.Int64
2602 return (object) convertValue.ToInt64 (provider);
2604 else if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64
2605 return (object) convertValue.ToUInt64 (provider);
2607 else if (conversionType == conversionTable[13]) // 13 TypeCode.Single
2608 return (object) convertValue.ToSingle (provider);
2610 else if (conversionType == conversionTable[14]) // 14 TypeCode.Double
2611 return (object) convertValue.ToDouble (provider);
2613 else if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal
2614 return (object) convertValue.ToDecimal (provider);
2616 else if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime
2617 return (object) convertValue.ToDateTime (provider);
2619 else if (conversionType == conversionTable[18]) // 18 TypeCode.String
2620 return (object) convertValue.ToString (provider);
2622 if (try_target_to_type)
2623 return convertValue.ToType (conversionType, provider);
2626 // Not in the conversion table
2627 throw new InvalidCastException ((Locale.GetText (
2628 "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));