Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / BCL / System / Variant.cs / 1 / Variant.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: Variant
**
**
** Purpose: The CLR implementation of Variant.
**
**
===========================================================*/
namespace System {
using System;
using System.Reflection;
using System.Threading;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Runtime.CompilerServices;
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
internal struct Variant {
//Do Not change the order of these fields.
//They are mapped to the native VariantData * data structure.
private Object m_objref;
private int m_data1;
private int m_data2;
private int m_flags;
// The following will call the internal routines to initalize the
// native side of variant.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void InitVariant();
static Variant() {
InitVariant();
}
private static Type _voidPtr = null;
// The following bits have been taken up as follows
// bits 0-15 - Type code
// bit 16 - Array
// bits 19-23 - Enums
// bits 24-31 - Optional VT code (for roundtrip VT preservation)
//What are the consequences of making this an enum?
///////////////////////////////////////////////////////////////////////
// If you update this, update the corresponding stuff in OAVariantLib.cs,
// COMOAVariant.cpp (2 tables, forwards and reverse), and perhaps OleVariant.h
///////////////////////////////////////////////////////////////////////
internal const int CV_EMPTY=0x0;
internal const int CV_VOID=0x1;
internal const int CV_BOOLEAN=0x2;
internal const int CV_CHAR=0x3;
internal const int CV_I1=0x4;
internal const int CV_U1=0x5;
internal const int CV_I2=0x6;
internal const int CV_U2=0x7;
internal const int CV_I4=0x8;
internal const int CV_U4=0x9;
internal const int CV_I8=0xa;
internal const int CV_U8=0xb;
internal const int CV_R4=0xc;
internal const int CV_R8=0xd;
internal const int CV_STRING=0xe;
internal const int CV_PTR=0xf;
internal const int CV_DATETIME = 0x10;
internal const int CV_TIMESPAN = 0x11;
internal const int CV_OBJECT=0x12;
internal const int CV_DECIMAL = 0x13;
internal const int CV_ENUM=0x15;
internal const int CV_MISSING=0x16;
internal const int CV_NULL=0x17;
internal const int CV_LAST=0x18;
internal const int TypeCodeBitMask=0xffff;
internal const int VTBitMask=unchecked((int)0xff000000);
internal const int VTBitShift=24;
internal const int ArrayBitMask =0x10000;
// Enum enum and Mask
internal const int EnumI1 =0x100000;
internal const int EnumU1 =0x200000;
internal const int EnumI2 =0x300000;
internal const int EnumU2 =0x400000;
internal const int EnumI4 =0x500000;
internal const int EnumU4 =0x600000;
internal const int EnumI8 =0x700000;
internal const int EnumU8 =0x800000;
internal const int EnumMask =0xF00000;
internal static readonly Type [] ClassTypes = {
typeof(System.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), // ptr for the moment
typeof(DateTime),
typeof(TimeSpan),
typeof(Object),
typeof(Decimal),
typeof(Object), // Treat enum as Object
typeof(System.Reflection.Missing),
typeof(System.DBNull),
};
internal static readonly Variant Empty = new Variant();
internal static readonly Variant Missing = new Variant(Variant.CV_MISSING, Type.Missing, 0, 0);
internal static readonly Variant DBNull = new Variant(Variant.CV_NULL, System.DBNull.Value, 0, 0);
//
// Native Methods
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern double GetR8FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern float GetR4FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR4(float val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR8(double val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsObject(Object val);
// Use this function instead of an ECALL - saves about 150 clock cycles
// by avoiding the ecall transition and because the JIT inlines this.
// Ends up only taking about 1/8 the time of the ECALL version.
internal long GetI8FromVar()
{
return ((long)m_data2<<32 | ((long)m_data1 & 0xFFFFFFFFL));
}
//
// Constructors
//
internal Variant(int flags, Object or, int data1, int data2) {
m_flags = flags;
m_objref=or;
m_data1=data1;
m_data2=data2;
}
public Variant(bool val) {
m_objref= null;
m_flags = CV_BOOLEAN;
m_data1 = (val)?Boolean.True:Boolean.False;
m_data2 = 0;
}
public Variant(sbyte val) {
m_objref=null;
m_flags=CV_I1;
m_data1=(int)val;
m_data2=(int)(((long)val)>>32);
}
public Variant(byte val) {
m_objref=null;
m_flags=CV_U1;
m_data1=(int)val;
m_data2=0;
}
public Variant(short val) {
m_objref=null;
m_flags=CV_I2;
m_data1=(int)val;
m_data2=(int)(((long)val)>>32);
}
public Variant(ushort val) {
m_objref=null;
m_flags=CV_U2;
m_data1=(int)val;
m_data2=0;
}
public Variant(char val) {
m_objref=null;
m_flags=CV_CHAR;
m_data1=(int)val;
m_data2=0;
}
public Variant(int val) {
m_objref=null;
m_flags=CV_I4;
m_data1=val;
m_data2=val >> 31;
}
public Variant(uint val) {
m_objref=null;
m_flags=CV_U4;
m_data1=(int)val;
m_data2=0;
}
public Variant(long val) {
m_objref=null;
m_flags=CV_I8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
public Variant(ulong val) {
m_objref=null;
m_flags=CV_U8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
public Variant(float val) {
m_objref=null;
m_flags=CV_R4;
m_data1=0;
m_data2=0;
SetFieldsR4(val);
}
public Variant(double val) {
m_objref=null;
m_flags=CV_R8;
m_data1=0;
m_data2=0;
SetFieldsR8(val);
}
public Variant(DateTime val) {
m_objref=null;
m_flags=CV_DATETIME;
ulong ticks = (ulong)val.Ticks;
m_data1 = (int)ticks;
m_data2 = (int)(ticks>>32);
}
public Variant(Decimal val) {
m_objref = (Object)val;
m_flags = CV_DECIMAL;
m_data1=0;
m_data2=0;
}
public Variant(Object obj) {
m_data1=0;
m_data2=0;
VarEnum vt = VarEnum.VT_EMPTY;
if (obj is DateTime) {
m_objref=null;
m_flags=CV_DATETIME;
ulong ticks = (ulong)((DateTime)obj).Ticks;
m_data1 = (int)ticks;
m_data2 = (int)(ticks>>32);
return;
}
if (obj is String) {
m_flags=CV_STRING;
m_objref=obj;
return;
}
if (obj == null) {
this = Empty;
return;
}
if (obj == System.DBNull.Value) {
this = DBNull;
return;
}
if (obj == Type.Missing) {
this = Missing;
return;
}
if (obj is Array) {
m_flags=CV_OBJECT | ArrayBitMask;
m_objref=obj;
return;
}
// Compiler appeasement
m_flags = CV_EMPTY;
m_objref = null;
#if FEATURE_COMINTEROP
// Check to see if the object passed in is a wrapper object.
if (obj is UnknownWrapper)
{
vt = VarEnum.VT_UNKNOWN;
obj = ((UnknownWrapper)obj).WrappedObject;
}
else if (obj is DispatchWrapper)
{
vt = VarEnum.VT_DISPATCH;
obj = ((DispatchWrapper)obj).WrappedObject;
}
else if (obj is ErrorWrapper)
{
vt = VarEnum.VT_ERROR;
obj = (Object)(((ErrorWrapper)obj).ErrorCode);
BCLDebug.Assert(obj != null, "obj != null");
}
else if (obj is CurrencyWrapper)
{
vt = VarEnum.VT_CY;
obj = (Object)(((CurrencyWrapper)obj).WrappedObject);
BCLDebug.Assert(obj != null, "obj != null");
}
else if (obj is BStrWrapper)
{
vt = VarEnum.VT_BSTR;
obj = (Object)(((BStrWrapper)obj).WrappedObject);
}
#endif //FEATURE_COMINTEROP
if (obj != null)
{
SetFieldsObject(obj);
}
// If the object passed in is one of the wrappers then set the VARIANT type.
if (vt != VarEnum.VT_EMPTY)
m_flags |= ((int)vt << VTBitShift);
}
unsafe public Variant(void* voidPointer,Type pointerType) {
if (pointerType == null)
throw new ArgumentNullException("pointerType");
if (!pointerType.IsPointer)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"pointerType");
m_objref = pointerType;
m_flags=CV_PTR;
m_data1=(int)voidPointer;
m_data2=0;
}
//This is a family-only accessor for the CVType.
//This is never to be exposed externally.
internal int CVType {
get {
return (m_flags&TypeCodeBitMask);
}
}
public Object ToObject() {
switch (CVType) {
case CV_EMPTY:
return null;
case CV_BOOLEAN:
return (Object)(m_data1!=0);
case CV_I1:
return (Object)((sbyte)m_data1);
case CV_U1:
return (Object)((byte)m_data1);
case CV_CHAR:
return (Object)((char)m_data1);
case CV_I2:
return (Object)((short)m_data1);
case CV_U2:
return (Object)((ushort)m_data1);
case CV_I4:
return (Object)(m_data1);
case CV_U4:
return (Object)((uint)m_data1);
case CV_I8:
return (Object)(GetI8FromVar());
case CV_U8:
return (Object)((ulong)GetI8FromVar());
case CV_R4:
return (Object)(GetR4FromVar());
case CV_R8:
return (Object)(GetR8FromVar());
case CV_DATETIME:
return new DateTime(GetI8FromVar());
case CV_TIMESPAN:
return new TimeSpan(GetI8FromVar());
case CV_ENUM:
return BoxEnum();
case CV_MISSING:
return Type.Missing;
case CV_NULL:
return System.DBNull.Value;
case CV_DECIMAL:
case CV_STRING:
case CV_OBJECT:
default:
return m_objref;
}
}
// This routine will return an boxed enum.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object BoxEnum();
// Helper code for marshaling managed objects to VARIANT's (we use
// managed variants as an intermediate type.
internal static void MarshalHelperConvertObjectToVariant(Object o, ref Variant v)
{
IConvertible ic = System.Runtime.Remoting.RemotingServices.IsTransparentProxy(o) ? null : o as IConvertible;
if (o == null)
{
v = Empty;
}
else if (ic == null)
{
// This path should eventually go away. But until
// the work is done to have all of our wrapper types implement
// IConvertible, this is a cheapo way to get the work done.
v = new Variant(o);
}
else
{
IFormatProvider provider = CultureInfo.InvariantCulture;
switch (ic.GetTypeCode())
{
case TypeCode.Empty:
v = Empty;
break;
case TypeCode.Object:
v = new Variant((Object)o);
break;
case TypeCode.DBNull:
v = DBNull;
break;
case TypeCode.Boolean:
v = new Variant(ic.ToBoolean(provider));
break;
case TypeCode.Char:
v = new Variant(ic.ToChar(provider));
break;
case TypeCode.SByte:
v = new Variant(ic.ToSByte(provider));
break;
case TypeCode.Byte:
v = new Variant(ic.ToByte(provider));
break;
case TypeCode.Int16:
v = new Variant(ic.ToInt16(provider));
break;
case TypeCode.UInt16:
v = new Variant(ic.ToUInt16(provider));
break;
case TypeCode.Int32:
v = new Variant(ic.ToInt32(provider));
break;
case TypeCode.UInt32:
v = new Variant(ic.ToUInt32(provider));
break;
case TypeCode.Int64:
v = new Variant(ic.ToInt64(provider));
break;
case TypeCode.UInt64:
v = new Variant(ic.ToUInt64(provider));
break;
case TypeCode.Single:
v = new Variant(ic.ToSingle(provider));
break;
case TypeCode.Double:
v = new Variant(ic.ToDouble(provider));
break;
case TypeCode.Decimal:
v = new Variant(ic.ToDecimal(provider));
break;
case TypeCode.DateTime:
v = new Variant(ic.ToDateTime(provider));
break;
case TypeCode.String:
v = new Variant(ic.ToString(provider));
break;
default:
throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_UnknownTypeCode"), ic.GetTypeCode()));
}
}
}
// Helper code for marshaling VARIANTS to managed objects (we use
// managed variants as an intermediate type.
internal static Object MarshalHelperConvertVariantToObject(ref Variant v)
{
return v.ToObject();
}
// Helper code: on the back propagation path where a VT_BYREF VARIANT*
// is marshaled to a "ref Object", we use this helper to force the
// updated object back to the original type.
internal static void MarshalHelperCastVariant(Object pValue, int vt, ref Variant v)
{
IConvertible iv = pValue as IConvertible;
if (iv == null)
{
switch (vt)
{
#if FEATURE_COMINTEROP
case 9: /*VT_DISPATCH*/
v = new Variant(new DispatchWrapper(pValue));
break;
#endif
case 12: /*VT_VARIANT*/
v = new Variant(pValue);
break;
#if FEATURE_COMINTEROP
case 13: /*VT_UNKNOWN*/
v = new Variant(new UnknownWrapper(pValue));
break;
#endif
case 36: /*VT_RECORD*/
v = new Variant(pValue);
break;
case 8: /*VT_BSTR*/
if (pValue == null)
{
v = new Variant(null);
v.m_flags = CV_STRING;
}
else
{
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
break;
default:
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
}
else
{
IFormatProvider provider = CultureInfo.InvariantCulture;
switch (vt)
{
case 0: /*VT_EMPTY*/
v = Empty;
break;
case 1: /*VT_NULL*/
v = DBNull;
break;
case 2: /*VT_I2*/
v = new Variant(iv.ToInt16(provider));
break;
case 3: /*VT_I4*/
v = new Variant(iv.ToInt32(provider));
break;
case 4: /*VT_R4*/
v = new Variant(iv.ToSingle(provider));
break;
case 5: /*VT_R8*/
v = new Variant(iv.ToDouble(provider));
break;
#if FEATURE_COMINTEROP
case 6: /*VT_CY*/
v = new Variant(new CurrencyWrapper(iv.ToDecimal(provider)));
break;
#endif
case 7: /*VT_DATE*/
v = new Variant(iv.ToDateTime(provider));
break;
case 8: /*VT_BSTR*/
v = new Variant(iv.ToString(provider));
break;
#if FEATURE_COMINTEROP
case 9: /*VT_DISPATCH*/
v = new Variant(new DispatchWrapper((Object)iv));
break;
case 10: /*VT_ERROR*/
v = new Variant(new ErrorWrapper(iv.ToInt32(provider)));
break;
#endif
case 11: /*VT_BOOL*/
v = new Variant(iv.ToBoolean(provider));
break;
case 12: /*VT_VARIANT*/
v = new Variant((Object)iv);
break;
#if FEATURE_COMINTEROP
case 13: /*VT_UNKNOWN*/
v = new Variant(new UnknownWrapper((Object)iv));
break;
#endif
case 14: /*VT_DECIMAL*/
v = new Variant(iv.ToDecimal(provider));
break;
// case 15: /*unused*/
// NOT SUPPORTED
case 16: /*VT_I1*/
v = new Variant(iv.ToSByte(provider));
break;
case 17: /*VT_UI1*/
v = new Variant(iv.ToByte(provider));
break;
case 18: /*VT_UI2*/
v = new Variant(iv.ToUInt16(provider));
break;
case 19: /*VT_UI4*/
v = new Variant(iv.ToUInt32(provider));
break;
case 20: /*VT_I8*/
v = new Variant(iv.ToInt64(provider));
break;
case 21: /*VT_UI8*/
v = new Variant(iv.ToUInt64(provider));
break;
case 22: /*VT_INT*/
v = new Variant(iv.ToInt32(provider));
break;
case 23: /*VT_UINT*/
v = new Variant(iv.ToUInt32(provider));
break;
default:
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: Variant
**
**
** Purpose: The CLR implementation of Variant.
**
**
===========================================================*/
namespace System {
using System;
using System.Reflection;
using System.Threading;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Runtime.CompilerServices;
[Serializable()]
[StructLayout(LayoutKind.Sequential)]
internal struct Variant {
//Do Not change the order of these fields.
//They are mapped to the native VariantData * data structure.
private Object m_objref;
private int m_data1;
private int m_data2;
private int m_flags;
// The following will call the internal routines to initalize the
// native side of variant.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void InitVariant();
static Variant() {
InitVariant();
}
private static Type _voidPtr = null;
// The following bits have been taken up as follows
// bits 0-15 - Type code
// bit 16 - Array
// bits 19-23 - Enums
// bits 24-31 - Optional VT code (for roundtrip VT preservation)
//What are the consequences of making this an enum?
///////////////////////////////////////////////////////////////////////
// If you update this, update the corresponding stuff in OAVariantLib.cs,
// COMOAVariant.cpp (2 tables, forwards and reverse), and perhaps OleVariant.h
///////////////////////////////////////////////////////////////////////
internal const int CV_EMPTY=0x0;
internal const int CV_VOID=0x1;
internal const int CV_BOOLEAN=0x2;
internal const int CV_CHAR=0x3;
internal const int CV_I1=0x4;
internal const int CV_U1=0x5;
internal const int CV_I2=0x6;
internal const int CV_U2=0x7;
internal const int CV_I4=0x8;
internal const int CV_U4=0x9;
internal const int CV_I8=0xa;
internal const int CV_U8=0xb;
internal const int CV_R4=0xc;
internal const int CV_R8=0xd;
internal const int CV_STRING=0xe;
internal const int CV_PTR=0xf;
internal const int CV_DATETIME = 0x10;
internal const int CV_TIMESPAN = 0x11;
internal const int CV_OBJECT=0x12;
internal const int CV_DECIMAL = 0x13;
internal const int CV_ENUM=0x15;
internal const int CV_MISSING=0x16;
internal const int CV_NULL=0x17;
internal const int CV_LAST=0x18;
internal const int TypeCodeBitMask=0xffff;
internal const int VTBitMask=unchecked((int)0xff000000);
internal const int VTBitShift=24;
internal const int ArrayBitMask =0x10000;
// Enum enum and Mask
internal const int EnumI1 =0x100000;
internal const int EnumU1 =0x200000;
internal const int EnumI2 =0x300000;
internal const int EnumU2 =0x400000;
internal const int EnumI4 =0x500000;
internal const int EnumU4 =0x600000;
internal const int EnumI8 =0x700000;
internal const int EnumU8 =0x800000;
internal const int EnumMask =0xF00000;
internal static readonly Type [] ClassTypes = {
typeof(System.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), // ptr for the moment
typeof(DateTime),
typeof(TimeSpan),
typeof(Object),
typeof(Decimal),
typeof(Object), // Treat enum as Object
typeof(System.Reflection.Missing),
typeof(System.DBNull),
};
internal static readonly Variant Empty = new Variant();
internal static readonly Variant Missing = new Variant(Variant.CV_MISSING, Type.Missing, 0, 0);
internal static readonly Variant DBNull = new Variant(Variant.CV_NULL, System.DBNull.Value, 0, 0);
//
// Native Methods
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern double GetR8FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern float GetR4FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR4(float val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR8(double val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsObject(Object val);
// Use this function instead of an ECALL - saves about 150 clock cycles
// by avoiding the ecall transition and because the JIT inlines this.
// Ends up only taking about 1/8 the time of the ECALL version.
internal long GetI8FromVar()
{
return ((long)m_data2<<32 | ((long)m_data1 & 0xFFFFFFFFL));
}
//
// Constructors
//
internal Variant(int flags, Object or, int data1, int data2) {
m_flags = flags;
m_objref=or;
m_data1=data1;
m_data2=data2;
}
public Variant(bool val) {
m_objref= null;
m_flags = CV_BOOLEAN;
m_data1 = (val)?Boolean.True:Boolean.False;
m_data2 = 0;
}
public Variant(sbyte val) {
m_objref=null;
m_flags=CV_I1;
m_data1=(int)val;
m_data2=(int)(((long)val)>>32);
}
public Variant(byte val) {
m_objref=null;
m_flags=CV_U1;
m_data1=(int)val;
m_data2=0;
}
public Variant(short val) {
m_objref=null;
m_flags=CV_I2;
m_data1=(int)val;
m_data2=(int)(((long)val)>>32);
}
public Variant(ushort val) {
m_objref=null;
m_flags=CV_U2;
m_data1=(int)val;
m_data2=0;
}
public Variant(char val) {
m_objref=null;
m_flags=CV_CHAR;
m_data1=(int)val;
m_data2=0;
}
public Variant(int val) {
m_objref=null;
m_flags=CV_I4;
m_data1=val;
m_data2=val >> 31;
}
public Variant(uint val) {
m_objref=null;
m_flags=CV_U4;
m_data1=(int)val;
m_data2=0;
}
public Variant(long val) {
m_objref=null;
m_flags=CV_I8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
public Variant(ulong val) {
m_objref=null;
m_flags=CV_U8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
public Variant(float val) {
m_objref=null;
m_flags=CV_R4;
m_data1=0;
m_data2=0;
SetFieldsR4(val);
}
public Variant(double val) {
m_objref=null;
m_flags=CV_R8;
m_data1=0;
m_data2=0;
SetFieldsR8(val);
}
public Variant(DateTime val) {
m_objref=null;
m_flags=CV_DATETIME;
ulong ticks = (ulong)val.Ticks;
m_data1 = (int)ticks;
m_data2 = (int)(ticks>>32);
}
public Variant(Decimal val) {
m_objref = (Object)val;
m_flags = CV_DECIMAL;
m_data1=0;
m_data2=0;
}
public Variant(Object obj) {
m_data1=0;
m_data2=0;
VarEnum vt = VarEnum.VT_EMPTY;
if (obj is DateTime) {
m_objref=null;
m_flags=CV_DATETIME;
ulong ticks = (ulong)((DateTime)obj).Ticks;
m_data1 = (int)ticks;
m_data2 = (int)(ticks>>32);
return;
}
if (obj is String) {
m_flags=CV_STRING;
m_objref=obj;
return;
}
if (obj == null) {
this = Empty;
return;
}
if (obj == System.DBNull.Value) {
this = DBNull;
return;
}
if (obj == Type.Missing) {
this = Missing;
return;
}
if (obj is Array) {
m_flags=CV_OBJECT | ArrayBitMask;
m_objref=obj;
return;
}
// Compiler appeasement
m_flags = CV_EMPTY;
m_objref = null;
#if FEATURE_COMINTEROP
// Check to see if the object passed in is a wrapper object.
if (obj is UnknownWrapper)
{
vt = VarEnum.VT_UNKNOWN;
obj = ((UnknownWrapper)obj).WrappedObject;
}
else if (obj is DispatchWrapper)
{
vt = VarEnum.VT_DISPATCH;
obj = ((DispatchWrapper)obj).WrappedObject;
}
else if (obj is ErrorWrapper)
{
vt = VarEnum.VT_ERROR;
obj = (Object)(((ErrorWrapper)obj).ErrorCode);
BCLDebug.Assert(obj != null, "obj != null");
}
else if (obj is CurrencyWrapper)
{
vt = VarEnum.VT_CY;
obj = (Object)(((CurrencyWrapper)obj).WrappedObject);
BCLDebug.Assert(obj != null, "obj != null");
}
else if (obj is BStrWrapper)
{
vt = VarEnum.VT_BSTR;
obj = (Object)(((BStrWrapper)obj).WrappedObject);
}
#endif //FEATURE_COMINTEROP
if (obj != null)
{
SetFieldsObject(obj);
}
// If the object passed in is one of the wrappers then set the VARIANT type.
if (vt != VarEnum.VT_EMPTY)
m_flags |= ((int)vt << VTBitShift);
}
unsafe public Variant(void* voidPointer,Type pointerType) {
if (pointerType == null)
throw new ArgumentNullException("pointerType");
if (!pointerType.IsPointer)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"pointerType");
m_objref = pointerType;
m_flags=CV_PTR;
m_data1=(int)voidPointer;
m_data2=0;
}
//This is a family-only accessor for the CVType.
//This is never to be exposed externally.
internal int CVType {
get {
return (m_flags&TypeCodeBitMask);
}
}
public Object ToObject() {
switch (CVType) {
case CV_EMPTY:
return null;
case CV_BOOLEAN:
return (Object)(m_data1!=0);
case CV_I1:
return (Object)((sbyte)m_data1);
case CV_U1:
return (Object)((byte)m_data1);
case CV_CHAR:
return (Object)((char)m_data1);
case CV_I2:
return (Object)((short)m_data1);
case CV_U2:
return (Object)((ushort)m_data1);
case CV_I4:
return (Object)(m_data1);
case CV_U4:
return (Object)((uint)m_data1);
case CV_I8:
return (Object)(GetI8FromVar());
case CV_U8:
return (Object)((ulong)GetI8FromVar());
case CV_R4:
return (Object)(GetR4FromVar());
case CV_R8:
return (Object)(GetR8FromVar());
case CV_DATETIME:
return new DateTime(GetI8FromVar());
case CV_TIMESPAN:
return new TimeSpan(GetI8FromVar());
case CV_ENUM:
return BoxEnum();
case CV_MISSING:
return Type.Missing;
case CV_NULL:
return System.DBNull.Value;
case CV_DECIMAL:
case CV_STRING:
case CV_OBJECT:
default:
return m_objref;
}
}
// This routine will return an boxed enum.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object BoxEnum();
// Helper code for marshaling managed objects to VARIANT's (we use
// managed variants as an intermediate type.
internal static void MarshalHelperConvertObjectToVariant(Object o, ref Variant v)
{
IConvertible ic = System.Runtime.Remoting.RemotingServices.IsTransparentProxy(o) ? null : o as IConvertible;
if (o == null)
{
v = Empty;
}
else if (ic == null)
{
// This path should eventually go away. But until
// the work is done to have all of our wrapper types implement
// IConvertible, this is a cheapo way to get the work done.
v = new Variant(o);
}
else
{
IFormatProvider provider = CultureInfo.InvariantCulture;
switch (ic.GetTypeCode())
{
case TypeCode.Empty:
v = Empty;
break;
case TypeCode.Object:
v = new Variant((Object)o);
break;
case TypeCode.DBNull:
v = DBNull;
break;
case TypeCode.Boolean:
v = new Variant(ic.ToBoolean(provider));
break;
case TypeCode.Char:
v = new Variant(ic.ToChar(provider));
break;
case TypeCode.SByte:
v = new Variant(ic.ToSByte(provider));
break;
case TypeCode.Byte:
v = new Variant(ic.ToByte(provider));
break;
case TypeCode.Int16:
v = new Variant(ic.ToInt16(provider));
break;
case TypeCode.UInt16:
v = new Variant(ic.ToUInt16(provider));
break;
case TypeCode.Int32:
v = new Variant(ic.ToInt32(provider));
break;
case TypeCode.UInt32:
v = new Variant(ic.ToUInt32(provider));
break;
case TypeCode.Int64:
v = new Variant(ic.ToInt64(provider));
break;
case TypeCode.UInt64:
v = new Variant(ic.ToUInt64(provider));
break;
case TypeCode.Single:
v = new Variant(ic.ToSingle(provider));
break;
case TypeCode.Double:
v = new Variant(ic.ToDouble(provider));
break;
case TypeCode.Decimal:
v = new Variant(ic.ToDecimal(provider));
break;
case TypeCode.DateTime:
v = new Variant(ic.ToDateTime(provider));
break;
case TypeCode.String:
v = new Variant(ic.ToString(provider));
break;
default:
throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_UnknownTypeCode"), ic.GetTypeCode()));
}
}
}
// Helper code for marshaling VARIANTS to managed objects (we use
// managed variants as an intermediate type.
internal static Object MarshalHelperConvertVariantToObject(ref Variant v)
{
return v.ToObject();
}
// Helper code: on the back propagation path where a VT_BYREF VARIANT*
// is marshaled to a "ref Object", we use this helper to force the
// updated object back to the original type.
internal static void MarshalHelperCastVariant(Object pValue, int vt, ref Variant v)
{
IConvertible iv = pValue as IConvertible;
if (iv == null)
{
switch (vt)
{
#if FEATURE_COMINTEROP
case 9: /*VT_DISPATCH*/
v = new Variant(new DispatchWrapper(pValue));
break;
#endif
case 12: /*VT_VARIANT*/
v = new Variant(pValue);
break;
#if FEATURE_COMINTEROP
case 13: /*VT_UNKNOWN*/
v = new Variant(new UnknownWrapper(pValue));
break;
#endif
case 36: /*VT_RECORD*/
v = new Variant(pValue);
break;
case 8: /*VT_BSTR*/
if (pValue == null)
{
v = new Variant(null);
v.m_flags = CV_STRING;
}
else
{
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
break;
default:
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
}
else
{
IFormatProvider provider = CultureInfo.InvariantCulture;
switch (vt)
{
case 0: /*VT_EMPTY*/
v = Empty;
break;
case 1: /*VT_NULL*/
v = DBNull;
break;
case 2: /*VT_I2*/
v = new Variant(iv.ToInt16(provider));
break;
case 3: /*VT_I4*/
v = new Variant(iv.ToInt32(provider));
break;
case 4: /*VT_R4*/
v = new Variant(iv.ToSingle(provider));
break;
case 5: /*VT_R8*/
v = new Variant(iv.ToDouble(provider));
break;
#if FEATURE_COMINTEROP
case 6: /*VT_CY*/
v = new Variant(new CurrencyWrapper(iv.ToDecimal(provider)));
break;
#endif
case 7: /*VT_DATE*/
v = new Variant(iv.ToDateTime(provider));
break;
case 8: /*VT_BSTR*/
v = new Variant(iv.ToString(provider));
break;
#if FEATURE_COMINTEROP
case 9: /*VT_DISPATCH*/
v = new Variant(new DispatchWrapper((Object)iv));
break;
case 10: /*VT_ERROR*/
v = new Variant(new ErrorWrapper(iv.ToInt32(provider)));
break;
#endif
case 11: /*VT_BOOL*/
v = new Variant(iv.ToBoolean(provider));
break;
case 12: /*VT_VARIANT*/
v = new Variant((Object)iv);
break;
#if FEATURE_COMINTEROP
case 13: /*VT_UNKNOWN*/
v = new Variant(new UnknownWrapper((Object)iv));
break;
#endif
case 14: /*VT_DECIMAL*/
v = new Variant(iv.ToDecimal(provider));
break;
// case 15: /*unused*/
// NOT SUPPORTED
case 16: /*VT_I1*/
v = new Variant(iv.ToSByte(provider));
break;
case 17: /*VT_UI1*/
v = new Variant(iv.ToByte(provider));
break;
case 18: /*VT_UI2*/
v = new Variant(iv.ToUInt16(provider));
break;
case 19: /*VT_UI4*/
v = new Variant(iv.ToUInt32(provider));
break;
case 20: /*VT_I8*/
v = new Variant(iv.ToInt64(provider));
break;
case 21: /*VT_UI8*/
v = new Variant(iv.ToUInt64(provider));
break;
case 22: /*VT_INT*/
v = new Variant(iv.ToInt32(provider));
break;
case 23: /*VT_UINT*/
v = new Variant(iv.ToUInt32(provider));
break;
default:
throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant")));
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CommunicationException.cs
- XmlArrayAttribute.cs
- PageSettings.cs
- MsmqPoisonMessageException.cs
- ReflectionTypeLoadException.cs
- HttpProfileGroupBase.cs
- ConfigXmlCDataSection.cs
- Select.cs
- WebBrowserHelper.cs
- CapabilitiesSection.cs
- CrossSiteScriptingValidation.cs
- uribuilder.cs
- GenericRootAutomationPeer.cs
- ServicePoint.cs
- ValueUtilsSmi.cs
- XPathNodeInfoAtom.cs
- UnionExpr.cs
- _LazyAsyncResult.cs
- XmlHierarchicalEnumerable.cs
- __ComObject.cs
- NotifyParentPropertyAttribute.cs
- XmlSignatureManifest.cs
- CompModSwitches.cs
- TypeUtil.cs
- ResolveResponse.cs
- WebPartTracker.cs
- RegexStringValidatorAttribute.cs
- SqlXmlStorage.cs
- IHttpResponseInternal.cs
- PermissionListSet.cs
- XomlCompiler.cs
- InputLanguage.cs
- control.ime.cs
- DataKey.cs
- SmtpNetworkElement.cs
- PreservationFileReader.cs
- XomlCompilerError.cs
- LiteralControl.cs
- AttributeUsageAttribute.cs
- EUCJPEncoding.cs
- ResourceManagerWrapper.cs
- SQLBinaryStorage.cs
- MarkupProperty.cs
- PageEventArgs.cs
- ProfileManager.cs
- ChannelRequirements.cs
- Compiler.cs
- MultipleViewProviderWrapper.cs
- DbModificationCommandTree.cs
- NetTcpBinding.cs
- CodeMemberMethod.cs
- TextServicesPropertyRanges.cs
- IHttpResponseInternal.cs
- PropertyDescriptorCollection.cs
- PolicyImporterElement.cs
- XpsColorContext.cs
- SimpleHandlerBuildProvider.cs
- DbXmlEnabledProviderManifest.cs
- BufferModesCollection.cs
- InitializerFacet.cs
- PanelDesigner.cs
- ToolTip.cs
- PartialToken.cs
- GlyphRun.cs
- TextContainerHelper.cs
- MsmqChannelFactoryBase.cs
- TextBoxAutomationPeer.cs
- WeakRefEnumerator.cs
- ReaderContextStackData.cs
- DependencyPropertyDescriptor.cs
- QuerySettings.cs
- SafeProcessHandle.cs
- GeometryValueSerializer.cs
- ConcurrentQueue.cs
- DataGridState.cs
- RequestTimeoutManager.cs
- DoubleLinkList.cs
- WebPartDescription.cs
- HandlerWithFactory.cs
- WindowsListViewGroup.cs
- ZipPackage.cs
- ColumnClickEvent.cs
- HttpConfigurationSystem.cs
- HTMLTagNameToTypeMapper.cs
- ObjectDataSourceView.cs
- XamlTreeBuilderBamlRecordWriter.cs
- LassoHelper.cs
- CompensateDesigner.cs
- ToolStripPanelCell.cs
- TransportContext.cs
- WebZone.cs
- SQLInt16.cs
- IItemProperties.cs
- FormViewModeEventArgs.cs
- PolyQuadraticBezierSegment.cs
- ExtensibleClassFactory.cs
- SimpleExpression.cs
- ArgumentNullException.cs
- SqlDataReaderSmi.cs
- XPathNode.cs