Initial commit
[mono.git] / mcs / class / referencesource / mscorlib / microsoft / win32 / oavariantlib.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  OAVariantLib
9 **
10 **
11 ** Purpose: This class only exists to provide support for 
12 **          implenting IDispatch on managed objects. It is 
13 **          used to provide OleAut style coercion rules.
14 **
15 ** 
16 ===========================================================*/
17 namespace Microsoft.Win32 {
18     
19     using System;
20     using System.Diagnostics.Contracts;
21     using System.Reflection;
22     using System.Runtime.CompilerServices;
23     using System.Runtime.Versioning;
24     using CultureInfo = System.Globalization.CultureInfo;
25
26     internal static class OAVariantLib
27     {
28         #region Constants
29
30         // Constants for VariantChangeType from OleAuto.h
31         public const int NoValueProp = 0x01;
32         public const int AlphaBool = 0x02;
33         public const int NoUserOverride = 0x04;
34         public const int CalendarHijri = 0x08;
35         public const int LocalBool = 0x10;
36         
37         internal static readonly Type [] ClassTypes = {
38             typeof(Empty),
39             typeof(void),
40             typeof(Boolean),
41             typeof(Char),
42             typeof(SByte),
43             typeof(Byte),
44             typeof(Int16),
45             typeof(UInt16),
46             typeof(Int32),
47             typeof(UInt32),
48             typeof(Int64),
49             typeof(UInt64),
50             typeof(Single),
51             typeof(Double),
52             typeof(String),
53             typeof(void),
54             typeof(DateTime),
55             typeof(TimeSpan),
56             typeof(Object),
57             typeof(Decimal),
58             null,  // Enums - what do we do here?
59             typeof(Missing),
60             typeof(DBNull),
61         };
62
63         // Keep these numbers in [....] w/ the above array.
64         private const int CV_OBJECT=0x12;
65         
66         #endregion
67
68         
69         #region Internal Methods
70
71         /**
72          * Changes a Variant from one type to another, calling the OLE
73          * Automation VariantChangeTypeEx routine.  Note the legal types here are
74          * restricted to the subset of what can be legally found in a VB
75          * Variant and the types that CLR supports explicitly in the 
76          * CLR Variant class.  
77          */
78         [System.Security.SecurityCritical]  // auto-generated
79         internal static Variant ChangeType(Variant source, Type targetClass, short options, CultureInfo culture)
80         {
81             if (targetClass == null)
82                 throw new ArgumentNullException("targetClass");
83             if (culture == null)
84                 throw new ArgumentNullException("culture");
85             Variant result = new Variant ();
86             ChangeTypeEx(ref result, ref source, 
87 #if FEATURE_USE_LCID
88                          culture.LCID, 
89 #else
90         // @CORESYSTODO: what does CoreSystem expect for this argument?
91                         0,
92 #endif
93                          targetClass.TypeHandle.Value, GetCVTypeFromClass(targetClass), options);
94             return result;
95         }       
96
97         #endregion
98
99
100         #region Private Helpers
101
102         private static int GetCVTypeFromClass(Type ctype) 
103         {
104             Contract.Requires(ctype != null);
105 #if _DEBUG
106             BCLDebug.Assert(ClassTypes[CV_OBJECT] == typeof(Object), "OAVariantLib::ClassTypes[CV_OBJECT] == Object.class");
107 #endif
108     
109             int cvtype=-1;
110             for (int i=0; i<ClassTypes.Length; i++) {
111                 if (ctype.Equals(ClassTypes[i])) {
112                     cvtype=i;
113                     break;
114                 }
115             }
116     
117             // OleAut Binder works better if unrecognized
118             // types were changed to Object.  So don't throw here.
119             if (cvtype == -1)
120                 cvtype = CV_OBJECT;
121     
122             return cvtype;
123         }
124
125         #endregion
126
127
128         #region Private FCalls
129
130         [System.Security.SecurityCritical]  // auto-generated
131         [MethodImplAttribute(MethodImplOptions.InternalCall)]
132         [ResourceExposure(ResourceScope.None)]
133         private static extern void ChangeTypeEx(ref Variant result, ref Variant source, int lcid, IntPtr typeHandle, int cvType, short flags);
134
135         #endregion
136     }
137 }