2002-07-10 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / corlib / System / Convert.cs
index d6ab2738f8752f952350d1df7e8129bbe5ac1ba8..97b7800e9ac89c580fed4f2045261266caffc08a 100644 (file)
 // UI64 |   X    X    X      X   X   X   X   X    X    X   X    X    X    X\r
 //\r
 \r
-using System.Security.Cryptography;\r
 using System.Globalization;\r
+using System.Security.Cryptography;\r
+using System.Text;\r
 \r
 namespace System {\r
   \r
-       [CLSCompliant(false)]\r
+//     [CLSCompliant(false)]\r
        public sealed class Convert {\r
+\r
+               // Fields\r
+               public static readonly object DBNull = System.DBNull.Value;\r
        \r
+               private Convert () {}\r
+\r
                // ========== BASE 64 Conversions ========== //\r
                // the BASE64 convert methods are using the Base64 converting methods\r
                // from System.Security.Cryptography.ToBase64Transform and\r
@@ -88,11 +94,13 @@ namespace System {
                        if (inArray == null)\r
                                throw new ArgumentNullException();\r
                        \r
-                       int len = inArray.Length;\r
-                       if (len < 4 || len % 4 != 0)\r
+                       if ((offset < 0) || (length < 0) || (offset + length > inArray.Length))\r
+                               throw new ArgumentOutOfRangeException();\r
+                       \r
+                       if (length < 4 || length % 4 != 0)\r
                                throw new FormatException();\r
                                \r
-                       byte[] inArr = new System.Text.UnicodeEncoding().GetBytes(inArray);\r
+                       byte[] inArr = new System.Text.UTF8Encoding().GetBytes(inArray, offset, length);\r
                        FromBase64Transform t = new FromBase64Transform();\r
                        \r
                        return t.TransformFinalBlock(inArr, 0, inArr.Length);\r
@@ -116,11 +124,9 @@ namespace System {
                                return Type.GetTypeCode (value.GetType ());\r
                }\r
 \r
-               public static bool ISDBNull (object value)\r
+               public static bool IsDBNull (object value)\r
                {\r
-                       TypeCode tc = Type.GetTypeCode (value.GetType ());\r
-                       \r
-                       if (tc == TypeCode.DBNull)\r
+                       if (value is DBNull)\r
                                return true;\r
                        else\r
                                return false;\r
@@ -218,6 +224,7 @@ namespace System {
                        return (value != 0); \r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static bool ToBoolean (sbyte value) \r
                { \r
                        return (value != 0); \r
@@ -237,17 +244,20 @@ namespace System {
                {\r
                        return Boolean.Parse (value); // provider is ignored.\r
                }\r
-       \r
+\r
+               [CLSCompliant (false)]\r
                public static bool ToBoolean (uint value) \r
                { \r
                        return (value != 0);\r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static bool ToBoolean (ulong value) \r
                { \r
                        return (value != 0); \r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static bool ToBoolean (ushort value) \r
                { \r
                        return (value != 0); \r
@@ -255,12 +265,14 @@ namespace System {
 \r
                public static bool ToBoolean (object value)\r
                {\r
-                       return (bool) ChangeType (value, typeof (System.Boolean));\r
+                       return ToBoolean (value, null);\r
                }\r
 \r
                public static bool ToBoolean (object value, IFormatProvider provider)\r
                {\r
-                       return (bool) ChangeType (value, typeof (System.Boolean), provider);\r
+                       if (value == null)\r
+                               return false;\r
+                       return ((IConvertible) value).ToBoolean (provider);\r
                }\r
 \r
                // ========== Byte Conversions ========== //\r
@@ -350,6 +362,7 @@ namespace System {
                        return (byte)value;\r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static byte ToByte (sbyte value) \r
                { \r
                        if (value < Byte.MinValue)\r
@@ -377,7 +390,19 @@ namespace System {
                {\r
                        return Byte.Parse (value, provider);\r
                }\r
-       \r
+\r
+               public static byte ToByte (string value, int fromBase)\r
+               {\r
+\r
+                       int retVal = ConvertFromBase (value, fromBase);\r
+\r
+                       if (retVal < (int) Byte.MinValue || retVal > (int) Byte.MaxValue)\r
+                               throw new OverflowException ();\r
+                       else\r
+                               return (byte) retVal;\r
+               }\r
+\r
+               [CLSCompliant (false)]\r
                public static byte ToByte (uint value) \r
                { \r
                        if (value > Byte.MaxValue)\r
@@ -387,6 +412,7 @@ namespace System {
                        return (byte)value;\r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static byte ToByte (ulong value) \r
                { \r
                        if (value > Byte.MaxValue)\r
@@ -396,6 +422,7 @@ namespace System {
                        return (byte)value;\r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static byte ToByte (ushort value) \r
                { \r
                        if (value > Byte.MaxValue)\r
@@ -407,12 +434,14 @@ namespace System {
 \r
                public static byte ToByte (object value)\r
                {\r
-                       return (byte) ChangeType (value, typeof (System.Byte));\r
+                       return ToByte (value, null);\r
                }\r
 \r
                public static byte ToByte (object value, IFormatProvider provider)\r
                {\r
-                       return (byte) ChangeType (value, typeof (System.Byte), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToByte (provider);\r
                }\r
 \r
                // ========== Char Conversions ========== //\r
@@ -470,6 +499,7 @@ namespace System {
                        throw new InvalidCastException ("This conversion is not supported.");\r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static char ToChar (sbyte value) \r
                { \r
                        if (value < Char.MinValue)\r
@@ -497,7 +527,8 @@ namespace System {
                {\r
                        return Char.Parse (value); // provider is ignored.\r
                }\r
-       \r
+\r
+               [CLSCompliant (false)]\r
                public static char ToChar (uint value) \r
                { \r
                        if (value > Char.MaxValue)\r
@@ -507,6 +538,7 @@ namespace System {
                        return (char)value; \r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static char ToChar (ulong value) \r
                { \r
                        if (value > Char.MaxValue)\r
@@ -516,6 +548,7 @@ namespace System {
                        return (char)value; \r
                }\r
 \r
+               [CLSCompliant (false)]\r
                public static char ToChar (ushort value) \r
                { \r
                        if (value > Char.MaxValue)\r
@@ -527,15 +560,14 @@ namespace System {
 \r
                public static char ToChar (object value)\r
                {\r
-                       return (char) ChangeType (value, typeof (System.Char));\r
+                       return ToChar (value, null);\r
                }\r
 \r
                public static char ToChar (object value, IFormatProvider provider)\r
                {\r
                        if (value == null)\r
-                               return Char.MinValue;\r
-                       else\r
-                               return (char) ChangeType (value, typeof (System.Char), provider);\r
+                               return (char) 0;\r
+                       return ((IConvertible) value).ToChar (provider);\r
                }\r
 \r
                // ========== DateTime Conversions ========== //\r
@@ -602,12 +634,14 @@ namespace System {
 \r
                public static DateTime ToDateTime (object value)\r
                {\r
-                       return (DateTime) ChangeType (value, typeof (System.DateTime));\r
+                       return ToDateTime (value, null);\r
                }\r
 \r
                public static DateTime ToDateTime (object value, IFormatProvider provider)\r
                {\r
-                       return (DateTime) ChangeType (value, typeof (System.DateTime), provider);\r
+                       if (value == null)\r
+                               return DateTime.MinValue;\r
+                       return ((IConvertible) value).ToDateTime (provider);\r
                }\r
 \r
                [CLSCompliant (false)]\r
@@ -671,7 +705,7 @@ namespace System {
 \r
                public static decimal ToDecimal (float value) \r
                {\r
-                       return (decimal) Math.Round (value);                            \r
+                       return (decimal) value;\r
                }\r
 \r
                public static decimal ToDecimal (int value) \r
@@ -725,12 +759,14 @@ namespace System {
 \r
                public static decimal ToDecimal (object value)\r
                {\r
-                       return (decimal) ChangeType (value, typeof (System.Decimal));\r
+                       return ToDecimal (value, null);\r
                }\r
 \r
                public static decimal ToDecimal (object value, IFormatProvider provider)\r
                {\r
-                       return (decimal) ChangeType (value, typeof (System.Decimal), provider);\r
+                       if (value == null)\r
+                               return new Decimal (0);\r
+                       return ((IConvertible) value).ToDecimal (provider);\r
                }\r
                                                 \r
 \r
@@ -743,7 +779,7 @@ namespace System {
        \r
                public static double ToDouble (byte value) \r
                { \r
-                       throw new InvalidCastException ("This conversion is not supported.");\r
+                       return (double) value;\r
                }\r
 \r
                public static double ToDouble (char value)\r
@@ -768,7 +804,7 @@ namespace System {
 \r
                public static double ToDouble (float value) \r
                { \r
-                       return (double) Math.Round (value);       \r
+                       return (double) value;\r
                }\r
 \r
                public static double ToDouble (int value) \r
@@ -822,12 +858,14 @@ namespace System {
 \r
                public static double ToDouble (object value)\r
                {\r
-                       return (double) ChangeType (value, typeof (System.Double));\r
+                       return ToDouble (value, null);\r
                }\r
 \r
                public static double ToDouble (object value, IFormatProvider provider)\r
                {\r
-                       return (double) ChangeType (value, typeof (System.Double), provider);\r
+                       if (value == null)\r
+                               return 0.0;\r
+                       return ((IConvertible) value).ToDouble (provider);\r
                }\r
 \r
                // ========== Int16 Conversions ========== //\r
@@ -928,7 +966,7 @@ namespace System {
                \r
                public static short ToInt16 (string value, int fromBase)\r
                {\r
-                       return (short) ConvertFromBase (value, fromBase);\r
+                       return Convert.ToInt16 (ConvertFromBase (value, fromBase));\r
                }\r
 \r
                [CLSCompliant (false)]\r
@@ -962,12 +1000,14 @@ namespace System {
 \r
                public static short ToInt16 (object value)\r
                {\r
-                       return (short) ChangeType (value, typeof (System.Int16));\r
+                       return ToInt16 (value, null);\r
                }\r
 \r
                public static short ToInt16 (object value, IFormatProvider provider)\r
                {\r
-                       return (short) ChangeType (value, typeof (System.Int16), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToInt16 (provider);\r
                }\r
        \r
                // ========== Int32 Conversions ========== //\r
@@ -1092,12 +1132,14 @@ namespace System {
 \r
                public static int ToInt32 (object value)\r
                {\r
-                       return (int) ChangeType (value, typeof (System.Int32));\r
+                       return ToInt32 (value, null);\r
                }\r
 \r
                public static int ToInt32 (object value, IFormatProvider provider)\r
                {\r
-                       return (int) ChangeType (value, typeof (System.Int32), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToInt32 (provider);\r
                }\r
 \r
                // ========== Int64 Conversions ========== //\r
@@ -1109,7 +1151,7 @@ namespace System {
        \r
                public static long ToInt64 (byte value) \r
                { \r
-                       return (long)value; \r
+                       return (long)(ulong)value; \r
                }\r
 \r
                public static long ToInt64 (char value) \r
@@ -1189,13 +1231,13 @@ namespace System {
                        if (NotValidBase (fromBase))\r
                                throw new ArgumentException ("fromBase is not valid.");\r
                        \r
-                       return (long) ConvertFromBase (value, fromBase);\r
+                       return ConvertFromBase64 (value, fromBase);\r
                }\r
 \r
                [CLSCompliant (false)]\r
                public static long ToInt64 (uint value) \r
                { \r
-                       return (long)value; \r
+                       return (long)(ulong)value; \r
                }\r
 \r
                [CLSCompliant (false)]\r
@@ -1211,17 +1253,19 @@ namespace System {
                [CLSCompliant (false)]\r
                public static long ToInt64 (ushort value) \r
                { \r
-                       return (long)value; \r
+                       return (long)(ulong)value; \r
                }\r
 \r
                public static long ToInt64 (object value)\r
                {\r
-                       return (long) ChangeType (value, typeof (System.Int64));\r
+                       return ToInt64 (value, null);\r
                }\r
 \r
                public static long ToInt64 (object value, IFormatProvider provider)\r
                {\r
-                       return (long) ChangeType (value, typeof (System.Int64), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToInt64 (provider);\r
                }\r
                \r
                // ========== SByte Conversions ========== //\r
@@ -1342,7 +1386,15 @@ namespace System {
                [CLSCompliant (false)]\r
                public static sbyte ToSByte (string value, int fromBase)\r
                {\r
-                       return (sbyte) ConvertFromBase (value, fromBase);\r
+                       int retVal = ConvertFromBase (value, fromBase);\r
+\r
+                       if (retVal == 255)\r
+                               return (sbyte)-1;\r
+\r
+                       if (retVal < (int) SByte.MinValue || retVal > (int) SByte.MaxValue)\r
+                               throw new OverflowException ();\r
+                       else\r
+                               return (sbyte) retVal;\r
                }\r
                \r
                [CLSCompliant (false)]\r
@@ -1378,13 +1430,15 @@ namespace System {
                [CLSCompliant (false)]\r
                public static sbyte ToSByte (object value)\r
                {\r
-                       return (sbyte) ChangeType (value, typeof (System.SByte));\r
+                       return ToSByte (value, null);\r
                }\r
 \r
                [CLSCompliant (false)]\r
                public static sbyte ToSByte (object value, IFormatProvider provider)\r
                {\r
-                       return (sbyte) ChangeType (value, typeof (System.SByte), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToSByte (provider);\r
                }\r
 \r
                // ========== Single Conversions ========== //\r
@@ -1477,16 +1531,17 @@ namespace System {
                        return (float)value; \r
                }\r
 \r
-               [CLSCompliant (false)]\r
                public static float ToSingle (object value)\r
                {\r
-                       return (float) ChangeType (value, typeof (System.Single));\r
+                       return ToSingle (value, null);\r
                }\r
 \r
-               [CLSCompliant (false)]\r
+//             [CLSCompliant (false)]\r
                public static float ToSingle (object value, IFormatProvider provider)\r
                {\r
-                       return (float) ChangeType (value, typeof (System.Single), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToSingle (provider);\r
                }\r
 \r
                // ========== String Conversions ========== //\r
@@ -1511,6 +1566,14 @@ namespace System {
                        return value.ToString (provider); \r
                }\r
 \r
+               public static string ToString (byte value, int toBase)\r
+               {\r
+                       if (NotValidBase (toBase))\r
+                               throw new ArgumentException ("toBase is not valid.");\r
+                       \r
+                       return ConvertToBase ((int) value, toBase);\r
+               }\r
+\r
                public static string ToString (char value) \r
                { \r
                        return value.ToString (); \r
@@ -1566,9 +1629,12 @@ namespace System {
                        return value.ToString (); \r
                }\r
 \r
-               public static string ToString (int value, int fromBase)\r
+               public static string ToString (int value, int toBase)\r
                {\r
-                       return (ConvertFromBase (value.ToString (), fromBase)).ToString ();\r
+                       if (NotValidBase (toBase))\r
+                               throw new ArgumentException ("toBase is not valid.");\r
+               \r
+                       return ConvertToBase ((int) value, toBase);\r
                }\r
 \r
                public static string ToString (int value, IFormatProvider provider) \r
@@ -1581,9 +1647,12 @@ namespace System {
                        return value.ToString (); \r
                }\r
 \r
-               public static string ToString (long value, int fromBase)\r
+               public static string ToString (long value, int toBase)\r
                {\r
-                       return (ConvertFromBase (value.ToString (), fromBase)).ToString ();\r
+                       if (NotValidBase (toBase))\r
+                               throw new ArgumentException ("toBase is not valid.");\r
+                       \r
+                       return ConvertToBase (value, toBase);\r
                }\r
 \r
                public static string ToString (long value, IFormatProvider provider) \r
@@ -1593,19 +1662,25 @@ namespace System {
 \r
                public static string ToString (object value)\r
                {\r
-                       return (string) ChangeType (value, typeof (System.String));\r
+                       return ToString (value, null);\r
                }               \r
 \r
                public static string ToString (object value, IFormatProvider provider)\r
                {\r
-                       return (string) ChangeType (value, typeof (System.String), provider);\r
+                       if (value is IConvertible)\r
+                               return ((IConvertible) value).ToString (provider);\r
+                       else if (value != null)\r
+                               return value.ToString ();\r
+                       return String.Empty;\r
                }                               \r
 \r
+               [CLSCompliant (false)]\r
                public static string ToString (sbyte value) \r
                { \r
                        return value.ToString (); \r
                }\r
 \r
+               [CLSCompliant (false)]                          \r
                public static string ToString (sbyte value, IFormatProvider provider) \r
                { \r
                        return value.ToString (provider); \r
@@ -1616,9 +1691,12 @@ namespace System {
                        return value.ToString (); \r
                }\r
 \r
-               public static string ToString (short value, int fromBase)\r
+               public static string ToString (short value, int toBase)\r
                {\r
-                       return (ConvertFromBase (value.ToString (), fromBase)).ToString ();\r
+                       if (NotValidBase (toBase))\r
+                               throw new ArgumentException ("toBase is not valid.");\r
+                       \r
+                       return ConvertToBase ((int) value, toBase);\r
                }\r
 \r
                public static string ToString (short value, IFormatProvider provider) \r
@@ -1818,13 +1896,15 @@ namespace System {
                [CLSCompliant (false)]\r
                public static ushort ToUInt16 (object value)\r
                {\r
-                       return (ushort) ChangeType (value, typeof (System.UInt16));\r
+                       return ToUInt16 (value, null);\r
                }\r
 \r
                [CLSCompliant (false)]\r
                public static ushort ToUInt16 (object value, IFormatProvider provider)\r
                {\r
-                       return (ushort) ChangeType (value, typeof (System.UInt16), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToUInt16 (provider);\r
                }\r
 \r
                // ========== UInt32 Conversions ========== //\r
@@ -1969,13 +2049,15 @@ namespace System {
                [CLSCompliant (false)]\r
                public static uint ToUInt32 (object value)\r
                {\r
-                       return (uint) ChangeType (value, typeof (System.UInt32));\r
+                       return ToUInt32 (value, null);\r
                }               \r
 \r
                [CLSCompliant (false)]\r
                public static uint ToUInt32 (object value, IFormatProvider provider)\r
                {\r
-                       return (uint) ChangeType (value, typeof (System.UInt32), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToUInt32 (provider);\r
                }               \r
                \r
 \r
@@ -2117,13 +2199,15 @@ namespace System {
                [CLSCompliant (false)]\r
                public static ulong ToUInt64 (object value)\r
                {\r
-                       return (ulong) ChangeType (value, typeof (System.UInt64));\r
+                       return ToUInt64 (value, null);\r
                }               \r
 \r
                [CLSCompliant (false)]\r
                public static ulong ToUInt64 (object value, IFormatProvider provider)\r
                {\r
-                       return (ulong) ChangeType (value, typeof (System.UInt64), provider);\r
+                       if (value == null)\r
+                               return 0;\r
+                       return ((IConvertible) value).ToUInt64 (provider);\r
                }               \r
                \r
 \r
@@ -2168,41 +2252,135 @@ namespace System {
                {\r
                        if (NotValidBase (fromBase))\r
                                throw new ArgumentException ("fromBase is not valid.");\r
-                       \r
+\r
+                       int chars = 0;\r
                        int result = 0;\r
+                       int digitValue;\r
+\r
+                       foreach (char c in value) {\r
+                               if (Char.IsNumber (c))\r
+                                       digitValue = c - '0';\r
+                               else if (Char.IsLetter (c))\r
+                                       digitValue = Char.ToLower(c) - 'a' + 10;\r
+                               else\r
+                                       throw new FormatException ("This is an invalid string: " + value);\r
+\r
+                               if (digitValue >= fromBase)\r
+                                       throw new FormatException ("the digits are invalid.");\r
+\r
+                               result = (fromBase) * result + digitValue;\r
+                               chars ++;\r
+                       }\r
+\r
+                       if (chars == 0)\r
+                               throw new FormatException ("Could not find any digits.");\r
+\r
+                       if (result > Int32.MaxValue || result < Int32.MinValue)\r
+                               throw new OverflowException ("There is an overflow.");\r
+                       \r
+                       return result;\r
+               }\r
+\r
+               private static long ConvertFromBase64 (string value, int fromBase)\r
+               {\r
+                       if (NotValidBase (fromBase))\r
+                               throw new ArgumentException ("fromBase is not valid.");\r
+\r
+                       int chars = 0;\r
+                       int digitValue;\r
+                       long result = 0;\r
 \r
                        foreach (char c in value) {\r
-                               if (Char.IsLetter (c))\r
-                                       result = (fromBase) * result + c - 'a' + 10;\r
+                               if (Char.IsNumber (c))\r
+                                       digitValue = c - '0';\r
+                               else if (Char.IsLetter (c))\r
+                                       digitValue = Char.ToLower(c) - 'a' + 10;\r
                                else\r
-                                       result = (fromBase) * result + c - '0';\r
+                                       throw new FormatException ("This is an invalid string: " + value);\r
+\r
+                               if (digitValue >= fromBase)\r
+                                       throw new FormatException ("the digits are invalid.");\r
+\r
+                               result = (fromBase) * result + digitValue;\r
+                               chars ++;\r
                        }\r
+\r
+                       if (chars == 0)\r
+                               throw new FormatException ("Could not find any digits.");\r
+\r
+                       if (result > Int64.MaxValue || result < Int64.MinValue)\r
+                               throw new OverflowException ("There is an overflow.");\r
+                       \r
                        return result;\r
                }\r
 \r
+               private static string ConvertToBase (int value, int toBase)\r
+               {\r
+                       StringBuilder sb = new StringBuilder ();\r
+                       BuildConvertedString (sb, value, toBase);\r
+                       return sb.ToString ();\r
+               }\r
+\r
+               private static string ConvertToBase (long value, int toBase)\r
+               {\r
+                       StringBuilder sb = new StringBuilder ();\r
+                       BuildConvertedString64 (sb, value, toBase);\r
+                       return sb.ToString ();\r
+               }\r
+               \r
+\r
+               internal static void BuildConvertedString (StringBuilder sb, int value, int toBase)\r
+               {\r
+                       int divided = value / toBase;\r
+                       int reminder = value % toBase;          \r
+\r
+                       if (divided > 0)\r
+                               BuildConvertedString (sb, divided, toBase);\r
+               \r
+                       if (reminder >= 10)\r
+                               sb.Append ((char) (reminder + 'a' - 10));\r
+                       else\r
+                               sb.Append ((char) (reminder + '0'));\r
+               }\r
+\r
+               internal static void BuildConvertedString64 (StringBuilder sb, long value, int toBase)\r
+               {\r
+                       long divided = value / toBase;\r
+                       long reminder = value % toBase;         \r
+\r
+                       if (divided > 0)\r
+                               BuildConvertedString64 (sb, divided, toBase);\r
+               \r
+                       if (reminder >= 10)\r
+                               sb.Append ((char) (reminder + 'a' - 10));\r
+                       else\r
+                               sb.Append ((char) (reminder + '0'));\r
+               }\r
+               \r
                 // Lookup table for the conversion ToType method. Order\r
                // is important! Used by ToType for comparing the target\r
                // type, and uses hardcoded array indexes.\r
                private static Type[] conversionTable = {\r
                        // Valid ICovnertible Types\r
-                       typeof (Boolean),  //  0 TypeCode.Boolean\r
-                       typeof (Byte),     //  1 TypeCode.Byte\r
-                       typeof (Char),     //  2 TypeCode.Char\r
-                       typeof (DateTime), //  3 TypeCode.DateTime\r
-                       typeof (Decimal),  //  4 TypeCode.Decimal\r
-                       typeof (Double),   //  5 TypeCode.Double\r
-                       typeof (Int16),    //  6 TypeCode.Int16\r
-                       typeof (Int32),    //  7 TypeCode.Int32\r
-                       typeof (Int64),    //  8 TypeCode.Int64\r
-                       typeof (SByte),    //  9 TypeCode.Sbyte\r
-                       typeof (Single),   // 10 TypeCode.Single\r
-                       typeof (String),   // 11 TypeCode.String\r
-                       typeof (UInt16),   // 12 TypeCode.UInt16\r
-                       typeof (UInt32),   // 13 TypeCode.UInt32\r
-                       typeof (UInt64),   // 14 TypeCode.UInt64\r
-         \r
-                       // Invalid IConvertible Interface Types\r
-                       typeof (Object)    // 15 TypeCode.Object\r
+                       null,              //  0 empty\r
+                       typeof (object),   //  1 TypeCode.Object\r
+                       typeof (DBNull),   //  2 TypeCode.DBNull\r
+                       typeof (Boolean),  //  3 TypeCode.Boolean\r
+                       typeof (Char),     //  4 TypeCode.Char\r
+                       typeof (SByte),    //  5 TypeCode.SByte\r
+                       typeof (Byte),     //  6 TypeCode.Byte\r
+                       typeof (Int16),    //  7 TypeCode.Int16\r
+                       typeof (UInt16),   //  8 TypeCode.UInt16\r
+                       typeof (Int32),    //  9 TypeCode.Int32\r
+                       typeof (UInt32),   // 10 TypeCode.UInt32\r
+                       typeof (Int64),    // 11 TypeCode.Int64\r
+                       typeof (UInt64),   // 12 TypeCode.UInt64\r
+                       typeof (Single),   // 13 TypeCode.Single\r
+                       typeof (Double),   // 14 TypeCode.Double\r
+                       typeof (Decimal),  // 15 TypeCode.Decimal\r
+                       typeof (DateTime), // 16 TypeCode.DateTime\r
+                       null,              // 17 null.\r
+                       typeof (String),   // 18 TypeCode.String\r
                };\r
 \r
                // Function to convert an object to another type and return\r
@@ -2212,91 +2390,74 @@ namespace System {
                internal static object ToType (object value, Type conversionType, \r
                                               IFormatProvider provider) \r
                {\r
+                       if (value == null && conversionType == null)\r
+                               return null;\r
+                       \r
                        if (value == null)\r
-                               throw new ArgumentException (Locale.GetText (\r
-                                       "Invalid conversion from null value"));\r
-\r
+                               throw new NullReferenceException ("Value is null.");\r
+                       \r
                        if (value is IConvertible) {\r
-                               IConvertible convertValue = (IConvertible)value;\r
-\r
-                               if (conversionType == conversionTable[0]) {\r
-                                       // 0 TypeCode.Boolean\r
-                                       return (object)(convertValue.ToBoolean (provider));\r
+                               IConvertible convertValue = (IConvertible) value;\r
 \r
-                               } else if (conversionType == conversionTable[1]) {\r
-                                       // 1 TypeCode.Byte\r
-                                       return (object)(convertValue.ToByte (provider));\r
-                 \r
-                               } else if (conversionType == conversionTable[2]) {\r
-                                       // 2 TypeCode.Char\r
-                                       return (object)(convertValue.ToChar (provider));\r
-                 \r
-                               } else if (conversionType == conversionTable[3]) {\r
-                                       // 3 TypeCode.DateTime\r
-                                       return (object)(convertValue.ToDateTime (provider));\r
+                               if (conversionType == conversionTable[0]) // 0 Empty\r
+                                       throw new ArgumentNullException ();\r
+                               \r
+                               else if (conversionType == conversionTable[1]) // 1 TypeCode.Object\r
+                                       return (object) value;\r
+                                       \r
+                               else if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull\r
+                                       throw new InvalidCastException ();     // It's not IConvertible\r
                  \r
-                               } else if (conversionType == conversionTable[4]) {\r
-                                       // 4 TypeCode.Decimal\r
-                                       return (object)(convertValue.ToDecimal (provider));\r
+                               else if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean\r
+                                       return (object) convertValue.ToBoolean (provider);\r
+                                       \r
+                               else if (conversionType == conversionTable[4]) // 4 TypeCode.Char\r
+                                       return (object) convertValue.ToChar (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[5]) {\r
-                                       // 5 TypeCode.Double\r
-                                       return (object)(convertValue.ToDouble (provider));\r
+                               else if (conversionType == conversionTable[5]) // 5 TypeCode.SByte\r
+                                       return (object) convertValue.ToSByte (provider);\r
 \r
-                               } else if (conversionType == conversionTable[6]) {\r
-                                       // 6 TypeCode.Int16\r
-                                       return (object)(convertValue.ToInt16 (provider));\r
-                 \r
-                               } else if (conversionType == conversionTable[7]) {\r
-                                       // 7 TypeCode.Int32\r
-                                       return (object)(convertValue.ToInt32 (provider));\r
-                 \r
-                               } else if (conversionType == conversionTable[8]) {\r
-                                       // 8 TypeCode.Int64\r
-                                       return (object)(convertValue.ToInt64 (provider));\r
-                 \r
-                               } else if (conversionType == conversionTable[9]) {\r
-                                       // 9 TypeCode.Sbyte\r
-                                       return (object)(convertValue.ToSByte (provider));\r
+                               else if (conversionType == conversionTable[6]) // 6 TypeCode.Byte\r
+                                       return (object) convertValue.ToByte (provider);\r
+                               \r
+                               else if (conversionType == conversionTable[7]) // 7 TypeCode.Int16\r
+                                       return (object) convertValue.ToInt16 (provider);\r
+                                       \r
+                               else if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16\r
+                                       return (object) convertValue.ToUInt16 (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[10]) {\r
-                                       // 10 TypeCode.Single\r
-                                       return (object)(convertValue.ToSingle (provider));\r
+                               else if (conversionType == conversionTable[9]) // 9 TypeCode.Int32\r
+                                       return (object) convertValue.ToInt32 (provider);\r
+                       \r
+                               else if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32\r
+                                       return (object) convertValue.ToUInt32 (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[11]) {\r
-                                       // 11 TypeCode.String\r
-                                       return (object)(convertValue.ToString (provider));\r
+                               else if (conversionType == conversionTable[11]) // 11 TypeCode.Int64\r
+                                       return (object) convertValue.ToInt64 (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[12]) {  \r
-                                       // 12 TypeCode.UInt16\r
-                                       return (object)(convertValue.ToUInt16 (provider));\r
+                               else if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64\r
+                                       return (object) convertValue.ToUInt64 (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[13]) {\r
-                                       // 13 TypeCode.UInt32\r
-                                       return (object)(convertValue.ToUInt32 (provider));\r
+                               else if (conversionType == conversionTable[13]) // 13 TypeCode.Single\r
+                                       return (object) convertValue.ToSingle (provider);\r
                  \r
-                               } else if (conversionType == conversionTable[14]) {\r
-                                       // 14 TypeCode.UInt64\r
-                                       return (object)(convertValue.ToUInt64 (provider));\r
-\r
-                               } else if (conversionType == conversionTable[15]) {\r
-                                       // 15 TypeCode.Object\r
-                                       return (object)(value);\r
-\r
-                               } else  {               \r
-                                       // Not in the conversion table\r
-                                       throw new InvalidCastException (Locale.GetText (\r
-                                               "Unknown target conversion type"));\r
-                               }\r
-                       } else {\r
-                               // Value is not IConvertible\r
-                               throw new ArgumentException (Locale.GetText (\r
-                                       "Value is not a convertible object: "+ value.GetType().ToString()+" to "+conversionType.ToString()));\r
-                       }\r
+                               else if (conversionType == conversionTable[14]) // 14 TypeCode.Double\r
+                                       return (object) convertValue.ToDouble (provider);\r
+\r
+                               else if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal\r
+                                       return (object) convertValue.ToDecimal (provider);\r
+\r
+                               else if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime\r
+                                       return (object) convertValue.ToDateTime (provider);\r
+                               \r
+                               else if (conversionType == conversionTable[18]) // 18 TypeCode.String\r
+                                       return (object) convertValue.ToString (provider);\r
+                               else\r
+                                       throw new ArgumentException (Locale.GetText ("Unknown target conversion type"));\r
+                       } else\r
+                               // Not in the conversion table\r
+                               throw new InvalidCastException ((Locale.GetText (\r
+                                       "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));\r
                }\r
        }\r
 }\r
-\r
-\r
-\r
-\r