public sealed class Convert {\r
\r
// Fields\r
- public static readonly object DBNull;\r
+ public static readonly object DBNull = System.DBNull.Value;\r
\r
private Convert () {}\r
\r
\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
\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
\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
\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
\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
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
{\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
if (NotValidBase (toBase))\r
throw new ArgumentException ("toBase is not valid.");\r
\r
- return ConvertToBase ((int) value, toBase);\r
+ return ConvertToBase (value, toBase);\r
}\r
\r
public static string ToString (long value, IFormatProvider provider) \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
- chars ++;\r
- } else if (Char.IsNumber (c)) {\r
- result = (fromBase) * result + c - '0';\r
- chars ++;\r
- } else\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 > Int64.MaxValue || result < Int64.MinValue)\r
+ throw new OverflowException ("There is an overflow.");\r
\r
return result;\r
}\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
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
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
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]) // 0 Empty\r
- return null;\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
- // return null; // It's not IConvertible\r
+ else if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull\r
+ throw new InvalidCastException (); // It's not IConvertible\r
\r
else if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean\r
return (object) convertValue.ToBoolean (provider);\r
else if (conversionType == conversionTable[18]) // 18 TypeCode.String\r
return (object) convertValue.ToString (provider);\r
else\r
- throw new InvalidCastException (Locale.GetText ("Unknown target conversion type"));\r
+ throw new ArgumentException (Locale.GetText ("Unknown target conversion type"));\r
} else\r
// Not in the conversion table\r
- throw new ArgumentException ((Locale.GetText (\r
- "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.ToString())));\r
+ throw new InvalidCastException ((Locale.GetText (\r
+ "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));\r
}\r
}\r
}\r