Merge pull request #2237 from xmcclure/container-owner
[mono.git] / mcs / class / corlib / ReferenceSources / DefaultBinder.cs
1 //
2 // DefaultBinder.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2015 Xamarin Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 namespace System
30 {
31         partial class DefaultBinder
32         {
33                 static bool CanConvertPrimitive (RuntimeType source, RuntimeType target)
34                 {
35                         if (source.IsEnum)
36                                 return false;
37
38                         var from = Type.GetTypeCode (source);
39                         var to = Type.GetTypeCode (target);
40                         if (from == to && source.IsPrimitive)
41                                 return true;
42                         switch (to) {
43                         case TypeCode.Char:
44                                 switch (from) {
45                                 case TypeCode.Byte:
46                                 case TypeCode.UInt16:
47                                         return true;
48                                 }
49                                 return false;
50                         case TypeCode.Int16:
51                                 switch (from) {
52                                 case TypeCode.Byte:
53                                 case TypeCode.SByte:
54                                         return true;
55                                 }
56                                 return false;
57                         case TypeCode.UInt16:
58                                 switch (from) {
59                                 case TypeCode.Byte:
60                                 case TypeCode.Char:
61                                         return true;
62                                 }
63                                 return false;
64                         case TypeCode.Int32:
65                                 switch (from) {
66                                 case TypeCode.Byte:
67                                 case TypeCode.SByte:
68                                 case TypeCode.Char:
69                                 case TypeCode.Int16:
70                                 case TypeCode.UInt16:
71                                         return true;
72                                 }
73                                 return false;
74                         case TypeCode.UInt32:
75                                 switch (from) {
76                                 case TypeCode.Byte:
77                                 case TypeCode.Char:
78                                 case TypeCode.UInt16:
79                                         return true;
80                                 }
81                                 return false;
82                         case TypeCode.Int64:
83                                 switch (from) {
84                                 case TypeCode.Byte:
85                                 case TypeCode.SByte:
86                                 case TypeCode.Int16:
87                                 case TypeCode.Char:
88                                 case TypeCode.UInt16:
89                                 case TypeCode.Int32:
90                                 case TypeCode.UInt32:
91                                         return true;
92                                 }
93                                 return false;
94                         case TypeCode.UInt64:
95                                 switch (from) {
96                                 case TypeCode.Byte:
97                                 case TypeCode.Char:
98                                 case TypeCode.UInt16:
99                                 case TypeCode.UInt32:
100                                         return true;
101                                 }
102                                 return false;
103                         case TypeCode.Single:
104                                 switch (from) {
105                                 case TypeCode.Byte:
106                                 case TypeCode.SByte:
107                                 case TypeCode.Int16:
108                                 case TypeCode.Char:
109                                 case TypeCode.UInt16:
110                                 case TypeCode.Int32:
111                                 case TypeCode.UInt32:
112                                 case TypeCode.Int64:
113                                 case TypeCode.UInt64:
114                                         return true;
115                                 }
116                                 return false;
117                         case TypeCode.Double:
118                                 switch (from) {
119                                 case TypeCode.Byte:
120                                 case TypeCode.SByte:
121                                 case TypeCode.Char:
122                                 case TypeCode.Int16:
123                                 case TypeCode.UInt16:
124                                 case TypeCode.Int32:
125                                 case TypeCode.UInt32:
126                                 case TypeCode.Int64:
127                                 case TypeCode.UInt64:
128                                 case TypeCode.Single:
129                                         return true;
130                                 }
131                                 return false;
132                         }
133
134                         if (target == typeof (IntPtr))
135                                 return source == target;
136
137                         if (target == typeof (UIntPtr))
138                                 return source == target;
139
140                         return false;
141                 }
142
143                 static bool CanConvertPrimitiveObjectToType (Object source, RuntimeType type)
144                 {
145                         if (source == null)
146                                 return true;
147
148                         var st = source.GetType ();
149                         return st == type || CanConvertPrimitive ((RuntimeType) st, type);
150                 }
151         }
152 }