2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq / Util / TypeConvert.cs
1 #region MIT license\r
2 // \r
3 // MIT license\r
4 //\r
5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne\r
6 // \r
7 // Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 // of this software and associated documentation files (the "Software"), to deal\r
9 // in the Software without restriction, including without limitation the rights\r
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 // copies of the Software, and to permit persons to whom the Software is\r
12 // furnished to do so, subject to the following conditions:\r
13 // \r
14 // The above copyright notice and this permission notice shall be included in\r
15 // all copies or substantial portions of the Software.\r
16 // \r
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 // THE SOFTWARE.\r
24 // \r
25 #endregion\r
26 \r
27 using System;\r
28 using System.Reflection;\r
29 \r
30 namespace DbLinq.Util\r
31 {\r
32     /// <summary>\r
33     /// Types conversion.\r
34     /// A "smart" extension to System.Convert (at least that's what we hope)\r
35     /// </summary>\r
36 #if MONO_STRICT || !DEBUG\r
37     internal\r
38 #else\r
39     public\r
40 #endif\r
41     static class TypeConvert\r
42     {\r
43         public static object ToNumber(object o, Type numberType)\r
44         {\r
45             if (o.GetType() == numberType)\r
46                 return o;\r
47             string methodName = string.Format("To{0}", numberType.Name);\r
48             MethodInfo convertMethod = typeof(Convert).GetMethod(methodName, new[] { o.GetType() });\r
49             if (convertMethod != null)\r
50                 return convertMethod.Invoke(null, new[] { o });\r
51             throw new InvalidCastException(string.Format("Can't convert type {0} in Convert.{1}()", o.GetType().Name, methodName));\r
52         }\r
53 \r
54         public static U ToNumber<U>(object o)\r
55         {\r
56             return (U)ToNumber(o, typeof(U));\r
57         }\r
58 \r
59         /// <summary>\r
60         /// Returns the default value for a specified type.\r
61         /// Reflection equivalent of default(T)\r
62         /// </summary>\r
63         /// <param name="t"></param>\r
64         /// <returns></returns>\r
65         public static object GetDefault(Type t)\r
66         {\r
67             if (!t.IsValueType)\r
68                 return null;\r
69             return Activator.CreateInstance(t);\r
70         }\r
71 \r
72         /// <summary>\r
73         /// Converts a value to an enum\r
74         /// (work with literals string values and numbers)\r
75         /// </summary>\r
76         /// <param name="o">The literal to convert</param>\r
77         /// <param name="enumType">The target enum type</param>\r
78         /// <returns></returns>\r
79         public static int ToEnum(object o, Type enumType)\r
80         {\r
81             var e = (int)Enum.Parse(enumType, o.ToString());\r
82             return e;\r
83         }\r
84 \r
85         public static E ToEnum<E>(object o)\r
86         {\r
87             return (E)(object)ToEnum(o, typeof(E));\r
88         }\r
89 \r
90         public static bool ToBoolean(object o)\r
91         {\r
92             if (o is bool)\r
93                 return (bool)o;\r
94             // if it is a string, we may have "T"/"F" or "True"/"False"\r
95             if (o is string)\r
96             {\r
97                 // regular literals\r
98                 var lb = (string)o;\r
99                 bool ob;\r
100                 if (bool.TryParse(lb, out ob))\r
101                     return ob;\r
102                 // alternative literals\r
103                 if (lb == "T" || lb == "F")\r
104                     return lb == "T";\r
105                 if (lb == "Y" || lb == "N")\r
106                     return lb == "Y";\r
107             }\r
108             return ToNumber<int>(o) != 0;\r
109         }\r
110 \r
111         public static string ToString(object o)\r
112         {\r
113             if (o == null)\r
114                 return null;\r
115             return o.ToString();\r
116         }\r
117 \r
118         public static char ToChar(object c)\r
119         {\r
120             if (c is char)\r
121                 return (char)c;\r
122             if (c is string)\r
123             {\r
124                 var sc = (string)c;\r
125                 if (sc.Length == 1)\r
126                     return sc[0];\r
127             }\r
128             if (c == null)\r
129                 return '\0';\r
130             throw new InvalidCastException(string.Format("Can't convert type {0} in GetAsChar()", c.GetType().Name));\r
131         }\r
132 \r
133         public static Guid ToGuid(object o)\r
134         {\r
135             if (o is Guid)\r
136                 return (Guid)o;\r
137             return new Guid(ToString(o));\r
138         }\r
139 \r
140         public static object To(object o, Type targetType)\r
141         {\r
142             if (targetType.IsNullable())\r
143             {\r
144                 if (o == null)\r
145                     return null;\r
146                 return Activator.CreateInstance(targetType, To(o, targetType.GetNullableType()));\r
147             }\r
148             if (targetType == typeof(string))\r
149                 return ToString(o);\r
150             if (targetType == typeof(bool))\r
151                 return ToBoolean(o);\r
152             if (targetType == typeof(char))\r
153                 return ToChar(o);\r
154             if (targetType == typeof(byte))\r
155                 return ToNumber<byte>(o);\r
156             if (targetType == typeof(sbyte))\r
157                 return ToNumber<sbyte>(o);\r
158             if (targetType == typeof(short))\r
159                 return ToNumber<short>(o);\r
160             if (targetType == typeof(ushort))\r
161                 return ToNumber<ushort>(o);\r
162             if (targetType == typeof(int))\r
163                 return ToNumber<int>(o);\r
164             if (targetType == typeof(uint))\r
165                 return ToNumber<uint>(o);\r
166             if (targetType == typeof(long))\r
167                 return ToNumber<long>(o);\r
168             if (targetType == typeof(ulong))\r
169                 return ToNumber<ulong>(o);\r
170             if (targetType == typeof(float))\r
171                 return ToNumber<float>(o);\r
172             if (targetType == typeof(double))\r
173                 return ToNumber<double>(o);\r
174             if (targetType == typeof(decimal))\r
175                 return ToNumber<decimal>(o);\r
176             if (targetType == typeof(DateTime))\r
177                 return (DateTime)o;\r
178             if (targetType == typeof(Guid))\r
179                 return ToGuid(o);\r
180             if (targetType.IsEnum)\r
181                 return ToEnum(o, targetType);\r
182             throw new ArgumentException(string.Format("L0117: Unhandled type {0}", targetType));\r
183         }\r
184 \r
185         public static T To<T>(object o)\r
186         {\r
187             return (T)To(o, typeof(T));\r
188         }\r
189     }\r
190 }\r