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